tl;dr

  • Exploit code for a vulnerability in Firefox, found by saelo and coinbase security.
  • IonMonkey does not check for indexed elements on the current element’s prototypes, and only checks on ArrayPrototype. This leads to type-confusion after inlining Array.pop.
  • We confuse a Uint32Array and a Uint8Array to get a overflow in an ArrayBuffer and proceed to convert this to arbitrary read-write and execute shellcode.

This school CTF had a good set of challenges for beginners

pwn1

32-bit executable, dynamically linked, not stripped

When you run the executable in the terminal, the program simple asks for an input and checks whether it is the secret it is looking for or not.

debugging in GDB…

1
2
3
4
5
6
gdb-peda$ checksec
CANARY : disabled
FORTIFY : disabled
NX : ENABLED
PIE : disabled
RELRO : Partial

Going through the assembly code, we can see that see a gets() function. This gives us a chance to corrupt any stack address higher than the stack address where the gets() is to read into. We can also see a call to ‘print_flag’ function. This call instruction is executed only after a cmp instruction which compares [ebp-0xc] with ‘0xf007ba11’.

1
2
3
0x0804861d <+107>:	cmp    DWORD PTR [ebp-0xc],0xf007ba11
0x08048624 <+114>: jne 0x804862d <main+123>
0x08048626 <+116>: call 0x804854b <print_flag>