Python使用SOCK_RAW构造HTTP原始数据包详解
本文解析如何在Python中利用SOCK_RAW原始套接字直接构造并发送HTTP数据报文。通过绕过标准TCP交互,使用Impacket库构建IP与TCP层,实现自定义HTTP内容的直接发送。文章提供完整代码示例及抓包验证,适用于需要精确控制网络数据包结构的场景。
本文深入解析Python中原始套接字(Raw Socket)的编程实例,通过详细的代码示例展示其应用方法,为相关学习或工作提供具有参考价值的技术指南。
原始套接字与标准套接字的区别
在特定实验场景中,若需自行构造独立的HTTP数据报文,使用标准的SOCK_STREAM套接字发送数据包时,必须经历完整的TCP三次握手及交互过程,这往往不符合直接注入报文的需求。
为此,采用原始套接字(SOCK_RAW)进行编程成为更优选择。该方法允许直接构造数据包,并在IP层进行发送,从而绕过传输层的封装限制。
使用SOCK_RAW的核心优势在于能够对数据包进行完全自定义的修改。它允许处理IP层上的所有数据包,并对各字段进行灵活调整,而不受UDP或TCP协议栈的固有约束。
HTTP数据包构造实现
接下来,我们将具体演示如何构造HTTP数据包。
在实现过程中,IP层和TCP层的构建借助Python的Impacket库完成,而HTTP报文的具体内容则根据实际需求自行填写。
完整代码示例
#!/usr/bin/env python
#-------------------------------------------------------------------------------
# Name: raw_http.py
# Purpose: construct a raw http get packet
#
# Author: Yangjun
#
# Created: 08/02/2014
# Copyright: (c) Yangjun 2014
# Licence: <your licence>
#-------------------------------------------------------------------------------
import sys
import socket
from impacket import ImpactDecoder, ImpactPacket
def main():
if len(sys.argv) < 3:
print "Use: %s <src ip> <dst ip>" % sys.argv[0]
print "Use: %s <src ip> <dst ip> <cnt>" % sys.argv[0]
sys.exit(1)
elif len(sys.argv) == 3:
src = sys.argv[1]
dst = sys.argv[2]
cnt = 1
elif len(sys.argv) ==4:
src = sys.argv[1]
dst = sys.argv[2]
cnt = sys.argv[3]
else:
print "Input error!"
sys.exit(1)
#print src, dst
ip = ImpactPacket.IP()
ip.set_ip_src(src)
ip.set_ip_dst(dst)
# Create a new ICMP packet of type ECHO.
icmp = ImpactPacket.ICMP()
tcp = ImpactPacket.TCP()
tcp.set_th_sport(55968)
tcp.set_th_dport(80)
tcp.set_th_seq(1)
tcp.set_th_ack(1)
tcp.set_th_flags(0x18)
tcp.set_th_win(64)
tcp.contains( ImpactPacket.Data("GET /att/DIYLife/41264/528 HTTP/1.1\r\nHost: 192.168.111.1\r\nAccept-Encoding: identity\r\n\r\n"))
ip.contains(tcp)
# Open a raw socket. Special permissions are usually required.
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
seq_id = 0
while cnt >= 1:
# Calculate its checksum.
seq_id = seq_id + 1
tcp.set_th_seq(seq_id)
tcp.calculate_checksum()
# Send it to the target host.
s.sendto(ip.get_packet(), (dst,80))
cnt= cnt -1
if __name__ == '__main__':
main()
代码运行后,通过抓包工具观察到的结果如下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













