• Stars
    star
    327
  • Rank 128,686 (Top 3 %)
  • Language
    Python
  • License
    MIT License
  • Created over 3 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Do pwn by command line

前言

一开始写这个工具是因为在学习pwn的过程中,经常反复的去注释和取消注释gdb.attach(xxx)这样的语句,下不同断点的时候要不断地修改脚本,本地调通打远程的时候也要改脚本。

习惯命令行操作后,我设想能否设计一个命令行工具,能通过命令行参数去控制一些东西,避免在调试pwn题的时候重复地执行上面这些工作而只专注于编写解题脚本。当想法酝酿起来,自己便试着写下第一行代码,于是,pwncli就此诞生。

工具的目的在于实用性,我觉得pwncli满足实用性要求,在调试pwn题时能节省大量的时间。

如果你觉得pwncli好用,请介绍给周围的pwner。如果你还有任何疑问,请提交issue或联系我[email protected],我将非常乐意与你讨论交流。如果你有好的想法,或者发现新的bug,欢迎提交pull requests

🏴🏴🏴 欢迎各位师傅关注我的个人博客,以下两个博客网站内容相同,互为备份。前者为github page,后者部署在国内阿里云服务器上。博客持续更新中~

简介

EN | ZH | API | VIDEO

pwncli是一款简单、易用的pwn题调试与攻击工具,能提高你在CTF比赛中调试pwn题脚本的速度与效率。

pwncli可以帮助你快速编写pwn题攻击脚本,并实现本地调试和远程攻击的便捷切换。pwncli支持三种使用模式:

  • 命令行使用模式
  • 脚本内使用模式
  • 库导入使用模式

以上三种模式分别简称为:命令行模式、脚本模式和库模式。其中,命令行模式与其他命令行工具(如linux下的lstar等命令)使用方式相同,可用于本地交互调试;脚本模式可将自己编写的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 ./pwnpwncli de ./pwnpwncli 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依赖于clickpwntools。前者是一款优秀的命令行编写工具,后者是pwner普遍使用的攻击库。

总结pwncli的优点为:

  • 脚本只需编写一次,使用命令行控制本地调试与远程攻击
  • 调试过程中方便设置断点与执行其他gdb命令
  • 可轻松扩展并自定义子命令
  • 内置许多有用的命令与函数

安装

pwncli可以在linuxwindows下使用,但在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.04debug命令的某些选项与默认发行版名称联系紧密。

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所拥有的各项命令与功能。

当然,你可以丰富你的脚本,使其实现更多功能,如使用debugremote命令时,你可以在脚本后面继续添加:

#!/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模块中的processremote对象,并与其交互。

库模式

库模式,顾名思义,适用于你仅仅需要使用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脚本,并不能解析命令行参数。

教程

视频教程如下: pwncli tutorial

asciinema版本教程依次如下:

asciicast

asciicast

asciicast

asciicast

以下为简易的文字版教程。

在使用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可以传递y1y2x选项
  • 多种使用方式:如-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.6ld.so。使用该命令的前提是,已安装patchelfglibc-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 示例

image-20220226232019621

debug 示例

pwncli -vv debug ./test

image-20220226232116090

pwncli -vv debug ./test -t

image-20220226232356871

pwncli de ./test -t -b main

image-20220226232710687

这个时候没有断住:

pwncli de ./test -p -t -b main

image-20220226232858593

image-20220226232946892

pwncli de ./test -H puts

image-20220226233434698

pwncli de ./test -t -s "vmmap;b main"

image-20220226233628316

pwncli de ./test -w

image-20220226233900484

pwncli de ./test -w -m wsl-u

image-20220226234010903

pwncli de ./test -w -m wsl-wts

image-20220226234057770

pwncli de ./test -t -g pwndbg

image-20220226234152877

pwncli de ./test -u:

image-20220226234307876

remote 示例

pwncli re ./test 127.0.0.1:10001

image-20220226235042604

pwncli -vv re ./test -i 127.0.0.1 -p 10001

image-20220226235158851

pwncli -vv re 127.0.0.1:10001

image-20220226235248653

config 示例

pwncli config list example

image-20220226235423624

misc 示例

pwncli misc gadget ./test

image-20220226235602674

sudo pwncli misc setgdb -g

image-20220226235738869

patchelf 示例

pwncli patchelf ./test -b 2.31

image-20220226235851991

qemu 示例

TODO