diff options
-rw-r--r-- | tools/sploit/__init__.py | 4 | ||||
-rw-r--r-- | tools/sploit/setup.py | 7 | ||||
-rwxr-xr-x | tools/sploit/sploit.py | 3 | ||||
-rw-r--r-- | tools/sploit/sploit/__init__.py | 10 | ||||
l--------- | tools/sploit/sploit/__main__.py | 1 | ||||
-rw-r--r-- | tools/sploit/sploit/arch.py | 21 | ||||
-rw-r--r-- | tools/sploit/sploit/comm.py | 180 | ||||
-rw-r--r-- | tools/sploit/sploit/log.py | 32 | ||||
-rw-r--r-- | tools/sploit/sploit/main.py | 60 | ||||
-rw-r--r-- | tools/sploit/sploit/mem.py | 53 | ||||
-rw-r--r-- | tools/sploit/sploit/payload.py | 75 | ||||
-rw-r--r-- | tools/sploit/sploit/rev/__init__.py | 6 | ||||
-rw-r--r-- | tools/sploit/sploit/rev/elf.py | 53 | ||||
-rw-r--r-- | tools/sploit/sploit/rev/ldd.py | 13 | ||||
-rw-r--r-- | tools/sploit/sploit/rev/r2.py | 99 | ||||
-rw-r--r-- | tools/sploit/sploit/until.py | 14 | ||||
-rw-r--r-- | tools/sploit/sploit/util.py | 14 |
17 files changed, 0 insertions, 645 deletions
diff --git a/tools/sploit/__init__.py b/tools/sploit/__init__.py deleted file mode 100644 index 8a53886..0000000 --- a/tools/sploit/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from os.path import join, dirname -libpath=join(dirname(__file__),"sploit") -__path__ = [libpath] -exec(open(join(libpath,"__init__.py")).read()) diff --git a/tools/sploit/setup.py b/tools/sploit/setup.py deleted file mode 100644 index 5afa958..0000000 --- a/tools/sploit/setup.py +++ /dev/null @@ -1,7 +0,0 @@ -from setuptools import setup, find_packages -setup( - name='sploit', - version='0', - packages=find_packages(), - entry_points={"console_scripts":["sploit=sploit.main:main"]} - ) diff --git a/tools/sploit/sploit.py b/tools/sploit/sploit.py deleted file mode 100755 index fd9b482..0000000 --- a/tools/sploit/sploit.py +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env python3 -from sploit.main import main -main() diff --git a/tools/sploit/sploit/__init__.py b/tools/sploit/sploit/__init__.py deleted file mode 100644 index f5a82fc..0000000 --- a/tools/sploit/sploit/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from sploit import ( - arch, - comm, - log, - mem, - payload, - until, - util, - rev, -) diff --git a/tools/sploit/sploit/__main__.py b/tools/sploit/sploit/__main__.py deleted file mode 120000 index 98537fc..0000000 --- a/tools/sploit/sploit/__main__.py +++ /dev/null @@ -1 +0,0 @@ -../sploit.py
\ No newline at end of file diff --git a/tools/sploit/sploit/arch.py b/tools/sploit/sploit/arch.py deleted file mode 100644 index e5de2ce..0000000 --- a/tools/sploit/sploit/arch.py +++ /dev/null @@ -1,21 +0,0 @@ -from collections import namedtuple as nt - -def btoi(b, signed=False): - return int.from_bytes(b, arch.endianness, signed=signed) - -def itob(i, signed=False): - return i.to_bytes(arch.wordsize, arch.endianness, signed=signed) - -Arch = nt("Arch", "wordsize endianness alignment nopcode") -x86 = Arch( 4, 'little', 16, b'\x90') -x86_64 = Arch( 8, 'little', 16, b'\x90') -ARM = Arch( 4, 'little', 8, b'\xe1\xa0\x00\x00') -THUMB = Arch( 4, 'little', 8, b'\x46\xc0') - -class __ActiveArch__: - __arch = x86_64 - def __getattr__(self,k): - return getattr(self.__arch,k) - def set(self,a): - self.__arch = a -arch = __ActiveArch__() diff --git a/tools/sploit/sploit/comm.py b/tools/sploit/sploit/comm.py deleted file mode 100644 index 67c97bc..0000000 --- a/tools/sploit/sploit/comm.py +++ /dev/null @@ -1,180 +0,0 @@ -import subprocess -import tempfile -import os -import sys -import select - -from sploit.log import * -from sploit.until import bind - -class Comm: - logonread = True - logonwrite = False - flushonwrite = True - readonwrite = False - timeout = 250 # milliseconds - - def __init__(self, backend): - self.back = backend - - def shutdown(self): - self.back.stdout.close() - - def read(self, size): - data = os.read(self.back.stdin.fileno(), size) - if(data == b''): - raise BrokenPipeError('Tried to read on broken pipe') - if self.logonread : ilog(data, file=sys.stdout, color=NORMAL) - return data - - def readline(self): - data = self.back.stdin.readline() - if(data == b''): - raise BrokenPipeError('Tried to read on broken pipe') - if self.logonread : ilog(data, file=sys.stdout, color=NORMAL) - return data - - def readall(self): - data = b'' - try: - for line in self.back.stdin: - if self.logonread : ilog(line, file=sys.stdout, color=NORMAL) - data += line - except KeyboardInterrupt: - pass - return data - - def readall_nonblock(self): - try: - data = b'' - os.set_blocking(self.back.stdin.fileno(), False) - poll = select.poll() - poll.register(self.back.stdin, select.POLLIN) - while True: - poll.poll(self.timeout) - d = self.readall() - if len(d) == 0: return data - data += d - finally: - os.set_blocking(self.back.stdin.fileno(), True) - - def readuntil(self, pred, /, *args, **kwargs): - data = b'' - pred = bind(pred, *args, **kwargs) - l = self.logonread - self.logonread = False - try: - while(True): - data += self.read(1) - if(pred(data)): - break - finally: - self.logonread = l - if self.logonread : ilog(data, file=sys.stdout, color=NORMAL) - return data - - def readlineuntil(self, pred, /, *args, **kwargs): - dataarr = [] - pred = bind(pred, *args, **kwargs) - while(True): - dataarr.append(self.readline()) - if(pred(dataarr)): - break - return dataarr - - def write(self, data): - self.back.stdout.write(data) - if self.flushonwrite : self.back.stdout.flush() - if self.logonwrite : ilog(data, file=sys.stdout, color=ALT) - if self.readonwrite : self.readall_nonblock() - - def writeline(self, data): - self.write(data + b'\n') - - def interact(self): - stdin = sys.stdin.buffer - event = select.POLLIN - - def readall_stdin(): - for line in stdin: - self.write(line) - - readtable = { - self.back.stdin.fileno(): self.readall_nonblock, - stdin.fileno(): readall_stdin, - } - - try: - ilog("<--Interact Mode-->") - os.set_blocking(stdin.fileno(), False) - - poll = select.poll() - poll.register(self.back.stdin, event) - poll.register(stdin, event) - - while True: - for fd, e in poll.poll(self.timeout): - if not e & event: return - readtable[fd]() - except KeyboardInterrupt: - pass - finally: - os.set_blocking(stdin.fileno(), True) - ilog("<--Interact Mode Done-->") - -def popen(cmdline=''): - io = Comm((Process(cmdline.split()) if len(cmdline) > 0 else Pipes())) - io.readall_nonblock() - io.readonwrite = True - return io - -class Process: - def __init__(self, args): - ilog(f"Running: {' '.join(args)}") - self.proc = subprocess.Popen(args, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - preexec_fn=lambda : os.setpgrp()) - ilog(f"PID: {self.proc.pid}") - self.stdin = self.proc.stdout - self.stdout = self.proc.stdin - - def __del__(self): - if getattr(self, 'proc', None) == None : return - if(self.proc.poll() != None): - return - try: - ilog("Waiting on Target Program to End...") - ilog("Press Ctrl+C to Forcefully Kill It...") - self.proc.wait() - except KeyboardInterrupt: - self.proc.kill() - -class Pipes: - def __init__(self, tmp=None): - if(tmp == None): - self.dir = tempfile.TemporaryDirectory() - dirname = self.dir.name - else: - if(not os.path.exists(tmp)): - os.mkdir(tmp) - dirname = tmp - self.pathin = os.path.join(dirname, "in") - self.pathout = os.path.join(dirname, "out") - os.mkfifo(self.pathin) - os.mkfifo(self.pathout) - ilog("Waiting on Target to Connect...", file=sys.stdout) - ilog(f"<{self.pathin} >{self.pathout}", file=sys.stdout) - self.stdout = open(self.pathin, "wb") - self.stdin = open(self.pathout, "rb") - ilog("Connected!") - - def __del__(self): - try: - if getattr(self,'stdout',None) : self.stdout.close() - if getattr(self,'stdin',None) : self.stdin.close() - except BrokenPipeError: - pass - if getattr(self,'pathin',None) and os.path.exists(self.pathin) : os.unlink(self.pathin) - if getattr(self,'pathout',None) and os.path.exists(self.pathout) : os.unlink(self.pathout) diff --git a/tools/sploit/sploit/log.py b/tools/sploit/sploit/log.py deleted file mode 100644 index 823b252..0000000 --- a/tools/sploit/sploit/log.py +++ /dev/null @@ -1,32 +0,0 @@ -import codecs -import sys - -# https://docs.python.org/3/library/codecs.html#standard-encodings -ENCODING = None - -ERROR = 31 -WARNING = 33 -STATUS = 32 -NORMAL = 0 -ALT = 90 - -def enc_value(value, enc): - if type(value) is bytes: - if enc is not None: - value = codecs.encode(value, enc) - elif ENCODING is not None: - value = codecs.encode(value, ENCODING) - value = str(value)[2:-1] # strip b'' - return str(value) - -def generic_log(*values, sep, end, file, flush, enc, color): - string = sep.join([ enc_value(x, enc) for x in values ]) - print(f'\033[{color}m{string}\033[0m', end=end, file=file, flush=flush) - -# For library internal use -def ilog(*values, sep=' ', end='\n', file=sys.stderr, flush=True, enc=None, color=STATUS): - generic_log(*values, sep=sep, end=end, file=file, flush=flush, enc=enc, color=color) - -# For external use in user script (via print = elog) -def elog(*values, sep=' ', end='\n', file=sys.stdout, flush=True, enc=None, color=ALT): - generic_log(*values, sep=sep, end=end, file=file, flush=flush, enc=enc, color=color) diff --git a/tools/sploit/sploit/main.py b/tools/sploit/sploit/main.py deleted file mode 100644 index b0fe3eb..0000000 --- a/tools/sploit/sploit/main.py +++ /dev/null @@ -1,60 +0,0 @@ -from argparse import ArgumentParser, REMAINDER -import gc -import tempfile -import traceback - -from sploit.comm import * -from sploit.log import * - -def print_banner(color, line1='', line2='', line3=''): - ilog() - ilog(' ░▒█▀▀▀█░▒█▀▀█░▒█░░░░▒█▀▀▀█░▀█▀░▀▀█▀▀ ', end='', color=ALT) - ilog(line1, color=ALT) - ilog(' ░░▀▀▀▄▄░▒█▄▄█░▒█░░░░▒█░░▒█░▒█░░░▒█░░ ', end='', color=color) - ilog(line2, color=ALT) - ilog(' ░▒█▄▄▄█░▒█░░░░▒█▄▄█░▒█▄▄▄█░▄█▄░░▒█░░ ', end='', color=ALT) - ilog(line3, color=ALT) - ilog() - -def main(): - parser = ArgumentParser(description='Execute Sploit script against target') - parser.add_argument('script', help='Exploit script to run') - parser.add_argument('target', nargs=REMAINDER, help='Target program to exploit') - args = parser.parse_args() - - if(len(args.target)>0): - target(args.script, args.target) - else: - pipe(args.script) - -def pipe(script): - print_banner(ERROR, line3='Pipe Mode') - with tempfile.TemporaryDirectory() as tmpdir: - while(True): - try: - p = Pipes(tmpdir) - except KeyboardInterrupt: - break - runscript(script, Comm(p)) - del p - -def target(script, target): - print_banner(STATUS, line3='Subprocess Mode') - runscript(script, Comm(Process(target))) - -def runscript(script, comm): - try: - ilog("Running Script...") - code = compile(open(script).read(), script, 'exec') - exec(code, {'io': comm, 'print': elog}) - ilog("Script Finished!") - comm.shutdown() - comm.readall() - return - except KeyboardInterrupt: - pass - except: - ilog(traceback.format_exc(), end='', color=ERROR) - finally: - gc.collect() - ilog("Script Ended Early!", color=WARNING) diff --git a/tools/sploit/sploit/mem.py b/tools/sploit/sploit/mem.py deleted file mode 100644 index 3a3e697..0000000 --- a/tools/sploit/sploit/mem.py +++ /dev/null @@ -1,53 +0,0 @@ -import types - -class Symtbl: - def __init__(self, *, base=0, **kwargs): - object.__setattr__(self, '_namesp', types.SimpleNamespace(base=base,sym={},sub={})) - for k, v in {**kwargs}.items(): - setattr(self, k, v) - - def __getattr__(self, ident): - self = self._namesp - if ident == 'base': return self.base - off = self.base + self.sym[ident] - if ident in self.sub: return self.sub[ident].map(off) - return off - - def __setattr__(self, ident, value): - if ident in dir(self): raise Exception(f'Symtbl: assignment would shadow non-symbol "{ident}"') - self = self._namesp - if ident == 'base': - self.base = value - else: - if type(value) is tuple: self.sub[ident], off = value - else: off = value - self.sym[ident] = off - self.base - - def map(self, addr, off=0): - self = self._namesp - mm = Symtbl() - mm._namesp.sym, mm._namesp.sub = self.sym, self.sub - mm._namesp.base = addr - off - return mm - - def adjust(self, off): - self = self._namesp - for k, v in self.sym.items(): - self.sym[k] = v + off - - def rebase(self, off): - self.adjust(self.base - off) - - def __str__(_self): - FMT = '\n{:<20} {:<20}' - self = _self._namesp - - s = f'{len(self.sym)} symbols @ {hex(_self.base)}' - s += FMT.format('ADDRESS', 'SYMBOL') - for sym, _ in sorted(self.sym.items(), key=lambda x:x[1]): - addr = getattr(_self, sym) - if type(addr) is Symtbl: - s += FMT.format(hex(addr.base), f'[{sym}]') - else: - s += FMT.format(hex(addr), sym) - return s diff --git a/tools/sploit/sploit/payload.py b/tools/sploit/sploit/payload.py deleted file mode 100644 index c916514..0000000 --- a/tools/sploit/sploit/payload.py +++ /dev/null @@ -1,75 +0,0 @@ -from sploit.arch import arch, itob -from sploit.mem import Symtbl - -class Payload: - MAGIC = b'\xef' - - def __init__(self, **kwargs): - self.payload = b'' - self.sym = Symtbl(**kwargs) - self.ctrs = {} - - def __len__(self): - return len(self.payload) - - def __call__(self, badbytes=b''): - found = [ hex(x) for x in set(self.payload).intersection(badbytes) ] - if len(found) > 0: - raise Exception(f'Payload: bad bytes in content: {found}') - return self.payload - - def _name(self, kind, sym): - if sym is not None: return sym - try: ctr = self.ctrs[kind] - except: ctr = 0 - self.ctrs[kind] = ctr + 1 - return f'{kind}_{ctr}' - - def _append(self, value, sym): - setattr(self.sym.map(0), sym, len(self)) - self.payload += value - return self - - def _prepend(self, value, sym): - self.sym.adjust(len(value)) - setattr(self.sym.map(0), sym, 0) - self.payload = value + self.payload - return self - - def bin(self, *values, sym=None): - return self._append(b''.join(values), sym=self._name('bin', sym)) - - def str(self, *values, sym=None): - values = [ v.encode() + b'\x00' for v in values ] - return self.bin(*values, sym=self._name('str', sym)) - - def int(self, *values, sym=None, signed=False): - values = [ itob(v, signed=signed) for v in values ] - return self.bin(*values, sym=self._name('int', sym)) - - def ret(self, *values, sym=None): - return self.int(*values, sym=self._name('ret', sym)) - - def sbp(self, *values, sym=None): - if len(values) == 0: - return self.rep(self.MAGIC, arch.wordsize, sym=self._name('sbp', sym)) - return self.int(*values, sym=self._name('sbp', sym)) - - def rep(self, value, size, sym=None): - return self.bin(self._rep_helper(value, size), sym=self._name('rep', sym)) - - def pad(self, size, value=None, sym=None): - return self.bin(self._pad_helper(size, value), sym=self._name('pad', sym)) - - def pad_front(self, size, value=None, sym=None): - return self._prepend(self._pad_helper(size, value), sym=self._name('pad', sym)) - - def _rep_helper(self, value, size, *, explain=''): - if size < 0: - raise Exception(f'Payload: {explain}rep: available space is negative') - if (size := size / len(value)) != int(size): - raise Exception(f'Payload: {explain}rep: element does not divide the space evenly') - return value * int(size) - - def _pad_helper(self, size, value): - return self._rep_helper(value or arch.nopcode, size - len(self), explain='pad: ') diff --git a/tools/sploit/sploit/rev/__init__.py b/tools/sploit/sploit/rev/__init__.py deleted file mode 100644 index 43cee7b..0000000 --- a/tools/sploit/sploit/rev/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from . import ( - ldd, - r2, - elf, -) - diff --git a/tools/sploit/sploit/rev/elf.py b/tools/sploit/sploit/rev/elf.py deleted file mode 100644 index e099819..0000000 --- a/tools/sploit/sploit/rev/elf.py +++ /dev/null @@ -1,53 +0,0 @@ -from sploit.rev import ldd, r2 - -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 __getattr__(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 deleted file mode 100644 index 1a28c7c..0000000 --- a/tools/sploit/sploit/rev/ldd.py +++ /dev/null @@ -1,13 +0,0 @@ -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 deleted file mode 100644 index 6dfd499..0000000 --- a/tools/sploit/sploit/rev/r2.py +++ /dev/null @@ -1,99 +0,0 @@ -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_base = 'iI~baddr' - base = run_cmd(elf,cmd_base) - base = re.split(r'\s+',base[0])[1] - base = int(base,0) - - 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(base=base, **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/until.py b/tools/sploit/sploit/until.py deleted file mode 100644 index b4f390f..0000000 --- a/tools/sploit/sploit/until.py +++ /dev/null @@ -1,14 +0,0 @@ -from functools import partial as bind -import re - -def lastline(pred, /, *args, **kwargs): - s = args[-1] - args = args[:-1] - p = bind(pred, *args, **kwargs) - return p(s[-1]) - -def contains(regex, s): - return re.search(regex, s) - -def equals(regex, s): - return re.fullmatch(regex, s) diff --git a/tools/sploit/sploit/util.py b/tools/sploit/sploit/util.py deleted file mode 100644 index c44ab78..0000000 --- a/tools/sploit/sploit/util.py +++ /dev/null @@ -1,14 +0,0 @@ -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 |