Appendices Appendix A: Source Code
Page 18/20 Date 16.07.2017 Size 0.59 Mb. #23501
Appendix A: Source Code
IDS.py
'''
Packet sniffer in python using the pcapy python library
Project website
http://oss.coresecurity.com/projects/pcapy.html
'''
import socket
from struct import *
from datetime import datetime
import pcapy # Import pcapy for the ability to scan network packets
import sys
import re # Import regex for parsing packets for suspect proxy traffic
import time
import os
import signal
# Globals
# creates the time so it can be used for the log filename and also within the log
textTime = time . strftime ( "%H-%M-%S" )
# creates the date so it can be used for the log filename and also within the log
textToday = time . strftime ( "%d-%m-%Y" )
# The directory for the log files to be stored, this can be changed to suit
directory = "C:\ProxyTempLogs"
# opens a log with the date and time in the logs filename
log = open ( directory + '\log_' + textToday + '_' + textTime + '.txt' , 'w' )
def main ( argv ):
# checks to make sure the directory doesn't exist
if not os . path . exists ( directory ):
# make the directory
os . makedirs ( directory )
# list all devices
devices = pcapy . findalldevs ()
'''
open device
# Arguments here are:
# device
# snaplen (maximum number of bytes to capture _per_packet_)
# promiscious mode (1 for true)
# timeout (in milliseconds)
'''
# No interfaces found
if len ( devices ) == 0 :
raise RuntimeError , "Error: no available network interfaces , or you don't have enough permissions on this system."
# A single interface was found
if len ( devices ) == 1 :
interface = devices [ 0 ]
# Multiple interfaces found
else :
print "Available network interfaces:"
for i in xrange ( len ( devices )):
print '\t%i - %s' % ( i + 1 , devices [ i ])
print
while 1 :
choice = raw_input ( "Choose an interface: " )
try :
i = int ( choice )
if i == 0 :
interface = None
break
interface = devices [ i - 1 ]
break
except Exception :
pass
# Return the selected interface
print "Sniffing device " + interface
cap = pcapy . open_live ( interface , 65536 , 1 , 0 )
# start sniffing packets
while ( 1 ) :
time . sleep ( 0.05 )
try :
( header , packet ) = cap . next ()
# print ('%s: captured %d bytes, truncated to %d bytes' %(datetime.datetime.now(), header.getlen(), header.getcaplen()))
parsedPacket = parse_packet ( packet )
######################
# Parse packet for suspect proxy data
result = isProxy ( parsedPacket )
# Inform user if packet contained suspect data
if result == 0 :
# OK
# This can be uncommented if the user wants to make sure there are no proxies, OK will be printed constantly
#print("OK")
a = 1
elif result == 1 :
# GLYPE proxy
print ( "Glype usage detected" )
elif result == 2 :
# PHPProxy
print ( "PHPProxy usage detected" )
elif result == 3 :
# Tor Browser
print ( "Onion Routing usage detected" )
elif result == 4 :
# CGI Proxy
print ( "CGI Proxy usage detected" )
else :
# INVALID
print ( "INVALID RESULT" )
sys . stdout . write ( "" )
sys . stdout . flush ()
# handle the pcapy error if the network drops
except pcapy . PcapError :
continue
# Convert a string of 6 characters of ethernet address into a dash separated hex string
def eth_addr ( a ) :
b = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x" % ( ord ( a [ 0 ]) , ord ( a [ 1 ]) , ord ( a [ 2 ]), ord ( a [ 3 ]), ord ( a [ 4 ]) , ord ( a [ 5 ]))
return b
def isProxy ( packet1 ) :
logTime = str ( datetime . now ())
# Regex for Glype
glypeStrings = ( ".*\.php\?u=.*(?i)\s" , ".*GET.*(?i)\s" , ".*HTTP.*(?i)\s" )
# Regex for PHPProxy
phpStrings = ( ".*\.php\?q=aHR0c.*(?i)\s" , ".*GET.*(?i)\s" , ".*HTTP.*(?i)\s" )
# Regex for the Tor Browser
torStrings = ( ".*Dest Port : 9001.*(?i)\s" , ".*Dest Port : 9002.*(?i)\s" , ".*Dest Port : 9003.*(?i)\s" , ".*Dest Port : 9004.*(?i)\s" , ".*Dest Port : 9030.*(?i)\s" , ".*Dest Port : 9031.*(?i)\s" , ".*Dest Port : 9032.*(?i)\s" , ".*Dest Port : 9033.*(?i)\s" , ".*Dest Port : 9150.*(?i)\s" , ".*Dest Port : 9151.*(?i)\s" )
# Regex for CGI Proxy
cgiStrings = ( ".*\.cgi.*(?i)\s" , ".*GET.*(?i)\s" , ".*HTTP.*(?i)\s" , ".*Dest Port : 80.*(?i)\s" ,)
glype = [ False , False , False ]
php = [ False , False , False ]
tor = [ False , False , False , False , False , False , False , False , False , False ]
cgi = [ False , False , False , False ]
result = 0 # Whether packet is a proxy, or not
# Search packet for regex
glype [ 0 ] = re . match ( glypeStrings [ 0 ], str ( packet1 ))
glype [ 1 ] = re . match ( glypeStrings [ 1 ], str ( packet1 ))
glype [ 2 ] = re . match ( glypeStrings [ 2 ], str ( packet1 ))
# If each of the regex strings match the print out the result and the packet to the log
if ( glype [ 0 ]
and glype [ 1 ]
and glype [ 2 ]) :
result = 1
print >> log , str ( "GLYPE: " + logTime + "\n" + packet1 + "\n" )
# Search packet for regex
php [ 0 ] = re . match ( phpStrings [ 0 ], str ( packet1 ))
php [ 1 ] = re . match ( phpStrings [ 1 ], str ( packet1 ))
php [ 2 ] = re . match ( phpStrings [ 2 ], str ( packet1 ))
# If each of the regex strings match the print out the result and the packet to the log
if ( php [ 0 ]
and php [ 1 ]
and php [ 2 ]) :
result = 2
print >> log , str ( "PHPProxy: " + logTime + "\n" + packet1 + "\n" )
# Search packet for regex
tor [ 0 ] = re . match ( torStrings [ 0 ], str ( packet1 ))
tor [ 1 ] = re . match ( torStrings [ 1 ], str ( packet1 ))
tor [ 2 ] = re . match ( torStrings [ 2 ], str ( packet1 ))
tor [ 3 ] = re . match ( torStrings [ 3 ], str ( packet1 ))
tor [ 4 ] = re . match ( torStrings [ 4 ], str ( packet1 ))
tor [ 5 ] = re . match ( torStrings [ 5 ], str ( packet1 ))
tor [ 6 ] = re . match ( torStrings [ 6 ], str ( packet1 ))
tor [ 7 ] = re . match ( torStrings [ 7 ], str ( packet1 ))
tor [ 8 ] = re . match ( torStrings [ 8 ], str ( packet1 ))
tor [ 9 ] = re . match ( torStrings [ 9 ], str ( packet1 ))
# If any of the regex strings match the print out the result and the packet to the log
if ( tor [ 0 ]
or tor [ 1 ]
or tor [ 2 ]
or tor [ 3 ]
or tor [ 4 ]
or tor [ 5 ]
or tor [ 6 ]
or tor [ 7 ]
or tor [ 8 ]
or tor [ 9 ]) :
result = 3
print >> log , str ( "Onion Routing: " + logTime + "\n" + packet1 + "\n" )
# Search packet for regex
cgi [ 0 ] = re . match ( cgiStrings [ 0 ], str ( packet1 ))
cgi [ 1 ] = re . match ( cgiStrings [ 1 ], str ( packet1 ))
cgi [ 2 ] = re . match ( cgiStrings [ 2 ], str ( packet1 ))
cgi [ 3 ] = re . match ( cgiStrings [ 3 ], str ( packet1 ))
# If each of the regex strings match the print out the result and the packet to the log
if ( cgi [ 0 ]
and cgi [ 1 ]
and cgi [ 2 ]
and cgi [ 3 ]) :
result = 4
print >> log , str ( "CGIProxy: " + logTime + "\n" + packet1 + "\n" )
return result
# function to parse a packet
def parse_packet ( packet ) :
# parse ethernet header
eth_length = 14
packetStr = ""
eth_header = packet [: eth_length ]
eth = unpack ( '!6s6sH' , eth_header )
eth_protocol = socket . ntohs ( eth [ 2 ])
packetStr += 'Destination MAC : ' + eth_addr ( packet [ 0 : 6 ]) + ' Source MAC : ' + eth_addr ( packet [ 6 : 12 ]) + ' Protocol : ' + str ( eth_protocol )
# Parse IP packets , IP Protocol number = 8
if eth_protocol == 8 :
# Parse IP header
# take first 20 characters for the ip header
ip_header = packet [ eth_length : 20 + eth_length ]
# now unpack them :)
iph = unpack ( '!BBHHHBBH4s4s' , ip_header )
version_ihl = iph [ 0 ]
version = version_ihl >> 4
ihl = version_ihl & 0xF
iph_length = ihl * 4
ttl = iph [ 5 ]
protocol = iph [ 6 ]
s_addr = socket . inet_ntoa ( iph [ 8 ]);
d_addr = socket . inet_ntoa ( iph [ 9 ]);
packetStr += 'Version : ' + str ( version ) + ' IP Header Length : ' + str ( ihl ) + ' TTL : ' + str ( ttl ) + ' Protocol : ' + str ( protocol ) + ' Source Address : ' + str ( s_addr ) + ' Destination Address : ' + str ( d_addr )
# TCP protocol
if protocol == 6 :
t = iph_length + eth_length
tcp_header = packet [ t : t + 20 ]
# now unpack them :)
tcph = unpack ( '!HHLLBBHHH' , tcp_header )
source_port = tcph [ 0 ]
dest_port = tcph [ 1 ]
sequence = tcph [ 2 ]
acknowledgement = tcph [ 3 ]
doff_reserved = tcph [ 4 ]
tcph_length = doff_reserved >> 4
packetStr += 'Source Port : ' + str ( source_port ) + ' Dest Port : ' + str ( dest_port ) + ' Sequence Number : ' + str ( sequence ) + ' Acknowledgement : ' + str ( acknowledgement ) + ' TCP header length : ' + str ( tcph_length )
h_size = eth_length + iph_length + tcph_length * 4
data_size = len ( packet ) - h_size
# get data from the packet
data = packet [ h_size :]
packetStr += 'Data : ' + data
# ICMP Packets
elif protocol == 1 :
u = iph_length + eth_length
icmph_length = 4
icmp_header = packet [ u : u + 4 ]
# now unpack them :)
icmph = unpack ( '!BBH' , icmp_header )
icmp_type = icmph [ 0 ]
code = icmph [ 1 ]
checksum = icmph [ 2 ]
packetStr += 'Type : ' + str ( icmp_type ) + ' Code : ' + str ( code ) + ' Checksum : ' + str ( checksum )
h_size = eth_length + iph_length + icmph_length
data_size = len ( packet ) - h_size
# get data from the packet
data = packet [ h_size :]
packetStr += 'Data : ' + data
# UDP packets
elif protocol == 17 :
u = iph_length + eth_length
udph_length = 8
udp_header = packet [ u : u + 8 ]
# now unpack them
udph = unpack ( '!HHHH' , udp_header )
source_port = udph [ 0 ]
dest_port = udph [ 1 ]
length = udph [ 2 ]
checksum = udph [ 3 ]
packetStr += 'Source Port : ' + str ( source_port ) + ' Dest Port : ' + str ( dest_port ) + ' Length : ' + str ( length ) + ' Checksum : ' + str ( checksum )
h_size = eth_length + iph_length + udph_length
data_size = len ( packet ) - h_size
# get data from the packet
data = packet [ h_size :]
packetStr += 'Data : ' + data
# some other IP packet like IGMP
else :
packetStr += 'Protocol other than TCP/UDP/ICMP'
# print(packetStr)
return packetStr
if __name__ == "__main__":
try :
main(sys.argv)
# Handle any exceptions caused when exiting the program
except KeyboardInterrupt:
pass
Share with your friends:
The database is protected by copyright ©ininet.org 2024
send message