TCPサーバの接続情報と、以下のファイルが与えられた。
Information for connecting to a TCP server and these files were given:
chall
chall.c
const.h
utils.h
サーバに接続すると、以下が出力された。
Connecting to the server, this text appeared:
ここでは、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:
ここでは区切りの入力を待ってくれるが、数値以外を入力すると大量の出力が発生して操作不能になるので注意が必要である。
入力すると、以下が出力された。
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:
出力されたメッセージに反して、ここも科目名ではなく数値を入力しないと操作不能になるトラップである。
入力すると、以下が出力された。
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:
与えられた 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
).
offset | mandatory_subject | elective_subject |
---|---|---|
+0x00 | char* name; | char* name; |
+0x08 | int time[2]; | int time[2]; |
+0x10 | char *target[4]; | char memo[32]; |
+0x18 | ||
+0x20 | ||
+0x28 | ||
+0x30 | char memo[32]; | char *professor; |
+0x38 | int (*IsAvailable)(student *); | |
+0x40 | - | |
+0x48 | - | |
+0x50 | char *professor; | - |
さらに、以下の点に注目する。
mandatory_subject
の memo
には、選択肢 4 で呼び出される write_memo
で任意の内容を書き込める。elective_subject
の professor
が指すデータは、選択肢 2 の処理で用いられる print_elective_list
(utils.h
で定義) で出力される。elective_subject
の IsAvailable
は、選択肢 2 で選んだ要素について user
へのポインタを渡して呼び出される。user
は chall.c
で宣言された、const.h
で宣言された構造体 student
のデータである。user
の先頭に最初に入力した名前が入る。
与えられたファイル chall
をprintf
のアドレスが 0x405038 に、read
のアドレスが 0x405048 に格納されることがわかる。
これに基づいて、professor
をこれらの位置に設定するための以下のペイロードを用意した。
Also note these points.
memo
in mandatory_subject
using the function write_memo
, called in the choice 4.professor
in elective_subject
is printed in the function print_elective_list
, defined in utils.h
and used in the choice 2.IsAvailable
in elective_subject
from the selected element is called in the choice 2 with a pointer to user
as the argument.user
is declared in chall.c
, and its type is student
, declared in const.h
.user
.
Disassembling one of the given files chall
using objdump in 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.
選択肢 4 (Write Memo) を選択し、FRI 3
を入力する。
これもコピペなどで一気に入力しないと、1回 (1文字) 入力しただけで次の処理に進み、無効な入力とみなされてしまうので注意する。
そして、ペイロードを
その後、選択肢 2 を選び、通信内容を
たとえば、printf
関数のアドレスは 0x7f3c58846770、read
関数のアドレスは 0x7f3c588fa980 と読み取れた。
これらの値を
候補によってアドレスは異なったが、printf
と system
のアドレスの差は全て同じであったので、十分絞れたといえる。
この情報を利用し、名前として /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
After that, select choice 2 and read the communication using
The address of printf
function was 0x7f3c58846770 and one of the read
function was 0x7f3c588fa980, for example.
I put these values to
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")
.
このプログラムにより、シェルを起動することができた。
起動したシェルで 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
.