在处理缓冲区溢出漏洞时,我发现了一些非常奇怪的东西。我已经成功地发现我需要在我想跳转到的正确地址之前提供 32 个字符,并且正确的地址是 0x08048a37
。当我执行
python -c "print '-'*32+'\x37\x8a\x04\x08'" | ./MyExecutable
漏洞利用成功了。但是,当我尝试时:
python3 -c "print('-'*32+'\x37\x8a\x04\x08')" | ./MyExecutable
它没有。可执行文件只是导致了段错误,而没有跳转到所需的地址。事实上,执行
python -c "print '-'*32+'\x37\x8a\x04\x08'"
和
python3 -c "print('-'*32+'\x37\x8a\x04\x08')"
在控制台上产生两种不同的输出。当然,这些字符不可读,但它们在视觉上有所不同。
我想知道为什么会这样?
最佳答案
Python 2 代码写入字节,Python 3 代码写入文本,然后将其编码为字节。因此后者不会写入相同的输出;这取决于为您的管道配置的编解码器。
在 Python 3 中,改为将字节写入 sys.stdout.buffer
对象:
python3 -c "import sys; sys.stdout.buffer.write(b'-'*32+b'\x37\x8a\x04\x08')"
您可能希望手动添加 \n
换行符,print
会添加。
sys.stdout
是 io.TextIOBase
object ,将写入它的数据编码为给定的编解码器(通常基于您的语言环境,但在使用管道时,通常默认为 ASCII),然后再将其传递给底层缓冲区对象。 TextIOBase.buffer
attribute让您直接访问底层 BufferedIOBase
object .
关于Python3 print() 与 Python2 打印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46874058/