【DVWA】 Inyección de comandos
Inyección de comandos significa inyección de comandos. Las aplicaciones a veces llaman a algunas funciones que ejecutan comandos del sistema. Por ejemplo, en PHP, los comandos del sistema se pueden ejecutar utilizando funciones como system, exec, shell_exec, passthru, popen y proc_popen. Cuando los piratas informáticos pueden controlar los parámetros de estas funciones , pueden empalmar comandos del sistema maliciosos en comandos normales para provocar ataques de ejecución de comandos. Esta es una vulnerabilidad de inyección de comandos.
Uno, nivel bajo
1. Prueba de vulnerabilidad
Como se muestra en la figura, ipconfig se ejecuta correctamente. Por supuesto, también puede ver algunos archivos confidenciales a través de cat en Linux, como / etc / password o archivos shadow. Documentación detallada
Respecto al uso de símbolos:
Windows dado Linux :
"|": comando1 | comando2; ejecute directamente el siguiente comando;
"||": command1 || command2; Solo si lo anterior es falso (error de ejecución) se ejecutará el siguiente comando. ping 2 || ipcongfig
"&": command1 & command2; ejecutará la siguiente declaración independientemente de si la anterior es verdadera o falsa.
"&&": command1 && command2; La siguiente declaración se ejecutará solo si la anterior es verdadera. Hacer ping 127.0.0.1 && whoami
Otro Linux :
";": comando1; comando2; Después de ejecutar la instrucción anterior, ejecute la siguiente instrucción.
2. Análisis del código fuente
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
//判断一下系统类别
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{
$cmd}</pre>";
}
?>
Función detallada:
php_uname('mode')
: Donde el modo es un solo carácter
'a'
: Este es el predeterminado. Contiene una secuencia"s n r v m"
en todos los modos.'s'
: Nombre del sistema operativo. PorFreeBSD
ejemplo:.'n'
: Nombre de la CPU. Porlocalhost.example.com
ejemplo:.'r'
: Nombre de la versión, por5.1.2-RELEASE
ejemplo:.'v'
:Información de versión. Existen grandes diferencias entre los sistemas operativos.'m'
: Tipo de máquina. Pori386
ejemplo:.
shell_exec('cmd')
: Donde cmd es el comando del sistema que se ejecutará
stristr()
Función: busque la primera aparición de una cadena en otra cadena y devuelva que la cadena y el resto son binarios seguros y no distinguen entre mayúsculas y minúsculas. Si necesita distinguir entre mayúsculas y minúsculas, debe usar la función strstr ()
2. Nivel medio
1. Prueba de vulnerabilidad
Error al ingresar 222.24.28.118 && nombre de host:
Ingrese 8 | nombre de host ejecutado con éxito:
2. Análisis del código fuente
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];
// Set blacklist
$substitutions = array(
'&&' => '',
';' => '',
);
// Remove any of the charactars in the array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
//将传入参数中的&&和;替换为空
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{
$cmd}</pre>";
}
?>
Por ejemplo, el código fuente anterior usa un mecanismo de filtrado de lista negra, reemplazando && y; en los parámetros pasados por el usuario con vacíos para tratar de evitar la inyección de comandos, pero se pueden usar otros símbolos como |, || y &.
También puede utilizar el método de mosaico :222.24.28.118 &;& ipconfig
Tres, alto nivel
1. Prueba de vulnerabilidad
Ingrese 222.24.28.118 || ipconfig
ejecutado exitosamente:
Entrada 222.24.28.118 |whoami
ejecutada con éxito:
2. Análisis del código fuente
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = trim($_REQUEST[ 'ip' ]); //trim函数去除开头和结尾的空格,以及换行符\n,Tab键\t等
// Set blacklist
$substitutions = array( //采用黑名单过滤机制
'&' => '',
';' => '',
'| ' => '', //过滤了| ,但注意|后有一个空格,可以直接绕过
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
// Remove any of the charactars in the array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{
$cmd}</pre>";
}
?>
Comparado con el nivel medio, el nivel alto mejora el mecanismo de la lista negra, pero una mirada más cercana revela que filtra | y espacios, por lo que puede omitirlo directamente escribiendo |.
Y 222.24.28.118 || ipconfig
también se puede omitir, porque el mecanismo de filtrado se filtra de acuerdo con el orden en la matriz, primero filtrando | espacios, y luego el resto 222.24.28.118 |ipconfig
se puede ejecutar con éxito.
Cuatro, nivel imposible
Análisis de código fuente
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$target = $_REQUEST[ 'ip' ];
$target = stripslashes( $target ); //删除所有反斜杠
// Split the IP into 4 octects
$octet = explode( ".", $target ); //把字符串打散为数组,这里是把ip用点区分为四个数组元素
// Check IF each octet is an integer //检查每个元素是否是一个数字,并且该数组有4个元素
if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
// If all 4 octets are int's put the IP back together.
$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
//将ip重新拼接为点分十进制的形式
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{
$cmd}</pre>";
}
else {
// Ops. Let the user name theres a mistake
echo '<pre>ERROR: You have entered an invalid IP.</pre>';
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
Se puede ver en el código anterior que primero divide la cadena entrante con '.' Y la divide en una matriz, y juzga si cada elemento de la matriz es un número y si la matriz tiene un total de 4 elementos. Restricciones de formato estrictamente impuestas, es más difícil de eludir.
V. Sugerencias de reparación de vulnerabilidades
1. No utilizado
Trate de no usar comandos para ejecutar funciones.
Para el lenguaje PHP, es mejor no utilizar funciones peligrosas que no se puedan controlar por completo.
2. Si tiene que usarlo, debe filtrar antes de que se pasen los parámetros.
Las variables enviadas por el terminal de cliente deben filtrarse y probarse antes de ingresar a la función de comando de ejecución.
Antes de utilizar funciones dinámicas, asegúrese de que la función utilizada sea una de las funciones especificadas.