Midnight Sun CTF 2019 Writeup - Marcodowno
Question
Someone told me to use a lib, but real developers rock regex one-liners. settings Service: http://marcodowno-01.play.midnightsunctf.se:3001
Solution
here
をクリックすると、http://marcodowno-01.play.midnightsunctf.se:3001/markdown?input=%23%23%20Example%20graph%0a...(snip)
に遷移する。
画面の表示内容とHTMLソースを見ると、inputパラメータにMarkDown記法で書いた文字列をセットすると、パースおよび装飾して画面にお表示する機能が実装されているようだ。機能の脆弱性を突いてalert(1)を表示するinputパラメータを考えて、そのURLをSUBMITすればフラグをゲットできるような問題と理解。
機能はクライアントサイドのJavaScriptで実装されている。コア部分は以下の通り。わかりやすく改行を挟んでいる。
text = .replace(/[<]/g, '') .replace(/----/g,'<hr>') .replace(/> ?([^\n]+)/g, '<blockquote>$1</blockquote>') .replace(/\*\*([^*]+)\*\*/g, '<b>$1</b>') .replace(/__([^_]+)__/g, '<b>$1</b>') .replace(/\*([^\s][^*]+)\*/g, '<i>$1</i>') .replace(/\* ([^*]+)/g, '<li>$1</li>') .replace(/##### ([^#\n]+)/g, '<h5>$1</h5>') .replace(/#### ([^#\n]+)/g, '<h4>$1</h4>') .replace(/### ([^#\n]+)/g, '<h3>$1</h3>') .replace(/## ([^#\n]+)/g, '<h2>$1</h2>') .replace(/# ([^#\n]+)/g, '<h1>$1</h1>') .replace(/(?<!\()(https?:\/\/[a-zA-Z0-9./?#-]+)/g, '<a href="$1">$1</a>') .replace(/!\[([^\]]+)\]\((https?:\/\/[a-zA-Z0-9./?#]+)\)/g, '<img src="$2" alt="$1"/>') .replace(/(?<!!)\[([^\]]+)\]\((https?:\/\/[a-zA-Z0-9./?#-]+)\)/g, '<a href="$2">$1</a>') .replace(/`([^`]+)`/g, '<code>$1</code>') .replace(/```([^`]+)```/g, '<code>$1</code>') .replace(/\n/g, "<br>");
最初のreplace関数で、<
記号が全て取り除かれてしまうためタグを挿入できない。
少し眺めると、以下のimgタグへの変換箇所に脆弱性を発見。alt属性にセットされる文字列に"
をいれれば、任意の属性をセットできそうだ。
.replace(/!\[([^\]]+)\]\((https?:\/\/[a-zA-Z0-9./?#]+)\)/g, '<img src="$2" alt="$1"/>')
![aaa" onerror=alert(1) hoge="bbb](http://hoge/)
をinputパラメータにセットしてみる。
ビンゴ。
URLをsubmitしたらフラグゲット。
midnight{wh0_n33ds_libs_wh3n_U_g0t_reg3x?}