Patator Brute Forcer 0.5 - multi-purpose brute-forcer

Patator is a multi-purpose brute-forcer, with a modular design and a flexible usage.

Currently it supports the following modules:
- ftp_login : Brute-force FTP
- ssh_login : Brute-force SSH
- telnet_login : Brute-force Telnet
- smtp_login : Brute-force SMTP
- smtp_vrfy : Enumerate valid users using the SMTP 'VRFY' command
- smtp_rcpt : Enumerate valid users using the SMTP 'RCPT TO' command
- finger_lookup : Enumerate valid users using Finger
- http_fuzz : Brute-force HTTP
- pop_login : Brute-force POP3
- pop_passd : Brute-force poppassd (http://netwinsite.com/poppassd/)
- imap_login : Brute-force IMAP4
- ldap_login : Brute-force LDAP
- smb_login : Brute-force SMB
- smb_lookupsid : Brute-force SMB SID-lookup
- vmauthd_login : Brute-force VMware Authentication Daemon
- mssql_login : Brute-force MSSQL
- oracle_login : Brute-force Oracle
- mysql_login : Brute-force MySQL
- mysql_queries : Brute-force MySQL queries
- pgsql_login : Brute-force PostgreSQL
- vnc_login : Brute-force VNC
- dns_forward : Brute-force DNS
- dns_reverse : Brute-force DNS (reverse lookup subnets)
- snmp_login : Brute-force SNMPv1/2 and SNMPv3

- unzip_pass : Brute-force the password of encrypted ZIP files
- keystore_pass : Brute-force the password of Java keystore files

Future modules to be implemented:
- rdp_login

The name "Patator" comes from http://www.youtube.com/watch?v=xoBkBvnTTjo
"Whatever the payload to fire, always use the same cannon"

* Why ?

Basically, I got tired of using Medusa, Hydra, Ncrack, Metasploit auxiliary modules, Nmap NSE scripts and the like because:
- they either do not work or are not reliable (got me false negatives several times in the past)
- they are not flexible enough (how to iterate over all wordlists, fuzz any module parameter)
- they lack useful features (display progress or pause during execution)

FEATURES
--------
* No false negatives, as it is the user that decides what results to ignore based on:
+ status code of response
+ size of response
+ matching string or regex in response data
+ ... see --help

* Modular design
+ not limited to network modules (eg. the unzip_pass module)
+ not limited to brute-forcing (eg. remote exploit testing, or vulnerable version probing)

* Interactive runtime
+ show progress during execution (press Enter)
+ pause/unpause execution (press p)
+ increase/decrease verbosity
+ add new actions & conditions during runtime (eg. to exclude more types of response from showing)
+ ... press h to see all available interactive commands

* Use persistent connections (ie. will test several passwords until the server disconnects)

* Multi-threaded

* Flexible user input
- Any module parameter can be fuzzed:
+ use the FILE keyword to iterate over a file
+ use the COMBO keyword to iterate over a combo file
+ use the NET keyword to iterate over every hosts of a network subnet
+ use the RANGE keyword to iterate over hexadecimal, decimal or alphabetical ranges
+ use the PROG keyword to iterage over the output of an external program

- Iteration over the joined wordlists can be done in any order

* Save every response (along with request) to seperate log files for later reviewing


INSTALL

* Dependencies (best tested versions)

| Required for | URL | Version |
--------------------------------------------------------------------------------------------------
paramiko | SSH | http://www.lag.net/paramiko/ | 1.7.7.1 |
--------------------------------------------------------------------------------------------------
pycurl | HTTP | http://pycurl.sourceforge.net/ | 7.19.0 |
--------------------------------------------------------------------------------------------------
openldap | LDAP | http://www.openldap.org/ | 2.4.24 |
--------------------------------------------------------------------------------------------------
impacket | SMB | http://code.google.com/p/impacket/ | svn#765 |
--------------------------------------------------------------------------------------------------
cx_Oracle | Oracle | http://cx-oracle.sourceforge.net/ | 5.1.1 |
--------------------------------------------------------------------------------------------------
mysql-python | MySQL | http://sourceforge.net/projects/mysql-python/ | 1.2.3 |
--------------------------------------------------------------------------------------------------
psycopg | PostgreSQL | http://initd.org/psycopg/ | 2.4.5 |
--------------------------------------------------------------------------------------------------
pycrypto | VNC | http://www.dlitz.net/software/pycrypto/ | 2.3 |
--------------------------------------------------------------------------------------------------
dnspython | DNS | http://www.dnspython.org/ | 1.10.0 |
--------------------------------------------------------------------------------------------------
pysnmp | SNMP | http://pysnmp.sourceforge.net/ | 4.2.1 |
--------------------------------------------------------------------------------------------------
pyasn1 | SNMP | http://sourceforge.net/projects/pyasn1/ | 0.1.2 |
--------------------------------------------------------------------------------------------------
IPy | NETx keywords | https://github.com/haypo/python-ipy | 0.75 |
--------------------------------------------------------------------------------------------------
unzip | ZIP passwords | http://www.info-zip.org/ | 6.0 |
--------------------------------------------------------------------------------------------------
Java | keystore files | http://www.oracle.com/technetwork/java/javase/ | 6 |
--------------------------------------------------------------------------------------------------
python | | http://www.python.org/ | 2.7 |
--------------------------------------------------------------------------------------------------

* Shortcuts (optionnal)
ln -s path/to/patator.py /usr/bin/ftp_login
ln -s path/to/patator.py /usr/bin/http_fuzz
so on ...


USAGE
-----

$ python patator.py -h
or
$ -h (if you created the shortcuts)

There are global options and module options:
- all global options start with - or --
- all module options are of the form option=value

All module options are fuzzable:
---------
./module host=FILE0 port=FILE1 foobar=FILE2.google.FILE3 0=hosts.txt 1=ports.txt 2=foo.txt 3=bar.txt

The keywords (FILE, COMBO, NET, ...) act as place-holders. They indicate the type of wordlist
and where to replace themselves with the actual words to test.

Each keyword is numbered in order to:
- match the corresponding wordlist
- and indicate in what order to iterate over all the wordlists

For instance, this would be the classic order:
---------
$ ./module host=FILE0 user=FILE1 password=FILE2 0=hosts.txt 1=logins.txt 2=passwords.txt
10.0.0.1 root password
10.0.0.1 root 123456
10.0.0.1 root qsdfghj
... (trying all passwords before testing next login)
10.0.0.1 admin password
10.0.0.1 admin 123456
10.0.0.1 admin qsdfghj
... (trying all logins before testing next host)
10.0.0.2 root password
...

While a smarter way might be:
---------
$ ./module host=FILE2 user=FILE1 password=FILE0 2=hosts.txt 1=logins.txt 0=passwords.txt
10.0.0.1 root password
10.0.0.2 root password
10.0.0.1 admin password
10.0.0.2 admin password
10.0.0.1 root 123456
10.0.0.2 root 123456
10.0.0.1 admin 123456
...

* Keywords

Brute-force a list of hosts with a file containing combo entries (each line := login:password).
---------
./module host=FILE0 user=COMBO10 password=COMBO11 0=hosts.txt 1=combos.txt

Scan subnets to just grab version banners.
---------
./module host=NET0 0=10.0.1.0/24,10.0.2.0/24,10.0.3.128-10.0.3.255

Fuzzing a parameter by iterating over a range of values.
---------
./module param=RANGE0 0=hex:0x00-0xffff
./module param=RANGE0 0=int:0-500
./module param=RANGE0 0=lower:a-zzz

* Actions & Conditions

Use the -x option to do specific actions upon receiving expected results. For instance:

To ignore responses with status code 200 *AND* a size within a range.
---------
./module host=10.0.0.1 user=FILE0 -x ignore:code=200,size=57-74

To ignore responses with status code 500 *OR* containing "Internal error".
---------
./module host=10.0.0.1 user=FILE0 -x ignore:code=500 -x ignore:fgrep='Internal error'

Remember that conditions are ANDed within the same -x option, use multiple -x options to
specify ORed conditions.

* Failures

During execution, failures may happen, such as a TCP connect timeout for
instance. A failure is actually an exception that the module does not expect,
and as a result the exception is caught upstream by the controller.

Such exceptions, or failures, are not immediately reported to the user, the
controller will retry 4 more times (see --max-retries) before reporting the
failed payload with logging level "FAIL".


* Read carefully the following examples to get a good understanding of how patator works.
{{{ FTP

* Brute-force authentication. Do not report wrong passwords.
---------
ftp_login host=10.0.0.1 user=FILE0 password=FILE1 0=logins.txt 1=passwords.txt -x ignore:mesg='Login incorrect.'

NB0. If you get errors like "500 OOPS: priv_sock_get_cmd", use -x ignore,reset,retry:code=500
in order to retry the last login/password using a new TCP connection. Odd servers like vsftpd
return this when they shut down the TCP connection (ie. max login attempts reached).

NB1. If you get errors like "too many connections from your IP address", try decreasing the number of
threads, the server may be enforcing a maximum number of concurrent connections.

* Same as before, but stop testing a user after his password is found.
---------
ftp_login ... -x free=user:code=0


* Find anonymous FTP servers on a subnet.
---------
ftp_login host=NET0 user=anonymous password=test@example.com 0=10.0.0.0/24

}}}
{{{ SSH
* Brute-force authentication with password same as login (aka single mode). Do not report wrong passwords.
---------
ssh_login host=10.0.0.1 user=FILE0 password=FILE0 0=logins.txt -x ignore:mesg='Authentication failed.'

NB. If you get errors like "Error reading SSH protocol banner ... Connection reset by peer",
try decreasing the number of threads, the server may be enforcing a maximum
number of concurrent connections (eg. MaxStartups in OpenSSH).


* Brute-force several hosts and stop testing a host after a valid password is found.
---------
ssh_login host=FILE0 user=FILE1 password=FILE2 0=hosts.txt 1=logins.txt 2=passwords.txt -x free=host:code=0


* Same as previous, but stop testing a user on a host after his password is found.
---------
ssh_login host=FILE0 user=FILE1 password=FILE2 0=hosts.txt 1=logins.txt 2=passwords.txt -x free=host+user:code=0

}}}
{{{ Telnet

* Brute-force authentication.
(a) Enter login after first prompt is detected, enter password after second prompt.
(b) The regex to detect the login and password prompts.
(c) Reconnect when we get no login prompt back (max number of tries reached or successful login).
(a)
telnet_login host=10.0.0.1 inputs='FILE0\nFILE1' 0=logins.txt 1=passwords.txt
prompt_re='tux login:|Password:' -x reset:egrep!='Login incorrect.+tux login:'
(b) (c)

NB. If you get errors like "telnet connection closed", try decreasing the number of threads,
the server may be enforcing a maximum number of concurrent connections.

}}}
{{{ SMTP

* Enumerate valid users using the VRFY command.
(a) Do not report invalid recipients.
(b) Do not report when the server shuts us down with "421 too many errors",
reconnect and resume testing.
(a)
smtp_vrfy host=10.0.0.1 user=FILE0 0=logins.txt -x ignore:fgrep='User unknown in local
recipient table' -x ignore,reset,retry:code=421
(b)

* Use the RCPT TO command in case the VRFY command is not available.

smtp_rcpt host=10.0.0.1 user=FILE0@localhost 0=logins.txt helo='ehlo mx.fb.com' mail_from=root

* Brute-force authentication.
(a) Send a fake hostname (by default your host fqdn is sent)
(a)
smtp_login host=10.0.0.1 helo='ehlo its.me.com' user=FILE0@dom.com password=FILE1 0=logins.txt 1=passwords.txt

}}}
{{{ HTTP

* Find hidden web resources.
(a) Use a specific header.
(b) Follow redirects.
(c) Do not report 404 errors.
(d) Retry on 500 errors.
--------- (a)
http_fuzz url=http://localhost/FILE0 0=words.txt header='Cookie: SESSID=A2FD8B2DA4'
follow=1 -x ignore:code=404 -x ignore,retry:code=500
(b) (c) (d)

NB. You may be able to go 10 times faster using webef (http://www.hsc.fr/ressources/outils/webef/).
It is the fastest HTTP brute-forcer I know, yet at the moment it still lacks useful features
that will prevent you from performing the following attacks.

* Brute-force phpMyAdmin logon.
(a) Use POST requests.
(b) Follow redirects using cookies sent by server.
(c) Ignore failed authentications.
(a) (b) (b)
http_fuzz url=http://10.0.0.1/phpmyadmin/index.php method=POST follow=1 accept_cookie=1
body='pma_username=root&pma_password=FILE0&server=1&lang=en' 0=passwords.txt
-x ignore:fgrep='Cannot log in to the MySQL server'
(c)

* Scan subnet for directory listings.
(a) Ignore not matching reponses.
(b) Save matching responses into directory.

http_fuzz url=http://NET0/FILE1 0=10.0.0.0/24 1=dirs.txt -x ignore:fgrep!='Index of'
-l /tmp/directory_listings (a)
(b)

* Brute-force Basic authentication.
(a) Single mode (login == password).
(b) Do not report failed login attempts.

http_fuzz url=http://10.0.0.1/manager/html user_pass=FILE0:FILE0 0=logins.txt -x ignore:code=401
(a) (b)

* Find hidden virtual hosts.
(a) Read template from file.
(b) Fuzz both the Host and User-Agent headers.

echo -e 'Host: FILE0\nUser-Agent: FILE1' > headers.txt
http_fuzz url=http://10.0.0.1/ header=@headers.txt 0=vhosts.txt 1=agents.txt
(a) (b)

* Brute-force logon using GET requests.
(a) Encode everything surrounded by the two tags _@@_ in hexadecimal.
(b) Ignore HTTP 200 responses with a content size (header+body) within given range
and that also contain the given string.
(c) Use a different delimiter string because the comma cannot be escaped.
(a) (a)
http_fuzz url='http://10.0.0.1/login?username=admin&password=_@@_FILE0_@@_' -e _@@_:hex
0=words.txt -x ignore:'code=200|size=1500-|fgrep=Welcome, unauthenticated user' -X '|'
(b) (c)

* Brute-force logon that enforces two random nonces to be submitted along every POST.
(a) First, request the page that provides the nonces as hidden input fields.
(b) Use regular expressions to extract the nonces that are to be submitted along the main request.

http_fuzz url=http://10.0.0.1/login method=POST body='user=admin&pass=FILE0&nonce1=_N1_&nonce2=_N2_' 0=passwords.txt accept_cookie=1
before_urls=http://10.0.0.1/index before_egrep='_N1_: (a) (b)

* Test the OPTIONS method against a list of URLs.
(a) Ignore URLs that only allow the HEAD and GET methods.
(b) Header end of line is '\r\n'.
(c) Use a different delimiter string because the comma cannot be escaped.

http_fuzz url=FILE0 0=urls.txt method=OPTIONS -x ignore:egrep='^Allow: HEAD, GET\r$' -X '|'
(a) (b) (c)
}}}
{{{ LDAP

* Brute-force authentication.
(a) Do not report wrong passwords.
(b) Talk SSL/TLS to port 636.

ldap_login host=10.0.0.1 binddn='cn=FILE0,dc=example,dc=com' 0=logins.txt bindpw=FILE1 1=passwords.txt
-x ignore:mesg='ldap_bind: Invalid credentials (49)' ssl=1 port=636
(a) (b)
}}}
{{{ SMB

* Brute-force authentication.

smb_login host=10.0.0.1 user=FILE0 password=FILE1 0=logins.txt 1=passwords.txt -x ignore:fgrep=STATUS_LOGON_FAILURE

NB. If you suddenly get STATUS_ACCOUNT_LOCKED_OUT errors for an account
although it is not the first password you test on this account, then you must
have locked it.

* Pass-the-hash.
(a) Test a list of hosts.
(b) Test every user (each line := login:rid:LM hash:NT hash).

smb_login host=FILE0 0=hosts.txt user=COMBO10 password_hash=COMBO12:COMBO13 1=pwdump.txt -x ...
(a) (b)
}}}
{{{ MSSQL

* Brute-force authentication.

mssql_login host=10.0.0.1 user=sa password=FILE0 0=passwords.txt -x ignore:fgrep='Login failed for user'

}}}
{{{ Oracle
Beware, by default in Oracle, accounts are permanently locked out after 10 wrong passwords,
except for the SYS account.

* Brute-force authentication.

oracle_login host=10.0.0.1 user=SYS password=FILE0 0=passwords.txt sid=ORCL -x ignore:code=ORA-01017

NB0. With Oracle 10g XE (Express Edition), you do not need to pass a SID.

NB1. If you get ORA-12516 errors, it may be because you reached the limit of
concurrent connections or db processes, try using "--rate-limit 0.5 -t 2" to be
more polite. Also you can run "alter system set processes=150 scope=spfile;"
and restart your database to get rid of this.

* Brute-force SID.

oracle_login host=10.0.0.1 sid=FILE0 0=sids.txt -x ignore:code=ORA-12505

NB. Against Oracle9, it may crash (Segmentation fault) as soon as a valid SID is
found (cx_Oracle bug). Sometimes, the SID gets printed out before the crash,
so try running the same command again if it did not.

}}}
{{{ MySQL

* Brute-force authentication.

mysql_login host=10.0.0.1 user=FILE0 password=FILE0 0=logins.txt -x ignore:fgrep='Access denied for user'

}}}
{{{ PostgresSQL

* Brute-force authentication.
-----------
pgsql_login host=10.0.0.1 user=postgres password=FILE0 0=passwords.txt -x ignore:fgrep='password authentication failed'

}}}
{{{ VNC
Some VNC servers have built-in anti-bruteforce functionnality that temporarily
blacklists the attacker IP address after too many wrong passwords.
- RealVNC-4.1.3 or TightVNC-1.3.10 for example, allow 5 failed attempts and
then enforce a 10 second delay. For each subsequent failed attempt that
delay is doubled.
- RealVNC-3.3.7 or UltraVNC allow 6 failed attempts and then enforce a 10
second delay between each following attempt.

* Brute-force authentication.
(a) No need to use more than one thread.
(b) Keep retrying the same password when we are blacklisted by the server.
(c) Exit execution as soon as a valid password is found.
--------- (a)
vnc_login host=10.0.0.1 password=FILE0 0=passwords.txt --threads 1
-x retry:fgrep!='Authentication failure' --max-retries -1 -x quit:code=0
(b) (b) (c)
}}}
{{{ DNS

* Brute-force subdomains.
(a) Ignore NXDOMAIN responses (rcode 3).

dns_forward name=FILE0.google.com 0=names.txt -x ignore:code=3
(a)
* Brute-force domain with every possible TLDs.

dns_forward name=google.MOD0 0=TLD -x ignore:code=3

* Brute-force SRV records.

dns_forward name=MOD0.microsoft.com 0=SRV qtype=SRV -x ignore:code=3

* Grab the version of several hosts.

dns_forward server=FILE0 0=hosts.txt name=version.bind qtype=txt qclass=ch

* Reverse lookup several networks.
(a) Ignore names that do not contain 'google.com'.

dns_reverse host=NET0 0=216.239.32.0-216.239.47.255,8.8.8.0/24 -x ignore:code=3 -x ignore:fgrep!=google.com -x ignore:fgrep=216-239-
(a) (b)
}}}
{{{ SNMP

* SNMPv1/2 : Find valid community names.
----------
snmp_login host=10.0.0.1 community=FILE0 1=names.txt -x ignore:mesg='No SNMP response received before timeout'

* SNMPv3 : Find valid usernames.
----------
snmp_login host=10.0.0.1 version=3 user=FILE0 0=logins.txt -x ignore:mesg=unknownUserName

* SNMPv3 : Find valid passwords.
----------
snmp_login host=10.0.0.1 version=3 user=myuser auth_key=FILE0 0=passwords.txt -x ignore:mesg=wrongDigest

NB0. If you get "notInTimeWindow" error messages, increase the retries option.
NB1. SNMPv3 requires passphrases to be at least 8 characters long.

}}}
{{{ Unzip

* Brute-force the ZIP file password (cracking older pkzip encryption used to be not supported in JtR).
----------
unzip_pass zipfile=path/to/file.zip password=FILE0 0=passwords.txt -x ignore:code!=0

}}}

CHANGELOG

* v0.5 2013/07/05
- new modules: mysql_query, tcp_fuzz
- new RANGE and PROG keywords (supersedes the reading from stdin feature)
- switched to impacket for mssql_login
- output more intuitive
- fixed connection cache
- minor bug fixes

Source-
http://packetstormsecurity.com/files/122392/Patator-Brute-Forcer-0.5.html

Website-
https://code.google.com/p/patator/

Screenshot -