よぴやまの自由帳

プログラミング(とベース)のメモ

KOSENセキュリティコンテスト2017に参加した(日記)(write up)

2017/10/21 ~ 2017/10/22までKOSENセキュリティコンテスト2017に参加してきました.

昨年の大会では"ONIHAINAI"というチームとして参加していたんですが今年は即席チームの"チャーハン定食背脂多め"というチームとして参加してきました.

開会式や閉会式でwriteupを書こうという話があったのですが,writeupとしてpublishするのはかなり気が引けたので日記として投稿してみます.

競技開始と同時に僕のmacさんが再起動されVPNに接続されないという問題が発生したため解きやすい問題は全てチームメイトに任せました(地味に申し訳ない)ので,その問題については省いて自分がやった問題や解けたものについて書きます.

結果の画像が上がっていたので一応載せて起きます.

f:id:yopiyama:20171023181146j:plain

目次

Binary 200 ボスを倒せ

とあるゲームを見つけたのだが、ボスがあまりに強すぎて一切倒せそうにない。
どうにか倒す方法はないだろうか。

nc hoge.xxx oooo

とあったのでとりあえずncします. するとゲームが起動するのですが

Input your name: 
Player's HP: 1000
Boss's HP: 12345678
Next round=>
Round 1/10
    Player's Attack!
    Boss's HP: 12345667 (-11)
    Boss's Attack!
    Player's HP: 834 (-166)
Next round=>
Round 2/10
    Player's Attack!
    Boss's HP: 12345658 (-9)
    Boss's Attack!
    Player's HP: 659 (-175)
Next round=>
Round 3/10
    Player's Attack!
    Boss's HP: 12345649 (-9)
    Boss's Attack!
    Player's HP: 484 (-175)
Next round=>
Round 4/10
    Player's Attack!
    Boss's HP: 12345639 (-10)
    Boss's Attack!
    Player's HP: 338 (-146)
Next round=>
Round 5/10
    Player's Attack!
    Boss's HP: 12345630 (-9)
    Boss's Attack!
    Player's HP: 177 (-161)
Next round=>
Round 5/10
    Player's Attack!
    Boss's HP: 12345621 (-9)
    Boss's Attack!
    Player's HP: 0 (-182)

You lose

こんな感じのとても楽しいゲームができました.

典型的なオーバーフローさせたら幸せになれる類のものかなと思いとりあえず"1111111111111111"(1を16個)と入力してみたら見事Player'sHPが0になりました(悲しい).

なのでchar PlayerHP[16]とかかなと思い"111111111111111111"(1を18個)ぐらい入力したら見事に溢れBoss's HPが49ぐらいになったのであとは殴って倒してフラグを手に入れました.

バイナリ弱者にはこれが精一杯です(笑)

Crypto 100 解凍して解答せよ

flag.zipというファイルをダウンロードさせられたのでとりあえず解凍してみたところmasks.pngというファイルとxor.pngというファイルがあったのでGIMPを使ってxor.pngにmasks.pngを重ねたらフラグが読めるようになりました.

Crypto 200 WeakRSA1

How can you break RSA encryption?

N=p*q
N=xxxxxxxxxxxxxxxxxxxxxxx
e=65537
encrypted=answere mod N
encrypted=xoxoxoxoxoxoxoxoxoxoxoxoxoxo

という感じに2400桁のNとencryptedがありガチのRSAじゃんとおったまげたので夜やることにして他の問題を解いていました.

夜時間になり冷静にみてみると問題文にWeakとあるのでNを素因数分解できたりするのかなと思いNに対してフェルマ法を使ってみたところ見事にpとqが計算できたので,あとは

{ \displaystyle
ed \equiv 1 (mod (p-1)(q-1))
}

してdを出して

{ \displaystyle
m \equiv (encrypted)^d (mod N)
}

でmを16進数にして文字列に変換したらフラグが取れました.

Crypt 300 WeakRSA2

Same modulo, different key. That means...?

N=xxxxxxxxxxxxxx
e1=65537
e2=65539
c1=xoxoxoxoxoxoxoxoxoxox
c2=oxoxoxoxoxoxoxoxoxoxo

とあったので「いやこれCommon Modulus Attackのやつじゃんwww」と思い解こうとしました.

