使用pwntools获取shell后cat命令无输出的问题求助
解决CTF环境中cat命令无输出的问题
可能的原因分析
- 文件描述符未正确继承:如果你的C程序在执行
execve("/bin/sh", ...)之前关闭了标准输入(stdin)或标准输出(stdout),会导致cat无法读取输入或输出结果。比如程序中存在close(0)或close(1)的操作,却没有重新绑定到有效文件描述符。 - Shell流绑定异常:pwntools脚本的交互逻辑可能未正确处理shell的stdin/stdout,导致cat的输出无法被捕获或传输。
- Docker环境细节问题:容器内
/bin/cat权限异常、shell(如dash)的特殊配置,但这种情况概率较低——毕竟ls、id等命令能正常运行。
排查与修复步骤
1. 检查C源码中的文件描述符操作
查看获取shell的代码段,确认是否有误关闭关键文件描述符的逻辑:
// 错误示例:关闭stdout后未恢复,导致shell输出失效 close(1); execve("/bin/sh", NULL, NULL);
修复方式:确保execve前保留stdin(0)、stdout(1)、stderr(2)这三个描述符。如果必须清理其他fd,不要触碰这三个,或用dup2重新绑定:
// 正确示例:确保stdout绑定到原有输出流 dup2(STDOUT_FILENO, 1); execve("/bin/sh", argv, envp);
2. 调整pwntools脚本的交互逻辑
默认的p.interactive()可能在某些场景下无法处理cat的输出,尝试改用手动读写或开启raw模式:
from pwn import * p = remote("localhost", 1337) # 发送触发shell的字符串 p.sendline(b"1n1tTheJourney2Pwnable") # 尝试raw模式交互,避免流处理异常 p.interactive(raw=True) # 或者手动发送命令并读取输出 # p.sendline(b"cat flag.txt") # print(p.recvall())
3. 直接验证Docker容器内的cat功能
进入容器手动测试,排除容器本身的问题:
docker exec -it <容器ID> /bin/sh # 执行cat命令测试 cat /etc/passwd
如果容器内cat正常,问题出在漏洞利用后的流绑定;如果也不正常,检查cat的权限:
ls -l /bin/cat # 若权限缺失,执行修复 chmod +x /bin/cat
4. 确保execve调用的参数完整性
execve传递空环境变量可能导致shell异常,建议传递基础环境变量:
#include <unistd.h> #include <string.h> int main() { char buf[100]; read(0, buf, sizeof(buf)); if (!strcmp(buf, "1n1tTheJourney2Pwnable\n")) { char *envp[] = {"PATH=/bin:/usr/bin", "HOME=/", NULL}; execve("/bin/sh", NULL, envp); } return 0; }
总结
最常见的问题是关键文件描述符被错误关闭,重点检查C源码中execve前后的fd操作,确保stdin、stdout、stderr未被破坏。同时调整pwntools的交互模式,保证流正常传输。
内容的提问来源于stack exchange,提问作者KnightChaser
相关产品推荐
相关产品推荐

