1. 程式人生 > >用Scapy解析TTL欄位的值

用Scapy解析TTL欄位的值

#!/usr/bin/python
#coding=utf-8
from scapy.all import *
import time
import optparse
# 為避免IPy庫中的IP類與Scapy庫中的IP類衝突,重新命名為IPTEST類
from IPy import IP as IPTEST

ttlValues = {}
THRESH = 5

# 檢查資料包的IP層,提取出源IP和TTL欄位的值
def testTTL(pkt):
    try:
        if pkt.haslayer(IP):
            ipsrc = pkt.getlayer(IP).src
            ttl = str(pkt.ttl)
            #print "[+] Pkt Received From: " + ipsrc + " with TTL: " + ttl
            checkTTL(ipsrc, ttl)
    except:
        pass

def checkTTL(ipsrc, ttl):

    # 判斷是否是內網私有地址
    if IPTEST(ipsrc).iptype() == 'PRIVATE':
        return

    # 判斷是否出現過該源地址,若沒有則構建一個發往源地址的ICMP包,並記錄迴應資料包中的TTL值
    if not ttlValues.has_key(ipsrc):
        #ICMP發現掃描
        #pkt = sr1(IP(dst=ipsrc) / ICMP(), retry=0, timeout=1, verbose=0)  
        pkt = sr1(IP(dst=ipsrc) / ICMP() / "zhou")
        print pkt
        ttlValues[ipsrc] = pkt.ttl


    # 若兩個TTL值之差大於閾值,則認為是偽造的源地址
    if abs(int(ttl) - int(ttlValues[ipsrc])) > THRESH:
        print '\n[!] Detected Possible Spoofed Packet From: ' + ipsrc
        print '[!] TTL: ' + ttl + ', Actual TTL: ' + str(ttlValues[ipsrc])

def main():
    parser = optparse.OptionParser("[*]Usage python spoofCheckTTL.py -i <interface> -t <thresh>")
    parser.add_option('-i', dest='iface', type='string', help='specify network interface')
    parser.add_option('-t', dest='thresh', type='int', help='specify threshold count ')
    (options, args) = parser.parse_args()
    if options.iface == None:
        conf.iface = 'eth0'
    else:
        conf.iface = options.iface
    if options.thresh != None:
        THRESH = options.thresh
    else:
        THRESH = 5

    sniff(prn=testTTL, store=0)

if __name__ == '__main__':
    main()

重點說明一下,避免大家走一些彎路,這段程式碼中最重要部分就是:
 # 判斷是否出現過該源地址,若沒有則構建一個發往源地址的ICMP包,並記錄迴應資料包中的TTL值   
if not ttlValues.has_key(ipsrc):       
     #ICMP發現掃描       
     #pkt = sr1(IP(dst=ipsrc) / ICMP(), retry=0, timeout=1, verbose=0)       
    pkt = sr1(IP(dst=ipsrc) / ICMP() / "zhou")
    ttlValues[ipsrc] = pkt.ttl其中原文中的
        #pkt = sr1(IP(dst=ipsrc) / ICMP(), retry=0, timeout=1, verbose=0)
我已註釋掉了,因為在除錯過過程,PKT結果一直是None,所我翻查了關於
scapy學習icmp報文資料,將程式碼改為       
 pkt = sr1(IP(dst=ipsrc) / ICMP() / "zhou") 後,結果正常輸出。有興趣有朋友可以深入研究。