scapy双线程,阻塞监听发包,握手挥手,发送http请求

1 篇文章 0 订阅
1 篇文章 0 订阅

涉及知识

1.握手和挥手的本质

这里的数据仅仅指的是应用层http里携带的的数据,不包括TCP和IP包头。

知识点1

假设你在发送数据,你常见的大致有以下可能:
1,起始的syn包,对于这个包,算它携带1字节长度数据
2,ack包,校验包,接收到消息后回复对方以收到的的包,算它不携带数据
3,psh_ack包,推送数据包,专门携带数据,和确认上次接收的数据无误
4,fin_psh_ack包,用于最后一次传输推送数据,和确认上次接收的数据无误(注意:是上一次接收数据哦,不是上一个包,tcp协议灵活就灵活在这里)这个算它携带数据再加一字节数据
总结:发送的是带有syn,fin的包都算一字节数据,ack包不算数据,psh包要计算自身携带的数据长度

知识点2

对于发送方(你自己),你发多少数据,你的序列号就增加多少,验证号不变
对于接收方(你自己),你接多少数据,你的验证号就增加多少,序列号不变
所以在处理验证号和序列号时,仅在在自己的角度去想就行,如设置全局变量,发送线程和接收线程两个线程去修改自己的序列号和验证号,实现时要注意控制好两个线程的执行顺序。

2其他知识

2.py threading模块

主要是要用线程事件来控制两个线程之间的执行顺序。
threading里有一个事件类Event(),生成一个全局实例对象后,可用其中的wait()方法使当前线程阻塞,让CPU去执行另一个线程,当在另一个线程里出现该对象的set()方法时,将切换到刚刚阻塞的wait()方法处去执行

3.scapy解析数据包

构建或者sniff()的数据包pkt,是分层的,seq = pkt[TCP].seq表示取数据包内的序列号;data = pkt[TCP].payload表示是取数据包的负载,也就是应用层的http数据

4.数据包里的flags

有好几种类型的包,其值取决于数据包的类型,如psh_ack其值就取“PA”

代码

之前写的一个关于scapy的帖子,用它自带的sr()发送和接收数据,没弄太懂怎么解析sr()方法返回的数据包的内容,就想着用sniff()另开一个线程试试

from scapy.all import *
from threading import *
from random import *

dport = 80
dst = "192.168.1.1"
sport = randrange(10241,22535)
seq=0
ack=0
###############便捷构造数据包模块函数#########
def createpkt(flags,data=""):
    global seq,ack 		#####引入全局变量############
    return IP(dst = dst)/TCP(dport=dport,sport=sport,seq=seq,ack=ack,flags=flags)/data
#################处理接收数据包####################
def a_handle(pkt):
    pass
def sa_handle(pkt):
    global ack
    ack = pkt[TCP].seq+1
def pa_handle(pkt):
    global ack
    ack += len(pkt[TCP].payload)
def fpa_handle(pkt):
    global ack
    ack += len(pkt[TCP].payload)+1
################选择哪一个处理方式##################
def handleflag(pkt):
    flags=pkt[TCP].flags
    print(flags)
    if flags == "A":
        a_handle(pkt)       
    elif flags == "SA":
        sa_handle(pkt)
        event1.set()
    elif flags == "PA":
        pa_handle(pkt)
    elif flags == "FPA":
        fpa_handle(pkt)		#####发送fin_psh_ack包,开始挥手
        event2.set()		####转跳到even2.wait()执行
    elif flags == "R":
        print("jianting  错误")
 #############监听线程入口###################
def sniffdata():
    sniff(filter = "src host 192.168.1.1 and tcp port 80",prn = handleflag,iface = 'Ethernet0')
##############设置两个线程事件############
event1 = Event()
event2 = Event()

Thread(target=sniffdata).start() ######开启监听线程
syn = createpkt(flags="S")	######获取第一个包
seq += 1		####趁监听线程没有回调处理函数(收到数据)之前,修改序列号
send(syn)		
event1.wait()		####设置阻塞,等待监听线程回调函数处理接收数据包————修改到正确的确认号,便于下次发包
send(createpkt(flags="A"))  ####	ack数据包序列号,确认号都不修改,可直接发包
data = "GET / HTTP/1.0/ \r\n\r\n"
psh_ack = createpkt(flags="PA",data=data)
seq += len(data)			###构造数据,计算自己增长多少序列号,然后发包并阻塞
send(psh_ack)
event2.wait()
send(createpkt(flags="A"))	###挥手ack确认
fin_ack = createpkt(flags = "FA") 
seq += 1
send(fin_ack)			###发送挥手

####还有一个包,目标机的挥手ack确认包
实现环境

目标机192.168.1.1,80端口,http服务
本机192.168.1.16,python环境,成功安装scapy

wireshark抓包

在这里插入图片描述
也不是尽善尽美,不知道为啥挥手时给我发了两次fin包,不过无关紧要,逻辑上没问题即可。

如果有收获就多多关注我吧,哎,一个粉丝都没有,太可怜了。

声明:仅用于技术分享,若私自用于违法活动,与本人无关。
另外:转载请注明出处,创作不易,谢谢啦
ps:本人胆小,怕被警察叔叔请去喝茶。如有不妥,请私信本人,本人立刻删除此贴

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值