TCPサーバの接続情報と、ELFファイル babygame が与えられた。
babygame を
NAMEに0x20バイトまでread関数で読み込む。RANDBUFに"/dev/urandom"のアドレスを設定する。set_username())
NAMEに、strlen(NAME)バイトをfread関数で読み込む。print_username())
NAMEのデータをputs関数で出力する。game())
RANDBUFが指すファイル名のファイルから4バイトの整数を読み込む。system("/bin/sh");を実行する。
さらに、RANDBUFはNAMEの0x20バイト先に配置されていた。
従って、最初にナル文字を含まない0x20バイトのデータを入力すると、NAMEに格納されている「文字列」がRANDBUFに繋がるので、
print_username()でRANDBUFに格納されているアドレスを出力させたり、
set_username()でRANDBUFに格納されているアドレスを変更したりできるようになる。
RANDBUFには最初は"/dev/urandom"のアドレスが格納されている。
これを"/bin/sh"のアドレスに書き換えると、game()がファイルから読み込む値が固定になると考えられる。
strings --radix=x babygame コマンドで調べると、位置2024に文字列/dev/urandomがあり、
位置20a3に文字列/bin/shがあることがわかった。
サーバ上のファイル/bin/shの内容はわからないが、仮にELFファイルであるとすれば、
先頭の4バイトはbabygameと同じ7f 45 4c 46であると予想できる。
これは、10進数にすると1179403647である。
この性質を用い、以下の手順でシェルを起動できた。
flag{tomorinao_wa_ayaneru_rasii}をコピペして送信する。read関数に読み込ませるため一気に送信すること、改行を入れてはいけないことに注意する。2を送信する。改行は入れない。puts関数によって追加される改行の間にアドレスが入っている部分があるはずである。例えば、この部分である。1を送信する。改行は入れない。1337を送信する。全体をコピペで一気に送信し、改行は入れない。1179403647を送信する。全体をコピペで一気に送信し、改行は入れない。
シェルでls -alコマンドを実行すると、ファイル flag.txt があることがわかった。
cat flag.txt コマンドを実行すると、flagが得られた。
Information to connect to a TCP server and a ELF file babygame were given.
Decompiling babygame via
read to NAME."/dev/urandom" to RANDBUF.set_username())
strlen(NAME) bytes via the function fread to NAME.print_username())
NAME via the function puts.game())
RANDBUF.system("/bin/sh"); if the integer from the file and the integer the user entered are the same.
I also found that RANDBUF was placed 0x20 bytes ahead from NAME.
Therefore, when we put 0x20-byte data that doesn't contain any null characters at the first step, the "string" in NAME is connected to RANDBUF.
It enables to have print_username() print the address stored in RANDBUF and to have set_username() modify the address stored in RANDBUF.
After the initialization, the address of "/dev/urandom" is stored to RANDBUF.
Putting the address of "/bin/sh" there will make the value that game() reads from the file be fixed.
Using the command strings --radix=x babygame, I found the string /dev/urandom is at 2024
and the string /bin/sh is at 20a3.
The contents of the file /bin/sh on the server is unknown,
but assuming that it is a ELF file, the first 4 bytes should be 7f 45 4c 46, which is the same as the file babygame.
This value is 1179403647 in decimal.
Using these facts, I succeeded to launch the shell by these steps:
flag{tomorinao_wa_ayaneru_rasii} by copy-and-pasting.read, and that you shouldn't put a newline character after that.2. Don't send newline characters.puts. I mean this part, for example:1. Don't send newline characters.1337. Send the whole part at once by copy-and-pasting, without putting newline characters.1179403647. Send the whole part at once by copy-and-pasting, without putting newline characters.
Executing a command ls -al on the shell, I found that there is a file flag.txt.
I obtained the flag by executing a command cat flag.txt.