我编写了这个简单的C程序来解释具有相同特征的更难的问题.
#include <stdio.h>
int main(int argc, char *argv[])
{
int n;
while (1){
scanf("%d", &n);
printf("%d\n", n);
}
return 0;
}
而且它的工作情况与预期一致.
我还编写了一个子流程脚本来与该程序交互:
from subprocess import Popen, PIPE, STDOUT
process = Popen("./a.out", stdin=PIPE, stdout=PIPE, stderr=STDOUT)
# sending a byte
process.stdin.write(b'3')
process.stdin.flush()
# reading the echo of the number
print(process.stdout.readline())
process.stdin.close()
问题是,如果我运行我的python脚本,readline()
上的执行就会冻结.事实上,如果我中断脚本,我会得到:
/tmp » python script.py
^CTraceback (most recent call last):
File "/tmp/script.py", line 10, in <module>
print(process.stdout.readline())
^^^^^^^^^^^^^^^^^^^^^^^^^
KeyboardInterrupt
如果我修改我的python脚本:
from subprocess import Popen, PIPE, STDOUT
process = Popen("./a.out", stdin=PIPE, stdout=PIPE, stderr=STDOUT)
with process.stdin as pipe:
pipe.write(b"3")
pipe.flush()
# reading the echo of the number
print(process.stdout.readline())
# sending another num:
pipe.write(b"4")
pipe.flush()
process.stdin.close()
我得到了以下输出:
» python script.py
b'3\n'
Traceback (most recent call last):
File "/tmp/script.py", line 13, in <module>
pipe.write(b"4")
ValueError: write to closed file
这意味着第一个输入被正确发送,并且读取也被完成.
我真的找不到任何东西来解释这种行为;有人能帮我理解吗? 提前谢谢你
[EDIT]:因为有很多点需要澄清,我添加了这个编辑.我正在使用rop
技术训练如何利用缓冲区溢出漏洞,我正在编写一个Python脚本来实现这一点.为了利用这个漏洞,由于ASLR,我需要发现libc
地址,并使程序重新启动而不终止.由于脚本将在目标机器上执行,我不知道哪些库可用,那么我将使用subprocess,因为它是内置在python中的.在不深入细节的情况下,攻击在第一个scanf
上发送一个序列bytes,目的是泄漏libc
基址并重新启动程序;然后发送第二个有效载荷以获得一个shell,我将在交互模式下与之通信.
这就是为什么:
- 我只能使用内置库
- 我必须发送字节并且不能追加结尾
\n
:我的有效负载将不对齐或可能利兹失败 - 我需要保持开放的
stdin
开放 - 我不能更改C代码