summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorMalfurious <m@lfurio.us>2022-03-14 00:43:15 -0400
committerMalfurious <m@lfurio.us>2022-03-14 00:43:15 -0400
commit380bc782b53bdafc2b1d5d37afb16d6d7b91a0e5 (patch)
tree6fb4228ddfc96d9591240e6a654e0fe199bb12fc /tools
parent6e24dc3d70b9e915c89d47dc8d7c816f1ba8ffab (diff)
parentcd12c17a6a41102f55ef034fb819a2ee093df356 (diff)
downloadlib-des-gnux-380bc782b53bdafc2b1d5d37afb16d6d7b91a0e5.tar.gz
lib-des-gnux-380bc782b53bdafc2b1d5d37afb16d6d7b91a0e5.zip
Merge tag 'pull-sploit-rev' of https://github.com/Dusoleil/lib-des-gnux
Add rev for basic reverse engineering * tag 'pull-sploit-rev' of https://github.com/Dusoleil/lib-des-gnux: sploit: Move __attr_filter__ to a general place in util sploit: Filter all magic python members by default in mem module sploit: add stack base pointer to locals symtbl sploit: print hex of addresses in rev logs sploit: add status logging to rev module sploit: lazy load libs for ELF sploit: cache results of external commands sploit: add the rest of r2 functions through elf sploit: typo fix in rev.r2 sploit: cache ELF loads sploit: add ELF helper class to rev sploit: consolidate r2 symbol search calls sploit: fix r2 module syntax error sploit: reverse direction of r2 get_locals offsets sploit: add r2 funcionality to rev module sploit: add ldd ability to rev module sploit: add rev module to sploit
Diffstat (limited to 'tools')
-rw-r--r--tools/sploit/setup.py4
-rw-r--r--tools/sploit/sploit/__init__.py2
-rw-r--r--tools/sploit/sploit/mem.py9
-rw-r--r--tools/sploit/sploit/rev/__init__.py6
-rw-r--r--tools/sploit/sploit/rev/elf.py56
-rw-r--r--tools/sploit/sploit/rev/ldd.py13
-rw-r--r--tools/sploit/sploit/rev/r2.py94
-rw-r--r--tools/sploit/sploit/util.py22
8 files changed, 201 insertions, 5 deletions
diff --git a/tools/sploit/setup.py b/tools/sploit/setup.py
index eb1b299..5afa958 100644
--- a/tools/sploit/setup.py
+++ b/tools/sploit/setup.py
@@ -1,7 +1,7 @@
-from setuptools import setup
+from setuptools import setup, find_packages
setup(
name='sploit',
version='0',
- packages=['sploit'],
+ packages=find_packages(),
entry_points={"console_scripts":["sploit=sploit.main:main"]}
)
diff --git a/tools/sploit/sploit/__init__.py b/tools/sploit/sploit/__init__.py
index 9e637df..f5a82fc 100644
--- a/tools/sploit/sploit/__init__.py
+++ b/tools/sploit/sploit/__init__.py
@@ -5,4 +5,6 @@ from sploit import (
mem,
payload,
until,
+ util,
+ rev,
)
diff --git a/tools/sploit/sploit/mem.py b/tools/sploit/sploit/mem.py
index 3ad0c50..ac2bbb1 100644
--- a/tools/sploit/sploit/mem.py
+++ b/tools/sploit/sploit/mem.py
@@ -1,3 +1,5 @@
+from sploit.util import __attr_filter__
+
class Symtbl:
__subs__ = {}
def __init__(self, **kwargs):
@@ -12,7 +14,7 @@ class Symtbl:
self.off = off
self.tbl = tbl
def __getattribute__(self,sym):
- if(sym in ['off','tbl','__class__']):
+ if(sym in (['off','tbl'] + __attr_filter__)):
return object.__getattribute__(self,sym)
addr = getattr(self.tbl,sym)
if(type(addr)==int):
@@ -30,7 +32,8 @@ class Symtbl:
def __getattribute__(self, sym):
addr = object.__getattribute__(self,sym)
- if(sym == '__subs__'):return addr
+ if(sym in (['__subs__'] + __attr_filter__)):
+ return addr
if(sym == 'base'):return 0
if(sym in self.__subs__):
return self.__InnerTable__(addr,self.__subs__[sym])
@@ -51,7 +54,7 @@ class Memmap:
self.base = addr - sym
def __getattribute__(self, sym):
- if(sym in ['__tbl__','base']):
+ if(sym in (['__tbl__','base'] + __attr_filter__)):
return object.__getattribute__(self, sym)
addr = getattr(self.__tbl__, sym)
if(type(addr)==Symtbl.__InnerTable__):
diff --git a/tools/sploit/sploit/rev/__init__.py b/tools/sploit/sploit/rev/__init__.py
new file mode 100644
index 0000000..43cee7b
--- /dev/null
+++ b/tools/sploit/sploit/rev/__init__.py
@@ -0,0 +1,6 @@
+from . import (
+ ldd,
+ r2,
+ elf,
+)
+
diff --git a/tools/sploit/sploit/rev/elf.py b/tools/sploit/sploit/rev/elf.py
new file mode 100644
index 0000000..7bfd31f
--- /dev/null
+++ b/tools/sploit/sploit/rev/elf.py
@@ -0,0 +1,56 @@
+from sploit.rev import ldd, r2
+from sploit.util import __attr_filter__
+
+class ELF:
+ def __init__(self, path):
+ self.path = path
+ self.sym = r2.get_elf_symbols(self.path)
+ libs = ldd.get_libraries(self.path)
+ self.libs = self.__LIBS__(libs)
+ self.locals = self.__LOCALS__(self)
+
+ def __str__(self):
+ s = 'ELF: '
+ s += self.path
+ s += '\nSymbol Table'
+ s += '\n------------'
+ s += '\n'
+ s += str(self.sym)
+ s += '\n------------'
+ s += '\nLibararies'
+ s += '\n------------'
+ s += str(self.libs)
+ return s
+
+ class __LIBS__(dict):
+ def __init__(self, libs):
+ super().__init__({lib.name:lib.path for lib in libs.values() if lib.path})
+ def __getitem__(self, lib):
+ get = super().__getitem__
+ if(type(get(lib))==str):self[lib] = ELF(get(lib))
+ return get(lib)
+ def __str__(self):
+ s = ''
+ for name,lib in self.items():
+ s += '\n' + str(name) + ' => ' + lib if(type(lib)==str) else str(lib.path)
+ return s
+
+ class __LOCALS__:
+ def __init__(self, elf):
+ self.elf = elf
+ def __getattribute__(self, sym):
+ if(sym in (['elf'] + __attr_filter__)):
+ return object.__getattribute__(self,sym)
+ return r2.get_locals(self.elf.path, getattr(self.elf.sym, sym))
+
+ def retaddr(self, caller, callee):
+ return [c.ret_addr for c in r2.get_call_returns(self.path, caller, callee)]
+
+ def retgad(self):
+ return r2.ret_gadget(self.path)
+
+ def gad(self, gad):
+ return [g.addr for g in r2.rop_gadget(self.path, gad)]
+
+ def egad(self, gad):
+ return r2.rop_gadget_exact(self.path, gad).addr
diff --git a/tools/sploit/sploit/rev/ldd.py b/tools/sploit/sploit/rev/ldd.py
new file mode 100644
index 0000000..1a28c7c
--- /dev/null
+++ b/tools/sploit/sploit/rev/ldd.py
@@ -0,0 +1,13 @@
+from sploit.util import run_cmd_cached
+from sploit.log import ilog
+
+import re
+from collections import namedtuple as nt
+
+def get_libraries(elf):
+ ilog(f'Retrieving linked libraries of {elf} with ldd...')
+ out = run_cmd_cached(['ldd',elf])
+ out = [re.split(r'\s+',lib)[1:] for lib in out]
+ Lib = nt("Lib", "name path addr")
+ out = {l[0]:Lib(l[0],l[0] if l[0][0]=='/' else l[2] if l[1]=='=>' else None,l[-1]) for l in out}
+ return out
diff --git a/tools/sploit/sploit/rev/r2.py b/tools/sploit/sploit/rev/r2.py
new file mode 100644
index 0000000..bb3edb3
--- /dev/null
+++ b/tools/sploit/sploit/rev/r2.py
@@ -0,0 +1,94 @@
+from sploit.mem import Symtbl
+from sploit.arch import arch
+from sploit.util import run_cmd_cached
+from sploit.log import ilog
+
+import re
+from collections import namedtuple as nt
+
+def run_cmd(binary,cmd):
+ return run_cmd_cached(['r2','-q','-c',cmd,'-e','scr.color=false',binary])
+
+def get_elf_symbols(elf):
+ ilog(f'Retrieving symbols of {elf} with r2...')
+ out = {}
+
+ cmd_syms = 'is'
+ out_syms = run_cmd(elf,cmd_syms)
+ out_syms = [re.split(r'\s+',sym) for sym in out_syms][4:]
+ out_syms = [sym for sym in out_syms if sym[6].find('.')<0]
+ out_syms = [sym for sym in out_syms if sym[4]=='FUNC' or sym[4]=='LOOS' or sym[4]=='TLS']
+ out_syms = {sym[6]:int(sym[2],0) for sym in out_syms}
+ out.update(out_syms)
+
+ cmd_syms = 'ii~ FUNC '
+ out_syms = run_cmd(elf,cmd_syms)
+ out_syms = [re.split(r'\s+',sym) for sym in out_syms]
+ out_syms = {"_PLT_"+sym[4]:int(sym[1],0) for sym in out_syms}
+ out.update(out_syms)
+
+ cmd_syms = 'fs relocs;f'
+ out_syms = run_cmd(elf,cmd_syms)
+ out_syms = [re.split(r'\s+',sym) for sym in out_syms]
+ out_syms = {"_GOT_"+sym[2][sym[2].rfind('.')+1:]:int(sym[0],0) for sym in out_syms}
+ out.update(out_syms)
+
+ cmd_strs = 'fs strings;f'
+ out_strs = run_cmd(elf,cmd_strs)
+ out_strs = [re.split(r'\s+',sym) for sym in out_strs]
+ out_strs = {sym[2][sym[2].rfind('.')+1:]:int(sym[0],0) for sym in out_strs}
+ out.update(out_strs)
+
+ return Symtbl(**out)
+
+def get_locals(binary,func):
+ ilog(f'Retrieving local stack frame of {hex(func)} in {binary} with r2...')
+
+ addr = hex(func)
+ cmd_locals = f's {func};af;aafr;aaft;afvf'
+ out = run_cmd(binary,cmd_locals)
+ out = [re.split(r':?\s+',var) for var in out]
+ out = {var[1]:-(int(var[0],0)-arch.wordsize) for var in out}
+ out = Symtbl(**out)
+ out.sbp = 0
+ return out
+
+def ret_gadget(binary):
+ ilog(f'Searching for a ret gadget in {binary} with r2...')
+
+ cmd_ret = '/R/ ret~ret'
+ out = run_cmd(binary,cmd_ret)
+ out = out[0]
+ out = re.split(r'\s+',out)
+ out = out[1]
+ return int(out,0)
+
+def rop_gadget(binary,gad):
+ ilog(f'Searching for "{gad}" gadgets in {binary} with r2...')
+
+ cmd_gad = f'"/R/q {gad}"'
+ out = run_cmd(binary,cmd_gad)
+ Gad = nt("Gad", "addr asm")
+ out = [Gad(int(gad[:gad.find(':')],0),gad[gad.find(':')+2:]) for gad in out]
+ return out
+
+def rop_gadget_exact(binary,gad):
+ gads = rop_gadget(binary,gad)
+ for g in gads:
+ if g.asm[:-1].replace('; ',';') == gad:
+ return g
+
+def get_call_returns(binary,xref_from,xref_to):
+ ilog(f'Getting return addresses of calls from {hex(xref_from)} to {hex(xref_to)} in {binary} with r2...')
+
+ cmd_xrefs = f's {hex(xref_from)};af;axq'
+ xrefs = run_cmd(binary,cmd_xrefs)
+ xrefs = [re.split(r'\s+',x) for x in xrefs]
+ xrefs = [x for x in xrefs if int(x[2],0)==xref_to]
+ rets = []
+ CallRet = nt("CallRet", "xref_from xref_to call_addr ret_addr")
+ for x in xrefs:
+ cmd_ret = f's {x[0]};so;s'
+ ret = run_cmd(binary,cmd_ret)
+ rets.append(CallRet(xref_from,xref_to,int(x[0],0),int(ret[0],0)))
+ return rets
diff --git a/tools/sploit/sploit/util.py b/tools/sploit/sploit/util.py
new file mode 100644
index 0000000..8a259c4
--- /dev/null
+++ b/tools/sploit/sploit/util.py
@@ -0,0 +1,22 @@
+from subprocess import run
+
+def run_cmd(cmd):
+ return run(cmd,capture_output=True).stdout.decode('utf-8').split('\n')[:-1]
+
+__RUN_CACHE__ = {}
+def run_cmd_cached(cmd):
+ key = ''.join(cmd)
+ if key in __RUN_CACHE__:
+ return __RUN_CACHE__[key]
+ else:
+ result = run_cmd(cmd)
+ __RUN_CACHE__[key] = result
+ return result
+
+__attr_filter__ = ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',
+ '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
+ '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__',
+ '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
+ '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
+ '__weakref__']
+