以下のコマンドを実行する.
makechallenge.c は, rand() の戻り値を key として設定する. 標準入力に key と同じ値を入力すると, flagが出力される.
challenge.c をコンパイルした challenge でどのようにプログラムが実行されているかを以下で調べていく.
challenge.c をコンパイルした challenge に対して, 以下のコマンドで実行時のライブラリ呼び出しのトレースを取得する.
ltrace ./challengetime(0) = 1545575934
srand(0x5c1f9dfe, 0x7ffc789bfdd8, 0x7ffc789bfde8, 0x564b3ccea8a0) = 0
rand(0x7f295a6e81d0, 0x7f295a6e8740, 0x7f295a6e81c4, 0x7f295a6e81d0) = 0x336aabdb
printf("Input Password > ") = 17
__isoc99_scanf(0x564b3ccea936, 0x7ffc789bfce0, 0, 0Input Password > dead
) = 0
printf("Wrong, Key is %d\n", 862628827Wrong, Key is 862628827
) = 24
+++ exited (status 0) +++以上の出力より, time(0) を呼び出して, その戻り値を引数として srand() を実行している.
srand の引数を同じにできれば, key の値は同じになる.
以下のコマンドで, challenge が使う共有ライブラリを調べる.
ldd ./challenge linux-vdso.so.1 (0x00007ffe8dfe4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc0307ea000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc030ddd000)glibcの time_t time (time_t *t) を真似て実際の時間+3[sec]の時間を返す関数を実装.
time.c から作った共有ライブラリ.
challenge から flag を取得するために, LD_PRELOAD を使って time() 関数を取り替えたものを実行して, 3秒後の key を取得し, それを利用してflagを取得するスクリプト.
https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/
https://qiita.com/koara-local/items/d5205f94decade3ffbf1
http://matsu911.github.io/Testing/2012/02/27/testing-with-ld_preload/
https://siguniang.wordpress.com/2015/05/15/override-functions-with-ld_preload/