[日本語] [English]

Curly fries

TCPサーバの接続情報と、サーバのファイル一式が与えられた。
与えられたファイルのうち app.c を読むと、以下の処理をしていることが読み取れた。

  1. URLの入力を受け付ける。
  2. mallocで1024バイトの領域を確保する。
  3. 確保した領域に./flag.txtの内容を読み込む。
  4. 確保した領域を開放する。
  5. 読み込んだURLにリクエストを送る。
  6. Content-Length または content-length で始まるヘッダが送られてきたら、mallocで指定された数値+1バイトの領域をレスポンス用に確保する。
  7. レスポンスが送られてきたら、確保したレスポンス用の領域に書き込む。
  8. リクエストに成功したら、レスポンス用の領域の内容を出力する。

mallocで同じサイズの領域を確保すると、バッファが使いまわしされることが期待できる。
そこで、1024バイトの領域を確保させるヘッダを送り、ボディはそれより少ないデータを渡すことで、バッファに残ったflagが出力される可能性があると考えた。

これを実行するため、AWSにAMI「Ubuntu Server 20.04 LTS (HVM), SSD Volume Type」(ami-03d5c68bab01f3496) を使用して t2.micro のEC2インスタンスを立て、そこでサーバのプログラムを動かすことにした。
このとき、サーバにアクセスできるように、セキュリティグループの設定でソース 0.0.0.0/0 からTCPの7777番ポートへのアクセスを許可した。

Content-Length で指定した長さより少ないデータしか送らずに接続を閉じると、エラーになってしまった。
そこで、Content-Length-Fake ヘッダで領域を確保させ、データのサイズは(小文字のlを使った) Content-length ヘッダで指定することにした。
最終的に、以下のサーバプログラムを用いることで、flagが得られた。
hello, world 1個ではバッファに領域を開放した時に書き込まれるナル文字が残っているようでflagが得られなかったので、hello, world を2個にした。

server.pl

buckeye{https://secret.club/2021/05/13/source-engine-rce-join.html}

writeup by MikeCAT

BuckeyeCTF 2021