初めてのPWN作り

10月27日はSECCON CTFオンライン予選!
手作りのPWN問題を職場の同僚や友達に送って,日ごろの感謝の気持ちを伝えてみませんか?

材料

下準備

Linuxにアップデートを入れてパッケージマネージャで馴染ませせてから,★を入れて混ぜ合わせる.:
ディストリビューションを確認して,その都度正しいパッケージマネージャでしっかり入れる.

# Arch
sudo pacman -Syu && sudo pacman -S docker git gcc-multilib python2 vim python2-pip && sudo pip2 install pwntools
# Ubuntu
sudo apt update && sudo apt upgrade && sudo apt install docker-ce git gcc python2 vim python2-pip && sudo pip2 install pwntools

問題作り

1. 生地を用意する

Buffer Over FlowやFormat String Attackなどどんな生地にするかを決める.

2.方法を考える

シェルコードやROPなどどんな方法でやるかを考えて適切なセキュリティ機構を選択する.

3.作る

作る.

【ここでおいしく作るためのワンポイントアドバイス!】
1. ユーザーに何かを入力してもらう前にfflush(stdout);を呼び出そう!バッファされているputs()やprintf()の出力が全部出力されて,解いてくれる人からの好感度もアップ!
2. 攻撃対象の関数はmain()以外の関数にしよう!インストラクションポインタより前にスタックポインタがエラーを吐いてしまうから,main()のretではeipは振り向いてくれないぞ!

#include <stdio.h>
void print_flag(void) {
    // 略
}
int in_name(void) {
    char name[16];
    printf("Type Your Name : ");
    fflush(stdout);
    scanf("%32s", name);
    return 0;
}
int main(void) {
    in_name();
    return 0;
}

4.コンパイル

コンパイルをする.
【注意!!】普段のプログラミングでは何気なく使っているこのコンパイラ,PWNを作るときには注意深く気持ちを込めてオプションを決定しよう!

mkdir bin
gcc pwn.c -o bin/pwn -m32 -O0 -fno-stack-protector -no-pie -fno-pie

5.完成

問題は完成!
実際に攻撃できるかどうかpwntoolsを使って味見をしてみよう!

動作環境作り

ここまでで問題は完成したけど,ラッピングをして実際に動作するようにしてあげよう!
なんかめんどくさくなってきたけど頑張って!

【なんで環境作るん?】
pwnでルート取らせる問題で実際のルート取られたら大変やろ?
だからDockerでルート取られてもいい環境作るんやで(まる) 別に自分で試すだけなら

socat TCP-LISTEN:8080,reuseaddr,fork EXEC:./pwn

でおk

1.サービス起動

Archだったらこれやる.

sudo systemctl start docker.service

2.設定ファイルの用意

設定ファイル落としてくる

git clone https://github.com/Eadom/ctf_xinetd

ctf.xinetdのserver_args = --userspec=1000:1000 /home/ctf ./helloworld部分をhelloworldから自分の実行ファイル名に書き換える

3.ビルド

ビルドする.

sudo docker build -t "pwn"

4.実行

sudo docker run --rm -d -p "9999:9999" -h "pwn" --name="pwn" pwn

5.接続確認

わーいできたー!

接続確認.

nc localhost 9999

さっき作ったpwntoolsを今度はネットワーク越しに実行

Oh, YEAH !