Analysis
Al ejecutar el binario que se otorga simplemente muestra una dirección de memoria, que ahora mismo no sabemos que es pero podria servirnos como leak del binario.
Iniciamos desensamblando el binario, la función main, reserva espacio a una variable varGlobal y le establece como contenido la string A o 0x41, luego muestra la dirección de la varible con printf y llama a 3 funciones que ahora analizaremos.
❯ tree
.
├── Dockerfile
├── banner_fail
├── build.sh
├── chal
│ ├── Makefile
│ ├── chal
│ ├── chal.cpp
│ ├── check_functions.cpp
│ ├── check_functions.h
│ ├── hackdef.cpp
│ ├── hackdef.h
│ ├── libc.so.6 -> libchecks.so
│ ├── libchecks.so
│ ├── libhackdef.so
│ ├── print_flag.cpp
│ └── print_flag_docker
├── service.conf
├── start.sh
├── stop.sh
└── wrapper
2 directories, 19 files
❯ cat Dockerfile
FROM ubuntu:latest
RUN apt-get -qq update && apt-get install -qq --no-install-recommends xinetd libssl3
RUN groupadd -g 1001 ctf
RUN useradd -m -u 1001 -g 1001 -s /bin/bash ctf
COPY service.conf /service.conf
COPY banner_fail /banner_fail
COPY wrapper /wrapper
COPY chal/chal /home/ctf/chal
RUN chown ctf:ctf /home/ctf/chal
COPY chal/libchecks.so /usr/lib/x86_64-linux-gnu/
COPY chal/libhackdef.so /usr/lib/x86_64-linux-gnu/
COPY chal/print_flag_docker /print_flag
RUN chmod 755 /print_flag
RUN chmod u+s /print_flag
COPY flags/flag_00.txt /
COPY flags/flag_01.txt /
COPY flags/flag_02.txt /
COPY flags/flag_03.txt /
COPY flags/flag_04.txt /
COPY flags/flag_05.txt /
RUN chmod 444 /flag_0*.txt
COPY flags/flag_06.txt /root/
COPY flags/flag_ahaumx.txt /root/
COPY flags/flag_bluetm.txt /root/
COPY flags/flag_hackfc.txt /root/
COPY flags/flag_hawkss.txt /root/
COPY flags/flag_mylpwn.txt /root/
COPY flags/flag_pwndir.txt /root/
COPY flags/flag_snoopy.txt /root/
COPY flags/flag_takzac.txt /root/
COPY flags/flag_yaquic.txt /root/
RUN chmod 400 /root/flag_*.txt
EXPOSE 1380
USER ctf
CMD ["/usr/sbin/xinetd", "-filelog", "/dev/stderr", "-dontfork", "-f", "/service.conf"]
❯ ls -l /print_flag
-rwsr-xr-x 1 root root 50912 Oct 19 15:18 /print_flag
❯ ls -l /usr/lib/x86_64-linux-gnu/libchecks.so
-rwxr-xr-x 1 root root 900168 Oct 19 15:17 /usr/lib/x86_64-linux-gnu/libchecks.so
❯ ls -l /usr/lib/x86_64-linux-gnu/libhackdef.so
-rwxr-xr-x 1 root root 267520 Oct 19 15:17 /usr/lib/x86_64-linux-gnu/libhackdef.so
❯ ls -l /flag_0*.txt
.rw-r--r-- root root 31 B Sun Oct 19 16:38:10 2025 /flag_00.txt
.rw-r--r-- root root 31 B Sun Oct 19 15:54:24 2025 /flag_01.txt
.rw-r--r-- root root 31 B Sun Oct 19 15:54:24 2025 /flag_02.txt
.rw-r--r-- root root 31 B Sun Oct 19 15:54:24 2025 /flag_03.txt
.rw-r--r-- root root 31 B Sun Oct 19 15:54:24 2025 /flag_04.txt
.rw-r--r-- root root 31 B Mon Oct 20 11:53:27 2025 /flag_05.txt
❯ cat cat /flag_0*.txt
hackdef{0_f4k3_fl4g_4_t35t1ng}
hackdef{1_f4k3_fl4g_4_t35t1ng}
hackdef{2_f4k3_fl4g_4_t35t1ng}
hackdef{3_f4k3_fl4g_4_t35t1ng}
hackdef{4_f4k3_fl4g_4_t35t1ng}
hackdef{5_f4k3_fl4g_4_t35t1ng}
❯ sudo ls -l /root/flag_*.txt
.rw-r--r-- root root 31 B Sat Nov 1 15:58:43 2025 /root/flag_06.txt
.rw-r--r-- root root 37 B Sun Nov 2 10:58:22 2025 /root/flag_mylpwn.txt
❯ sudo cat /root/flag_*.txt
hackdef{6_f4k3_fl4g_4_t35t1ng}
hackdef{mylpwn_f4k3_fl4g_4_t35t1ng}
❯ ./chal
Servicio interno de tarjetas de credito
** Menu:
1. Registrar tarjeta
2. Registrar NIP
3. Consultar NIP
4. Borrar NIP
5. Salir
> cnt_checker = 1
Checking... 550
OK
int main() {
init_buffers();
init_flagprocess();
init_seccomp();
init_handlers();
init_flags();
ignorar_signals();
std::future<void> fut_flag_check = std::async(std::launch::async, service_flag_checker);
std::future<void> fut = std::async(std::launch::async, service_checker);
std::future<void> fut2 = std::async(std::launch::async, main_menu);
fut.wait_for(std::chrono::seconds(30));
return 0;
}
#define TIMEOUT_CHECK_FUNC 100
CheckFunc handlers[NUM_CHECK_FUNCS];
void init_handlers() {
handlers[0] = fn_000;
handlers[1] = fn_001;
handlers[2] = fn_002;
handlers[3] = fn_003;
.........................
handlers[1157] = fn_1157;
handlers[1158] = fn_1158;
handlers[1159] = fn_1159;
}
#define NUM_CHECK_FUNCS 290 * 4
#define TIMEOUT_CHECK_FUNC 100
void service_checker() {
int cnt_checks = 0;
while (cnt_checks++ < 4) {
std::cout << "cnt_checker = " << cnt_checks << std::endl;
int op = randint(NUM_CHECK_FUNCS - 1);
std::future<bool> fut = std::async(std::launch::async, execute_check, op);
if (fut.wait_for(std::chrono::milliseconds(TIMEOUT_CHECK_FUNC)) == std::future_status::ready) {
bool result = fut.get();
if (result) {
std::cout << "OK" << std::endl;
} else {
std::cout << "WA - Algo no anda bien. Te estare vigilando..." << std::endl;
salir();
}
} else {
std::cout << "Te descubri hacker!" << std::endl;
salir();
}
std::this_thread::sleep_for(std::chrono::seconds(10));
}
puts("Bye!");
salir();
}
bool execute_check(int op) {
std::cout << "Checking... " << op << std::endl;
switch (op) {
case 0: return check_000(handlers[0]);
case 1: return check_001(handlers[1]);
case 2: return check_002(handlers[2]);
.............................................
case 1157: return check_1157(handlers[1157]);
case 1158: return check_1158(handlers[1158]);
case 1159: return check_1159(handlers[1159]);
default:
std::cout << "NO" << std::endl;
salir();
}
return true;
}
#define TIMEOUT_CHECK_FUNC 160
bool check_000(CheckFunc check) {
int a=397540806, b=808190108, c=948268558, d=403076592, e=488643755;
std::future<void> fut = std::async(std::launch::async, check, &a, &b, &c, &d, &e);
if (fut.wait_for(std::chrono::microseconds(TIMEOUT_CHECK_FUNC)) == std::future_status::ready) {
if (b != 152045996) return false;
if (c != 727562417) return false;
if (d != 153545182) return false;
return true;
} else {
return false;
}
}
bool check_1159(CheckFunc check) {
int a=852726792, b=398756715, c=1025465896, d=783751113, e=391710928;
std::future<void> fut = std::async(std::launch::async, check, &a, &b, &c, &d, &e);
if (fut.wait_for(std::chrono::microseconds(TIMEOUT_CHECK_FUNC)) == std::future_status::ready) {
if (e != 898176514) return false;
if (a != 117814948) return false;
if (d != 87295856) return false;
return true;
} else {
return false;
}
}
void fn_000(int *a, int *b, int *c, int *d, int *e) {
*b = 152045996;
*c = 727562417;
*a = 333394009;
*d = 153545182;
*e = 460636857;
}
void fn_1159(int *a, int *b, int *c, int *d, int *e) {
*b = 76210336;
*c = 778987935;
*d = 87295856;
*a = 117814948;
*e = 898176514;
}





