並び順とか違うけど、同じ音程の和音になってるね。}縦の列の音階を全部XORしたものをASCIIコードとして見るんですね。0;}output.txt0xbff3c3f40xbff3c3940xbff3c4340xbff3c3940xbff3c4140xbff3c3340xbff3c3d40xbff3c4540xbff3c4140xbff3c3540xbff3c4140xbff3c3140xbff3c3d40xbff3c3d40xbff3c4340xbff3c4140xbff3c3f40xbff3c3540xbff3c4340xbff3c4140xbff3c3d40xbff3c3d40xbff3c4540xbff3c3b40xbff3c4540xbff3c3940xbff3c4540xbff3c4540xbff3c3f40xbff3c3d40xbff3c4140xbff3c3140xbff3c3d40xbff3c3b40xbff3c4140xbff3c3340xbff3c4540xbff3c3b40xbff3c4140xbff3c3140xbff3c4540xbff3c4340xbff3c4340xbff3c4340xbff3c4540xbff3c4540xbff3c4340xbff3c414なんかアドレス出力してますね。入力文字のアドレスを5文字単位と11文字単位で丸めてアドレス出力しているような感じ。自分のLinux環境だと、ASLRが動いちゃって、毎回実行する度に勝手にアドレス変わっちゃって困る。いう実行の仕方すると、ASLR無効で実行できる。z3.自分の環境の結果と照らし合わせる。¶4文字目が"c"というのは、すぐ解る。同じ差が出ている文字でも、%5している開始アドレスが変わってくるので判別できる。"(スペース)だった。writeupAPK-Multi-Toolでデコンパイル・コンパイル、BlueStacksで動作確認しました。答えらしき文字列が分からなかったので、命令を書き換えてごり押し・・・。以下はデコンパイル後にコードを修正した部分の差分パッチです。前半の短い部分は、クリック回数をカウントしてる変数が1000万で無い場合に弾く処理を消しました。後半の大量のif,iput,igetは、特定のクリック回数のときに何か処理をしているようなので、クリック回数の変数にその特定の値を設定する処理を追加しました。コンパイルしてアプリを起動し、何回かクリックするとクリアできます。100¶vonnというELFファイルが渡される。VMMと表示して、自身のファイルを削除して終了する。/tmp/...,,,...,,なんか、ファイルを作ってる。writeupまず素数の積を表示。ea7bfc0x00b62dce9f2581635723db6b188f12f0469cbee0cbc5dacb36c36e0c96b6ea7bfc答えは最終bitが反転してたんだけど、そもそもこれ偶数じゃないか・・・。先人のツールを拝借しつつ、素因数分解して復号化を実施。TMCTF{$@!zbo4+qt9=5}PCを無駄に頑張らせてしまいましたが、せっかく書いたので全bit反転させながら調べるプログラムも貼っておきます。問題アルファベットのみで構成された同じ長さの異なる2つの文字列を考えます。その文字列をそれぞれBase64でエンコードした結果、同じ位置に同じ文字があれば抜きだすことにします。抜きだした文字を順に左から並べたとき、できあがる文字列が「2015」「Japan」になるような入力列として、以下のようなものがあります。例)CaEkMbVnD→(Base64)→Q2FFa01iVm5EGePoMjXNW→(Base64)→R2VQb01qWE5XaBckjTiRgbpS→(Base64)→YUJja2pUaVJnYnBTURehZQjLyvwk→(Base64)→VVJlaFpRakx5dndrこのとき、抜き出してできる文字列に上記のように「a」が現れることはありますが、「f」*が現れることはありません。「ASCIIコード順」に並べたものを「SHA1」でハッシュ化した小文字の値で出力し、"TMCTF{<出力した値>}"として回答してください。*訂正前の問題文は「A」となっていました。誤りなので訂正します。4文字にエンコードされるので、1~3文字の全ての組み合わせのエンコードを実施。エンコード後の文字の位置毎に出現回数を数えて、一度も現れない文字を探します。writeupURLを開くと色つきの正方形が沢山並んでいて、1つだけ違う色のマスをクリックするという問題。マスがどんどん小さくなっていくので、自力では流石に無理ですね。1ピクセルずつ色を数えて、(白を除く)一番少なかった色の座標をクリックするプログラムを書きました。最後まで行くと答えが表示されます。エラーはご愛嬌ということで・・・。51740みんな大好き計算問題。見せてやるぜ!オレのシェル芸を!と、思ってやり始めたら撃沈した。3種類の数値表現¶3種類の数値表現が出てくる。パーサー書くのめんどくさくなって、英語を逐次google翻訳して数値を得ようとして失敗した。みたいな気分になった。ローマ数字と英語の対応¶ローマ数字は、辞書を作って対応。ローマ数字(1から3999まで)の一覧を参照しました。Nine英語は結局、perlのLingua::EN::Words2Numsという英語を数値に変換してくれるライブラリを見つけて対応した。$num最後、こんな感じでフラグが出る。Studioをダウンロード&インストール。コンパイラはC++のものですが、C言語でプログラミングしました。迷路の単純な解法は、右手か左手を壁につけたまま移動する、という方法もあるのですが、この方法だけでは解けない迷路も存在するので、「上下左右に移動する経路を全探索する」というアプローチをとりました。今回は「チェックポイントを通過する」「エナジードリンク(以下E缶と表記)」ということから後戻り禁止にもできません。いって、まともに探索するといくら時間があっても足りなさそうです。そこで、「最後にチェックポイントかE缶を取ったあとに」通った経路を通ってはいけない、という制約を付けました。あとは仕様通りプログラミングして、コスト(同じ経路を2回目以降に通った場合に+1、ゴール時残したE缶1つにつき+20)を計算して最適なルートを通るようにしました。ちなみに、いしのなかにいるとはWizardlyの言葉です。プログラムで迷路を解こうとするときは、石があっても突っ込むので数多くの勇者が石に吸い込まれていったことでしょう・・・。//残りのチェックポイント数を調べます。//残りのE缶の数を調べます。//対象の位置をすでに通ったかどうかを判定します。Eを残した場合はペナルティ加算。ノードを追加(ホントは要らなかった。writeupブラックジャックで、特定の手のときにStandしたときと、Hitしたときの勝率を求める問題です。ブラックジャックは知っていたのですが、昨今ラスベガスで行われているルールとは若干違っています。ブラックジャックは、正しくプレイした場合、掛け金の99%が戻ってくる程度の期待値と言われています。100%ではないのは、次のような理由からです。このルールにより、プレイヤーは圧倒的に不利になります。これを緩和するために、以下のようなルールが設けられます。ダブルダウン:プレイヤーは、最初のHitをするとき、その次以降Hitできる権利を放棄するかわりに掛け金を倍にすることができる。ディーラーのカードが見えた状態(ディーラーがBUSTしやすいことが判明した状態)で掛け金を増やせるので、プレイヤー有利になります。対して、このカジノは以下のような変更点が加えられています。(そもそも期待値99%なので、そもそもブラックジャックをプレイしないのが正しいのですが...。)さて、そうは言ってもCTFの問題ですから、確率を計算しなければなりません。このカジノでのブラックジャックは以下の手順で進められます。プレイヤー2枚、ディーラー2枚の手札が配られる。ディーラーは2枚のうち、1枚だけを表にする。プレイヤーが好きなだけ枚数を増やす。ディーラーがルールに従って枚数を増やす。プレイヤーの手とディーラーの手を比較し、強いほうが勝利。上記の順序でプログラミングしてみましょう。カード2組104枚を使う、とのことでしたので、点数別にカード枚数を定義します。},0点は0枚、1点(A)は8枚・・・10点(10JQK)は32枚です。初期状態が与えられているので、見えているカードを減らします。0;ちなみに、aceを別管理するのは、「22以上になっても10を引いて復活」という仕組みにしています。プレイヤーがStandをした場合の確率を、calc_win_dealerという関数で実装。プレイヤーがHitした場合の確率を求めることを考慮し、あらゆる状態に対応した勝率を求める関数を作ります。(その数字を引く確率)の合計です。Hitした数字で勝つ確率は、再帰的に呼び出すことにしています。次にHitした場合の勝率を求めてみましょう。効率化のため、さすがに19以上でHitするケースの方が勝率が上がるワケがないので19以下の場合だけHitを考慮するという方針で実装しました。ret;}これが中心部分です。全ソースは添付していますので、興味があればダウンロードして解析してみてください。ConsoleApplication2.cpp※上記ソースは、エラー処理等の考慮が不十分な点があります。これは、CTFという環境のもと、エラーが発生しないケースで1度正常に動作すれば良いというプログラムであったために無視しています。writeupじゃんけんに30連勝しろよ、という指令。ふつうに考えると1/(3の30乗)=0.0000000000004%くらいで発生するのですが、Trendmicroが出してくる手は「チートしない」「学習する」との記載がありましたので、どう学習データを作るか悩んでました。さんから「1回のアクセスで5000勝負までできる」という情報をもらって、ちょっとひらめきました。「これって、4970回ランダムに入れて学習成果を一定にすれば、その後出してくる手はだいたい同じなんじゃない...?」というわけで、Excelでランダム手を5000個生成。最近はRANDBETWEENが使えるからじゃんけんの手の生成も楽勝です。それで4971手目から、Trendmicroが出してくる手に勝つ手に変更していきます。完全に固定というわけではなく、ランダムになる箇所もありましたが、おそらく学習を忘れてしまったところなので、その場合はリロードして勝つまでやっています。地味な作業でしたが、何とか30連勝できました。こちらは相手の駒を取れない、対戦相手のAIは連続2手動かせる、とやりたい放題。上手くアンパックできなかったので、とりあえず手番管理してるメモリでも探そうか。・・・と思ったが、見つからず。代わりに、よく分からないアドレスを発見。書き換えてみると、以下のように状況が改善される。自分の手番で駒を取れる相手の手番のうち1回は、こちらの駒を動かしてくれる相手の手番でも駒が取れてしまうが、上手いこと頑張って一つも駒を取られずに最後の1枚をとることができれば、フラグが表示される。