Hacking Tube

Site no longer updated. Migrated to https://bruce30262.github.io/

SCTF 2014 -- Pwn200

| Comments

SCTF is a CTF contest hold by XCTF ( seems like a Chinese version's CTFtime.org ). Teaming up with my labmates, we have a lot of fun solving the challenges, and scored 2161 pts with the final rank 13/659.

In Pwn200, they gave us a binary file and a libc.so. First we open the binary file with IDA Pro, and check the main function:

  int buf; // [sp+9Ch] [bp-1Ch]@1
  size_t n; // [sp+ACh] [bp-Ch]@1
 read(0, &buf, n + 1);
 if ( strlen((const char *)&buf) - 1 > 9 || strncmp("syclover", (const char *)&buf, 8u) )
    result = -1;
    write(1, "input slogan:", 0xEu);
    read(0, &v1, n);
    result = write(1, &v1, n);

notice at line read(0, &buf, n + 1);, we can overwrite the variable n by overflowing the buf variable. After we control n, we can input at most 255 characters at the line read(0, &v1, n);. By doing this, we can overwrite (control) the return address!

But there's one problem: the program has enable the DEP protection. Since it gave us the libc.so, we think they might want us to use the return-to-libc attack. By checking the GOT entry using objdump, we know the GOT entry of read() is at address 0x08049850.

So how do we get the address of system()? Well, since we can overwrite the return address, we can set the return address to write()'s GOT entry. By giving the parameter 0x08049850, we can leak the function pointer of read(), and calculate system()'s address by adding the offset ( we can get the offset by checking libc.so ).

After getting the address of system(), we can set the return address back to the head of main function, so we can execute the whole program again and write the memory by using read(). We can write "/bin/sh" to a memory address in .bss section, and set the return address to system(), with pointer to "/bin/sh" as the parameter. Finally, we spawn a shell and capture the flag.

To sum up, here's the step of the exploitation:
1. Overwrite n, so we can use read() to overwrite (control) the return address
2. Set the return address to write(), with the parameter 0x08049850 (read()'s GOT entry)
3. Calculate the address of system()
4. Set the return address back to the head of main function
5. Write "/bin/sh" to an address in .bss section by using read()
6. Repeat step 3 (for the final exploit)
7. Set the return address to system(), with pointer to "/bin/sh" as the parameter
8. Spawn the shell & capture the flag



comments powered by Disqus