TCPサーバの接続情報、サーバのプログラム(ELFファイル) ret2libc
、そのソースコード ret2libc.c
、
ELFファイル ld-2.31.so
および libc-2.31.so
が与えられた。
ret2libc.c
を読むと、gets
関数で入力を読み込む処理がある関数learn
があった。
そこで、objdump
による ret2libc
の逆アセンブル結果を用いて、
以下のデータを用いた ROP (Return-Oriented Programming) により、puts
関数のメモリ上のアドレスを出力させ、learn
関数をもう一度呼ばせることにした。
gets
関数が読み込んだデータの書き込み先は-0x20(%rbp)
であり、%rbp
は関数の呼び出し後1回push
した時の%rsp
なので、
リターンアドレスは読み込んだデータの書き込み先の先頭から0x28バイト後である。
pop rdi; ret
のアドレスputs
関数のメモリ上のアドレスが格納されるアドレスret
のアドレスputs
関数を実行させるアドレスret
のアドレスlearn
関数の先頭アドレス以下が実際にサーバに送信するデータである。
Information to connect to a TCP server, the server program (a ELF file) ret2libc
, its source code ret2libc.c
,
and ELF files ld-2.31.so
and libc-2.31.so
were given.
Reading ret2libc.c
, I found a function learn
that reads some input via the function gets
.
Seeing this, I decided to perform ROP (Return-Oriented Programming) using following sequence of data
to have it output the address of the function puts
on the memory and call the function learn
again
using the result of disassembling of ret2libc
via objdump
in
The function gets
here will write what it read from -0x20(%rbp)
and %rbp
is %rsp
after one push
from the beginning of the function,
so the return address is 0x28 bytes after the head of data written by the function gets
.
pop rdi; ret
puts
in the memory is storedret
puts
ret
learn
Here is the actual data to send to the server:
この payload_leak.bin
をputs
関数のメモリ上のアドレスがわかる。
さらに、readelf -s
コマンドを libc-2.31.so
に適用し、
puts
関数とsystem
関数のファイル中の位置を調べると、以下のようになった。
We can obtain the address of the function puts
in the memory by sending this file payload_leak.bin
via "Send file" in
Also, I applied readelf -s
command to the file libc-2.31.so
to obtain the place in the file of the functions puts
and system
.
Here is the result:
また、libc-2.31.so
から文字列 /bin/sh
をバイナリエディタで検索すると、
0x18A152 バイト目 (0-origin) に見つかった。
これらに基づき、求めたputs
関数のメモリ上のアドレスを引数とし、
system("/bin/sh");
を実行させるためのデータを生成するプログラム payload_gen.pl
を作成した。
Moreover, I searched for a string /bin/sh
from the file libc-2.31.so
via a binary editor,
finding at the 0x18A152-nd byte. (the first byte is 0th)
Based on these, I created this program payload_gen.pl
that takes the address of the function puts
in the memory as an argument
and generates data to have it execute system("/bin/sh");
.
生成したデータをls
コマンドを実行すると flag.txt
があることがわかった。
cat flag.txt
コマンドを実行すると、flagが得られた。
I succeeded to launch the shell by sending generated data via "Send file" in flag.txt
by executing ls
command.
I obtained the flag by executing cat flag.txt
command.