TCPサーバの接続情報、サーバのプログラム(C言語のソースコードとELFファイル)、
そしてELFファイルlibc.so.6
とld-linux-x86-64.so.2
が与えられた。
与えられたソースコードを読むと、gets
関数で入力を読み込む処理を含む関数verify
を呼び出していた。
objdump
で逆アセンブルした結果より、
読み込み先はRBPの0x100バイト前で、RBPの8バイト先にリターンアドレスがあることが読み取れた。
そこで、リターンアドレスの手前までを埋めるデータplaceholder.bin
と、
ROP (Return-Oriented Programming) を用いて以下の処理を行うデータleak.bin
を用意した。
pop rsi; pop r15; ret
というgadgetを用い、RSIをputs
のアドレスが格納されているアドレスに設定する。pop rdi; ret
というgadgetを用い、RDIを"Hi %s!\n"
のアドレスに設定する。printf
関数を呼び出す。verify
関数の先頭 (スタックのアラインメントを考え、プロローグの次) に制御を移す。
Information to connect to a TCP server, the program of the server (C source code and a ELF file),
and ELF files libc.so.6
and ld-linux-x86-64.so.2
were given.
Reading the source code given, I found that a function verify
that reads some input via the function gets
called.
Disassembling via objdump
in
Based on these, I created a data to fill the stack before the return address placeholder.bin
and a data to do following things via ROP (Return-Oriented Programming) leak.bin
.
puts
is stored via a gadget pop rsi; pop r15; ret
."Hi %s!\n"
via a gadget pop rdi; ret
.printf
function.verify
(after the function prologue, considering the stack alignment).
placeholder.bin
、leak.bin
の順に送信し、
puts
関数のアドレスを知り、
再び入力を受け付けさせることができた。
次の手順の準備のため、libc.so.6
をTDM-GCCのobjdump
で逆アセンブルし、
先頭の以下の関数のアドレスを
I sent placeholder.bin
and then leak.bin
via "Send file" with puts
and have the server accept another input.
To prepare for the next step, I disassembled libc.so.6
via objdump
in TDM-GCC,
and put the addresses of following functions to
abort
__libc_init_first
__libc_start_main
gnu_get_libc_release
結果は複数出たが、使いたいputs
、str_bin_sh
、system
の値は共通しており、特定ができたといえる。
この情報を利用し、ROPにより以下を行うデータを生成するプログラムgen.pl
を作成した。
pop rdi; ret
というgadgetを用い、RDIをstr_bin_sh
に設定する。ret
というgadgetを用い、スタックのアラインメントを調整する。system
に制御を移す。
There were several results, but the values of puts
, str_bin_sh
, and system
to use were the same, so this can be considered as identified.
Using this information, I created a program gen.pl
to generate a data to do following things via ROP.
str_bin_sh
via a gadget pop rdi; ret
.ret
.system
.
もう一度placeholder.bin
を「ファイル送信」した後、生成したデータを「ファイル送信」することで、シェルを起動できた。
シェルでls
コマンドを実行することでファイルflag.txt
が存在することがわかり、
cat flag.txt
コマンドを実行することでflagが得られた。
I sent placeholder.bin
again via "Send file", and then sent the generated data via "Send file" to launch the shell.
Using a command ls
in the shell revealed that there is a file flag.txt
.
I obtained the flag by executing a command cat flag.txt
.