代码审计:
$_SERVER["REMOTE_ADDR"]获取客户端的 IP地址;
$_SERVER['HTTP_X_FORWARDED_FOR']是透过代理服务器获取客户端真实IP地址;
若未设置GET传入参数host的值,将显示源码;以host为参数上传参数;
变量$host经过escapeshellar()与escapeshellcmd()方法防止注入参数;
Nmap的扫描结果。
根据最后一行,得知可以利用nmap工具上传$host
-oG xxx.php
nmap上传文件的命令
利用escapeshellarg()+escapeshellcmd()的两次转义,闭合单引号后即可执行任意参数
因为两端单引号闭合,所以一句话木马只是被当成了字符串处理。
所以需要闭合所有的单引号,将一句话木马变成一条命令,尝试在Payload前后均加上'
单引号
构造payload:
?host=' -oG shell.php ’
蚁剑连接
找flag
得到flag
flag{b9e833e6-c916-4047-9b46-c790d276a840}
escapeshellarg
绕过(参考链接)
(PHP 4 >= 4.0.3, PHP 5, PHP 7)
把字符串转码为可以在 shell 命令里使用的参数
string escapeshellarg ( string $arg )
escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。对于用户输入的部分参数就应该使用这个函数。shell 函数包含 exec(), system() 执行运算符
概述:
1.确保用户只传递一个参数给命令
2.用户不能指定更多的参数一个
3.用户不能执行不同的命令
(PHP 4, PHP 5, PHP 7)
shell 元字符转义
string escapeshellcmd ( string $command )
escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec() 或 system() 函数,或者 执行操作符 之前进行转义;反斜线(\)会在以下字符之前插入: `|*?~<>^()[]{}$, \x0A 和 \xFF;’ 和 " 仅在不配对儿的时候被转义;在 Windows 平台上,所有这些字符以及 % 和 ! 字符都会被空格代替
概述:
1.确保用户只执行一个命令
2.用户可以指定不限数量的参数
3.用户不能执行不同的命令
参考:https://www.cnblogs.com/NineOne/p/14100125.html
一开始试过访问index.php和robots.txt,都没有回显
御剑也没有扫描出东西
试着用dirsearch扫描一下目录,但是也没有扫出有用的信息
尝试一下是否为git源码泄露,利用GitHack工具扫描找到了源码
";
if(isset($_GET['exp'])){
if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
// echo $_GET['exp'];
@eval($_GET['exp']);
}
else{
die("还差一点哦!");
}
}
else{
die("再好好想想!");
}
}
else{
die("还想读flag,臭弟弟!");
}
}
// highlight_file(__FILE__);
?>
代码审计:
最吸引眼球的就是 eval的一句话木马,题目又加了好多过滤限制了REC
首先是 php伪协议 data协议 filter协议 都不能使用了
然后该网站使用了正则匹配 其实这就是无参数的rce
如果如果’;'===preg_replace(…),那么就执行exp传递的命令
(?R)? : (?R)代表当前表达式,就是这个(/[a-z,_]+((?R)?)/),所以会一直递归,?表示递归当前表达式0次或1次(若是(?R)*则表示递归当前表达式0次或多次,例如它可以匹配a(b(c()d())))
无参数REC 一般有三种绕过姿势:
gettallheaders()
get_defined_vars()
session_id()
具体可以参考博客
紧接着 又是一次黑名单过滤,很多的关键字都被黑掉了(带有get 函数的,肯定是不能用了)
但还有一个函数 scandir 以扫描当前目录下的文件
payload:
?exp=highlight_file(next(array_reverse(scandir(pos(localeconv())))));
- highlight_file() 函数对文件进行语法高亮显示,本函数是show_source() 的别名
- next() 输出数组中的当前元素和下一个元素的值。
- array_reverse() 函数以相反的元素顺序返回数组。(主要是能返回值)
- scandir() 函数返回指定目录中的文件和目录的数组。
- pos() 输出数组中的当前元素的值。
- localeconv() 函数返回一个包含本地数字及货币格式信息的数组,该数组的第一个元素就是"."。
原理:
loacleconv 函数会固定返回一个 . 然后pos将我们获得的 .返回到我们构造的 payload 使得 scandir能够返回当前目录下的数组(换句话说,就是读出当前目录下的文件) rray_reverse()以相反的顺序输出(目的是以正序输出查询出来的内容)然后 next 提取第二个元素(将.过滤出去),最后用highlight_file()给显示出来。
GitHack 下载地址:https://github.com/lijiejie/GitHack
使用githack要在python的环境下进行,所以在下载使用githack之前要下载好python环境
下载后解压进入文件夹
然后cmd进入终端
成功进入终端
使用命令将网站源码下载到文件夹
python GitHack.py http://www.openssl.org(目标网址)/.git/
文件夹中下载好了源码,接着就可以查看源码了
GIT文件基本介绍:
Git 是目前最流行的版本控制系统。版本控制系统在一种特殊的基于文件系统的数据库中记录对我们的项目代码库所做的更改。在 Git 中,这个数据库被称为存储库,其结构受 Linux 文件系统的启发。存储库维护我们代码库更改的历史记录。
git的文件夹将包含对代码库的每一个微小变动的细节。修改的所有快照都将像数据库一样记录在此文件夹中,这使得撤消更改并回滚到所需的代码版本成为可能。
git的文件夹被隐藏,以防止意外删除或文件夹的修改。如果删除此文件夹,代码库的版本历史将丢失。这意味着,将来我们将无法回滚对代码所做的更改。也意味这如果git文件夹没能及时隐藏,会导致数据泄露,源代码暴露。
几个php的函数规则:
assert函数:
assert ( mixed $assertion [, string $description ] ) : bool
assert() 会检查指定的 assertion 并在结果为 FALSE 时采取适当的行动
如果assertion是字符串,他会被assert()当做php代码执行。 思路是通过可控变量file传入恶意参数,构造闭合 file_exists(),使assert()执行恶意代码。
strpos函数
strpos() 函数查找字符串在另一字符串中第一次出现的位置(区分大小写。
语法:strpos(string,find,start)
参考:【转】Git的简单介绍与.git文件导致源码泄露_LovelyLucy的博客-CSDN博客