OverTheWire:Narnia3
narnia3 で ssh 接続。
ssh narnia3@narnia.labs.overthewire.org -p 2226
このステージのお題(/narnia/narnia3.c)はこちら。引数で指定されたファイルを /dev/null へコピーするプログラムになっている。
int main(int argc, char **argv){
int ifd, ofd;
char ofile[16] = "/dev/null";
char ifile[32];
char buf[32];
if(argc != 2){
printf("usage, %s file, will send contents of file 2 /dev/null\n",argv[0]);
exit(-1);
}
/* open files */
strcpy(ifile, argv[1]);
if((ofd = open(ofile,O_RDWR)) < 0 ){
printf("error opening %s\n", ofile);
exit(-1);
}
if((ifd = open(ifile, O_RDONLY)) < 0 ){
printf("error opening %s\n", ifile);
exit(-1);
}
/* copy from file1 to file2 */
read(ifd, buf, sizeof(buf)-1);
write(ofd,buf, sizeof(buf)-1);
printf("copied contents of %s to a safer place... (%s)\n",ifile,ofile);
/* close 'em */
close(ifd);
close(ofd);
exit(1);
}
脆弱性は strcpy(ifile, argv[1]) の部分。引数に32バイト以上のデータを注入すれば、オーバーフローが起きて、すぐ隣に定義されている変数 ofile を上書きしてしまう。
実際にやってみる。"A"を32文字+"BBB" という文字列を入力すると、ofile は ”BBB” になることが判る。
なので、予め「"A"を32文字+"BBB"」という名前でパスワードファイルにシンボリックリンクを張っておき、このファイル名を指定してプログラムを起動すれば、パスワードファイルの内容は BBB というファイルにコピーされることになる。
実際にやってみよう。
まずは準備。/tmp の下に適当なディレクトリを作成し、上述のシンボリックリンクと出力用のファイル"BBB" を配置する。
準備完了したので、「"A"を32文字+"BBB"というファイル名」を引数にプログラムを起動してみる。コマンドは以下の通り。
<コマンド>
/narnia/narnia3 $(perl -e 'print "A"x32 . "BBB"')
ありゃ? "BBB"のオープンに失敗してエラーになった。なんでだろう?
なるほど…。/narnia/narnia3 は suid されていて、narnia4 の権限で動くから、BBBに対する「書き込み権限」が無いのだ。。BBB に誰でも書き込みできるよう権限を追加しよう。
これでよし。
さっきのコマンドで再度 narnia3 を実行してみる。
うまくいった。
あとは BBB の中身を見ればパスワードが書いてあるはず。
というわけで、次のステージへ。。