diff --git a/Dockerfile b/Dockerfile index 7c66bf3..a55bd37 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,13 +23,13 @@ RUN wget https://download.oracle.com/otn_software/linux/instantclient/instantcli && rm -f instantclient-basiclite-linuxx64.zip \ && unzip instantclient-sdk-linuxx64.zip \ && rm -f instantclient-sdk-linuxx64.zip \ - && cd /opt/oracle/instantclient* \ + && cd /opt/oracle/instantclient_* \ && rm -f *jdbc* *occi* *mysql* *README *jar uidrvci genezi adrci \ - && echo /opt/oracle/instantclient* > /etc/ld.so.conf.d/oracle-instantclient.conf \ + && echo /opt/oracle/instantclient_* > /etc/ld.so.conf.d/oracle-instantclient.conf \ && ldconfig RUN git clone --branch 5.3 https://github.com/oracle/python-cx_Oracle \ - && cd python-cx_Oracle && export ORACLE_HOME=/opt/oracle/instantclient_19_6 && python2 setup.py build && python2 setup.py install + && cd python-cx_Oracle && export ORACLE_HOME=$(echo /opt/oracle/instantclient_*) && python2 setup.py build && python2 setup.py install # xfreerdp (see https://github.com/FreeRDP/FreeRDP/wiki/Compilation) RUN apt-get update && apt-get install -y ninja-build build-essential git-core debhelper cdbs dpkg-dev autotools-dev cmake pkg-config xmlto libssl-dev docbook-xsl xsltproc libxkbfile-dev libx11-dev libwayland-dev libxrandr-dev libxi-dev libxrender-dev libxext-dev libxinerama-dev libxfixes-dev libxcursor-dev libxv-dev libxdamage-dev libxtst-dev libcups2-dev libpcsclite-dev libasound2-dev libpulse-dev libjpeg-dev libgsm1-dev libusb-1.0-0-dev libudev-dev libdbus-glib-1-dev uuid-dev libxml2-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libfaad-dev libfaac-dev \ diff --git a/README.md b/README.md index 9f37fdb..0e15175 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ Currently it supports the following modules: * pop_passd : Brute-force poppassd (not POP3) * imap_login : Brute-force IMAP * ldap_login : Brute-force LDAP +* dcom_login : Brute-force DCOM * smb_login : Brute-force SMB * smb_lookupsid : Brute-force SMB SID-lookup * rlogin_login : Brute-force rlogin diff --git a/docker-compose.yml b/docker-compose.yml index df8a123..02763dc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ services: unix: build: testing/unix image: patator-unix-testing -# ports: +# ports: # - "21:21" # - "22:22" # - "23:23" @@ -26,6 +26,7 @@ services: # - "5900:5900" # - "8009:8009" # - "8080:8080" +# - "161:161/udp" volumes: - .:/opt/patator @@ -51,5 +52,8 @@ services: - unix - oracle - mssql + environment: + - DISPLAY volumes: - .:/opt/patator + - /tmp/.X11-unix:/tmp/.X11-unix diff --git a/patator.py b/patator.py index 18f2abe..684c32d 100755 --- a/patator.py +++ b/patator.py @@ -2931,7 +2931,7 @@ class LDAP_login: code = p.returncode mesg = (out + err).strip() - trace = '[out]\n%s\n[err]\n%s' % (out, err) + trace = '%s\n[out]\n%s\n[err]\n%s\n' % (' '.join(cmd), out, err) return self.Response(code, mesg, timing, trace) @@ -4179,7 +4179,7 @@ class RDP_login: err = 'OK' mesg = (out + err).strip() - trace = '[out]\n%s\n[err]\n%s' % (out, err) + trace = '%s\n[out]\n%s\n[err]\n%s\n' % (' '.join(cmd), out, err) return self.Response(code, mesg, timing, trace) @@ -4681,7 +4681,13 @@ class DNS_forward: # SNMP {{{ try: - from pysnmp.entity.rfc3413.oneliner import cmdgen + from pysnmp.hlapi import getCmd, SnmpEngine, CommunityData, UsmUserData + from pysnmp.hlapi import UdpTransportTarget, ContextData, ObjectType, ObjectIdentity + from pysnmp.hlapi import usmHMACMD5AuthProtocol, usmHMACSHAAuthProtocol, usmHMAC384SHA512AuthProtocol + from pysnmp.hlapi import usmDESPrivProtocol, usmAesCfb128Protocol + + SNMP_AUTHPROTO = {'md5': usmHMACMD5AuthProtocol, 'sha': usmHMACSHAAuthProtocol, 'sha512': usmHMAC384SHA512AuthProtocol} + SNMP_PRIVPROTO = {'des': usmDESPrivProtocol, 'aes': usmAesCfb128Protocol} except ImportError: notfound.append('pysnmp') @@ -4703,13 +4709,12 @@ class SNMP_login: ('host', 'target host'), ('port', 'target port [161]'), ('version', 'SNMP version to use [2|3|1]'), - #('security_name', 'SNMP v1/v2 username, for most purposes it can be any arbitrary string [test-agent]'), ('community', 'SNMPv1/2c community names to test [public]'), - ('user', 'SNMPv3 usernames to test [myuser]'), - ('auth_key', 'SNMPv3 pass-phrases to test [my_password]'), - #('priv_key', 'SNMP v3 secret key for encryption'), # see http://pysnmp.sourceforge.net/docs/4.x/index.html#UsmUserData - #('auth_protocol', ''), - #('priv_protocol', ''), + ('user', 'SNMPv3 usernames to test [op5user]'), + ('auth_key', 'SNMPv3 passwords to test [authPass]'), + ('auth_proto', 'SNMPv3 authentication protocol [md5|sha|sha512]'), + ('priv_key', 'SNMPv3 encryption key'), + ('priv_proto', 'SNMPv3 encryption protocol [des|aes]'), ('timeout', 'seconds to wait for a response [1]'), ('retries', 'number of successive request retries [2]'), ) @@ -4717,32 +4722,48 @@ class SNMP_login: Response = Response_Base - def execute(self, host, port=None, version='2', community='public', user='myuser', auth_key='my_password', timeout='1', retries='2'): - if version in ('1', '2'): - security_model = cmdgen.CommunityData('test-agent', community, 0 if version == '1' else 1) + def execute(self, host, port=None, version='2', community='public', user='op5user', auth_key='authPass', auth_proto='md5', priv_key='', priv_proto='des', timeout='1', retries='2'): + if version in ('1', '2', '2c'): + security_model = CommunityData(community, mpModel=0 if version == '1' else 1) elif version == '3': - security_model = cmdgen.UsmUserData(user, auth_key) # , priv_key) - if len(auth_key) < 8: - return self.Response('1', 'SNMPv3 requires passphrases to be at least 8 characters long') + if auth_proto not in SNMP_AUTHPROTO: + raise ValueError('Unsupported SNMPv3 auth protocol %r' % auth_proto) + if priv_proto not in SNMP_PRIVPROTO: + raise ValueError('Unsupported SNMPv3 priv protocol %r' % priv_proto) + + if len(auth_key) < 8 or priv_key and len(priv_key) < 8: + return self.Response('1', 'SNMPv3 requires passwords to be at least 8 characters long') + + kwargs = dict(authKey=auth_key, authProtocol=SNMP_AUTHPROTO[auth_proto]) + if priv_key: + kwargs.update(dict(privKey=priv_key, privProtocol=SNMP_PRIVPROTO[priv_proto])) + + security_model = UsmUserData(user, **kwargs) else: raise ValueError('Incorrect SNMP version %r' % version) with Timing() as timing: - errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd( - security_model, - cmdgen.UdpTransportTarget((host, int(port or 161)), timeout=int(timeout), retries=int(retries)), - (1, 3, 6, 1, 2, 1, 1, 1, 0) + errorIndication, errorStatus, errorIndex, varBinds = next( + getCmd( + SnmpEngine(), + security_model, + UdpTransportTarget((host, int(port or 161)), timeout=int(timeout), retries=int(retries)), + ContextData(), + ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0))) #(1, 3, 6, 1, 2, 1, 1, 1, 0) ) - code = '%d-%d' % (errorStatus, errorIndex) - if not errorIndication: - mesg = '%s' % varBinds - else: + if errorIndication: mesg = '%s' % errorIndication + elif errorStatus: + mesg = '%s' % (errorStatus.prettyPrint()) + if errorIndex > 0: + mesg += ' %s' % varBinds[int(errorIndex) - 1][0] + else: + mesg = ''.join(' = '.join([x.prettyPrint() for x in varBind]) for varBind in varBinds) - return self.Response(code, mesg, timing) + return self.Response(int(errorStatus), mesg, timing) # }}} @@ -4856,7 +4877,7 @@ class IKE_enum: out, err = map(B, p.communicate()) code = p.returncode - trace = '%s\n[out]\n%s\n[err]\n%s' % (cmd, out, err) + trace = '%s\n[out]\n%s\n[err]\n%s\n' % (' '.join(cmd), out, err) logger.debug('trace: %r' % trace) has_sa = 'SA=(' in out @@ -4907,7 +4928,7 @@ class Unzip_pass: code = p.returncode mesg = out.strip() - trace = '%s\n[out]\n%s\n[err]\n%s' % (cmd, out, err) + trace = '%s\n[out]\n%s\n[err]\n%s\n' % (' '.join(cmd), out, err) return self.Response(code, mesg, timing, trace) @@ -4944,7 +4965,7 @@ class Keystore_pass: code = p.returncode mesg = out.strip() - trace = '%s\n[out]\n%s\n[err]\n%s' % (cmd, out, err) + trace = '%s\n[out]\n%s\n[err]\n%s\n' % (' '.join(cmd), out, err) return self.Response(code, mesg, timing, trace) diff --git a/run-tests.sh b/run-tests.sh index 39f419a..c4123ad 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -1,6 +1,6 @@ #!/bin/bash -if ! type docker-compose 2>/dev/null; then +if ! type docker-compose &>/dev/null; then echo 'docker-compose is required' exit 1 fi @@ -22,6 +22,8 @@ esac UNIX='unix' ORACLE='oracle' MSSQL='mssql' +WIN10='' # vagrant add senglin/win-7-enterprise +VPN='' # LOGS='-l ./asdf -y --hits ./hits.txt' @@ -29,7 +31,7 @@ run() { echo echo "$ $@" - docker-compose run --rm --entrypoint "$PYTHON patator.py" patator "$@" + docker-compose run --no-deps --rm --entrypoint "$PYTHON patator.py" patator "$@" } echo @@ -62,6 +64,16 @@ run ldap_login host=$UNIX binddn='cn=admin,dc=example,dc=com' bindpw=PasswordRAN run smb_login host=$UNIX run smb_login host=$UNIX user=userRANGE0 password=PasswordRANGE0 0=int:0-9 +if [[ ! -z $WIN10 ]]; then + run smb_login host=$WIN10 user=vagranRANGE0 password=vagranRANGE0 0=lower:r-v + run smb_lookupsid host=$WIN10 user=vagrant password=vagrant rid=RANGE0 0=int:500-2000 -x ignore:code=1 + run dcom_login host=$WIN10 user=vagranRANGE0 password=vagranRANGE0 0=lower:r-v + + xhost +si:localuser:root + run rdp_login host=$WIN10 user=vagranRANGE0 password=vagranRANGE0 0=lower:r-v + xhost -si:localuser:root +fi + run pop_login host=$UNIX run pop_login host=$UNIX user=userRANGE0 password=PasswordRANGE0 0=int:0-9 @@ -97,6 +109,15 @@ run vnc_login host=$UNIX port=5900 password=PassworRANGE0 0=lower:a-f run dns_reverse host=NET0 0=216.239.32.0-216.239.32.255,8.8.8.0/24 -x ignore:code=3 -x ignore:fgrep!=google.com -x ignore:fgrep=216-239- run dns_forward name=MOD0.microsoft.com 0=SRV qtype=SRV -x ignore:code=3 --auto-progress 15 +run snmp_login host=$UNIX community=publiRANGE0 0=lower:a-f +run snmp_login host=$UNIX community=public version=3 user=userRANGE0 0=int:0-5 auth_key=whatever +run snmp_login host=$UNIX community=public version=3 user=user3 auth_proto=sha auth_key=authPasRANGE0 0=lower:q-v +run snmp_login host=$UNIX community=public version=3 user=user3 auth_proto=sha auth_key=authPass priv_proto=aes priv_key=privPasRANGE0 0=lower:q-v + +if [[ ! -z $VPN ]]; then + run ike_enum host=$VPN transform=MOD0 0=TRANS aggressive=RANGE1 1=int:0-1 -x ignore:fgrep=NO-PROPOSAL +fi + run unzip_pass zipfile=enc.zip password=PasswordRANGE0 0=int:0-9 run keystore_pass keystore=keystore.jks password=PasswordRANGE0 0=int:0-9 run sqlcipher_pass database=enc.db password=PasswordRANGE0 0=int:0-9 diff --git a/testing/unix/Dockerfile b/testing/unix/Dockerfile index d4c1d6a..a1a027b 100644 --- a/testing/unix/Dockerfile +++ b/testing/unix/Dockerfile @@ -96,6 +96,11 @@ RUN apt-get update && apt-get install -y samba \ && { for i in {3..5}; do echo -e "Password$i\nPassword$i" | smbpasswd -a "user$i"; done; } \ && sed -ie 's,map to guest =,#map to guest =,' /etc/samba/smb.conf +RUN apt-get update && apt-get install -y snmpd snmp \ + && sed -ie 's,agentAddress udp:127.0.0.1:161,agentAddress udp:161,' /etc/snmp/snmpd.conf \ + && echo 'createUser user3 SHA authPass AES privPass' >> /var/lib/snmp/snmpd.conf \ + && echo 'rouser user3 priv .1' >> /etc/snmp/snmpd.conf + RUN echo -e "echo Starting services\n\ service vsftpd start\n\ service ssh start\n\ @@ -112,6 +117,7 @@ socat tcp-l:4444,fork,reuseaddr exec:\"echo -e 'W\xe1\xc0me'\" &\n\ cp -v /root/enc.zip /root/keystore.jks /root/enc.db /root/umbraco_users.pw /opt/patator/\n\ su - vncuser -c 'vncserver -rfbport 5900'\n\ service smbd start\n\ +service snmpd start\n\ tail -f /dev/null\n" > /usr/local/sbin/start-all-services.sh CMD ["bash", "/usr/local/sbin/start-all-services.sh"]