|
用Python写漏洞利用代码,漏洞利用最怕的漏洞利用不是写不出来,而是漏洞利用写出来跑不通。我见过太多人拿着GitHub上的漏洞利用PoC改半天,结果连目标端口都连不上——问题往往出在环境差异和内存地址随机化上。漏洞利用去年帮朋友打一个CTF题,漏洞利用栈溢出漏洞,漏洞利用本地exp跑得飞起,漏洞利用远程一打就崩。漏洞利用折腾两小时才发现,漏洞利用远程的漏洞利用libc版本差了0.1,偏移量全变了。漏洞利用 Python做漏洞利用,漏洞利用核心就两件事:构造payload,漏洞利用发送payload。漏洞利用但这两件事的坑,比想象中深得多。 pwntools不是万能药 pwntools确实好用。`from pwn import *`一敲,`remote()`、`process()`、`sendline()`全有了。但很多人不知道,`context.log_level`默认是'info',调试时满屏日志,真正关键的报错反而被淹了。设成'debug'才看得清`recv()`到底收回了什么鬼东西。 有个细节:`sendline()`会自动加`\n`,但有些服务端用`read()`而不是`recvuntil()`,多一个换行符就可能让payload错位。我习惯用`send()`手动控制,虽然麻烦,但心里有数。 from pwn import * context(arch='amd64', os='linux', log_level='debug') p = remote('target.com', 1337) payload = b'A'*cyclic_find(0x6161616c) payload += p64(elf.symbols['system']) p.send(payload) p.interactive() 这段代码看着简单,`cyclic_find`那行要是填错偏移,直接段错误。`cyclic(100)`生成的是De Bruijn序列,`cyclic_find`找的是四字节值在序列中的位置。32位和64位系统,这个值不一样。我见过有人拿32位的偏移去打64位程序,崩得连回显都没有。 shellcode的编码陷阱 写shellcode最头疼的是坏字符。比如目标程序用`strcpy()`拷贝输入,`\x00`直接截断。这时候得用`msfvenom`编码,或者手写自解码。但`msfvenom`生成的编码shellcode,体积会膨胀三到五倍,缓冲区不够大就放不下。 更坑的是,有些WAF会检测`\xcd\x80`这种`int 0x80`指令。绕过的办法是用`syscall`替代,或者把指令拆成两半,运行时再拼回去。我试过用Python的`bytearray`动态构造,比纯静态shellcode灵活得多。 格式化字符串的精确打击 格式化字符串漏洞,Python写exp其实比C方便。因为`%n`写入的值可以用`pwntools`的`fmtstr_payload()`自动生成。但自动生成的东西,偏移量算错一位,整个payload就废了。 手动算偏移的方法:先发`AAAA%p.%p.%p...`,看第几个`%p`输出`0x41414141`。那个位置就是偏移。然后`%$n`写入。但要注意,写入的值如果太大,比如要写`0x0804a000`,得拆成两个`%hn`分两次写。`fmtstr_payload()`默认就是这么干的,但有时候它选的写入顺序会导致中间出现`\x00`,直接截断。 堆利用的Python表达 堆漏洞用Python写,比栈溢出麻烦。因为堆操作往往是多次交互,不是一次`send`就完事。比如`fastbin attack`,得先`malloc`几块,`free`掉,再`malloc`回来覆盖`fd`指针。每一步都要精确控制`send`和`recv`的时机。 我习惯用`recvuntil()`而不是`recv()`,因为`recv()`可能收到半截数据。但`recvuntil()`如果等不到指定字符串,会一直阻塞。加个`timeout`参数,超时就抛异常,比死等强。 堆的地址随机化比栈更烦。栈还能用`ret2libc`绕,堆得先泄露`heap base`。泄露方法通常是`unsorted bin`的`fd`指针,但前提是得先把chunk放进`unsorted bin`。这中间任何一步错了,泄露出来的就是垃圾数据。 调试比写exp重要 我写exp的时间,三分之一在写代码,三分之二在调试。`gdb.attach()`配合`pwntools`的`gdb.debug()`,能直接下断点看内存。但远程目标没法attach,只能用`cyclic`和`core dump`反推。 有个笨办法但管用:把payload分段发送,每段后面加个`\n`,看程序在哪一段崩溃。崩溃点对应的偏移,就是溢出点。这方法慢,但比瞎猜强。 Python漏洞利用,说到底是个手艺活。工具再顺手,也得知道底层发生了什么。不然`pwntools`报个`EOFError`,你连从哪查起都不知道。 |