Common Modulus Attackは

{ \displaystyle
c1 \equiv m^{e1} (mod N)  
} { \displaystyle
c2 \equiv m^{e2} (mod N)  
}

とした時,

{ \displaystyle
e1 * u + e2 * v = 1 
}

となるu,vを見つけると平文mが

{ \displaystyle
c1^u * c2^v $\equiv$ (m^{e1})^u * (m^{e2})^v (mod N)  
} { \displaystyle
\equiv m^{e1 * u + e2 * v} (mod N)  

\equiv m (mod N)  
}

のようにもとまるといった攻撃法なので,拡張ユークリッドを実装すれば簡単に解けます.

しかし1日目の競技時間の大半に与えられていた値が間違ったものだったらしく僕はそれを保存していて夜時間は完全に詰んでいました.そして2日目に値を保存し直してみたのですがなぜか解けませんでした.

インターネッツにあるコードを使わせてもらったりもしたんですが,解けないままで時間だけが溶けていってしまいました.

卒研でRSAなどの暗号に関することをしているのですごく悔しいです.リベンジします.

Web 200 Web1

urlがありそこを踏んだら"deobfuscate js and find the key"とだけ書いてあるページが開けたのでとりあえずjavascriptをのぞいてみたら地獄のような難読化されたjavascriptがありました

___ = window;
__ = document;
s = "shift";
m = ["addEventListener", "DOMContentLoaded", "createElement", "div", "textContent", "deobfuscate js and find the key", "body", "appendChild", "length", "join", "forEach", "parseInt", "toString", "toUpperCase"];
__[m[s]()](m[s](), () => {
    _ = __[m[s]()](m[s]());
    _[m[s]()] = m[s]();
    __[m[s]()][m[s]()](_);
    (() => {
        __ = [18234125, 323835316891, 11523, 907531478812, 744387234, 44203240442235, 844002446169231, 4601, ];
        ____ = {
            _: m[s](),
            ___: m[s]()
        };
        ____.__ = `____`[[____._]];
        __[m[s]()]((n, _) => {
            __[_] = `${___[m[s | s]](n, _ + 1)[m[s ^ s ^ 1]](0O22 << 1)[m[-~-~s]]()}{${n}}`;
            if (__[_][____["_"]] > 4){
              __[_] = Array(__[_][____["_"]])[____["___"]]("_");
            }


        });
    })();
}, false);

チームメンバーと一緒に読み解いていくと

document.addEventListener("DOMContentLoaded",() => {
    doc_ele = document.createElement("div");
    doc_ele.document.textContent = "deobfuscate js and find the key";
    document.body.appendChild(doc_ele);
    (() => {
        u2 = [18234125, 323835316891, 11523, 907531478812, 744387234, 44203240442235, 844002446169231, 4601, ];
        u4 = {
            _ : "length",
            ___ : "join"
        };
        u4.u2 = 4;
        u2.forEach((n, index) => {
            u2[index] = join.m[s](n, index+1).m[s](36).m[s]()
            if(u2[index].length > 4)
                u2[index] = Array(u2[index].u4.length).u4.join("_")
                console.log(u2);
        });
    });
}, false);

こんな感じにjavasciprtっぽいのができましたがjs力が足りずエラーが出続けました.(jsの構文を少し学べたきがする.)

しかしこのコードを読んでいると18行目あたりで"文字列{変数を文字列にしたやつ}"みたいな処理をしていることに気がつき,試しに元の問題のそれの下の部分を下記のように変更したところフラグが出力されました.

 ____.__ = `____`[[____._]];
__[m[s]()]((n, _) => {
    __[_] = `${___[m[s | s]](n, _ + 1)[m[s ^ s ^ 1]](0O22 << 1)[m[-~-~s]]()}{${n}}`;
    console.log(__[_]);
    if (__[_][____["_"]] > 4){
        __[_] = Array(__[_][____["_"]])[____["___"]]("_");
    }

僕が解いた(解けなかったのも)はこんな感じです.

ちなみにうちのチームは2000ポイントでした.チームメンバーもすごく頑張っていたのでとても良かったです.

僕は今年石川高専5年生で来年から福井大学の3年生に編入するので今年が最後なので来年以降は後輩たちを応援したいと思います.