python3-pwntools教程_pwntools使用

本文详细介绍PWNTOOLS在pwn题目中的应用,涵盖工具安装、模块介绍、连接方式、IO操作、汇编与反汇编、Shellcode生成、ELF文件操作、ROP链生成等方面,帮助读者掌握PWNTOOLS的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

pwntools工具是做pwn题必备的EXP编写工具,这里写(抄)一些简单的用法,以备查询。

1.安装

安装可以参考我写的另一篇文章,不过也就几条命令。链接

2.模块介绍

使用from pwn import *将所有的模块导入到当前namespace,这条语句还会帮你把os,sys等常用的系统库导入。

常用模块如下:

asm : 汇编与反汇编,支持x86/x64/arm/mips/powerpc等基本上所有的主流平台

dynelf : 用于远程符号泄漏,需要提供leak方法

elf : 对elf文件进行操作

gdb : 配合gdb进行调试

memleak : 用于内存泄漏

shellcraft : shellcode的生成器

tubes : 包括tubes.sock, tubes.process, tubes.ssh, tubes.serialtube,分别适用于不同场景的PIPE

utils : 一些实用的小功能,例如CRC计算,cyclic pattern等

3.连接

本地 :sh = porcess("./level0")

远程:sh = remote("127.0.0.1",10001)

关闭连接:sh.close()

4.IO模块

sh.send(data) 发送数据

sh.sendline(data) 发送一行数据,相当于在数据后面加\n

sh.recv(numb = 2048, timeout = dufault) 接受数据,numb指定接收的字节,timeout指定超时

sh.recvline(keepends=True) 接受一行数据,keepends为是否保留行尾的\n

sh.recvuntil("Hello,World\n",drop=fasle) 接受数据直到我们设置的标志出现

sh.recvall() 一直接收直到EOF

sh.recvrepeat(timeout = default) 持续接受直到EOF或timeout

sh.interactive() 直接进行交互,相当于回到shell的模式,在取得shell之后使用

5. 汇编和反汇编

汇编:

>>> 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

使用disasm进行反汇编

>>> print disasm('6a0258cd80ebf9'.decode('hex'))

0: 6a 02 push 0x2

2: 58 pop eax

3: cd 80 int 0x80

5: eb f9 jmp 0x0

注意,asm需要binutils中的as工具辅助,如果是不同于本机平台的其他平台的汇编,例如在我的x86机器上进行mips的汇编就会出现as工具未找到的情况,这时候需要安装其他平台的cross-binutils。

6.Shellcode生成器

>>> print shellcraft.i386.nop().strip('\n')

nop

>>> print shellcraft.i386.linux.sh()

/* push '/bin///sh\x00' */

push 0x68

push 0x732f2f2f

push 0x6e69622f

...

结合asm可以可以得到最终的pyaload。

from pwn import *

context(os='linux',arch='amd64')

shellcode = asm(shellcraft.sh())

或者

from pwn import *

shellcode = asm(shellcraft.amd64.linux.sh())

除了直接执行sh之外,还可以进行其它的一些常用操作例如提权、反向连接等等。

7.ELF文件操作

>>> 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的地址

8.整数pack与数据unpack

pack:p32,p64

unpack:u32,u64

from pwn import *

elf = ELF('./level0')

sys_addr = elf.symbols['system']

payload = 'a' * (0x80 + 0x8) + p64(sys_addr)

...

9.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(elf)来产生一个rop的对象,这时rop链还是空的,需要在其中添加函数。

因为ROP对象实现了getattr的功能,可以直接通过func call的形式来添加函数,rop.read(0, elf.bss(0x80))实际相当于rop.call('read', (0, elf.bss(0x80)))。

通过多次添加函数调用,最后使用str将整个rop chain dump出来就可以了。

call(resolvable, arguments=()) : 添加一个调用,resolvable可以是一个符号,也可以是一个int型地址,注意后面的参数必须是元组否则会报错,即使只有一个参数也要写成元组的形式(在后面加上一个逗号)

chain() : 返回当前的字节序列,即payload

dump() : 直观地展示出当前的rop chain

raw() : 在rop chain中加上一个整数或字符串

search(move=0, regs=None, order=’size’) : 按特定条件搜索gadget

unresolve(value) : 给出一个地址,反解析出符号

LINK:

### Python pwntools教程 #### 安装与环境准备 为了使用 `pwntools` 进行开发,首先需要安装该库。可以通过 pip 工具来完成这一操作: ```bash pip install pwntools ``` 这一步骤确保了开发者拥有最新版本的 `pwntools`[^2]。 #### 基本概念理解 `pwntools` 是一个专门为CTF竞赛设计的强大框架和漏洞利用开发库。它简化了许多复杂的任务,比如创建shellcode、处理网络连接以及解析二进制文件等。 #### 创建Shellcode 通过内置命令可以方便地查看支持的目标平台及其对应的汇编指令集列表: ```python from pwn import * context.arch = 'amd64' print(shellcraft.linux.sh()) ``` 上述代码片段展示了如何生成适用于Linux系统的简单shellcode,这里设置架构为AMD64位并打印出相应的shellcode[^3]。 #### 处理远程服务交互 对于需要与远程服务器通信的情况,`pwntools` 提供了一个简洁而强大的接口来进行socket编程: ```python r = remote('example.com', 1234) r.recvuntil(b': ') r.sendline(b'hello world') response = r.recvall() print(response.decode()) ``` 这段脚本说明了怎样建立到指定主机和服务端口之间的TCP连接,并发送接收数据流。 #### 解析ELF文件 当涉及到逆向工程或分析可执行文件时,`pwntools` 的 ELF模块能够帮助读取和修改这些文件的信息: ```python binary = ELF('./vulnerable_binary') plt_write = binary.plt['write'] got_read = binary.got['read'] log.info(f"PLT entry for write(): {hex(plt_write)}") log.info(f"GOT entry for read(): {hex(got_read)}") ``` 此部分演示了获取特定函数在程序链接表(PLT)中的位置以及全局偏移量表(GOT)条目地址的方法[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值