codezen.fr code hacking, zen coding

24Mar/13Off

iCTF 2013 CTF – Nuclearboom Writeup

Posted by aXs

$ file nuclearboom
nuclearboom: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, not stripped

Nuclearboom was a service binary in the iCTF 2013 Attack & Defense CTF. You use it to manage your various nuclear plants.

$ nc localhost 4444
Control Panel:
1) build a new nuclear plant
2) list existing nuclear plants
3) display info of a nuclear plant
4) edit an existing nuclear plant
5) get self-destruction code
6) set new self-destruction code
7) exit
Your choice: 5
Choice: 5
Password: lol?
Wrong password. And since the self-destruction code is exactly what the Sicilian hackers are supposed to get, I will not give it to you. I hope you understand.

We need to get the self-destruction code but we don't have the password.

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align
  PHDR           0x000034 0x08048034 0x08048034 0x000120 0x000120 R E 0x4
  INTERP         0x000154 0x08048154 0x08048154 0x000013 0x000013 R   0x1
  [Requesting program interpreter: /lib/ld-linux.so.2]
  LOAD           0x000000 0x08048000 0x08048000 0x002620 0x002620 R E 0x1000
  LOAD           0x002f14 0x0804bf14 0x0804bf14 0x0001b4 0x000240 RW  0x1000
  DYNAMIC        0x002f28 0x0804bf28 0x0804bf28 0x0000c8 0x0000c8 RW  0x4
  NOTE           0x000168 0x08048168 0x08048168 0x000044 0x000044 R   0x4
  GNU_EH_FRAME   0x00219c 0x0804a19c 0x0804a19c 0x0000e4 0x0000e4 R   0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x000000 0x000000 RW  0x4
  GNU_RELRO      0x002f14 0x0804bf14 0x0804bf14 0x0000ec 0x0000ec R   0x1

Stack is not executable and .got/.dtor are read-only.

Where is the vulnerability ? After some disassembly and testing, we find a vulnerability in the sequence of checks of the "1) build a new nuclear plant" option.

Lets trace it in reverse order:

signed int __cdecl check_uranium_level(const char *plant_name)
{
  signed int status; // [sp+1Ch] [bp-Ch]@1

  status = 0;
  if ( *((_WORD *)plant_name + 54) <= 0 )
  {
    status = 1;
    printf("ARE YOU CRAZY? Uranium in nuclear plant \"");
    printf(plant_name);
    puts("\" is TOO HIGH!");
  }
  else
  {