ブログ未満のなにか

ブログなのか誰にも分からない

1人で1日1writeup advent calendar

はじめに

私は、CTFを初めて3年目ぐらいの、まだまだ成長期真っ只中の初心者だ。 だが最近全然実力が伸びない、というか成長を感じることができなくなった。 事実実力が伸び悩んでいるのかもしれないが、以前には感じていた問題を解くたびに成長したなぁという感覚というか感動がない。 問題が解けても「やるだけで特に面白みを感じなかった」というのが増えてきた。 面白い問題も勿論あるが、「へー勉強になったなぁ」ぐらいの感想しか出ない。 このままではモチベが崩壊してしまうので、今までの自分では挑戦してこなかった問題に挑んで、成長した喜びを噛み締めて初めの頃の気持ちを思い出そうと考えた。 「難しい問題に挑戦して、懐かしい昔の自分の感覚を思い出す」が、このadvent calendarの主旨である。

12/12 追記

修論などが予想以上に重く、現状は問題を解いてwriteupを書く時間が充分に確保できない。 一旦7日目で更新は途絶えるが、目処が立ったら再開する。

予定している問題

とりあえず今の所は以下の問題を予定している。 解けなかったら別の問題に差し替えることも有り得る。 自分の進捗管理も兼ねて、既に解けている問題に関してはdoneを付けている。 どの問題のwriteupから出すか特に決めていないので、リクエストがあれば応えたい。 writeupは、このブログで順次公開していき、下の表のリンク先を埋めていく (予定) 。

