1. 前言
如果只需要研究Linux的tcp协议栈行为,只需要使用packetdrill就能够满足我的所有需求。packetdrill才是让我随心所欲地撩tcp协议栈。packetdrill的简单使用手册。
然而悲剧的是,除了要研究Linux的TCP协议栈行为,还需要研究Windows的tcp协议栈的行为,Windows不开源,感觉里面应该有挺多未知的坑。
为了能够重现Windows的tcp协议栈的一些网络行为,这里使用python的scapy进行包构造撩撩Windows的tcp协议栈。scapy在tcp数据报文注入会有一点的时延,这个工具在要求时延严格的场景无法使用(还是packetdrill好用,囧)。针对目前遇到的场景,勉强能用,再则已经撸惯了python,上手起来比较容易。
2. 基本语法
- 安装scapy
在Centos 7.2中直接使用yum install 来安装。
yum install scapy.noarch
- help 能解决大部分问题
[root@localhost ~]# scapy INFO: Can't import python gnuplot wrapper . Won't be able to plot. INFO: Can't import PyX. Won't be able to use psdump() or pdfdump(). WARNING: No route found for IPv6 destination :: (no default route"htmlcode">> IP() <IP |> IP()/TCP() <IP frag=0 proto=tcp |<TCP | IP(proto=55)/TCP() <IP frag=0 proto=55 |<TCP Ether()/IP()/TCP() <Ether type=IPv4 |<IP frag=0 proto=tcp |<TCP |> IP()/TCP()/"GET /HTTP/1.0\r\n\r\n" 数据部分可以直接使用字符串 <IP frag=0 proto=tcp |<TCP |<Raw load='GET /HTTP/1.0\r\n\r\n' |> Ether()/IP()/UDP() <Ether type=IPv4 |<IP frag=0 proto=udp |<UDP |> Ether()/IP()/IP()/UDP() <Ether type=IPv4 |<IP frag=0 proto=ipencap |<IP frag=0 proto=udp |<UDP | > str(IP()) 'E\x00\x00\x14\x00\x01\x00\x00@\x00|\xe7\x7f\x00\x00\x01\x7f\x00\x00\x01' > IP(_) <IP version=4L ihl=5L tos=0x0 len=20 id=1 flags= frag=0L ttl=64 proto=hopopt chksum=0x7ce7 src=127.0.0.1 dst=127.0.0.1 |> > a=Ether()/IP(dst="www.baidu.com")/TCP()/"GET /index.html HTTP/1.0 \n\n" > hexdump(a) 0000 00 03 0F 19 6A 49 08 00 27 FE D8 12 08 00 45 00 ....jI..'.....E. 0010 00 43 00 01 00 00 40 06 70 78 C0 A8 73 C6 B4 61 .C....@.px..s..a 0020 21 6C 00 14 00 50 00 00 00 00 00 00 00 00 50 02 !l...P........P. 0030 20 00 B3 75 00 00 47 45 54 20 2F 69 6E 64 65 78 ..u..GET /index 0040 2E 68 74 6D 6C 20 48 54 54 50 2F 31 2E 30 20 0A .html HTTP/1.0 . 0050 0A . > b=str(a) > b "\x00\x03\x0f\x19jI\x08\x00'\xfe\xd8\x12\x08\x00E\x00\x00C\x00\x01\x00\x00@\x06px \xc0\xa8s\xc6\xb4a!l\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xb3u \x00\x00GET /index.html HTTP/1.0 \n\n"1.数据包发送
数据包的发送主要包括以下函数send/sendp/sr/sr1/srp 主要区别是:
send函数工作在第三层
send(IP(dst="192.168.115.188")/ICMP())sendp函数工作在第二层,你可以选择网卡和协议
sendp(Ether()/IP(dst="192.168.115.188",ttl=(1,4)),iface="eth0")fuzz函数的作用:可以更改一些默认的不可以被计算的值(比如校验和checksums),更改的值是随机的,但是类型是符合字段的值的。
send(IP(dst="www.baidu.com")/UDP()/NTP(version=4),loop=2) #未使用fuzz() send(IP(dst=" www.baidu.com")/fuzz(UDP()/NTP(version=4)),loop=2) #使用fuzz()SR()函数用来来发送数据包和接收响应。该函数返回有回应的数据包和没有回应的数据包;该函数也算得上是scapy的核心了,他会返回两个列表数据,一个是answer list 另一个是unanswered
> sr(IP(dst="192.168.115.1")/TCP(dport=[21,22,23])) Begin emission: Finished to send 3 packets. *** Received 3 packets, got 3 answers, remaining 0 packets Results: TCP:3 UDP:0 ICMP:0 Other:0>, Unanswered: TCP:0 UDP:0 ICMP:0 Other:0 > ans,unans=_ 这也是scapy的核心了 > ans.show() 0000 IP / TCP 192.168.115.198:ftp_data > 192.168.115.1:ftp S ==> IP / TCP 192.168.115.1:ftp > 192.168.115.198:ftp_data RA / Padding 0001 IP / TCP 192.168.115.198:ftp_data > 192.168.115.1:ssh S ==> IP / TCP 192.168.115.1:ssh > 192.168.115.198:ftp_data RA / Padding 0002 IP / TCP 192.168.115.198:ftp_data > 192.168.115.1:telnet S ==> IP / TCP 192.168.115.1:telnet > 192.168.115.198:ftp_data SA / Padding >sr(IP(dst="192.168.115.1")/TCP(dport=[21,22,23]),inter=0.5,retry=-2,timeout=1) 网络环境不好时,也可以追加inter retry timeout等附加信息,函数sr1()是sr()一个变种,只返回应答发送的分组(或分组集)。这两个函数发送的数据包必须是第3层数据包(IP,ARP等)。而函数SRP()位于第2层(以太网,802.3,等)。
> p=sr1(IP(dst="192.168.115.188")/ICMP()/"test") Begin emission: .....Finished to send 1 packets. .* Received 7 packets, got 1 answers, remaining 0 packets > p <IP version=4L ihl=5L tos=0x0 len=32 id=26000 flags= frag=0L ttl=128 proto=icmp chksum=0x6c79 src=192.168.115.188 dst=192.168.115.198 options=[] |<ICMP type=echo-reply code=0 chksum=0x1826 id=0x0 seq=0x0 |<Raw load='test' |<Padding load='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' | > p.show() ###[ IP ]### version= 4L ihl= 5L tos= 0x0 len= 32 id= 26000 flags= frag= 0L ttl= 128 proto= icmp chksum= 0x6c79 src= 192.168.115.188 dst= 192.168.115.198 \options###[ ICMP ]### type= echo-reply code= 0 chksum= 0x1826 id= 0x0 seq= 0x0 ###[ Raw ]### load= 'test' ###[ Padding ]### load= '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'1.数据包sniff
a=sniff(count=1,filter="tcp and host 192.168.1.1 and port 80")使用sniff主要是用于数据包的接收,根据filter设定的条件,将符合条件的数据包接收回来。
3. 场景构造
scapy的缺点是,他只负责构造包,是单向的。不像packetdrill这么完美,packetdrill 不但可以构造包,还能实现系统调用构造不同的场景,还能帮你检查协议栈发出的数据包是否符合预期。撩协tcp协议栈的过程不外乎两端,一端使用系统调用模拟协议栈行为,另外一端则是我们构造的包。常见场景主要是:服务器场景、客户端场景。
- 服务器场景:
服务器场景使用系统调用(即用户态程序),而客户端则是scapy构造的包。
在这里构造一个简单的三次握手后向服务器端发送数据。为了防止Linux客户端rst。
iptables -A OUTPUT -p tcp --tcp-flags RST RST -s 192.168.56.1 -j DROP
#!/usr/local/bin/python from scapy.all import * # VARIABLES src = sys.argv[1] dst = sys.argv[2] sport = random.randint(1024,65535) dport = int(sys.argv[3]) # SYN ip=IP(src=src,dst=dst) SYN=TCP(sport=sport,dport=dport,flags='S',seq=1000) SYNACK=sr1(ip/SYN) # ACK ACK=TCP(sport=sport, dport=dport, flags='A', seq=SYNACK.ack, ack=SYNACK.seq + 1) send(ip/ACK)
在这里可以安装一个nginx来验证。
- 客户端场景:
客户端场景使用系统调用(即用户态程序),而服务器端则是scapy构造包。
在这里使用scapy构造一个简单的http服务器。为了防止协议栈发送RST,需要对iptables进行设置。
iptables -A OUTPUT -p tcp --tcp-flags RST RST --sport 80 -j DROP
#!/usr/bin/python from scapy.all import * # Interacts with a client by going through the three-way handshake. # Shuts down the connection immediately after the connection has been established. # Akaljed Dec 2010, http://www.akaljed.wordpress.com # Wait for client to connect. a=sniff(count=1,filter="tcp and host 192.168.1.1 and port 80") # some variables for later use. ValueOfPort=a[0].sport SeqNr=a[0].seq AckNr=a[0].seq+1 # Generating the IP layer: ip=IP(src="/UploadFiles/2021-04-08/192.168.1.1">这个服务器只需要使用wget或者curl就可以实现验证了。
4. 参考资料
http://www.secdev.org/projects/scapy/doc/usage.html#starting-scapy
https://akaljed.wordpress.com/2010/12/12/scapy-as-webserver/
http://lost-and-found-narihiro.blogspot.com/2012/12/scapy-simple-web-server-with-scapy.html
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新动态
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]