前言

由于pwn题中经常会遇到glibc版本与本地环境不一致,需要patch的问题,遇到流行的版本,本地有对应的文件的情况还比较方便,但是一旦遇到小众版本,尤其是清华镜像站或者glibc-all-in-one找不到的版本时,patch就成了一大问题。同时,下载的glibc如果不包含调试信息,在某些手法的学习或者利用过程中会很不舒服。而且patch题目文件,修改exp对应的文件地址是每次上手pwn题之前必不可少的步骤,因此结合pwninit的功能,利用python实现了一个脚本,可以自动解决这些问题,并在此基础上,提供调试时显示glibc源码的功能,原理参考gdb文档。本文将简要介绍脚本的功能及用法。

项目地址:cpwn

功能特性

安装步骤在项目首页已经作了详细介绍,不再赘述,此处主要通过图文的方式展示实现的功能效果。

获取主流版本的glibc

https://launchpad.net/ubuntu/+source/glibc/ 上列举了Ubuntu LTS发行版使用的glibc,使用cpwn fetch命令会自动下载这些glibc版本在amd64和i386架构的libc,debug-symbol,source。

初始化利用环境

在目录下运行cpnw init,如果当前目录不存在glibc则会提示用户选择cpwn包含的glibc版本:

如果目录下存在glibc,但是cpwn没有下载过这个版本的glibc,则会向远程拉取对应版本的glibc:

确定好版本之后会将pwn文件patch,生成pwn_patched注意被patch的文件必须是没有使用[--set-rpath RPATH]选项patch过的文件

1
2
3
4
$ ldd ./pwn_patched
    linux-vdso.so.1 (0x00007ffe238a2000)
    /home/geekcmore/.config/cpwn/pkgs/2.35-0ubuntu3.7/amd64/libc6_2.35-0ubuntu3.7_amd64/lib/x86_64-linux-gnu/libc.so.6 (0x00007fddbd1c4000)
    /home/geekcmore/.config/cpwn/pkgs/2.35-0ubuntu3.7/amd64/libc6_2.35-0ubuntu3.7_amd64/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007fddbd3f9000)

并根据对应的glibc版本生成初始化的exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/usr/bin/python3
from pwn import *
 
filename = "pwn_patched"
libcname = "/home/geekcmore/.config/cpwn/pkgs/2.35-0ubuntu3.8/libc6_2.35-0ubuntu3.8_amd64/lib/x86_64-linux-gnu/libc.so.6"
host = "127.0.0.1"
port = 1337
elf = context.binary = ELF(filename)
context.terminal = ['tmux', 'neww']
if libcname:
    libc = ELF(libcname)
gs = '''
b main
set debug-file-directory /home/geekcmore/.config/cpwn/pkgs/2.35-0ubuntu3.8/libc6-dbg_2.35-0ubuntu3.8_amd64/usr/lib/debug
set directories /home/geekcmore/.config/cpwn/pkgs/2.35-0ubuntu3.8/glibc-source_2.35-0ubuntu3.8_all/usr/src/glibc/glibc-2.35
'''
 
def start():
    if args.GDB:
        return gdb.debug(elf.path, gdbscript = gs)
    elif args.REMOTE:
        return remote(host, port)
    else:
        return process(elf.path)
 
p = start()
 
# Your exploit here
 
p.interactive()

在当前目录下运行python ./exp.py GDB可以弹出gdb调试界面,并显示调试符号:

源码:

配置文件

配置文件默认保存在~/.config/cpwn,对应的目录树为:

1
2
3
4
5
6
$ tree ~/.config/cpwn/ -L 1
/home/geekcmore/.config/cpwn/
├── config.json
├── exp_template.py
├── pkgs
└── template.py

需要修改模板时可以直接编辑此处的template.py或者修改配置文件中的template的路径:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
    "author": "GeekCmore",
    "template": "~/.config/cpwn/exp_template.py",
    "script_name": "exp.py",
    "file_path": "~/.config/cpwn/pkgs",
    "mirror": "",
    "archs": [
        "amd64",
        "i386"
    ],
    "pkgs": [
        "libc6",
        "libc6-dbg",
        "glibc-source"
    ],
    "threads": 10,
    "force": false
}

其他配置项也可以按需修改,如果网络情况不好,或者无需下载调试符号,源码,可以修改archspkgs,仅仅下载amd64libc6

最新回复:
GeekCmore 2024-08-31 13:37:26
后续计划添加对libseccomp.so等不在libc6包内的库提供patch支持,另外对于其他功能,有想法的师傅欢迎评论区交流。
mb_zjktbyux 2024-10-28 19:46:44
感谢分享,终于能调符号了
mb_eneyoyay 2024-12-02 16:04:59
试了下这东西,bug不少:
对于有些二进制文件编译成了application/x-sharedlib格式而不是appliaction/x-executable的可执行文件,程序找不到要patch的二进制文件(cpwn.py的detect函数(206-241行)通过mime来类型为application/*-excutable是可执行文件)。修正这句后,后面subprocess报错提示多了一个参数text=true,注释掉后面又一堆。。。
不清楚这个工具用的python3哪个版本,我在18.04、python3.6下测的,暂时放弃了,自己手动patchelf吧
mb_dowwiawp 2024-12-02 22:34:02
好像有点问题,运行cpnw init的时候,程序报错
  File "/usr/bin/cpwn", line 498
    content = f"target remote :1234\nfile vmlinux\nadd-symbol-file {os.path.join("./extracted", os.path.basename(kpm))}"
                                                                                  ^
SyntaxError: f-string: unmatched '('


GeekCmore 2024-12-03 08:52:24
mb_eneyoyay 试了下这东西,bug不少: 对于有些二进制文件编译成了application/x-sharedlib格式而不是appliaction/x-executable的可执行文件,程序找不到要patch的二 ...
师傅你好,对lib的支持暂时没添加进来,后续添加。测试过Ubuntu22.04和24.04版本下的默认python版本,对低版本还没有充分测试,近期进行测试。
GeekCmore 2024-12-03 08:53:42
mb_dowwiawp 好像有点问题,运行cpnw init的时候,程序报错 File "/usr/bin/cpwn", line 498 content = f"target ...
这个貌似也是python版本的问题,我去修一下。
mb_eneyoyay 2024-12-03 09:33:21
GeekCmore 师傅你好,对lib的支持暂时没添加进来,后续添加。测试过Ubuntu22.04和24.04版本下的默认python版本,对低版本还没有充分测试,近期进行测试。
没想到大佬亲自回复了。当时在18.04下装的初衷是,栈溢出环境主要还是16.04、18.04,有劳大佬在再辛苦一下。
GeekCmore 2024-12-03 16:41:07
mb_eneyoyay 没想到大佬亲自回复了。当时在18.04下装的初衷是,栈溢出环境主要还是16.04、18.04,有劳大佬在再辛苦一下。
感觉一般是用较高版本做主力机,碰到低版本程序patch
z2zccc 2024-12-28 17:02:27
这调试就直接能直接有源码嘛?还是需要gdb加载呀