TCPサーバの接続情報、サーバのプログラム(ELFファイル)hotel_codeifornia
、テキストファイルpubkey.pem
が与えられた。
hotel_codeifornia
をmain
関数があった。
Information to connect to a TCP server, a server program (ELF file) hotel_codeifornia
and a text file pubkey.pem
were given.
Decompiling hotel_codeifornia
via main
:
main
関数は、codeとsignを入力させた後、入力データを以下のverify_sig
関数でチェックし、
チェックを通ればpython -c '(入力したcode)'
を実行するようになっていた。
The main
function firstly asks to input "code" and "sign".
Then, check the input via the following function verify_sig
.
Finally, it executes python -c '(the "code" entered)'
if the input passes the check.
verify_sig
関数は、「signをe乗してnで割った余りを__gmpz_export
関数で変換したもの」と
「codeのSHA-256ハッシュ値」をstrncmp
関数で比較し、一致と判定されればOKとみなすという処理をしていた。
eとnの値はpubkey.pem
から読み込んでいた。
pubkey.pem
にはBase64エンコードされたデータが書かれていた。
この部分を
大きい方のINTEGERがn、小さい方のINTEGERがeであると仮定した。
The function verify_sig
compares "sign to e-th power modulo n, converted via a function __gmpz_export
" and
"the SHA-256 hash value of code" via the function strncmp
and judge as passed when the comparision results in equal.
The values of e and n were read from pubkey.pem
.
The file pubkey.pem
had a Base64-encoded data.
I obtained two INTEGERs by pasting the data to
I assumed that the large INTEGER is n and the small INTEGER is e.
From Base64, To Hex, Parse ASN.1 hex string - CyberChef
strncmp
関数は0x00のバイトまでしか比較しないので、
余りの変換結果とSHA-256ハッシュそれぞれについて2バイト目が0x00となり、1バイト目が一致するcodeとsignを探せばよさそうである。
まず、変換方法が明らかではないが、上位のバイトほど先に来ると仮定した以下のプログラムで余りが条件を満たすsignを探した。
The function strcmp
only compare data until 0x00 byte.
Therefore, it should be useful to search for "sign" and "code" such that
the second bytes of the converted remainder and the SHA-256 hash value are 0x00 and the first bytes are equal.
Firstly, I searched for a satisfying "sign" via this program.
(How the remainder is converted is not obvious, but I assumed that the highest byte comes first.)
この結果を用い、以下のプログラムで条件を満たすcodeを探した。
Using the result, I searched for a satisfying "code" via this program:
結果、codeに';/bin/sh;'\Y#
、signにad
を入力するとシェルを起動できることがわかった。
(signは16進数で入力することに注意する)
ls
コマンドを用いるとファイルflag.txt
があることがわかり、
cat flag.txt
コマンドを実行するとflagが出力された。
As a result, I found that entering ';/bin/sh;'\Y#
as "code" and ad
as "sign" launches the shell.
(note that "sign" should be entered in hexadecimal)
I found that a file flag.txt
exists via the ls
command.
Executing a command cat flag.txt
resulted in the flag printed.