做pwn感觉可以总结一些工具
脚本模板
首先是写pwn题exp的脚本模板
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
|
from pwn import * import os
DEBUG = 1
def localDebug(p): pid = util.proc.pidof(p)[0] with open("debug.sh", "w") as f: f.write("#!/bin/bash\n") f.write(f"gdb -p {pid}") os.chmod("debug.sh", 0o777)
def main(): if DEBUG: p = process("xxx") context.log_level = "debug" localDebug(p) else: p = remote("x.x.x.x", 1111)
if __name__ == "__main__": main()
|
没啥好说的,一个本地调试模式,一个远程模式。就说说调试方式,我不喜欢pwntools自带的gdb模块,因为要图形界面,但是我一般用的都是只有终端的,所以我喜欢一个屏幕对半分开,一个运行脚本,一个执行gdb。但是每次这种方式,都是手动打gdb -p xxx
,所以把这个直接加在模版里,就方便多了。这种方式加上pause()
来调试,感觉挺不错的。
加符号
有些题目有一些复杂的结构体,在ida里逆向逆出来了,但是使用gdb调试的时候却没办法直观的看这个结构体,然后想了个办法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| struct xx1 { xx };
struct xx2 { ... };
int main(int argc, char *argv[]) { struct xx1 a; struct xx2 b; write(1, "hello\n", 6); return 0; }
|
然后编译一下:
能得到一个symbol.o
然后在.gdbinit
里面加入:
1 2 3 4 5
| $ cat .gdbinit add-symbol-file symbol.o define SF p *(struct xx1 *) $arg0 end
|
然后可以加上一个命令,来打印出我们自己加上的这个结构体。
加插件
在调试开了PIE的程序的时候,每次想看看BSS段的数据,都要查看一下程序基地址,非常麻烦,所以我写了个插件,辅助我的操作:
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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
from email.mime import base import gdb
def getBase(pid): with open(f"/proc/{pid}/maps", "r") as f: data = f.readline() data = data.split("-")[0].strip("-") baseAddr = int(data, 16) return hex(baseAddr)
class PIEBreakPoint(gdb.Command): """when pie is on, show address, breakpoint etc. Usage: pb [offset] Example: (gdb) pb 0x1234 """
def __init__(self): super(self.__class__, self).__init__("pb", gdb.COMMAND_USER) def invoke(self, args, from_tty): pid = gdb.selected_inferior().pid if not pid: print("Please run program first.") return args = args.split(" ") if len(args) != 1: print("args error.") return offset = args[0] baseAddr = getBase(pid) cmd = f"b *({baseAddr} + {offset})" gdb.execute(cmd)
class PIEShowData(gdb.Command): """when pie is on, show address, breakpoint etc. Usage: pies [format] [offset] Example: (gdb) pies """
def __init__(self): super(self.__class__, self).__init__("pies", gdb.COMMAND_USER) def invoke(self, args, from_tty): pid = gdb.selected_inferior().pid if not pid: print("Please run program first.") return args = args.split(" ") if len(args) != 2: print("args error.") return offset = args[1] baseAddr = getBase(pid) cmd = f"{args[0]} ({baseAddr} + {offset})" gdb.execute(cmd)
PIEBreakPoint() PIEShowData()
|
以后还需要啥功能再继续加。上面这个功能好像GEF里面已经有了,但是我做堆题的时候还是比较喜欢pwndbg插件,这个插件里好像还没实现这个功能。
其他
以后想到啥再继续加