Zj_W1nd's BLOG

Awdp-PWN准备技巧

2025/02/25

环境问题

首先,我有两套环境。一个windows一个arch,都是物理机。

其中,windows上拥有kali-wsl和win_penetration_toolkit-vmware,平常的pwn题是采用

  • wsl-kali执行python脚本/gdb调试,patchelf+glibc-all-in-one,windows主机ida分析

缺点是,windows上没有docker。做不了内核题。优点是,windows上具有渗透测试的虚拟机,可以说渗透基本上必须用win(blackarch开发不是很全)

而linux环境上也有原生ida支持,也能做,缺点在于没有杂七杂八的工具比如anytxt,localsend这种,也缺misc工具,以及渗透的工具。

linux准备好ubuntu的三个docker,都安装gdb?

pwn题配置

参考自文章1

文章2(包括流量转发,批量攻击脚本)

准备

手动patch,使用ida keypatch即可。打包命令:

1
2
3
4
5
6
tar -cvf archive.tar file1 file2 directory
tar -czvf archive.tar.gz directory
tar -rvf archive.tar newfile

tar -xvf archive.tar
tar -zcvf update.tar.gz update.sh pwn_fix

常见漏洞的patch方法

格式化字符串漏洞

  1. printf=>puts,直接改call的地址即可。风险是puts会在结尾添加换行,不一定能过检查。

  2. 强行调整参数。rdi放"%s",rsi放原参数。程序里有%s在的话会好一点,如果没有%s的话,我们可能要找3字节塞进去如下内容:

1
0x25 0x73 0x00== %s\0

但是指令也可能不够长?

UAF

“UAF就直接把free nop掉” ——某位大跌学长

check过程中没办法检查是否有free,所以直接nop掉free似乎是个不错的方案。反正也爆不了,内存就在那扔着你也不能怎么样

整数溢出

整数溢出比较简单,修改相应判断指令的跳转逻辑就行(?)将有符号跳转改为无符号?

缓冲区溢出

改小相关的输入长度,分x86和x64,写死的数值参数x86需要patch push指令,但是注意,在操作数大于0x100的时候push内容可能会变化,涉及到栈平衡的问题需要注意。
x64就直接patch寄存器赋值即可。

scanf的话尝试将"%s"改成"%ns"来限制输入长度,如果长度是动态的尝试了下改成read(0,buf,len)一般汇编也是够的

VM

核心是防止在vm指令执行过程中越界/非预期的读写,具体问题具体分析,肯定会有执行指令过程中的check漏洞

逻辑漏洞

nop漏洞分支(nop掉跳转指令)敏感函数的参数权限(如mmap等)

通防

给程序加沙箱直接无脑关闭execve调用,但是通防可能被检测,自行斟酌
https://github.com/TTY-flag/evilPatcher

测试下来,二进制文件大小没有变化,线下试试吧。

或者还有一招,如果程序设置了alarm(xx)的话(一般会有alarm(60))这种限制时间的,测试下之后把它改的很小让exp利用不完,也能行。

非预期?

程序如果exit退出,打io的话尝试nop掉exit或者改成_exit?

检查漏洞

敏感功能函数,strlen获取长度限制能不能塞满溢出,scanf%s的输入

docker命令

pwn调试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
docker run -it -d -v host_path:container_path -p host_port:container_port --cap-add=SYS_PTRACE IMAGE_ID # auto update 自动执行update.sh脚本

docker run -it -d -v host_path:container_path -p host_port:container_port --cap-add=SYS_PTRACE IMAGE_ID /bin/sh # do not update 不会自动更新

docker run -it -d -v host_path:container_path -p host_port:container_port --privileged IMAGE_ID # privileged enabled and auto update 给特权标志和自动更新

docker run -it -d -v host_path:container_path -p host_port:container_port --privileged IMAGE_ID /bin/sh # privileged enabled and auto update 给特权标志和自动更新


docker run -it -d -v $PWD:/home/ctf/hacker

docker exec -it CONTAINER_ID /bin/sh
docker exec -it -u root CONTAINER_ID /bin/sh

/bin/test-this-container.sh

用官方镜像启动本地环境:

1
docker load -i xxx.tar
1
2
docker ps -a --no-trunc 输出所有命令

PHP PWN???

2025.3.17: 事实上根本就没工夫看这题…

