🚩 CMFの書き込みを無効にする


不眠症の2022年のCTFは、ジュネーブ、スイスで不眠症の会議の間、主催されるCTFです.あなたはオンサイトCTFに出席できるように、あなた自身を登録しなければなりませんでした.合計31の課題があった.CTFの初心者として、私は主に簡単な課題を取ることを決めた.CTFは3月25日(現地時間午後6時15分)から2026年3月26日(現地時間午前4時).
私の最初のオンサイトのCTFとして、それは多くの人々が参加していたのを見てうれしかったです.一部の人々がどのように準備されたかについて見ることも、非常に驚くべきものでした;一部の人々は、彼ら自身の大きなモニターを輸送することさえ決めました🤯 それはオーガナイザーにとても感謝しています.
すべてのフラグは同じ形式であったINS{...} . 道、十分に話して、ここでは、ライトアップです:

🐛 120ポイント


バイナリファイルを与えられました(Download the file ) 我々は右旗を得るために実行しなければならなかった.基本で走りましょう./gdbug :
ファイルを実行するとき、チェックするシリアル番号は引数として与えられる必要があります.引数として1つを指定した後は、シリアルチェックを行い、有効であるかどうかを返します.では、逆アセンブラでバイナリを開きましょう.

頂上を見る--debug , そのシリアルでバイナリを実行した後に、それは成功でありませんでした;INS{Th1$Fl4gSuck$} . そこへの呼び出しもあったptrace() , 典型的なアンチデバッグトリック.バイナリがどんなデバッガからでも実行されることになっているならば、それはこの旗を与えますINS{W0ULDNT-1T-B3-T00-34SY} . 単にptraceチェック全体をnopingすることは、それを迂回するのに十分でした.では、シリアルワークのチェック方法を見てみましょう.

