发送UDP数据包指定源端口,但未绑定
我想在Python中发送一个UDP数据包,并指定源端口,但不想进行绑定。
类似于用hping3实现的效果:
hping3 -s $sourceport -p $remoteport --udp --file message.bin -d 1024 -c 1 $remoteaddr
我尝试做了这样的事情:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((SHOST, SPORT))
但当然,Python会尝试进行绑定,这样就不行了。如果我不进行绑定,我可以这样做:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
s.sendto("message", (RHOST, RPORT))
消息确实发送出去了,但现在源端口没有被定义。
有没有人有什么想法?
补充说明:我这个Python脚本是为了配合另一个应用程序,这个应用程序是一个绑定在特定端口(1024以上)的UDP服务器。我的脚本只需要向一个远程服务器发送UDP数据包,但希望使用和我本地UDP服务器相同的源端口,这样远程UDP服务器就会认为本地UDP服务器是这个数据包的发送者,并会继续与它进行通信。
我还想说,这完全是合法的应用,和任何黑客行为没有关系(实际上,它已经可以在hping3中工作,但我想去掉这个依赖)。
补充说明 2:解决方案在下面的评论中 Nos的回答:
使用pyip这个Python包,创建一个原始套接字。别忘了要以root身份运行,因为只有root用户才能发送原始数据包(这不是Python的限制,而是操作系统的限制,这是为了防止安全问题,所以作为普通用户发送原始数据包需要调整你的操作系统配置)。
1 个回答
在Python中,没有直接的办法可以发送一个指定源端口的UDP数据包,而且在大多数(几乎所有?)Python可以运行的操作系统上也是如此,除非你先把套接字绑定到一个本地端口。
所以,如果你想控制源端口,就必须使用bind()来绑定你的套接字。
如果bind()“不工作”,那么可能是因为你试图绑定一个已经被其他进程占用的端口,或者你绑定的端口号小于1024,这个端口号只能由超级用户(root用户)来绑定,或者你给bind()传递了其他错误的参数——不过我们需要更多的信息来帮助你,比如你收到的错误信息,实际传给bind的参数等等。