>>> context.arch= 'i386'>>> context.os= 'linux'>>> context.endian= 'little'>>> context.word_size = 32
当然 , 你也可以一次性设置好这些变量:
>>> asm('nop')'\x90'>>> context(arch='arm', os='linux', endian='big', word_size=32)>>> asm('nop')'\xe3 \xf0\x00'
send(data): 发送数据sendline(data) : 发送一行数据 , 相当于在末尾加\nrecv(numb=4096, timeout=default) : 给出接收字节数,timeout指定超时recvuntil(delims, drop=False) : 接收到delims的pattern(以下可以看作until的特例)recvline(keepends=True) : 接收到\n , keepends指定保留\nrecvall() : 接收到EOFrecvrepeat(timeout=default) : 接收到EOF或timeoutinteractive() : 与shell交互
- ELF模块:获取基地址、获取函数地址(基于符号)、获取函数got地址、获取函数plt地址
e = ELF('/bin/cat')>>> print hex(e.address)# 文件装载的基地址0x400000>>> print hex(e.symbols['write']) # 函数地址0x401680>>> print hex(e.got['write']) # GOT表的地址0x60b070>>> print hex(e.plt['write']) # PLT的地址0x401680>>> print hex(e.search('/bin/sh').next())# 字符串/bin/sh的地址
- 在编写exp时 , 最常见的工作就是在整数之间转换 , 而且转换后 , 它们的表现形式就是一个字节序列 , pwntools提供了打包函数 。
p32/p64: 打包一个整数 , 分别打包为32位或64位u32/u64: 解包一个字符串 , 得到整数# 比如将0xdeadbeef进行32位的打包 , 将会得到'\xef\xbe\xad\xde'(小端序)payload = p32(0xdeadbeef)#pack 32 bits numberpayload = p64(0xdeadbeef)#pack 64 bits number
- 汇编和反汇编
# 汇编:>>> asm('nop')'\x90'>>> asm('nop', arch='arm')'\x00\xf0 \xe3'# 可以使用context来指定cpu类型以及操作系统>>> context.arch= 'i386'>>> context.os= 'linux'>>> context.endian= 'little'>>> context.word_size = 32# 反汇编>>> print disasm('6a0258cd80ebf9'.decode('hex'))0:6a 02push0x22:58popeax3:cd 80int0x805:eb f9jmp0x0
注意 , asm需要binutils中的as工具辅助 , 如果是不同于本机平台的其他平台的汇编 , 例如在我的x86机器上进行mips的汇编就会出现as工具未找到的情况 , 这时候需要安装其他平台的cross-binutils 。
- Shellcode生成器
>>> print shellcraft.i386.nop().strip('\n')nop>>> print shellcraft.i386.linux.sh()/* push '/bin///sh\x00' */push 0x68push 0x732f2f2fpush 0x6e69622f...
结合asm可以可以得到最终的pyaload
from pwn import *context(os='linux',arch='amd64')shellcode = asm(shellcraft.sh())或者from pwn import *shellcode = asm(shellcraft.amd64.linux.sh())
- ROP链生成器
elf = ELF('ropasaurusrex')rop = ROP(elf)rop.read(0, elf.bss(0x80))rop.dump()# ['0x0000:0x80482fc (read)',#'0x0004:0xdeadbeef',#'0x0008:0x0',#'0x000c:0x80496a8']str(rop)# '\xfc\x82\x04\x08\xef\xbe\xad\xde\x00\x00\x00\x00\xa8\x96\x04\x08'
rop.read(0, elf.bss(0x80))
实际相当于rop.call('read', (0,elf.bss(0x80)))
。通过多次添加函数调用 , 最后使用str将整个rop chain dump出来就可以了 。call(resolvable, arguments=())
: 添加一个调用 , resolvable可以是一个符号 , 也可以是一个int型地址 , 注意后面的参数必须是元组否则会报错 , 即使只有一个参数也要写成元组的形式(在后面加上一个逗号)经验总结扩展阅读
- 四十一 增删查改分页 Java开发学习----MyBatisPlus标准数据层开发
- 中 学习ASP.NET Core Blazor编程系列十——路由
- CC1,3,6回顾
- 图学习【参考资料2】-知识补充与node2vec代码注解
- 二十四 设计模式学习:Spring 中使用到的设计模式
- Java安全之CC3
- TensorFlow深度学习!构建神经网络预测股票价格!?
- JUC学习笔记——共享模型之管程
- Seata Server 1.5.2 源码学习
- 2022极端高温!机器学习如何预测森林火灾?? 万物AI