this is not an alternative to pwntools, just some optimizations that i had found when working with it.
Pwntools is great, the best tool out there for binary exploitation. But we all agree that it is slow as all hell.
log - pretty formatting optimized for speed - warning - info - debug ; 3 levels to log
cyclic - Custom De Bruijn sequence
pack/unpack - Python Struct Module
aslr - read/write proc
gadgets - custom algorithm to form ROP gadgets
I will not be creating anything that interacts directly with the binary. This will be left to the big guns in paramiko, sockets, and pwntools. If I were to create a custom ssh, remote, and process handler for binaries, it would not be able to work alongside pwntools.
I cannot say for certain that I will be able to deliver the best in stability, speed, and implemetation so I will leave it to pwntools. My only goal with this project is to optimize.
The gadgets module is a little special, as in this case it is extremely unstable and experimental. It will first disassemble the binary provided, and run a custom algorithm to detect rop gadgets. These gadgets are then placed within a list and checked to see if it matches any templates.
For example, one template for a rop gadget is:
mov_gadget
pop_rax
pop_rdi
pop_rsi
pop_rdx
syscall
in this template, if we have all of the necessary gadgets within the binary, we will then begin to:
1. search for writeable regions in memory, will try .bss, then .data
2. write '/bin//sh' to writeable region, if x86 will split into 2 different writes
3. pop parameters depending on architecture, and pointer to '/bin//sh'
4. syscall and profit!
Obviously the point of this project is speed and optimization, so i will attempt to make everything as fast as pythonly possible. haha get it? because python is dreadfully slow? haha.
pack.py
this module is for fast packing and unpacking of 32/64 bit addresses. It uses python's struct packing module so it is essentially as fast as it gets, in as little lines of code as humanly possible.
also, a little not on the unpacking lambda function, why does struct.unpack return a tuple?? its the dumbest thing ive ever seen in my life, why does it do that???
#!/usr/bin/env python3
from struct import pack, unpack
pk32=lambda x,endian="little":pack(">I",x) if endian=="big" else pack("I", x)
pk64=lambda y,endian="little":pack(">Q",y) if endian=="big" else pack("Q", y)
up32=lambda x,endian="little":unpack(">I",x)[0] if endian=="big" else unpack("I",x)[0]
up64=lambda y,endian="little":unpack(">Q",y)[0] if endian=="big" else unpack("Q",y)[0]
aslr.py
next we have our aslr module, this is not exactly a sophisticated one, but simple one i have created for efficiency within my binary. I will not have to echo 0 into some randomize_va_space file that ive forgotten the path to, i can simple just turn it off.
#!/usr/bin/env python3
from sys import argv
path="/proc/sys/kernel/randomize_va_space"
def write(n):
with open(path, "w") as f:
f.write(n)
f.close()
def read():
with open(path, "r") as f:
return True if int(f.read())==0 else False
f.close()
if __name__ == "__main__":
try:
if len(argv)>1 and argv[1]=="-n":
write("0")
print("done!")
elif argv[1] == "-c":
if read():
print("Aslr is disabled")
else:
print("Aslr is enabled")
elif argv[1]=="-w":
try:
write(argv[2])
print("done!")
except IndexError:
print("Error: Must provide integer to write!\nExample: aslr -w 1")
except IndexError:
print("Usage: aslr [-n] [-c] [-w]")
print("-n\tturn off aslr\n-c\tcheck if aslr is enabled\n-w \twrite custom integer to aslr")
cyclic.py
This module has not been finished yet due to the complexity of it. I am going to attempt to make the fastest debrujin sequence generator and searcher. This means that i will need an extremely efficient generation and search algorithm.
#!/usr/bin/env python3
# not finished :)