diff options
Diffstat (limited to '')
-rw-r--r-- | tools/sploit/sploit/__init__.py | 10 | ||||
-rw-r--r-- | tools/sploit/sploit/arch.py | 8 | ||||
-rw-r--r-- | tools/sploit/sploit/payload.py | 64 |
3 files changed, 76 insertions, 6 deletions
diff --git a/tools/sploit/sploit/__init__.py b/tools/sploit/sploit/__init__.py index 5082cfa..9e637df 100644 --- a/tools/sploit/sploit/__init__.py +++ b/tools/sploit/sploit/__init__.py @@ -1,2 +1,8 @@ -__all__ = ["log","comm","until","arch","mem"] -from sploit import log, comm, until, arch, mem +from sploit import ( + arch, + comm, + log, + mem, + payload, + until, +) diff --git a/tools/sploit/sploit/arch.py b/tools/sploit/sploit/arch.py index d75bbda..ce88111 100644 --- a/tools/sploit/sploit/arch.py +++ b/tools/sploit/sploit/arch.py @@ -5,24 +5,24 @@ def itob(i, signed=False): return i.to_bytes(arch.wordsize, arch.endianness, signed=signed) class Arch: - def __init__(self, wordsize, endianness, alignment, nop): + def __init__(self, wordsize, endianness, alignment, nopcode): self.wordsize = wordsize self.endianness = endianness self.alignment = alignment - self.nop = nop + self.nopcode = nopcode archx86 = Arch( wordsize = 4, endianness = "little", alignment = 16, - nop = b'\x90' + nopcode = b'\x90' ) archx86_64 = Arch( wordsize = 8, endianness = "little", alignment = 16, - nop = b'\x90' + nopcode = b'\x90' ) arch = archx86_64 diff --git a/tools/sploit/sploit/payload.py b/tools/sploit/sploit/payload.py new file mode 100644 index 0000000..49e0c04 --- /dev/null +++ b/tools/sploit/sploit/payload.py @@ -0,0 +1,64 @@ +from sploit.arch import arch, itob +from sploit.mem import Symtbl + +# Users can set this to the (absolute) address of a 'ret' ROP gadget. Some +# features may require it. +RETGADGET : int = None + +class Placeholder(bytearray): + def __init__(self, text='_unnamed_'): + self += bytearray(itob(0)) + self.text = text + +class Payload: + def __init__(self, size=0, base=0, **kwargs): + self.payload = b'' + self.size = size + self.alignstart = None + self.tab = Symtbl(base=base, **kwargs) + + def __len__(self): + return len(self.payload) + + def __getattr__(self, sym): + return getattr(self.tab, sym) + + def data(self, x, sym='_'): + off = len(self) + self.payload += x + setattr(self.tab, sym, off) + return getattr(self.tab, sym) + + def value(self, x, sym='_', signed=False): + return self.data(itob(x, signed=signed), sym=sym) + + def ret(self, x, sym='_'): + self.align() + return self.value(x, sym=sym) + + def stuff(self, x, size, sym='_', *, explain=''): + if size >= 0: + if (size := size / len(x)) == int(size): + if size == 0 or not isinstance(x, Placeholder): + return self.data(x * int(size), sym=sym) + + raise Exception(explain+"Can not stuff payload: " + f"Placeholder for {x.text} detected") + raise Exception(explain+"Can not stuff payload: " + "Element does not divide the space evenly") + raise Exception(explain+"Can not stuff payload: " + "Available space is negative") + + def pad(self, x=None, sym='_'): + size = self.size - len(self) + return self.stuff((x or arch.nopcode), size, sym=sym, + explain='Error padding payload: ') + + def align(self, x=None, sym='_'): + if self.alignstart is None: + self.alignstart = len(self) + + retgad = (itob(RETGADGET) if RETGADGET else Placeholder('ret gadget')) + size = (self.alignstart - len(self)) % arch.alignment + return self.stuff((x or retgad), size, sym=sym, + explain='Error aligning payload: ') |