ライブCTF
2019-11-24 東京大学駒場祭 TSG出展企画「TSG LIVE! 4」
気軽にコメントしてね♫
↘
@hakatashi
Hidden Page
ジャンル: Reversing
難易度: easy (100pts)
作問者: @hakatashi
「隠しページ」を探す問題
実は、通常の操作をするだけではたどり着けないページに
「フラグ」が記されている
→ プログラムの中身を解析して「フラグ」の場所を探す
→ リバースエンジニアリング
Webの「リバースエンジニアリング」は
通常不可能
クライアント
サーバー
プログラムはサーバーにあるので
入手不可能。解析もできない
プログラム実行
実行結果を返す
返されたデータを表示
しかし、この問題では
SPAという技術が用いられている
クライアント
サーバー
手元でプログラムが実行される
→リバースエンジニアリング可能!
プログラムを返す
プログラム実行
何も実行しない
中身を見てみる
- SPAは便利だけどプログラムがユーザーにバレる
- 通常は問題にはならないが、
URLなどに隠したいデータがある場合には不向き - ちゃんと理解して使おう
Is the order a flag?
ジャンル: Web
難易度: easy (100pts)
作問者: @hakatashi
「行えない操作」の検証ロジック
クライアント
サーバー
「残高が足りない」などにより
「行えない操作」は、まずクライアントで検証される
データ検証
OKならサーバーに問い合わせ
操作を実行
「行えない操作」の検証ロジック
悪いクライアント
サーバー
クライアントでの検証だけでは不十分。
悪いクライアントによりハックすることができる
データ検証をスキップ
NGだけどサーバーに問い合わせ
操作を実行
デモ
適切な検証ロジック
クライアント
サーバー
悪意あるユーザーからのリクエストを
ブロックするには、操作を二重に検証する必要がある
データ検証
OKならサーバーに問い合わせ
操作を実行
データ検証
OKなら
- サーバーでのバリデーション不備は、
あまりに地味なのでCTFではほぼ出題されないが
「現実に最も発生しやすい脆弱性」のひとつ - 初歩的な話なので意識して実装をしよう
Stegano Voltex
ジャンル: Stego
難易度: medium (200pts)
作問者: @hakatashi
音声ファイルが与えられる
使用楽曲: “One Day” by Tune Down!, licensed under CC BY 3.0 - https://soundcloud.com/electronicotaku/one-day
某音ゲーを
題材にした (?)
問題
ぶっちゃけゲームは
あまり関係ない
余談ですが、最近TSG内で
音ゲー界隈が盛り上がってる
Slackの#sig-rhythm-gameチャンネルで
わいわいしています
怪しいのはこのGateエフェクトの部分
なんか聞き心地悪い気がしませんか?
プツプツの長さに長いのと短いのがある
→モールス信号
エフェクトがかかるのは4回。
それぞれをモールス信号として読むと
- ・・・ --・ -・-・ - ・・-・ -・--・
--- -・ ・-・・ -・-- -・・・・- ・・-・
--- ・-・ -・・・・- --・ --- ・-・ ・・
・-・・ ・-・・ ・- --・・ -・--・-
となる。
復号すると
TSGCTF(ONLY-FOR-GORILLAZ)
Furuikeya
ジャンル: Misc
難易度: medium (200pts)
作問者: @bitmath
SlackのChatBotとして
問題が与えられる
const {RTMClient, WebClient} = require('@slack/client');
const rtm = new RTMClient(process.env.SLACK_TOKEN);
const slack = new WebClient(process.env.SLACK_TOKEN);
const postFlag = require('./postFlag');
const pond = {
'その辺で売ってる普通の斧': (channel) => {slack.chat.postMessage({channel, text:'普通の斧がありましたよ!'})},
'ギラギラと輝く白銀色の斧': (channel) => {slack.chat.postMessage({channel, text:'銀の斧がありましたよ!'})},
'ピカピカに光る黄金色の斧': (channel) => {slack.chat.postMessage({channel, text:'金の斧がありましたよ!'})},
'f': (channel) => {postFlag(slack, {channel})},
}
rtm.on('message', async (message) => {
if (!message.channel.startsWith('D')) {
// not available in public channels
return;
}
const match = message.text.match(/^(?<obj>.+)が池に落ちちゃった$/);
if (match) {
await slack.chat.postMessage({channel: message.channel, text:':statue_of_liberty:「あらあら,かわいそうに。わたしが探してあげましょう。」'});
for (kind of ['その辺で売ってる普通の', 'ギラギラと輝く白銀色の', 'ピカピカに光る黄金色の']) {
const text = [
':statue_of_liberty:「どのようなものかわからないけれど,試しに',
kind,
match.groups.obj,
'を探してみますわ。どこかにあればいいのだけれど。」'
];
const reply = await slack.chat.postMessage({channel: message.channel, text:text.join('')});
const obj = reply.message.text.slice(text[0].length, -text[3].length);
if (pond[obj]) {
pond[obj](message.channel);
} else {
slack.chat.postMessage({channel: message.channel, text:':statue_of_liberty:「見つからなかったわ……ごめんなさい。」'});
}
}
}
});
rtm.start();
「f」を探させられると
フラグが手に入る
とても長い文を投げた時の
Slack API の仕様を利用します
通常、Slackでは非常に長い文章を投げることができない
しかし、APIから投稿すると、自動で短い文章に
分割されて投稿される → 文章としては別のものに
KillKirby4Free
ジャンル: Pwn
難易度: hard (300pts)
作問者: @smallkirby
Anti-Quantum
ジャンル: Crypto
難易度: hard (300pts)
作問者: @hakatashi
最近
- 量子コンピューターがどうとかで
RSA暗号が話題ですね - RSA暗号は現在実用的に用いられている
暗号の中では最も基礎的なもの - 破られた時のダメージもでかい
- この問題もそんな「RSAを破る」趣旨の
問題です
priv.json.encを
開いてみましょう
暗号化後なのに怪しいビットパターンが
AES暗号の不適切な利用が原因
- AESのECBモードは、同じ平文を
同じ暗号文に変換してしまう - つまり、もとのpriv.jsonにも同じような
繰り返しパターンが現れているはず
数式で表現してみる
priv.jsonを手元で生成したりして
実験すると、pおよびqが以下の形を
していることがわかる
ただし
のような定数
この状態で\(N\)を計算する。
\(\mathrm{X}\gg a,b,c,d\)なので、
\(N\)を\(\mathrm{X}\)進表示することで
直ちに以下の係数を得る。
これらを連立させることで、式
を得る。これを\(bc\)の2次方程式として解くと\(bc\)が得られるので、
を計算する。
ところで\(p\)は
であり、RSA暗号の要件からこれは素数。
つまり\(a\)と\(c\)は互いに素であるので、
が成り立つ。GCDは拡張ユークリッドの互除法を用いて高速に求まるので\(b+d\)が求まり、
これと上式から\(a,c\)も直ちに求まる。
いま\(a,b,c,d\)の全てが求まったので\(p,q\)を復元できる。
よってRSA暗号の秘密鍵が求まりこれにより問題が解ける。
⋯⋯ともかく、デモをお見せします
- RSA暗号は広く使われているぶん、
さまざまな攻撃手法が研究されている - いまは適切に利用すれば安全とされているが、
今後の計算能力の向上などにより安全性が
崩壊する可能性も考えられる - 新しい暗号への乗り換えも検討しよう
おしまい
TSG LIVE! 4「ライブCTF」解説スライド
By Koki Takahashi
TSG LIVE! 4「ライブCTF」解説スライド
- 1,474