CTF 問題名 ジャンル リンク 補足
NCSTISC CTF 2018 babydriver linux kernel https://hama.hatenadiary.jp/entry/2018/12/03/000000 done
Blaze CTF 2018 blazeme linux kernel https://hama.hatenadiary.jp/entry/2018/12/01/000100 done
SECT CTF 2018 gh0st linux kernel https://hama.hatenadiary.jp/entry/2018/12/02/000000 done
Sharif CTF 2018 kdb linux kernel https://hama.hatenadiary.jp/entry/2018/12/04/000000 done
0CTF 2017 Finals cred_jar linux kernel https://hama.hatenadiary.jp/entry/2018/12/06/000000 done
QWB2018 solid_core linux kernel exploit only (https://gist.github.com/hama7230/de338959ada9935e9f2dd5f1492e4478) done
Midnight Sun CTF Finals Flitbip linux kernel https://hama.hatenadiary.jp/entry/2018/12/19/233626 done
0CTF 2017 Quals KNOTE linux kernel exploit only (https://gist.github.com/hama7230/10772ba9e1a0abb610fa38834c30961b) done
N1CTF 2018 network card linux kernel
WCTF 2018 (by Shellphish) klist linux kernel exploit only (https://gist.github.com/hama7230/ca8df1d28243553e2a5eb995119cde09) done
WCTF 2018 (by Cykor) cpf linux kernel exploit only (https://gist.github.com/hama7230/07cd52a0e6838ea8e6b562b852e37608) done
Blaze CTF 2018 blazefox js engine done
33C3 CTF feuerfuchs js engine
PlaidCTF 2018 roll a d8 js engine
SECCON 2018 Online CTF q-escape qemu escape
HITCON CTF 2018 children tcache heap done
HITCON CTF 2018 baby tcache heap done
34C3 CTF 300 heap
CODE GLAY CTF resured race condition https://hama.hatenadiary.jp/entry/2018/12/05/130055 done

HCTF 2018 the end, baby printf ver2, Heapstorm zero writeup

the end

バイナリは小さく単純である。最初にsleep()関数のアドレスを教えてくれる。標準出力と標準エラーを閉じた後に、任意アドレスへの1byteずつの書き込みを5回行える。

int main(void) {
    char* buf;
    sleep(0);
    printf("here is a gift %p, good luck ;)\n", &sleep);
    close(1); close(2);
    for (int i=0; i<=4; i++) {
        read(0, &buf, 8);
        read(0, buf, 1);
    }
    exit(1337);
}

exploit

libcのアドレスを最初に得られるため、ライブラリ内への書き込みが可能となっている。 exit()を実行する際に呼ばれる処理を追っていくと、__GI_exit() -> __run_exit_handlers() -> _dl_fini() 経由で rtld_lock_default_lock_recursive()rtld_lock_default_unlock_recursive()が呼び出される。2つの関数はldのrwな領域に登録されており、これを書き換えると制御を奪える。ldとlibcのオフセットは固定なので、同じ環境を揃えてオフセットを求めた。問題バイナリに使用されたgccや配布されたlibcから、問題サーバーの環境をubuntu16.04と推測した。同じ環境を用意しオフセットを求めると、libc_base + 0x5f0f48であり、このアドレスを書き換えると制御を奪えた。rtld_lock_default_lock_recursive()system()に書き換え、呼び出し時にrdiが指している領域へshを書き込んでおくことで、system("sh")が呼び出されシェルを取れる。

HCTF 2018 the end · GitHub

baby printf ver2

最初にバイナリがマッピングされているアドレスを得られる。 自明なfsbがあるが、__printf_chk()を使用しているため任意オフセットからの読み出しや書き込みは出来ない。また_printf_chk()呼び出し時に、スタックが0xdeadbbefで埋め尽くされるためアドレスのリークも行えない。入力は、0x200byteがdata領域に保存される。オーバーフローしており、stdoutを指すポインタを書き換えることができる。 入力後に、stdoutのvtableが入力前と同じか確認している。元のstdoutのvtableをローカル変数に保存し、書き換わっていた場合元の値に上書きしている。

# ./babyprintf_ver2
Welcome to babyprintf_v2.0
heap is too dangrous for printf :(
So I change the buffer location to 0x564d0930d010
Have fun!
%p.%p
0xdeadbeef.0xdeadbeef
int main(void) {
    puts("Welcome to babyprintf_v2.0");
    puts("heap is too dangrous for printf :(");
    __printf_chk(1LL, "So I change the buffer location to %p\n", bin_base + 0x202010);

    while (1) {
        void* vtable = stdout.vtable;

        // 本当は1byteずつ読み込んでいるが面倒なので省略
        read(0, bin_base + 0x202010, 0x200);

        if (vtable != stdout.vtable)
            stdout.vtable = vtable;
            
        // スタックを0xdeadbeefで埋める処理がある
        __printf_chk(1, bin_base + 0x202010);
    };
}

exploit

バイナリがマッピングされているアドレスが分かるので、偽のstdoutを用意し、stdoutが指す先を偽の方へ向ける。vtableは改竄されていた場合元に戻されるので適当な値にしておいてよい。 フラグやバッファのアドレスを任意に制御できるので、任意箇所の読み書きが可能である。FILE構造体を利用した諸々のテクニックについては、217のangelboyのスライドで詳細に解説されている(Play with FILE Structure - Yet Another Binary Exploit Technique)。シェルを取るまでの流れは、libcのアドレスをリークして__free_hookへone gadget RCEを書き込んでおき、最後に__printf_chk()内でmallocが呼ば出せばシェルが取れる。

HCTF 2018 baby printf ver2 · GitHub

heapstorm zero

競技中に解けなかった。 note管理系のアプリで、動作は以下の通りである。

  • Allocate: 指定したサイズでcalloc()が実行され、確保された領域へ指定サイズ分の書き込みが行える。指定できるサイズは、0x1 <= size <= 0x38で、fastbinに該当する大きさだけである(とてもしんどい)。off-by-oneがあり、1byteだけnull byteで上書きできる。
  • View: 指定したインデックスの中身をputsで表示する。 存在しないチャンクを見るなどのバグはない。
  • Delete: 指定したインデックスが存在する場合freeを行う。 ポインタはクリアされるためUAFはない。
# ./heapstorm_zero
ooooo   ooooo   .oooooo.   ooooooooooooo oooooooooooo
`888'   `888'  d8P'  `Y8b  8'   888   `8 `888'     `8
 888     888  888               888       888
 888ooooo888  888               888       888oooo8
 888     888  888               888       888    "
 888     888  `88b    ooo       888       888
o888o   o888o  `Y8bood8P'      o888o     o888o

===== (fake) HEAP STORM ZERO =====

1. Allocate
2. View
3. Delete
4. Exit
Choice:

exploit

上記の動作だけからでは、シェルを取るところまでは到達できない。 実は動作の選択時の入力にはscanf("%d")が呼ばれており、入力を工夫することでscanf()内でmalloc/freeを呼び出すことができる。scanf()では、1度の入力のサイズが大きいと一時的なバッファを確保するために、malloc()を呼び出す。バッファは使用後にはfree()される。scanf("%d")に対して、'1'*0x400を入力すると内部では0x800サイズのチャンクが確保されて解放される。 これを利用すると、__malloc_consolidateを呼び出すことができ、fastbinチャンクをまとめてsmallbin/largebinへ繋ぐことができる。 あとは、チャンクのPREV_INUSEをクリアしてチャンクをオーバーラップさせれば、いつも通りのheap系の問題になる。シェルをとるまでの流れは、unsotedbin attackをstdinの_IO_buf_endに対して行い、オーバーフローが起きるようにする。最後に__malloc_hookを書き換えてシェルを起動した。

HCTF 2018 heapstorm zero · GitHub

参考リンク

Hctf 2018 heapstorm zero | Ne0’s blog

HackIT CTF 2018 writeup

はじめに

TokyoWesternsで参加した。 結果は8731点の2位だった。 トップ5にはHackITのカンファレンスチケットが貰えて、さらにトップ3にはスポンサーから何かしらのソフトウェアのライセンスが貰えるらしい。 自分はArmy, A Heap Interface, Bank Reimplemented, KAMIKAZE, HashManを解いた。つまりpwnを全完した。 良い問題だったので楽しかった。

Army

実行すると3つの選択肢を選ぶことができる。Beginner's Luckとしてlibcのアドレスを教えてくれるので、アドレスリークは必要ない。 Join the Armymalloc()に失敗するようなサイズを入れると、heap上に持っているサイズと、bssで保持しているサイズが合わなくなる。 なのでalloc()read()で呼ばれるサイズが異なり、stack bofを起こせる。 canaryはなくlibcのアドレスは既に得られているので、ropをする。

HackIT CTF 2018 army · GitHub

A Heap Interface

unsortedbin attackをglobal_max_fastに対して行う。通常0x80までがfastbinsに入るが、0x90以上のサイズのチャンクもfastbinsに入るようになる。あとは適当にlibcのアドレスをリークさせて、_dl_open_hookに適当な値を書き込んでstdoutのvtableを上書きして制御を取った。

HackIT CTF 2018 HashMan · GitHub

Bank Reimplemented

直下のチャンクのサイズを1byteだけ書き換えることができるのでチャンクをオーバーラップさせる。__malloc_hookは監視されているので、FSOPで_IO_str_jumpを使って制御を取った。

HackIT CTF 2018 Bank Reimplemented · GitHub

KAMIKAZE

MMAPEDビットを立ててcalloc()が0初期化しないようにする。calooc()の初期化が起きないと未初期化バグが発現する。

HackIT CTF 2018 KAMIKAZE · GitHub

HashMan

race conditionとtype confusion。sha1の処理で用いる構造体をxorの処理で用いる構造体に見せかけるために、race conditionを使う。 別スレッドでは同一のkeyがあるか定期的に確認しており、同一のkeyが登録されているとkeyを消す処理が実行される。これはkeyを0にすることと同じであり、xorのkeyの制限範囲と合致する。 同じkeyのsha1を2つ作り、edit/print時のkey入力時に別スレッドの処理を待つことでrace conditonが発動する。

HackIT CTF 2018 HashMan · GitHub

MeePwn CTF 2018 Quals babysandbox, house_of_card, secure_message, 0xBAD MINTON writeup

はじめに

TokyoWesternsで参加して5920ptsで6位だった。finalsに行ける順位なのでベトナムに行くかもしれない。ワールドカップの試合の結果を予想して当てると点数が貰えたりする良いCTFだった。 共同で解いた分を含めて4問解いた。house_of_cardとsecure_messageはfirst solveだったので良かった。

babysandbox

pythonで書かれたサーバ部分では、投げられたペイロードに対してシステムコールのチェックを行っている。 open, read, write, execveといった、よくあるシステムコールが禁止されている。 チェックを通るとバイナリが実行される。 実行結果は、実行が成功したかどうかしか知ることができない。つまりバイナリ側の出力は分からない。

バイナリはシェルコードを受け取り実行するだけである。

以上から、システムコールが制限された状況でシェルコードを書くだけである。 方針は単純で、open, read, writeは禁止されているので、openat, readv, writevで代用する。 出力の受け取りは、socketを作ってサーバーで待ち受けるようにする。

MeePwn CTF 2018 Quals babysandbox · GitHub

% nc -lv 31337
Listening on [0.0.0.0] (family 0, port 31337)
Connection from [178.128.100.75] port 31337 [tcp/*] accepted (family 2, sport 42588)
MeePwnCTF{Unicorn_Engine_Is_So_Good_But_Not_Perfect}

(Unicorn関係あったか?)

house_of_card

first solveだった。ログを見ると問題が公開されて1時間程度で解けていた。

実行すると以下のようにnoteを作ったり編集したり削除ができる。編集と削除を行うときにnoteの中身を見ることができる。noteは以下の構造体で管理される。バグは、edit時に作った時のサイズよりも0x40多く指定しても問題ないので、heap bofが起きることである。

# ./house_of_card
============ 📚 Notes 📚 ============
     1. New Note
     2. Edit Note
     3. Del Note
     4. Quit
    ⛩
struct note {
    char name[0x40];
    int length;
    char description[length];
};

struct node {
    struct note* note;
    struct node* own;
    struct node* next;  
};

まずは、libcのアドレスをリークさせるためにチャンクのサイズを書き換えてオーバーラップを起こした。リーク後は、単方向リストを形成する方の構造体のポインタを書き換えて、__free_hookを書き換えた。

MeePwnCTF 2018 Quals house_of_card · GitHub

# python exploit.py r
[*] '/root/ctf/MeePwnCTF/House_of_Card/house_of_card'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
    FORTIFY:  Enabled
[+] Opening connection to 178.128.87.12 on port 31336: Done
[*] Pwning
[*] libc_base: 0x7f01a3333000
[*] Switching to interactive mode

>$ cat flag
MeePwnCTF{no_moreeeeee_h43p}

secure_message

これもfirst solveだった。

適当にやっていたら解けたのでよくわかっていない。 urandomのfdを保持している箇所は、4番目のユーザーのパスワードを最大で入れるとnull終端時に0で上書きされる。つまりランダムっぽくしたい部分を任意にできる。 messageはmmap()で取得された領域が使用され、第一引数はurandomから呼んでランダムになるはずである。上記のバグで任意の第一引数でmmap()を実行できる。MAP_FIXEDが付いているので、おおよそ第一引数通りのアドレスが取得できる。 edit時にサイズを変えるとsegvで落ちるパターンがあり、落ちないように適当にやっていたら解けた。

MeePwn CTF 2018 Quals secure_message · GitHub

# python exploit.py r
[*] '/root/ctf/MeePwnCTF/secure_message'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
    FORTIFY:  Enabled
[+] Opening connection to 178.128.87.12 on port 31337: Done
[*] Pwning
[*] bin_base: 0x557bac867000
[*] libc_base: 0x7fb8da3da000
[*] heap_base: 0x557bacb57000
[*] Switching to interactive mode
$ cat /home/sm/flag
MEEPWNCTF{MAP_FIXED_1s_v3ry_dangerous}

0xBAD MINTON

misc(web+pwn)。 pwnパートをやった。フロントエンドではアカウントのregister/loginができ、アカウントごとに固有のトークンが付与される。 3回までenrollでき、4回目以降は普通ではできなかった。

リスティングが有効でファイル一覧が取得できた。ファイル一覧では各種phpファイルとTODO.txtbackend_serverが見れる。 TODOには、178.128.84.72:9997で待ち受けている旨が書かれている。 実際にアクセスしてみると、backend_serverが動いていた。 backend_serverは、トークンをもとにDBからアカウントの情報を取得し諸々の処理を行う。 enrollしている場合、enrollした回数だけstack上にペイロードを投げることができる。ペイロードはstack上に保存される。 backend_serverのバグは、4回以上enrollしている場合stack bofとなる点である。しかし、SSPが有効なのでROPはできない。

フラグは事前にbss上に直置きされる。No PIEなのでアドレスは固定である。

方針は単純で、webパートで4回以上enrollしてstack bofを起こし、argv[0] leakを行う。チームメンバが4回enrollしたアカウントを作ってくれたので、あとはやるだけだった。pwnパートは以下の通りである。stderrがネットワーク越しに漏れてこないと面倒だったが特に気にしなくて良かった。

MeePwn CTF 2018 Quals 0xBAD MINTON · GitHub

# python exploit.py r
[*] '/root/ctf/MeePwnCTF2018/0xBADMINTON/backend_server'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
[+] Opening connection to 178.128.84.72 on port 9997: Done
[*] Pwning
[*] Switching to interactive mode
 Okie let's recheck your courses again:
#0 aaaaaaaaaaaaaaaa

#1 aaaaaaaaaaaaaaaa

#2 aaaaaaaaaaaaaaaa

#3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxp@`
Okay! Let's warm-up
----------------BADMINTON TRAINING----------------
1. Push-up
2. Running
3. Give up
> *** stack smashing detected ***: MeePwnCTF{web+pwn+oldschool+stuff+stack+terminated}
 terminated
[*] Got EOF while reading in interactive

0CTF/TCTF Finals Baby Heap 18.04, freenote2018 writeup

Baby Heap 18.04

機能

起動すると以下のように機能を選択できる。

===== Baby Heap 18.04 =====
1. Allocate
2. Update
3. Delete
4. View
5. Exit
Command:

各機能は、

  • 1. Allocate 0x1 ~ 0x58までのサイズでmallocを実行できる。取得された領域はmemsetによって取得したサイズ分0埋めされる。ポインタは、bss上にある配列でサイズ、管理フラグと共に保管される。
  • 2. Update 指定したindexの領域へ、サイズを指定して書き込みを行える。サイズはAllocateで指定したサイズ+1まで指定できる。off-by-one overflow
  • 3. Delete 指定したindexをfreeする。管理フラグを0にする。
  • 4. View 指定したindexの領域を、Allocateした時のサイズ分だけwriteで出力する。

方針

Updateでoff-by-one overflowがあるので、直下のチャンクのサイズを任意の値にすることができる。 まずは、チャンクのoverlapを起こし、address leakを行う。heapのアドレスは簡単に取ることできるが、この問題の環境はubuntu 18.04でありglibc 2.27である。つまりtcacheが有効になっている。tcacheが有効な環境では、サイズが0x420以上のチャンクをfreeすれば、そのチャンクはunsorted binに入り、fd/bkにmain_arenaを指すポインタが置かれる。あとはこのアドレスを出力させればいい、

制御の奪取はとても簡単で、tcacheには、繋がっているチャンクのサイズの確認が一切なく、fake chunkのサイズに該当する部分がどのような値であろうと問題なく動作する。__free_hookを指すようにtcacheのfdを書き換えて、mallocするだけで、__free_hookを指す領域を取得できる。

exploit

0CTF/TCTF 2018 Finals Baby Heap 18.04 pwn · GitHub

freenote2018

機能

選択肢は以下の5つ。

1. init a note
2. edit a note
3. free a note
4. show a note
5. exit

各機能は以下の通りである。

  • init a note 指定したサイズでmallocを実行できる。サイズの制限は0x1 ~ 0x100となっている。確保した領域のポインタはbss上にある配列でポインタと一緒に管理される。
  • edit a note index指定で1で取得した領域へ書き込みができる。書き込みできるサイズは、initした時のサイズと同じであり、overflowはない。
  • free a note index指定で指定した領域をfreeできる。free後にポインタをNULL埋めしないため、double freeできる。
  • shoe a note 選択肢として存在するだけで、何もしない(表示もしない)

freeしたポインタがそのまま残っており、editとfreeで何度でも指定することができる。ただし、address leakに使えそうな機能が存在しない。

方針

最近読んで覚えていたので、以下の手法を使った。 House_of_Roman.md · GitHub

手法の概要は、unsortedbinに繋がるチャンクをfastbinsの方へforgeし、さらにチャンクのfdのmain_arena辺りを指すポインタをpartialで書き換えることで、__malloc_hook付近を指すように書き換えてfastbin attackを成立させる。これで__malloc_hook付近を覆うようにmallocで取得できる。 さらに、__malloc_hookへunsortedbin attackによってlibcのアドレスを書き込み、partialで下位3byteを書き換えることで、one gadget RCEのアドレスを作る、といったものである。当然だが、brute forceが必要であり提案者は12bit分だと言っている(体感だともっと悪い気がする)。

今回のバイナリでは、

  • initでmallocはするが書き込みeditと別になっている
  • UAFによるfd辺りの書き換えがeditで容易にできる
  • double freeによってfastbin attackが用意である といった感じで都合が良い。

exploit

12bit brute forceが必要となる。

0CTF/TCTF 2018 Finals freenote2018 pwn · GitHub

SECCON BeginnersCTF 2018 writeup

はじめに

ShenzhenWesternsで参加して全完した。普段はTokyoだが、0CTF Finalsで深圳に行っているメンバーがいたのでShenzhenになった(たぶん)

condition

main関数での[rbp-0x4]が0xdeadbeefであれば、flagが出力される。

# python -c 'print "\xef\xbe\xad\xde"*0x10' | nc pwn1.chall.beginners.seccon.jp 16268
Please tell me your name...OK! You have permission to get flag!!
ctf4b{T4mp3r_4n07h3r_v4r14bl3_w17h_m3m0ry_c0rrup710n}

BBS

入力でgets()を使っているので自明なstack bof。 バイナリ内でsystemを使っているので、適当にROPするだけ。 '/bin/sh'が必要なので、先にgets()bssあたりに書き込み、systemを呼んだ。

SECCON BeginnersCTF 2018 BBS · GitHub

Seczon

comment機能にFSBがある。 まずは、libcとstackのアドレスをリークした。 制御を取るためにstackに積まれているmain関数の戻りアドレスを書き換えた。 commentとして入力した文字列は、stackにそのまま乗っているのでやるだけ。

SECCON BeginnersCTF 2018 Seczon · GitHub

Veni, vidi, vici

1行目は、ROT13。2行目は、https://quipqiup.com/ に投げた。3行目は読むだけ。

plain mail

zipファイルがbase64で見えるので、取り出す。zipのパスワードはメール中に書いてある。

てけいさん

やるだけ

SECCON BeginnersCTF 2018 てけいさん · GitHub

RCTF 2018 writeup

babyheap

bug: 1. Allocにoff-by-one single byte null overflowがある。 下のチャンクのsizeが上書きでき、サイズの縮小とPREV_INUSEビットのクリアができる。 適当にやればチャンクのoverlapができるので、libcのアドレスをリークをしてfastbin attackをした。 __malloc_hookにone gadget rceを書き込んだ。

https://gist.github.com/hama7230/86643fbf8ad4b6f31521e77a3339b4cf

RNote4

editで入力するサイズの整合性を確認していないため、allocで作成した時のサイズよりも大きい値を入れればheap bofとなる。 editで書き込めるポインタがあるので、そこを書き換えることで任意アドレスの書き換えが出来るようになる。 リークができそうな部分がないが、No PIEでNo RELROとなっているので何とでも出来る。 No RELROなのでstrtabを偽装して、名前解決時にfreeをsystemへとすり替えた。

https://gist.github.com/hama7230/2483803ead0853b7b218b5402986b9fe

stringer

競技中には解けなかった。 UAFがありdouble freeができる。しかしcallocによって割り当てられた領域は0初期化されてしまうので、アドレスのリークができない。 callocでは、IS_MMAPPEDビットがたつチャンクの0初期化が行われないようになっているので、editで当該ビットを立てるようにする。

あとはfastbin attackから__malloc_hookへone gadget rceを書き込んだ。

https://gist.github.com/hama7230/9c74cf53fa2d553cb3baea56a881fbbc

cpushop

hash length extention attackをする。

https://gist.github.com/hama7230/c6b89247bb7a941cdc4e976e16232779

git

blobをzlibで解凍してみたら、flagがあった。