赛前发的附件名字叫php-master怀疑要出php-pwn了,搜了下结果还挺常见的但是都没做过,麻。先速通一下fix?

PHP pwn的核心是一个C编写的扩展动态库,为php提供一些可用的函数。

环境搭建

php的版本也比较多,准备8.1-8.3的docker和本机的8.4.4,以及7.4备用

实际操作时,去对应docker下将/usr/src的源码解压。找到源码目录的ext,ext_skel.php,这个脚本可以自动生成一套扩展用的基础文件

1
2
3
4
5
6
7
8
创建容器: docker run -itd --name php -p 80:80 -v /Users/xiaosheng/docker:/var/www/html -v /Users/xiaosheng/docker/etc:/usr/local/etc -v /Users/xiaosheng/docker/conf:/etc/apache2/sites-enabled php:apache-buster
命令详解:
--name php: php 表示创建出来的镜像名称
-p 80:80: 表示本机的 80 端口映射到容器内的 80 端口, 其中第一个 80 是本机的
-v /Users/xiaosheng/docker:/var/www/html: 数据卷挂载, 将本机的代码文件夹映射到容器内的代码文件夹, 冒号前面的是本机的文件夹地址
-v /Users/xiaosheng/docker/etc:/usr/local/etc: 将容器内 PHP 的配置文件映射到本机, 这样方便修改配置文件, 冒号前面的是本地的文件夹地址
-v /Users/xiaosheng/docker/conf:/etc/apache2/sites-enabled: 将容器内 Apache 站点的配置文件映射到本地, 方便添加和修改站点配置文件, 冒号前面的是本地的文件夹地址
php:apache-buster: 表示的是使用哪个镜像来创建容器, 即 镜像名称:tag名称、
1
2
3
4
5
6
容器中 PHP 没有 MySQL 的扩展, 所以需要自己手动下载, 下载步骤可以参考该链接 https://www.yoyoask.com/?p=122
docker-php-source : 在 /usr/src 目录下创建出来 php 文件夹
进入 /usr/src/php/ext 文件夹, 使用 docker-php-ext-install 安装所需要的扩展, 如安装 pdo-mysql 扩展, 可以使用 docker-php-ext-install pdo_mysql 来安装
修改 PHP 的配置文件
去掉 ;extension=pdo_mysql 前面的 ;
使用 docker restart 容器ID 来重启容器

php的核心配置文件在php.ini 执行

1
php --ini

命令来输出所有的配置文件位置

思路

首先,直接读/proc/self/map来拿地址,不多bb

然后php堆类似于linux内核的slab,没有复杂的metadata,而是通通用bucket管理,空闲链表也是类似tcache直接fd连接有UAF的话随便改。

fix的话可以考虑nop掉efree

逆向结构体

module_entry:

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
struct  _zend_module_entry {
unsigned short size;
unsigned int zend_api;
unsigned char zend_debug;
unsigned char zts;
void *ini_entry;
void *deps;
const char *name;
void* functions;
void* module_start_up_func
void* module_shutdown_func;
void* request_startup_func;
void* request_shutdown_func;
void *info_func;
const char *version;
size_t globals_size;
void* globals_id_ptr;
void* globals_ptr;
void* globals_ctor;
void* globals_dtor;
void* post_deactivate_func;
int module_started;
unsigned char type;
void* handle;
int module_number;
const char *build_id;
}

6:str
7:arr
4:int?

patch

off by null(D^3CTF 2024 pwnshell)

非预期

cve-2024-2961,借助libc的溢出从文件包含提升至命令执行。现成exp环境配好了,搜到的去年决赛pwn的awdp中php可以用这个一键打通,万一呢

CATALOG
  1. 1. 环境问题
    1. 1.1. pwn题配置
  2. 2. 准备
  3. 3. 常见漏洞的patch方法
    1. 3.1. 格式化字符串漏洞
    2. 3.2. UAF
    3. 3.3. 整数溢出
    4. 3.4. 缓冲区溢出
    5. 3.5. VM
    6. 3.6. 逻辑漏洞
    7. 3.7. 通防
    8. 3.8. 非预期?
  4. 4. 检查漏洞
  5. 5. docker命令
  6. 6. PHP PWN???
    1. 6.1. 环境搭建
    2. 6.2. 思路
    3. 6.3. 逆向结构体
    4. 6.4. patch
    5. 6.5. 非预期