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.name); return user; } int main() { char flag[0x100] = {}; auth_t user = get_auth(); if (user....

2023-04-22 · 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を考えます。 php://filter/convert.base64-encode/resource=index.php このURLにはフィルタリングされている文字が含まれるので、それをUnicode文字列に置き換えます。...

2022-07-22 · 1 分 · Me