Jumpy

ELFファイルjumpyとC言語のソースコードjumpy.cが与えられ、 Request Session ボタンが用意されていた。

jumpy.c を読むと、以下のことが読み取れた。

moveax命令で設定する値の最下位のバイト(リトルエンディアンで一番最初のバイト)を0xb8に設定し、 jmp命令でこの最下位のバイトに飛ばすようにすると、
このmoveax命令の次の命令の最初のバイトまでをmoveax命令で設定する値と解釈させ、 その次に配置された値を命令として実行させることができる。
すなわち、次のように命令を配置することで、yy yy yy yyの部分に書いた命令を実行させることができる。

A ELF file jumpy and a C source code jumpy.c were given and there was a "Request Session" button.

Reading jumpy.c, I found these:

Now think about setting the least byte (the first byte in little-endian) of the value to set in the moveax instruction to 0xb8 and jumping to the least byte via the jmp instruction.
This will have it interpret the first byte of the next instruction of this moveax instruction and execute the value after that as instructions.
In other words, you can have it execute instructions in the yy yy yy yy part by placing instructions like this:

jmp moveax moveax eb 01 | b8 b8 xx xx xx | b8 yy yy yy yy

また、readelf -h jumpy の結果は以下のようになり、 実行環境はよくあるx86-64のLinuxであると予想できた。

Also, this is the output of readelf -h jumpy. It seemed that the execution environment is the widely-used x86-64 Linux.

readelf-h.txt

Firefox上で Request Session ボタンを押すと、 Calculating Proof of Work などが表示されるだけのようで、上手く動作しないようだった。
Google Chrome上で Request Session ボタンを押し、しばらくすると、 ncat --ssl (ドメイン) (整数) という文字列が表示された。

表示された整数をポート番号と解釈し、 Tera Termで表示されたドメインとポート番号に接続したところ、 接続はできるものの何も出力されず、10秒ほどで接続が切れてしまった。
また、手元のOpenSSL (OpenSSL 1.0.2n 7 Dec 2017) を用い、openssl s_client -connect (ドメイン):(ポート番号) で接続したところ、 証明書やセッションの情報は表示されたものの、すぐに接続が切れてしまった。
以下のサイトから OpenSSL 1.1.1l 24 Aug 2021 をダウンロードし、同様にs_clientで接続すると、通信に成功した。

When I hit the "Request Session" button in Firefox, it seemed only showing "Calculating Proof of Work" and some other texts. It didn't look working well.
Pressing the button on Google Chrome resulted in a string ncat --ssl (a domain name) (an integer) appearing after a while.

I assumed that the integer is the port number.
I tried connecting to the domain and the port number via Tera Term, finding that a connection is established but nothing was shown after that and it became disconnected after about 10 seconds.
Also, I tried connection to the server like openssl s_client -connect (domain name):(port number) with OpenSSL that had already installed (OpenSSL 1.0.2n 7 Dec 2017).
As a result, information about the certificate, the session, etc. was printed, but it became disconnected right after that.
I succeeded to communicate with the server by downloading OpenSSL 1.1.1l 24 Aug 2021 from this page and using s_client in the same way:

ICS Download - Overbyte

通信ができるようになったので、execveシステムコールを用いて/bin/shを実行するコードを送信してみたが、 シェルのコマンドを送信しても反応がみられず、シェルは使えないようだった。
そこで、指定のコマンドを実行させるコードを構築できるようにした。

まず、これが実行させるプログラムのもととなるコードである。
CS50 IDEで試した結果、/bin/lsexecveの第2引数が0だと上手く動かないようだったので、 コマンドライン引数の配列も構築するようにした。

Now I found how to communicate with the server.
I tried sending a code to launch /bin/sh via the execve system call. However, no response appeared after sending commands for shell and the shell didn't look available.
After that, I prepared to build a code to execute the specified command.

This is a program for building the code to execute based on.
Testing on CS50 IDE, I found that /bin/ls doesn't work well when the 2nd argument of execve is set to zero. Therefore, I had this program construct the array for the command-line arguments.

payload_work.asm

これをもとにして、指定したコマンドを実行するコードを構築する以下のプログラムを作成した。

Based on this, I created this program to construct a code to execute the specified command:

payload_gen.pl

以下が、このプログラムで構築した /bin/ls を実行するコードである。

This is a code to execute /bin/ls created via this program:

payload_ls.txt

このコードをサーバに送信すると、ルートディレクトリによくあるディレクトリ名に混ざって flag という項目が出力された。

そこで、コードを構築するプログラムを改良し、引数を1個指定できるようにした。
以下がその改良後の構築プログラムと、そのもととなるコードである。

Sending this code to the server, I found an entry flag printed among the common directory names in the root directory.

Seeing this, I updated the program to construct a code to enable it specifying an argument.
These are the updated program and a program to work based on:

payload_work_onearg.asm

payload_gen_onearg.pl

これを用いて以下の /bin/cat flag を実行するコードを構築し、サーバに送信すると、flagが出力された。

I built this code to execute /bin/cat flag via this program and sent it to the server, finding the flag printed.

payload_cat_flag.txt

ALLES!{people have probably done this before but my google foo is weak. segmented shellcode maybe?}

ALLES! CTF 2021