まず変数があるx 値で初期化される0x539 , 新しい変数i 値で初期化される0x0 . その後、ループが始まります.
  • まで永遠にループi はシリアルの長さに達したので、シリアル
  • 次に、文字の16進値をx
  • i が1ずつ増加する
  • また、GDBは、それが加えられた各々のキャラクタの16進値であることを確認しましたx :

    このループの最後には、以下のようなチェックがありました.

    場合はチェックされますx が等しい0xb38 , それで、シリアルのすべてのキャラクタのすべての16進値の合計は0xb38 . このチェックの後、本当に理解しやすい5つのチェックがあります.
  • シリアルの長さは0x18
  • インデックスで0x4 , 0x9 , 0xe and 0x13 シリアルの場合、16進値の文字が必要です0x2d , の値は- .
  • 有効なシリアルパターンは次のようになりますxxxx-xxxx-xxxx-xxxx-xxxx .
    これらの制限に基づいて、単純にBruteforceツールをPythonで作成できます.
    from string import ascii_uppercase
    import itertools
    
    def iter():
        for s in itertools.product(ascii_uppercase, repeat=24):
            s = list(s)
            s[4] = "-"
            s[9] = "-"
            s[14] = "-"
            s[19] = "-"
            yield "".join(s)
    
    def solve():
        while True:
            for serial in iter():
                x = 0x539 # Setup the variables
                i = 0
                while (True):
                    if (i >= len(serial)): # Go over the length of the string
                        break
                    x += ord(serial[i]) # Append the hexadecimal value of the current character to 'x'
                    i += 1
                print(f"Trying {serial}", end="\r")
                if (hex(0xb38)==hex(x)): # Check if the serial is a valid serial or not
                    print(f"Found: INS{{{serial}}}")
                    return # Remove this to see all possible flags
    
    solve()
    
    Code
    出力はかなり面白かったです.
    Found: INS{AAAA-AAAA-AAAA-AAAA-AFZZ}
    Found: INS{AAAA-AAAA-AAAA-AAAA-AGYZ}
    Found: INS{AAAA-AAAA-AAAA-AAAA-AGZY}
    Found: INS{AAAA-AAAA-AAAA-AAAA-AHXZ}
    Found: INS{AAAA-AAAA-AAAA-AAAA-AHYY}
    Found: INS{AAAA-AAAA-AAAA-AAAA-AHZX}
    ...
    
    理由は非常に簡単だった、それらのすべてが有効なフラグだった!

    🤖 ボット電報- 75ポイント


    この挑戦は私の個人的な好みだった.我々は、チャットのために電報ボットを与えられました、そして、我々はそれを利用するために挑戦をしました.最初はコマンドの実行を試みました.実行されるとき、彼らのどれも本当に驚くべきものでした.それから、私はコマンドの後の若干のランダムな議論で試みました、そして、ブーム!コマンド実行時/challs leet 復帰したボット

    Oops an error occured : (1054, "Unknown column 'leet' in where clause")


    課題はSQLインジェクションについてです.実行するテーブルのリストを取得しようとした後UNION ボットは、ホワイトスペースが許されなかったと言いました.幸いなことに、すべての空白を置き換えるための簡単なバイパスがあります/** (comments), it will then be interpreted the same as a whitespace.
    The first discovery was that some fields are too long to be sent along in some fields, so using
    substr () did the trick. The bot ended up leaking the ユーザ`テーブル.


    それから、私たちはそのテーブルの中のコラムを漏らすことができますusername and password :

    だから今、我々は単に既存の行の資格情報を漏らすことができます.3人のユーザがいました.admin フラグとパスワードINS{C0ngr@tz_YoU_d3$eRvE_T3iS_Fl@g} .

    また、親愛なるスタッフのメンバーは、ボットいじめに申し訳ありません

    🅰️ wordle - 9ポイント


    この挑戦は人気に基づいていたworlde game どこで文字を5文字の単語を与えるし、文字を推測する単語の場合は、正しい場所かどうかで知っている.
    私たちはポートを聞いていたnetcatサーバを与えられました1337 そして、我々はゲームを利用しなければなりませんでした.また、全く同じことをしたバイナリファイルもありました.Download the file ).
    私の最初の試みは実際にWordleのバイナリの実行をスパムし、正しい単語が何であるかを言った出力を与えられて以来、いくつかの時点で正しい単語を得ることでした.
    正しい単語を得るときでも、それはエラーメッセージを与えました.それで、私は逆アセンブラでファイルを開けました.ロジックのアセンブリコードはとても簡単でした.

    プログラムはアドレスに移動する0xcb1data_2020e0 が等しい0xdeadbeef . その後、system() 機能は、ランダムな文字列から可能な単語から.これらの言葉の一つは/bin/sh , それで、最後にシェルアクセスがあったことは明らかでした.
    では、置きましょうdeadbeef ユーザー入力として?さて、ユーザ入力はdata_2020c0 , それで、それは働きません.しかし、ユーザー入力は、unsafegets() この値をオーバーフローすることができます.
    両アドレス間には32バイトの差がある.それで、32バイトの単純なオーバーフローは、私を中に入れさせましたdata_2020e0 .
    オーバーフローのペイロードは次のようになります.
    (python2 -c 'print "A"*32 + "\xef\xbe\xad\xde"'; cat) | nc wordle.insomnihack.ch 1337
    
    がなかったので/bin/sh 語のリストでは、プログラムは複数回実行されなければなりませんでした.
    結局旗はINS{C0ngr@tulat1on5!_th3_word_was_d3adBeef!} .

    🌊 弱いribest 4 - 7ポイント


    弱いribest 4は、私を思い出しましたRC4 cipher . 暗号は、キーストレームを使用しており、もちろん、安全でないと見なされます.
    3つの文字列、1つの平文と2つの暗号文を与えられた.
    pt1 = I_do_not_like_ponies
    ct1 = D058DECB037A10916E9D8B0E5345BB381AE8D8EE
    ct2 = D049E9DF182420AB5EC6BD101229940517B59CE0
    
    すべての文字列は、同じ長さがあった、我々は単に変換する必要がpt1 十六進数に495F646F5F6E6F745F6C696B655F706F6E696573 40の長さも得る.私たちには1つの平文がありました.そして、それはキーで暗号化されて、暗号テキストの1つに終わりました.旗は2番目の平文である可能性が高いpt2 ), 不明.
    チャレンジを解決するにはreused key attack ストリーム暗号について説明するには、両方の暗号化テキストをxoringすることでキーを削除します.そのためには

    ct1 ⊕ ct2 = pt1 ⊕ pt2


    だから得るpt2 単に必要です.
  • 両方から毎回2文字を取るct1 and ct2
  • 16進数に変換する
  • XORを一緒に取得するresult
  • から2文字を得るpt1
  • 16文字からなる2文字をXORした場合の16進数を検索するpt1 , リードするresult
  • その値に対応する文字をflag 変数.
  • 次のPythonスクリプトを作りました.
    import time
    
    pt1 = "495F646F5F6E6F745F6C696B655F706F6E696573"
    ct1 = "D058DECB037A10916E9D8B0E5345BB381AE8D8EE"
    ct2 = "D049E9DF182420AB5EC6BD101229940517B59CE0"
    
    flag = ""
    
    for i in range(0, len(ct1) - 1, 2):
        ct1_pair = int("0x" + ct1[i:i+2], 16) # Get two characters from ct1
        ct2_pair = int("0x" + ct2[i:i+2], 16) # Get two characters from ct2
        result = ct1_pair ^ ct2_pair
        for k in range (0x0, 0x7f): # Loop over all characters in the ASCII table
            if (int("0x" + pt1[i:i+2], 16) ^ k) == result: # Check if the XORed number is the same as the result
                flag += chr(k)
                print(flag, end="\r")
                time.sleep(0.5) # That is just to look cool 😎
                break
    
    Code
    これにより以下のフラグが得られた.INS{D0_No7_u$3_Rc4!}

    🔮 魔法の言葉


    この挑戦のために、我々はウェブサイトへのリンクを与えられました.ウェブサイトは文を求めたので、基本的に私たちはこの判決を受けなければなりませんでした.ソースコードを見るとき、いくつかのチェックがあったので、最初にすることはローカルマシンで同じファイルを作成することでした.
    その後、単に1つずつチェックを1つずつ、各段落の単語を取得します.それからローカルでチェックを再現して、スクリプトを実行してください.
    // More code above...
    
    // This is the needed code
    p1 = 'Later, on my walk, I wondered why I felt I had to be suspicious of ‘normality’. The striking thing about the normal is that there is nothing normal about it: normality is the gentrification of ordinary madness – ask an Surrealist. In analysis ‘the normal child’ is often synonymous with the obedient good child, the one who only wants to please parents and develops what Winnicott called ‘a false self’';
    p2 = 'In the hospital men’s room, as I’m washing my hands, I glance in the mirror. The man I see is not so much me as my father. When did he show up? There is no soap; I rub hand sanitizer into my face–it burns. I nearly drown myself in the sink trying to rinse it off.';
    p3 = 'Your only chance of survival, if you are sincerely smitten, lies in hiding this fact from the woman you love, of feigning a casual detachment under all circumstances. What sadness there is in this simple observation! What an accusation against man! However, it had never occurred to me to contest this law, nor to imagine disobeying it: love makes you weak, and the weaker of the two is oppressed, tortured and finally killed by the other, who in his or her turn oppresses, tortures and kills without having evil intentions, without even getting pleasure from it, with complete indifference; that’s what men, normally, call love.';
    p4 = 'Looking back on those incidents, he was always appalled by the memory of his passivity, hard though it was to see what else he could have done. He could have refused to pay for such gravy damage to his room, could have refused to change his shoes, could have refused to kneel to supplicate for his B.A.';
    p5 = 'The way he went after that plump sister in the lace tucker, was an outrage on the credulity of human nature. Knocking down the fire-irons, tumbling over the chairs, bumping against the piano, smothering himself among the curtains, wherever she went, there went he. He always knew where the plump sister was. He wouldn’t catch anybody else. If you had fallen up against him (as some of them did), on purpose, he would have made a feint of endeavouring to seize you, which would have been an affront to your understanding, and would instantly have sidled off in the direction of the plump sister. She often cried out that it wasn’t fair; and it really was not.';
    
    var response = '';
    
    var words = p1.split(' ');
    for (var i = 0; i < words.length; i += 1) {
        if (words[i] == 'please') response += words[i];
    }
    
    var words = p2.split(' ');
    for (var i = 0; i < words.length; i += 1) {
        if (beautify(words[i]) == 'siqz') response += ' ' + words[i];
    }
    
    var words = p3.split(' ');
    for (var i = 0; i < words.length; i += 1) {
        if (uglify(words[i]) == 'MDA=') response += ' ' + words[i];
    }
    
    var words = p4.split(' ');
    for (var i = 0; i < words.length; i += 1) {
        if (digitalize(words[i]) == '746865') response += ' ' + words[i];
    }
    
    var words = p5.split(' ');
    for (var i = 0; i < words.length; i += 1) {
        if (mystify(words[i]) == 'c83b72dd001482ce10f0b106c7a0ed0e') response += ' ' + words[i];
    }
    
    console.log(response);
    
    Code
    その結果はplease show of if in of is in an it to me to to of is by in or the way . ちょうどその文章に合う良い言葉を見つけることができたpleas show [of if in of is in an it to me to to of is by in or] the way , ベストは間違いなくplease show me the way .
    フラグを指定すると、INS{jQu3ry_1$_Fr3@kiNg_C0oL} ) が与えられた.

    👋 ようこそチャレンジ- 6ポイント


    我々は、実際には変更を開始含まれている課題を解決するために従うように指示されているgitlabリポジトリへのリンクを取得します.
    私のシェルは、奇妙な、奇妙な見た最初の手順を
    You are infected 🧟 $
    
    しかし、私は、この冗談を得た唯一の人でありませんでした:

    これがどこから来たかをチェックした後に、それは2009年に位置しましたinso/.circleci/pre-commit , そこにもexec $SHELL ファイルの最後にあるコマンドを参照してください.単に変更された行を削除することによってPS1 変数と削除exec $SHELL コマンドは、私は戻ってフラグを得ることができた.
    フラグは以下のような失敗したコミットに応答して与えられた.remote: INS{S0_F4r_S0_g00d} .