我正在用docker做一个简单的CTF(捕获旗帜)问题。目前的情况很简单(这不是一个真实的的问题,只是一个测试);输入指定的字符串并获取shell(/bin/bash
)(如果正确)。
原始的C源代码在这里。如果用户的输入正好是1n1tTheJourney2Pwnable
,则程序运行get_shell()
,从而向用户提供/bin/sh
。
// welcome.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
void get_shell() {
char *cmd = "/bin/sh";
char *args[] = {cmd, NULL};
execve(cmd, args, NULL);
}
int main() {
char buf[32];
initialize();
printf("input: ");
scanf("%s", buf);
if(strcmp(buf,"1n1tTheJourney2Pwnable") == 0) {
printf("SUCCESS!!\n");
get_shell();
} else {
printf("Wrong..!!\n");
}
return 0;
}
字符串
下面是该问题的Dockerfile
。
FROM ubuntu:20.04
# user name and the title of the problem are identical
ENV user welcome
ENV port 2023
RUN apt-get update
RUN apt-get install -y
RUN apt-get install -y socat gcc
RUN adduser $user
WORKDIR /home/$user
ADD ./$user.c /home/$user/$user.c
ADD ./flag /home/$user/flag
RUN gcc -o /home/$user/$user /home/$user/$user.c
RUN chown $user:$user /home/$user/$user
RUN chown $user:$user /home/$user/flag
RUN chmod 755 /home/$user/$user
RUN chmod 750 /home/$user/flag
USER $user
EXPOSE $port
CMD socat -T 30 TCP-LISTEN:$port,reuseaddr,fork EXEC:/home/$user/$user
型
我按如下方式构建Dockerfile
:
sudo docker build -t system_welcome <dockerfile location>
sudo docker run -p 2023:2023 system_welcome
型
当然,这个问题非常简单,只要在通过点击命令nc 127.0.0.1 2023
建立连接后键入以下字符串即可。不过,我想演示一下pwntool
的基本用法。所以我写了一个简单的脚本。
from pwn import context, remote, process
context.log_level = 'debug'
#p = process('./welcome')
p = remote('127.0.0.1', 2023)
p.recvuntil(b'input: ')
p.sendline(b'1n1tTheJourney2Pwnable')
p.interactive()
型
因此,程序按预期工作并获得shell(/bin/sh
)。但是,正如下面的图片所示,shell不会打印任何cat
命令的结果,即使交互式程序收到了数据。奇怪的是,来自其他命令(如id
或ls
)的结果却能正确显示。x1c 0d1x的数据
这是高度期望的pwntool
的问题或Dockerfile
的问题,但我找不到任何解决方案或提示来解决这个问题,所以我需要一些相关的帮助。
1条答案
按热度按时间lp0sw83n1#
问题的根本原因是
\r\n
和\n
之间的差异。在上一个问题的内容中,pwntool
接收到带有分隔符\r\n
的字符串数据,该分隔符在Windows操作系统中用作新行字符。然而,我使用的是Linux(Windows 11上的Ubuntu 22.04@WSL2)。经过检查,我发现
flag
不是在分隔符为\n
的Linux上编写的。(假设它将在Windows或Mac OS中创建。因此,我删除了带有
\r\n
分隔符的flag
文件,并完全在Linux中重新创建了flag
文件。修改后,一切都按我的意图和预期工作。的数据
问题的主要原因是近,但我看不到近18个小时(是的,这可能听起来很滑稽。)。我希望我的情况将有助于谁有麻烦与我的类似问题。总之,Docker和“pwn”都没有提出任何问题。
更多阅读:What is the difference between \r\n, \r, and \n?