08. Time Table

TCPサーバの接続情報と、以下のファイルが与えられた。

Information for connecting to a TCP server and these files were given:

サーバに接続すると、以下が出力された。

Connecting to the server, this text appeared:

WELCOME TO THE TIME TABLE PROGRAM Enter your name :

ここでは、1回入力すると改行などを待たずに先に進むため、注意が必要である。
入力すると、以下が出力された。

Here, you should be careful because it goes to next step after only single input (it doesn't wait for things like a newline character).
Entering something, this text appeared:

Enter your student id :

ここでは区切りの入力を待ってくれるが、数値以外を入力すると大量の出力が発生して操作不能になるので注意が必要である。
入力すると、以下が出力された。

Here it waits for a delimiter to be entered, but you should be careful entering something not an integer will lead to loss of control with a lot of output.
Entering something, this text appeared:

Enter your major :

出力されたメッセージに反して、ここも科目名ではなく数値を入力しないと操作不能になるトラップである。
入力すると、以下が出力された。

Despite the message, you should enter not a name of subject but an integer, or the control will be lost.
Entering something, this text appeared:

MON TUE WED THU FRI 1 (null) (null) (null) (null) (null) 2 (null) (null) (null) (null) (null) 3 (null) (null) (null) (null) (null) 4 (null) (null) (null) (null) (null) 5 (null) (null) (null) (null) (null) 1. Register Mandatory Class 2. Register Elective Class 3. See Class Detail 4. Write Memo 5. Exit >

与えられた chall.c を読むと、選択肢1と2では配列の範囲外を含む任意の要素にアクセスできることがわかる。
1 を選択し、続いて 4 を入力すると、FRI 3 の場所の表示が「The World of Intellect」になった。
選択肢 1 では mandatory_list にアクセスするが、これは const.h で確認できる elective_list の要素である。
mandatory_list の要素 mandatory_subject と、elective_list の要素 elective_subject の構造は、それぞれ以下のようになっている。

Reading one of the given files chall.c, we can find that we can access arbitrary elements of arrays, including out-of-range ones, in the choice 1 and 2.
I selected 1, and then entered 4. Then, information for "FRI 3" turned to "The World of Intellect".
While the choice 1 uses mandatory_list, this is from one of the elements of elective_list, defined in const.h.
Here are the structures of mandatory_subject (elements of mandatory_list) and elective_subject (elements of elective_list).

offsetmandatory_subjectelective_subject
+0x00char* name;char* name;
+0x08int time[2];int time[2];
+0x10char *target[4];char memo[32];
+0x18
+0x20
+0x28
+0x30char memo[32];char *professor;
+0x38int (*IsAvailable)(student *);
+0x40-
+0x48-
+0x50char *professor;-

さらに、以下の点に注目する。

与えられたファイル challTDM-GCCのobjdumpで逆アセンブルした結果より、printf のアドレスが 0x405038 に、read のアドレスが 0x405048 に格納されることがわかる。
これに基づいて、professor をこれらの位置に設定するための以下のペイロードを用意した。

Also note these points.

Disassembling one of the given files chall using objdump in TDM-GCC, I found that the address of printf is stored at 0x405038 and that one of read is stored at 0x405048.
Based on this, I created these payloads to set professor to these values.

payload_printf.bin

payload_read.bin

選択肢 4 (Write Memo) を選択し、FRI 3 を入力する。
これもコピペなどで一気に入力しないと、1回 (1文字) 入力しただけで次の処理に進み、無効な入力とみなされてしまうので注意する。
そして、ペイロードをTera Term の「ファイル送信」で送信する。
その後、選択肢 2 を選び、通信内容をWiresharkで確認すると、各関数のアドレスを読み取ることができる。
たとえば、printf 関数のアドレスは 0x7f3c58846770、read関数のアドレスは 0x7f3c588fa980 と読み取れた。

これらの値を libc-database に入力すると、3個の候補が出てきた。
候補によってアドレスは異なったが、printfsystem のアドレスの差は全て同じであったので、十分絞れたといえる。
この情報を利用し、名前として /bin/sh を入れることで system("/bin/sh") を呼び出させる以下のプログラムを作成した。

Select choice 4 (Write Memo) and enter FRI 3.
Note that you should enter at once (via copy-and-paste) here, or it will proceed to next step at entering only once (one character) and consider that as an invalid input.
Then, send the payload via "Send File" on Tera Term.
After that, select choice 2 and read the communication using Wireshark to see the address of the functions.
The address of printf function was 0x7f3c58846770 and one of the read function was 0x7f3c588fa980, for example.

I put these values to libc-database. As a result, 3 candidates were found.
Some of the candidates had different addresses, but the difference of the addresses for printf and system were the same in the all candidates and it is useful.
Using this information, I created this program to enter /bin/sh as the name and have it call system("/bin/sh").

solve.pl

このプログラムにより、シェルを起動することができた。
起動したシェルで ls -al コマンドを実行すると、ファイル FLAG があることがわかった。
続いて cat FLAG コマンドを実行すると、flagが得られた。

This program succeeded to launch the shell.
In the shell, I executed a command ls -al and found a file FLAG.
Then, I obtained the flag by executing a command cat FLAG.

FLAG{Do_n0t_confus3_mandatory_and_el3ctive}

WaniCTF 2023