Tracert 命令跟踪路由原理是IP路由每经过一个路由节点TTL值会减一,假设TTL值=0时数据包还没有到达目标主机,那么该路由则会回复给目标主机一个数据包不可达,由此我们就可以获取到目标主机的IP地址,如下我们通过scapy构造一个路由追踪工具并实现一次追踪。

首先Scapy是如何发包与收包的,看以下案例的演示。

>>> from random import randint>>>>>> RandomID=randint(1,65534)>>> packet = IP(dst="61.135.169.125", ttl=1, id=RandomID) / ICMP(id=RandomID, seq=RandomID) / "hello lyshark">>> respon = sr1(packet,timeout=3,verbose=0)>>>>>> respon<IP  version=4 ihl=5 tos=0xc0 len=61 id=14866 flags= frag=0 ttl=64 proto=icmp chksum=0xbc9a src=192.168.1.1 dst=192.168.1.2 |<ICMP  type=time-exceeded code=ttl-zero-during-transit chksum=0xf4ff reserved=0 length=0 unused=None |<IPerror  version=4 ihl=5 tos=0x0 len=33 id=49588 flags= frag=0 ttl=1 proto=icmp chksum=0x4f79 src=192.168.1.2 dst=61.135.169.125 |<ICMPerror  type=echo-request code=0 chksum=0x30c4 id=0xc1b4 seq=0xc1b4 |>>>>

路由追踪原理(参考于互联网):一开始发送一个TTL为1的包,这样到达第一个路由器的时候就已经超时了,第一个路由器就发ICMP通知说包超时,这样就能够记录下所经过的第一个路由器的IP。然后将TTL加1,安全通过第一个路由器,而第二个路由器的的处理与第一个同样,丢包,发通知说包超时了,这样记录下第二个路 由器IP,由此能够一直进行下去,直到这个数据包到达目标主机,由此打印出全部经过的路由器。

将这个过程自动化,就可以完成数据包的跟踪,Python 代码如下所示

from scapy.all import *from random import randintimport time,ipaddress,threadingfrom optparse import OptionParserdef ICMP_Ping(addr):    RandomID=randint(1,65534)    packet = IP(dst=addr, ttl=64, id=RandomID) / ICMP(id=RandomID, seq=RandomID) / "lyshark"    respon = sr1(packet,timeout=3,verbose=0)    if respon:        print("[+] --> {}".format(str(respon[IP].src)))# By: LyShark.comdef TraceRouteTTL(addr):    for item in range(1,128):        RandomID=randint(1,65534)        packet = IP(dst=addr, ttl=item, id=RandomID) / ICMP(id=RandomID, seq=RandomID)        respon = sr1(packet,timeout=3,verbose=0)        if respon != None:            ip_src = str(respon[IP].src)            if ip_src != addr:                print("[+] --> {}".format(str(respon[IP].src)))            else:                print("[+] --> {}".format(str(respon[IP].src)))                return 1        else:            print("[-] --> TimeOut")        time.sleep(1)if __name__== "__main__":    parser = OptionParser()    parser.add_option("--mode",dest="mode",help="选择使用的工具模式")    parser.add_option("-a","--addr",dest="addr",help="指定一个IP地址或范围")    (options,args) = parser.parse_args()    print("By: LyShark.com")    # 使用方式: lyshark.py --mode=ping -a 192.168.1.0/24    if options.mode == "ping":        net = ipaddress.ip_network(str(options.addr))        for item in net:            t = threading.Thread(target=ICMP_Ping,args=(str(item),))            t.start()    # 使用方式: lyshark.py --mode=trace -a 8.141.58.64    elif options.mode == "trace":        TraceRouteTTL(str(options.addr))    else:        parser.print_help()

追踪探测效果如下:

文章作者:lyshark (王瑞)
文章出处:https://www.cnblogs.com/LyShark/p/16753870.html
版权声明:本博客文章与代码均为学习时整理的笔记,文章 [均为原创] 作品,转载请 [添加出处] ,您添加出处是我创作的动力!
转载文章请遵守《中华人民共和国著作权法》相关规定或遵守《署名CC BY-ND 4.0国际》禁止演绎规范,合理合规携带原创出处转载。