I was making a simple CTF(Capture The Flag) problem with docker. The current case is simple(It's not a real problem, it's just a test.); enter a specified string and get a shell(/bin/bash
) if correct.
The original C source code is here. If the user's input is exactly 1n1tTheJourney2Pwnable
, the program runs get_shell()
which gives /bin/sh
to the user.
// 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;
}
Here is the Dockerfile
for the problem.
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
I build that Dockerfile
as below:
sudo docker build -t system_welcome <dockerfile location>
sudo docker run -p 2023:2023 system_welcome
Of course, this problem is very easy as just typing the following string after establishing a connection by hitting the command nc 127.0.0.1 2023
. However, I wanted to demonstrate the basic usage of pwntool
. So I wrote a simple script doing so.
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()
So, the program does work as expected and obtains the shell(/bin/sh
). However, as suggested in the picture below, the shell doesn't print anything as a result of cat
commands, even though the interactive program received the data. Oddly, results from other commands like id
or ls
are being shown correctly.
It's highly expected of pwntool
's problem or Dockerfile
's problem, but I couldn't find any solution or tips to resolve this problem, so I need some help related to this.