2019-11-24 東京大学駒場祭 TSG出展企画「TSG LIVE! 4」
気軽にコメントしてね♫
↘
@hakatashi
ジャンル: Reversing
難易度: easy (100pts)
作問者: @hakatashi
実は、通常の操作をするだけではたどり着けないページに
「フラグ」が記されている
→ プログラムの中身を解析して「フラグ」の場所を探す
→ リバースエンジニアリング
クライアント
サーバー
プログラムはサーバーにあるので
入手不可能。解析もできない
プログラム実行
実行結果を返す
返されたデータを表示
クライアント
サーバー
手元でプログラムが実行される
→リバースエンジニアリング可能!
プログラムを返す
プログラム実行
何も実行しない
ジャンル: Web
難易度: easy (100pts)
作問者: @hakatashi
クライアント
サーバー
「残高が足りない」などにより
「行えない操作」は、まずクライアントで検証される
データ検証
OKならサーバーに問い合わせ
操作を実行
悪いクライアント
サーバー
クライアントでの検証だけでは不十分。
悪いクライアントによりハックすることができる
データ検証をスキップ
NGだけどサーバーに問い合わせ
操作を実行
クライアント
サーバー
悪意あるユーザーからのリクエストを
ブロックするには、操作を二重に検証する必要がある
データ検証
OKならサーバーに問い合わせ
操作を実行
データ検証
OKなら
ジャンル: 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チャンネルで
わいわいしています
なんか聞き心地悪い気がしませんか?
→モールス信号
- ・・・ --・ -・-・ - ・・-・ -・--・
--- -・ ・-・・ -・-- -・・・・- ・・-・
--- ・-・ -・・・・- --・ --- ・-・ ・・
・-・・ ・-・・ ・- --・・ -・--・-
TSGCTF(ONLY-FOR-GORILLAZ)
ジャンル: Misc
難易度: medium (200pts)
作問者: @bitmath
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();
とても長い文を投げた時の
Slack API の仕様を利用します
通常、Slackでは非常に長い文章を投げることができない
しかし、APIから投稿すると、自動で短い文章に
分割されて投稿される → 文章としては別のものに
ジャンル: Pwn
難易度: hard (300pts)
作問者: @smallkirby
ジャンル: Crypto
難易度: hard (300pts)
作問者: @hakatashi
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暗号の秘密鍵が求まりこれにより問題が解ける。
⋯⋯ともかく、デモをお見せします