前言
一开始写这个工具是因为在学习pwn
的过程中,经常反复的去注释和取消注释gdb.attach(xxx)
这样的语句,下不同断点的时候要不断地修改脚本,本地调通打远程的时候也要改脚本。
习惯命令行操作后,我设想能否设计一个命令行工具,能通过命令行参数去控制一些东西,避免在调试pwn
题的时候重复地执行上面这些工作而只专注于编写解题脚本。当想法酝酿起来,自己便试着写下第一行代码,于是,pwncli
就此诞生。
工具的目的在于实用性,我觉得pwncli
满足实用性要求,在调试pwn
题时能节省大量的时间。
如果你觉得pwncli
好用,请介绍给周围的pwner
。如果你还有任何疑问,请提交issue
或联系我[email protected]
,我将非常乐意与你讨论交流。如果你有好的想法,或者发现新的bug
,欢迎提交pull requests
。
🏴🏴🏴 欢迎各位师傅关注我的个人博客,以下两个博客网站内容相同,互为备份。前者为github page
,后者部署在国内阿里云服务器上。博客持续更新中~
简介
pwncli
是一款简单、易用的pwn
题调试与攻击工具,能提高你在CTF
比赛中调试pwn
题脚本的速度与效率。
pwncli
可以帮助你快速编写pwn
题攻击脚本,并实现本地调试和远程攻击的便捷切换。pwncli
支持三种使用模式:
- 命令行使用模式
- 脚本内使用模式
- 库导入使用模式
以上三种模式分别简称为:命令行模式、脚本模式和库模式。其中,命令行模式与其他命令行工具(如linux
下的ls
、tar
等命令)使用方式相同,可用于本地交互调试;脚本模式可将自己编写的python
攻击脚本包装为命令行工具,然后调用子命令执行所需功能;库模式则只会调用一些便捷的工具函数,方便快速解题。
在下面的使用模式章节将会详细的阐述三种模式的使用方式与技巧。
pwncli
设计为主命令-子命令模式(与git
类似),目前已拥有的(子)命令有:
pwncli
config
list
set
debug
misc
gadget
setgdb
patchelf
qemu
remote
其中,pwncli
为主命令,config/debug/misc/patchelf/qemu/remote
为一级子命令,list/set
为隶属config
的二级子命令,gadget/setgdb
为隶属misc
的二级子命令。
pwncli
支持命令的前缀匹配(与gdb
的命令前缀匹配类似),通常只需要给出命令的前缀即可成功调用该命令。即输入pwncli debug ./pwn
、pwncli de ./pwn
和pwncli d ./pwn
的执行效果是完全一样的。但是,必须保证前缀不会匹配到两个或多个子命令,否则将会抛出MatchError
的匹配错误。
pwncli
极易扩展。只需要在pwncli/commands
目录下添加cmd_xxx.py
,然后编写自己的子命令即可。pwncli
会自动探测并加载子命令。例如,你想新增一个magic
命令,你只需要:
1. 在pwncli/commands目录下新增cmd_magic.py文件
2. 在cmd_magic.py内编写命令的执行逻辑
当需要移除该命令时,可以删除cmd_magic
文件,或将其重命名为非cmd_
开头即可。
pwncli
依赖于click 和 pwntools。前者是一款优秀的命令行编写工具,后者是pwner
普遍使用的攻击库。
总结pwncli
的优点为:
- 脚本只需编写一次,使用命令行控制本地调试与远程攻击
- 调试过程中方便设置断点与执行其他
gdb
命令 - 可轻松扩展并自定义子命令
- 内置许多有用的命令与函数
安装
pwncli
可以在linux
和windows
下使用,但在windows
下使用受限严重,如debug
命令将无法使用,remote
命令仅部分可用。pwncli
只能在python3
环境上使用,目前暂不考虑与python2
兼容。
建议在ubuntu
系统上使用pwncli
,特别的,如果你了解WSL
并选择使用WSL
解答pwn
题,pwncli + WSL
将是一个极佳的选择。debug
子命令为WSL
系统设计了许多实用的参数,并实现了一些有趣的功能。
如果你选择使用WSL
,那么,请尽量保证发行版的名字(distribution name)为默认的Ubuntu-16.04/Ubuntu-18.04/Ubuntu-20.04/Ubuntu-22.04
。debug
命令的某些选项与默认发行版名称联系紧密。
pwncli
的安装方式有两种,第一种是本地安装(强烈建议使用此种方式安装):
git clone https://github.com/RoderickChan/pwncli.git
cd ./pwncli
pip3 install --editable .
安装结束后,别忘了将pwncli
所在的路径添加到PATH
环境变量,其路径一般为~/.local/bin
。可以在家目录下的.bashrc/.zshrc
文件中添加export PATH=$PATH:/home/xxx/.local/bin
。
这种方式安装的好处是:当你需要pwncli
保持更新时,只需要执行git pull
即可使用最新版本的pwncli
。
第二种安装方式是使用pip3
安装:
pip3 install pwncli
这种方式安装的pwncli
可能不是最新版本,会遇到一些已解决的bug
。不过请相信我,我会及时将pwncli
更新到pypi
上去的。
安装结束后,执行pwncli --version
,看到版本信息输出则代表安装成功。
使用模式
命令行模式
你可以将pwncli
视为一个命令行工具,虽然其本质是一个python
脚本。使用pwncli -h
或者pwncli --help
将会获取到命令行的使用指导。如果你想获取某个子命令的使用指导,如debug
命令,输入pwncli debug -h
即可。
脚本模式
除了将pwncli
当作命令行工具使用外,你还可以将脚本封装为一个命令行工具,之后,就能像使用pwncli
一样使用这个脚本。
脚本模式的使用非常简单,如你的攻击脚本为exp.py
,在脚本中写下:
#!/usr/bin/env python3
from pwncli import *
cli_script() # 使用脚本模式必须调用这个函数
然后,在命令行输入python3 exp.py -h
即可获得和命令行模式下pwncli -h
一样的输出。特别的,如果你在脚本的第一行指定了解释器路径,那么你可以输入./exp.py -h
而无需显式输入python3
。
之后,你可以将exp.py
当成pwncli
,使用pwncli
所拥有的各项命令与功能。
当然,你可以丰富你的脚本,使其实现更多功能,如使用debug
和remote
命令时,你可以在脚本后面继续添加:
#!/usr/bin/env python3
from pwncli import *
cli_script() # 使用脚本模式必须显式调用这个函数
# 你能够从gift里面取到很多东西
io = gift['io'] # process或remote对象
elf = gift["elf"] # ELF对象,ELF("./pwn")
libc = gift.libc # ELF对象, ELF("./libc.so.6")
filename = gift.filename # current filename
is_debug = gift.debug # is debug or not
is_remote = gift.remote # is remote or not
gdb_pid = gift.gdb_pid # gdb pid if debug
# 有时候远程提供的libc与本地不一样,打靶机时替换libc为远程libc
if gift.remote:
libc = ELF("./libc.so.6")
gift['libc'] = libc
# 这里写下攻击函数等
# ......
io.interactive() # 与socket保持交互
熟悉pwntools
的小伙伴对上面的脚本肯定不会陌生。从本质上来说,调用cli_script()
后会解析命令行参数,之后将一些有用的数据放置在gift
中。如你可以取出io
,就是pwntools
模块中的process
或remote
对象,并与其交互。
库模式
库模式,顾名思义,适用于你仅仅需要使用pwncli
的一些函数或功能而不需要使用命令行解析参数的场景。你可以像使用其他python
库一样使用pwncli
,如在脚本中写下:
from pwncli import *
# 这里写下脚本的其他内容
# 你可以使用pwncli中提供的使用接口
context.arch="amd64"
io = process("./pwn")
# 如你需要根据偏移搜索libc版本与其他函数
# 该功能与LibcSearcher类似,但不需要本地安装,需要联网使用
libc_box = LibcBox()
libc_box.add_symbol("system", 0x640)
libc_box.add_symbol("puts", 0x810)
libc_box.search(download_symbols=False, download_so=False, download_deb=True) # 是否下载到本地
read_offset = libc_box.dump("read")
# 根据pid获取程序的libc基地址
res = get_segment_base_addr_by_proc_maps(pid=10150)
libc_base = res['libc']
heap_base = get_current_heapbase_addr() # 仅用于本地调试
# 获取shellcode
cat_flag = ShellcodeMall.amd64.cat_flag
reverse_tcp = ShellcodeMall.amd64.reverse_tcp_connect(ip="127.0.0.1", port=10001)
# 使用一些便捷的装饰器
# 在调用该函数前休眠
@sleep_call_before(1)
def add():
pass
# 若该函数10s内都没有运行结束,就会抛出异常
@bomber(10)
def del_():
pass
# api不再使用
@unused()
def wtf():
pass
# 搜索gadget
ropper_box = RopperBox()
ropper_box.add_file("libc", "libc.so.6", arch=RopperArchType.x86_64)
pop_rdi_ret = ropper_box.get_pop_rdi_ret()
leav_ret = ropper_box.search_gadget("leave; ret")
# 构造IO_FILE结构体
fake_file = IO_FILE_plus_struct()
fake_file.flags = 0xfbad1887
fake_file._mode = 1
fake_file.vtable = 0xdeadbeef
payload = bytes(fake_file)
# 替换payload
payload = "aaaabbbbcccc"
new_payload = payload_replace(payload, {4: "eeee"}) # aaaaeeeecccc
# 获取当前装载的libc的gadget
all_ogs = get_current_one_gadget_from_libc()
# 封装当前io的常用操作函数
# sendline
sl("data")
# sendafter
sa("\n", "data)
# 直接使用当前gadget
CurrentGadgets.set_find_area(find_in_elf=True, find_in_libc=False, do_initial=False)
pop_rdi_ret = CurrentGadgets.pop_rdi_ret()
execve_chain = CurrentGadgets.execve_chain(bin_sh_addr=0x11223344)
# pwncli中还有许多其他实用的接口
# ......
io.interactive()
不难发现,库模式与命令模式的使用区别:去掉cli_script()
即可。需要注意,库模式下的脚本就是一个普通的python
脚本,并不能解析命令行参数。
教程
asciinema
版本教程依次如下:
以下为简易的文字版教程。
在使用pwncli
之前,建议掌握gdb/tmux
的基本命令,确保已安装了pwndbg/gef/peda
等其中一个或多个插件。
以脚本模式下的debug
命令为例(这也是最常使用的模式和命令)。
首先进入tmux
环境,使用tmux new -s xxx
进入即可。
然后在脚本exp.py
里写下:
#!/usr/bin/python3
# -*- encoding: utf-8 -*-
from pwncli import *
# use script mode
cli_script()
# get use for obj from gift
io: tube = gift['io']
elf: ELF = gift['elf']
libc: ELF = gift['libc']
ia()
然后赋予脚本执行权限,然后输入./exp.py de ./pwn -t
即可看到开启了tmux
调试窗口。
对于无PIE
的程序,下断点的方式为:
./exp.py de ./pwn -t -b 0x400088a # 在0x400088a处下断点
./exp.py de ./pwn -t -b malloc -b free # 下2个断点
对于有PIE
的程序,下断点的方式为:
./exp.py de ./pwn -t -b b+0xafd # 在 0xafd处下断点
./exp.py de ./pwn -t -b malloc -b free -b b+0x101f # 下3个断点
./exp.py de ./pwn -t -b malloc+0x10 # 在malloc+0x10处下断点,首先在libc里面寻找malloc符号,然后在elf中寻找malloc符号
想要hook
掉某些函数,如ptrace
:
./exp.py de ./pwn -H ptrace -H alarm:1 # hook掉ptrace,默认返回0;hook掉alarm,返回值为1
./exp.py de ./pwn -h ./hook.c # 自己写好hook.c后指定即可
使用带桌面的ubuntu
虚拟机调试,可以选择gnome
弹出窗口:
./exp.py de ./pwn -g -b 0x400088a # 在0x400088a处下断点
./exp.py de ./pwn -g -s "directory /usr/glibc/glibc-2.31/malloc" # 指定源码调试目录
脚本调试好后需要打远程:
./exp.py re ./pwn 127.0.0.1:13337
pwncli 主命令
选项的相关说明:
flag
选项:带上该选项即为开启,如ls -a
中的-a
即为flag
选项- 多选的:可以指定多个值,如
-x y1 -x y2
可以传递y1
和y2
给x
选项 - 多种使用方式:如
-x --xxx --xxx-xx
,那么使用-x
或者--xxx
或者--xxx-xxx
均可
pwncli
命令为主命令,输入pwncli -h
将得到以下输出:
Usage: pwncli [OPTIONS] COMMAND [ARGS]...
pwncli tools for pwner!
For cli:
pwncli -v subcommand args
For python script:
script content:
from pwncli import *
cli_script()
then start from cli:
./yourownscript -v subcommand args
Options:
-f, --filename TEXT Elf file path to pwn.
-v, --verbose Show more info or not.
-V, --version Show the version and exit.
-h, --help Show this message and exit.
Commands:
config Get or set something about config data.
debug Debug the pwn file locally.
misc Misc of useful sub-commands.
patchelf Patchelf executable file using glibc-all-in-one.
qemu Use qemu to debug pwn, for kernel pwn or arm/mips arch.
remote Pwn remote host.
test Test command.
选项:
-f 可选的 待调试的pwn文件路径,如./pwn,在这里指定后,debug/remote子命令中可无需指定。
-v 可选的 flag选项,默认关闭。开启后将显示log信息,如果需要显示更多信息,可以输入-vv。
-V 查看版本信息。
-h 查看帮助。
命令(即pwncli
下拥有的子命令):
config 操作pwncli配置文件,配置文件路径为~/./pwncli.conf。
debug 最常用的子命令,用于本地调试pwn题。
misc 杂项命令,收录了一些实用的子命令。
patchelf 快速地执行patchelf,以用于调试不同版本的glibc。
qemu 使用qemu调试pwn题,用于kernel pwn或其他架构的pwn。
remote 最常用的子命令,用于远程攻击靶机。
test 测试命令,无其他用途。
debug 子命令
输入pwncli debug -h
将得到以下帮助文档:
Usage: pwncli debug [OPTIONS] [FILENAME]
FILENAME: The ELF filename.
Debug in tmux:
python3 exp.py debug ./pwn --tmux --gdb-breakpoint malloc -gb 0x400789
Options:
--argv TEXT Argv for process.
-e, --set-env, --env TEXT The env setting for process, such as
LD_PRELOAD setting, split using ',' or ';',
assign using '=' or ':'.
-p, --pause, --pause-before-main
Pause before main is called or not, which is
helpful for gdb attach. [default: False]
-f, -hf, --hook-file TEXT Specify a hook.c file, where you write some
functions to hook.
-H, -HF, --hook-function TEXT The functions you want to hook would be out
of work.
-t, --use-tmux, --tmux Use tmux to gdb-debug or not. [default:
False]
-w, --use-wsl, --wsl Use wsl to pop up windows for gdb-debug or
not. [default: False]
-m, -am, --attach-mode [auto|tmux|wsl-b|wsl-u|wsl-o|wsl-wt|wsl-wts]
Gdb attach mode, wsl: bash.exe | wsl:
ubuntu1x04.exe | wsl: open-wsl.exe | wsl:
wt.exe wsl.exe [default: auto]
-u, -ug, --use-gdb Use gdb possibly. [default: False]
-g, -gt, --gdb-type [auto|pwndbg|gef|peda]
Select a gdb plugin.
-b, -gb, --gdb-breakpoint TEXT Set gdb breakpoints while gdb-debug is used,
it should be a hex address or '\$rebase'
addr or a function name. Multiple
breakpoints are supported.
-s, -gs, --gdb-script TEXT Set gdb commands like '-ex' or '-x' while
gdb-debug is used, the content will be
passed to gdb and use ';' to split lines.
Besides eval-commands, file path is
supported.
-n, -nl, --no-log Disable context.log or not. [default:
False]
-P, -ns, --no-stop Use the 'stop' function or not. Only for
python script mode. [default: False]
-v, --verbose Show more info or not.
-h, --help Show this message and exit.
debug
子命令是最常用的子命令,为其设计的参数也最多,下面将详细讲述每一个参数的意义和使用方式。
参数:
FILENAME 可选的 本地调试的pwn文件路径,还可以在pwncli主命令中通过-f选项设置;如pwncli主命令未设置,此处必须设置。
选项:
--argv 可选的 除文件路径,传递给process构造函数的参数。
-e 可选的 设置启动的环境变量,如LD_PRELOAD=./libc.so.6;PORT_ENV:1234,IP_ADDR=localhost,数据将传递给process构造函数的env参数。环境变量会统一转换为大写。LD_PRELOAD可以简写为PRE=./libc.so.6。
-p 可选的 flag选项,开启gdb后生效,默认关闭。开启后将在main函数之前执行一个getchar()函数,方便gdb attach上去调试,避免有时候gdb.attach失败的问题。本质上是编译生成一个so文件,并将其设置为LD_PRELOAD环境变量,在init段执行getchar函数。
-f 可选的 开启gdb后生效,自己定义的hook.c文件,该文件会被编译为so,并设置为LD_PRELOAD环境变量。
-H 可选的 多选的,开启gdb后生效。选择要hook的函数名,如alarm函数,被hook的函数将直接返回0,支持多个选项,即可以 -H alarm -H ptrace。
-t 可选的 flag选项,默认关闭。开启后使用tmux开启gdb,并使用竖屏分屏。开启前必须保证在tmux环境中,否则会报错。
-w 可选的 flag选项,默认关闭。开启后使用wsl模式开启gdb,弹窗口调试。开启前必须保证在wsl的发行版环境中,否则会报错。
-m 可选的 开启gdb后生效,默认为auto。指定开启gdb的调试模式。auto:自动选择;tmux:开启-t后生效;wsl-b:开启-w后生效,使用bash.exe弹窗;wsl-u:开启-w后生效,使用ubuntu1x04.exe弹窗,前提是将其加入到windows宿主机的PATH环境变量中;wsl-o:开启-w后生效,使用open-wsl.exe弹窗,须到https://github.com/mskyaxl/wsl-terminal下载并将其加入到windows的PATH环境变量中;wsl-wt:开启-w后生效,使用windows-terminal弹窗,需安装windows terminal;wsl-wts:开启-w后生效,使用windows terminal分屏调试,需保证其版本至少为1.11.3471.0。
-u 可选的 flag选项,默认关闭。开启后会尽可能的使用gdb调试。
-g 可选的 开启gdb后生效,默认为auto。选择gdb插件类型。使用的前提是将gef、peda、pwndbg均安装在家目录下。auto:使用~/.gdbinit的配置,否则使用pwncli/conf/.gdbinit-xxx的配置。
-b 可选的 多选的,开启gdb后生效。在gdb中设置断点。支持设置的方式有三种:1)函数地址,-b 0x401020或-b 4198432;2)函数名,-b malloc;3)相对于PIE基址的偏移,适用于开启PIE的场景,-b base+0x4f0或-b b+0x4f0或-b \$rebase(0x4f0)或-b \$_base(0x4f0),只支持gef和pwndbg插件。支持设置多个断点,如-b malloc -b 0x401020。
-s 可选的 开启gdb后生效。可以是文件路径或者语句。如果是语句,设置后将在gdb中执行,每个子语句之间使用分号;分割,如-s "directory /usr/src/glibc/glibc-2.27/malloc;b malloc";如果是文件路径,则会在gdb中依次执行文件内的每一行语句。
-n 可选的 flag选项,默认关闭。设置pwntools为无log信息。若开启该选项,则会关闭pwntools的log。
-P 可选的 flag选项,默认关闭。设置stop函数失效。stop函数会等待输入并打印出当前信息,方便gdb调试。开启此选项后stop函数将失效。
-v 可选的 flag选项,默认关闭。开启后将显示log信息,如果需要显示更多信息,可以输入-vv。
-h 可选的 查看帮助。
remote 子命令
输入pwncli remote -h
得到以下帮助:
Usage: pwncli remote [OPTIONS] [FILENAME] [TARGET]
FILENAME: ELF filename.
TARGET: Target victim.
For remote target:
pwncli -v remote ./pwn 127.0.0.1:23333 -up --proxy-mode default
Or to specify the ip and port:
pwncli -v remote -i 127.0.0.1 -p 23333
Options:
-i, --ip TEXT The remote ip addr.
-p, --port INTEGER The remote port.
-P, -up, --use-proxy Use proxy or not. [default: False]
-m, -pm, --proxy-mode [undefined|notset|default|primitive]
Set proxy mode. undefined: read proxy data
from config data(do not set this type in
your file); notset: not use proxy; default:
pwntools context proxy; primitive: pure
socks connection proxy. [default:
undefined]
-n, -nl, --no-log Disable context.log or not. [default:
False]
-v, --verbose Show more info or not.
-h, --help Show this message and exit.
remote
也是使用较多的子命令,用于远程攻击靶机。在本地调试好脚本后,只需要将debug
命令替换为remote
,并设置参数,即可开始攻击靶机,不需要更改脚本。
参数:
FILENAME 可选的 本地调试的pwn文件路径,还可以在pwncli主命令中通过-f选项设置;设置后将不需要手动设置context.arch、context.os等信息。
TARGET 可选的 目标靶机;如果不用-i和-p参数,则必须指定。格式为:ip:port,如127.0.0.1:1234。
选项:
-i 可选的 设置目标靶机,可为域名或ip地址。若TARGET参数中未设置,则此处必须设置。若~/.pwncli.conf中有配置,则将读取配置文件中的目标ip地址为默认值。
-p 可选的 设置目标靶机的端口。若TARGET参数未设置,则此处必须设置。
-P 可选的 flag选项,默认关闭。开启后将使用代理。
-m 可选的 开启代理后生效。将会从~/.pwncli.conf中读取代理配置。undefined:未定义代理;notset:不使用代理;default:使用pwntools的context.proxy设置;primitive:使用socks设置。
-n 可选的 flag选项,默认关闭。设置pwntools为无log信息。若开启该选项,则会关闭pwntools的log。
-v 可选的 flag选项,默认关闭。开启后将显示log信息,如果需要显示更多信息,可以输入-vv。
-h 查看帮助。
config 子命令
config
子命令主要用于操作pwncli
的配置文件,配置文件的路径为~/.pwncli.conf
,其指导为:
Usage: pwncli config [OPTIONS] COMMAND [ARGS]...
Options:
-h, --help Show this message and exit.
Commands:
list List config data.
set Set config data.
选项:
-h 查看帮助。
命令:
list 查看配置文件数据。
set 设置配置文件数据。
list 二级子命令
输入pwncli config list -h
获得如下输出:
Usage: pwncli config list [OPTIONS] [LISTDATA]
LISTDATA: List all data or example data or section names.
Options:
-s, -sn, --section-name TEXT List config data by section name.
-h, --help Show this message and exit.
参数:
LISTDATA 可选的 列出的数据类型。all:列出配置文件所有数据;example:列出示例的配置文件数据;section:列出配置文件中数据的section;其他值为非法值。
选项:
-s 可选的 多选的。根据section的名字列出数据。
-h 查看帮助。
set 二级子命令
输入pwncli config set -h
获得如下输出:
Usage: pwncli config set [OPTIONS] [CLAUSE]
Options:
-s, -sn, --section-name TEXT Set config data by section name.
-h, --help Show this message and exit.
参数:
CLAUSE 必须的 设置的语句,格式为key=value。
选项:
-s 可选的 根据section设置数据。
-h 查看帮助。
misc 子命令
misc
子命令是一个杂项命令合集,即其会包含许多二级子命令,每个二级子命令的功能都不一样。
输入pwncli misc -h
得到帮助信息:
Usage: pwncli misc [OPTIONS] COMMAND [ARGS]...
Options:
-h, --help Show this message and exit.
Commands:
gadget Get all gadgets using ropper and ROPgadget, and then store them in
files.
setgdb Copy gdbinit files from and set gdb-scripts for current user.
选项:
-h 查看帮助。
命令:
gadget 使用ropper和ROPgadget工具获取所有的gadgets,并将其存储在本地。
setgdb 将pwncli/conf/.gdbinit-xxx的配置文件拷贝到家目录。使用该命令的前提是将gef、peda、pwndbg、Pwbgdb插件下载到家目录。
gadget 二级子命令
输出pwncli misc gadget -h
得到帮助信息:
Usage: pwncli misc gadget [OPTIONS] [FILENAME]
Options:
-a, --all, --all-gadgets Get all gadgets and don't remove duplicates.
[default: False]
-d, --dir, --directory TEXT The directory to save files.
-h, --help Show this message and exit.
参数:
FILENAME 必须的 要获取gadgets的binary路径。
选项:
-a 可选的 flag选项,默认关闭。开启后将不会移除重复的gadgets。
-d 可选的 保存gadgets文件的路径。若未指定则为当前目录。
-h 查看帮助。
setgdb 二级子命令
输出pwncli misc setgdb -h
得到帮助信息:
Usage: pwncli misc setgdb [OPTIONS]
Options:
-g, --generate-script Generate the scripts of gdb-gef/gdb-pwndbg/gdb-peda
in /usr/local/bin or not. [default: False]
--yes Confirm the action without prompting.
-h, --help Show this message and exit.
选项:
-g 可选的 flag选项,默认关闭。开启后将在/usr/local/bin下生成三个shell脚本,gdb-gef、gdb-peda、gdb-pwndbg。该选项需要在sudo下使用。
--yes 确认项 输入y后该命令生效。
-h 查看帮助。
其中gdb-pwndbg
的内容为:
#!/bin/sh
cp ~/.gdbinit-pwndbg ~/.gdbinit
exec gdb "$@"
patchelf 子命令
使用patchelf
修改二进制文件使用的libc.so.6
和ld.so
。使用该命令的前提是,已安装patchelf
和glibc-all-in-one
,并将各个版本的库文件放置在glibc-all-in-one/libs
,该路径可在配置文件中配置。
输入pwncli patchelf -h
得到帮助信息:
Usage: pwncli patchelf [OPTIONS] FILENAME LIBC_VERSION
FILENAME: ELF executable filename.
LIBC_VERSION: Libc version.
pwncli patchelf ./filename 2.29 -b
Options:
-b, --back, --back-up Backup target file or not.
-f, --filter, --filter-string TEXT
Add filter condition.
-h, --help Show this message and exit.
参数:
FILENAME 必须的 待patch的文件路径。
选项:
-b 可选的 flag选项,默认关闭。开启后将备份一份文件后再执行patchelf命令,建议开启。
-f 可选的 过滤器,设置过滤条件。如-f 2.23,则会匹配到2.23版本的glibc库。
-h 查看帮助。
qemu 子命令
该子命令方便使用qemu
进行其他架构arm/mips
文件的调试以及kernel pwn
的调试。该命令的使用与debug
子命令非常类似,很多选项与参数与debug
子命令相同,使用方法也是一样的。在使用该子命令之前,请确保已安装了qemu
和所需依赖库。
输入pwncli qemu -h
得到帮助信息:
Usage: pwncli qemu [OPTIONS] [FILENAME] [TARGET]
FILENAME: The binary file name.
TARGET: remote_ip:remote_port.
Debug mode is default setting, debug with qemu:
pwncli qemu ./pwn -S --tmux
pwncli qemu ./pwn -L ./libs --tmux
Specify qemu gdb listen port:
pwncli qemu ./pwn -L ./libs -S -p 1235
Attack remote:
pwncli qemu ./pwn 127.0.0.1:10001
pwncli qemu ./pwn -r -i 127.0.0.1 -p 10001
Options:
-d, --debug, --debug-mode Use debug mode or not, default is opened.
-r, --remote, --remote-mode Use remote mode or not, default is debug
mode. [default: False]
-i, --ip TEXT The remote ip addr or gdb listen ip when
debug.
-p, --port INTEGER The remote port or gdb listen port when
debug.
-L, --lib TEXT The lib path for current file.
-S, --static Use tmux to gdb-debug or not. [default:
False]
-l, -ls, --launch-script TEXT The script to launch the qemu, only used for
qemu-system mode and the script must be
shell script.
-t, --use-tmux, --tmux Use tmux to gdb-debug or not. [default:
False]
-w, --use-wsl, --wsl Use wsl to pop up windows for gdb-debug or
not. [default: False]
-g, --use-gnome, --gnome Use gnome terminal to pop up windows for
gdb-debug or not. [default: False]
-G, -gt, --gdb-type [auto|pwndbg|gef|peda]
Select a gdb plugin.
-b, -gb, --gdb-breakpoint TEXT Set gdb breakpoints while gdb-debug is used,
it should be a hex address or a function
name. Multiple breakpoints are supported.
-s, -gs, --gdb-script TEXT Set gdb commands like '-ex' or '-x' while
gdb-debug is used, the content will be
passed to gdb and use ';' to split lines.
Besides eval-commands, file path is
supported.
-n, -nl, --no-log Disable context.log or not. [default:
False]
-P, -ns, --no-stop Use the 'stop' function or not. Only for
python script mode. [default: False]
-v, --verbose Show more info or not. [default: 0]
-h, --help Show this message and exit.
参数:
FILENAME 可选的 调试的binary文件路径,kernel pwn可以是ko
TARGET 可选的 远程攻击时的ip和port,FILENAME和TARGET必须指定一个
选项:
-d 可选的 flag选项,默认开启。该选项一般不需要显示指定。
-r 可选的 flag选项,默认关闭。可显示指定,表明此时为攻击远程。
-i 可选的 在remote mode下为靶机ip地址;在debug mode下为gdb的监听ip地址。
-p 可选的 在remote mde下为靶机端口;在debug mode下为gdb的监听端口。
-L 可选的 在qemu-user下的动态链接库目录,会传递给qemu,若未指定,则会到/usr目录下寻找
-S 可选的 flag选项,默认关闭。开启后将使用qemu-xxxx-static。
-l 可选的 qemu启动的脚本路径,方便kernel pwn调试。
-t 可选的 flag选项,默认关闭。开启后使用tmux开启gdb-multiarch调试。
-w 可选的 flag选项,默认关闭。开启后使用wsl调试。
-g 可选的 flag选项,默认关闭。开启后使用gnome-terminal调试。
-G 可选的 显示指定本次调试使用的gdb插件,pwndbg/peda/gef。
-b 可选的 设置断点,与debug子命令的设置方式类似,但是不支持PIE类的断点。
-s 可选的 设置gdb的命令,与debug子命令的设置方式类似,支持语句或文件路径。
-n 可选的 flag选项,默认关闭。开启后将设置pwntools的日志级别为error。
-P 可选的 flag选项,默认关闭。开启后使stop函数失效。
template 子命令
该子命令方便生成各种攻击模板脚本文件,包括使用pwncli
的命令行模式与脚本模式的攻击脚本,同时还提供了使用原生的pwntools
需要使用到的模板。模板中定义了本地调试与远程攻击的相关代码,提供了常用的缩写函数,如sa/sla/r/rl
等。
输入pwncli template -h
得到帮助信息:
Usage: pwncli template [OPTIONS] [FILETYPE]
FILETYPE: The type of exp file
pwncli template cli
pwncli template lib
pwncli template pwn
Options:
-h, --help Show this message and exit.
其中,cli
类型模板会使用pwncli
的脚本模式,lib
类型模板会使用库模式,pwn
类型模板直接使用原始的pwntools
来构建而不会使用pwncli
。
依赖库
pwncli
的依赖库清单如下所示:
click
ropper
pwntools
截图示例
pwncli 示例
debug 示例
pwncli -vv debug ./test
:
pwncli -vv debug ./test -t
:
pwncli de ./test -t -b main
:
这个时候没有断住:
pwncli de ./test -p -t -b main
:
pwncli de ./test -H puts
:
pwncli de ./test -t -s "vmmap;b main"
:
pwncli de ./test -w
:
pwncli de ./test -w -m wsl-u
:
pwncli de ./test -w -m wsl-wts
:
pwncli de ./test -t -g pwndbg
:
pwncli de ./test -u
:
remote 示例
pwncli re ./test 127.0.0.1:10001
:
pwncli -vv re ./test -i 127.0.0.1 -p 10001
:
pwncli -vv re 127.0.0.1:10001
:
config 示例
pwncli config list example
:
misc 示例
pwncli misc gadget ./test
:
sudo pwncli misc setgdb -g
:
patchelf 示例
pwncli patchelf ./test -b 2.31
:
qemu 示例
TODO