首先获取要捕获的网卡的流量(其实这个不太好,因为我们要检测的网卡不一定排在第一啊,这个可以根据自己的实际情况修改)
LANip = commands.getoutput("/sbin/ifconfig").split("\n")[1].split()[1][5:]
作者捕获用的是socket,因为是AF_PACKET在windows用不了,所以这种方式就只能在linux用了
s = socket.socket( socket.AF_PACKET , socket.SOCK_RAW , socket.ntohs(0x0003))
packet = s.recvfrom(65565)
packet = packet[0]
捕获数据后接下来就是去解析ip,tcp协议的一些字段
下一步就是检测是不是三次握手的包,是3次握手才会将信息插入到threewayhandshake数组
testdata = s_addr+":"+str(source_port)+"->"+d_addr+":"+str(dest_port)
if(testdata not in threewayhandshake):
threewaycheck(s_addr,d_addr,source_port,dest_port,seq_numb,dest_numb,tcp_flags)
接下来核心的就是scancheck函数
scancheck(s_addr,d_addr,source_port,dest_port,seq_numb,dest_numb,tcp_flags)
具体实现如下:
def scancheck(sip,dip,sport,dport,seqnum,acknum,flags):
global data,dataforthreewaycheck,dbdata,reverse
data = sip+":"+str(sport)+"->"+dip+":"+str(dport)+"_"+str(seqnum)+"_"+str(acknum)+"_"+"/".join(flags)
dataforthreewaycheck = sip+":"+str(sport)+"->"+dip+":"+str(dport)
revthreeway = dip+":"+str(dport)+"->"+sip+":"+str(sport)
dbdata = sip+"->"+dip
reverse = dip+"->"+sip
if(halfconnectscan(sip,dip,sport,dport,seqnum,acknum,flags)):
returned = halfconnectscan(sip,dip,sport,dport,seqnum,acknum,flags)
if(isinstance(returned,(str))):
print returned
else:
print bgcolors.BOLD+bgcolors.OKBLUE+revthreeway+bgcolors.ENDC+bgcolors.WARNING+bgcolors.BOLD+" Port Scanning Detected: [Style not Defined]:Attempt to connect closed port!"+bgcolors.ENDC
elif(fullconnectscan(sip,dip,sport,dport,seqnum,acknum,flags)):
returned = fullconnectscan(sip,dip,sport,dport,seqnum,acknum,flags)
if(isinstance(returned,(str))):
print returned
else:
print bgcolors.BOLD+bgcolors.OKBLUE+revthreeway+bgcolors.ENDC+bgcolors.WARNING+bgcolors.BOLD+" Port Scanning Detected: [Style not Defined]:Attempt to connect closed port!"+bgcolors.ENDC
elif(xmasscan(sip,dip,sport,dport,seqnum,acknum,flags)):
print bgcolors.BOLD+bgcolors.OKBLUE+dataforthreewaycheck+bgcolors.ENDC +bgcolors.BOLD+bgcolors.FAIL+ " => [Runtime Detection:] XMAS scan detected!"+bgcolors.ENDC
elif(finscan(sip,dip,sport,dport,seqnum,acknum,flags)):
print bgcolors.BOLD+bgcolors.OKBLUE+ dataforthreewaycheck+bgcolors.ENDC+ bgcolors.BOLD+bgcolors.FAIL+" => [Runtime Detection:] FIN scan detected!"+bgcolors.ENDC
elif(nullscan(sip,dip,sport,dport,seqnum,acknum,flags)):
print bgcolors.BOLD+bgcolors.OKBLUE+dataforthreewaycheck +bgcolors.ENDC+bgcolors.BOLD+bgcolors.FAIL+ " => [Runtime Detection:] NULL scan detected!"+bgcolors.ENDC
那么其实就是依次判断每种端口扫描技术
对于每种扫描,通用的就是将扫描的目标端口记录下来
if(scannedports.has_key(dip)):
scannedports[dip].append(str(sport))
else:
scannedports[dip] = []
scannedports[dip].append(str(sport))
下面依次看每种扫描技术判断,只要发现了,就加到黑名单
就是发SYN包,之后发了个含RST,ACK的包,那就是半连接扫描了
if("SYN" in flags and seqnum>0 and acknum==0 and len(flags)==1):
halfscandb[dbdata+"_"+str(seqnum)] = dbdata+"_SYN_ACK_"+str(seqnum)+"_"+str(acknum)
elif("RST" in flags and "ACK" in flags and len(flags)==2):
if(halfscandb.has_key(reverse+"_"+str(acknum-1))):
del halfscandb[reverse+"_"+str(acknum-1)]
if(str(dip) not in blacklist):
blacklist.append(str(dip))
return True
elif("SYN" in flags and "ACK" in flags and len(flags)==2):
if(halfscandb.has_key(reverse+"_"+str(acknum-1))):
del halfscandb[reverse+"_"+str(acknum-1)]
halfscandb[reverse+"_"+str(acknum)] = dbdata+"_RST_"+str(seqnum)+"_"+str(acknum)
elif("RST" in flags and len(flags)==1):
if(halfscandb.has_key(dbdata+"_"+str(seqnum))):
if(str(dip) not in blacklist):
blacklist.append(str(dip))
return bgcolors.BOLD+bgcolors.OKBLUE+sip+":"+str(sport)+"->"+dip+":"+str(dport) +bgcolors.ENDC+ bgcolors.BOLD+bgcolors.FAIL+" => [Runtime Detection:] Half connect(SYN scan) scan detected!"+bgcolors.ENDC
return False
这个分了两种
第一种:有三次握手,但是之后就发了ACK RST
if(dataforthreewaycheck in threewayhandshake):
if("ACK" in flags and "RST" in flags and len(flags)==2):
if(fullscandb.has_key(dbdata)):
counter = int(fullscandb[dbdata])
if(counter>=3):
if(str(dip) not in blacklist):
blacklist.append(str(dip))
return bgcolors.BOLD+bgcolors.OKBLUE+ dip+":"+str(dport)+"->"+sip+":"+str(sport)+bgcolors.ENDC+ bgcolors.BOLD+bgcolors.FAIL+" => [Runtime Detection:] Full connect scan detected!"+bgcolors.ENDC
else:
counter = counter + 1
fullscandb[dbdata] = str(counter)
else:
counter = 0
fullscandb[dbdata] = str(counter)
第二种情况
这是连续3次在SYN后发了”RST” and “ACK”,这个我感觉还是半连接的感觉啊
else:
if("SYN" in flags and len(flags)==1):
if(seqnum>0 and acknum==0):
fullscandb[dbdata+"_SYN"] = str(seqnum)+"_"+str(acknum)+"_"+str(sport)+"_"+str(dport)
elif("RST" in flags and "ACK" in flags and len(flags)==2):
if(fullscandb.has_key(dip+"->"+sip+"_SYN")):
manage = fullscandb[dip+"->"+sip+"_SYN"]
pieces = manage.split("_")
old_acknum = int(pieces[1])
old_seqnum = int(pieces[0])
if(seqnum==0 and acknum==old_seqnum+1):
if(fullscandb.has_key(dbdata)):
counter = int(fullscandb[dbdata])
if(counter>=3):
if(str(dip) not in blacklist):
blacklist.append(str(dip))
return True
else:
counter = counter + 1
fullscandb[dbdata] = str(counter)
else:
counter = 0
fullscandb[dbdata] = str(counter)
只含下面3个flag的
“FIN” ,”URG” , “PSH”
这个没三次握手的前提下就只有一个FIN
if(dataforthreewaycheck not in threewayhandshake):
if("FIN" in flags and len(flags)==1):
没有一个flag置位
if(len(flags)==0):
只有ack
if("ACK" in flags and len(flags)==1):