misolog

CTFとか勉強とか諸々

HSCTF 7 writeup

6/1(月) 21:00(JST)~6/6(土) 9:00(JST)に開催されたHSCTF 7に参加にソロ参加。

約1週間の長期開催だったので、色んな問題に触れられたので楽しかった。 まだまだ難しい問題を解けるレベルではないけど、SharkyCTFと比較すると解けた問題が結構増えた感じ。

f:id:mis0kin:20200606101615p:plain

Binary Exploitation

Intro to Netcat 2: Electric Boogaloo

ncコマンドを叩くとフラグゲット。

Boredom

ソースファイルと実行ファイルが渡される。

ソースから、setup()でバッファを初期化し、main()内のgets()で入力を受け取る事がわかる。

よって、バッファオーバーフローを起こし、リターンアドレスをflag()に書き換えるとフラグが取れる。 gdbで解析すると、flag()のアドレスは0x4011d5であり、オフセットが216である事が判明。

適当な文字*216 + flag()のアドレスを入力するもフラグ取れず。

適当な文字*208 + flag()のアドレスにするとフラグゲット。

オフセットの計算間違えたかな…

スタックは以下のようになると予想。


(低)

buffer 200byte

フレームポインタ(ベースポインタ?)8byte

リターンアドレス8byte ←ココをflag()に書き換える

(高)


Forensics

Mad Libs

Steganography Onlineでdecodeするとフラグゲット。

ツールに頼らない場合、どうやるんだろうか…

Comments

Comments.zip内に1.zip~8.zipのzipファイルが圧縮されている。バイナリエディタで見るも、特に怪しいところはない。

全て解凍し、zipinfoで全てのzipのメタ情報を見る。file comment内の文字を1つずつ繋げるとフラグゲット。

Meta Mountains

exiftoolを実行すると、3分割された形でフラグが書いてある

Picture Lab: Activity 10

データとpdfファイルが与えられる。pdfを読む限り、データをPNG画像とみなし、chunkを修正すればフラグが取れそう。

ファイル名をmogodb.pngに変更し、バイナリエディタで開く。マジックナンバーを「89 50 4E 47 0D 0A 1A 0A」に変更し、IHDR, IDAT, IEND chunkをそれぞれ付け加えてpngcheckを実行すると整合性が取れ、画像が開けるようになったので開くとフラグが書いてある。

SharkyCTFでの経験が活かせた◎

Algorithms

Pythagorean Tree Fractal 1

pdfファイルをみると、Stage 50の時の長方形の数がフラグになるらしい。Stage 7の長方形の数のカウントは断念。

Stage 3を見ると、Stage 1の長方形の頂点2つから新しく長方形できており、さらに、互いに重なっていない頂点から長方形が2つ新しくできている。

おそらくStage 2は、Stage 3の赤丸で繋がれた長方形までと推測。これをもとに、以下に各Stage毎の長方形の数を示すと、

Stage 1: 1個

Stage 2: 3個

Stage 3: 7個

となるため、長方形の数が2の累乗単位で増加している事がわかる。よって、Stage 50まで計算するプログラムを書いてフラグゲット。

ググると、ピタゴラスの木というみたい。こっちを調べたほうが早かった…

Pythagorean Tree Fractal 2

Stage 1の面積が70368744177664のとき、Stage 25の面積を答える問題。

ja.wikipedia.org

wikipediaより、

n回目の作図操作で一辺が(√2/2)^{n}の正方形が2^{n}個付け足されるので、新しく付け足される正方形の面積の合計は常に1になる。そのため、木の面積は無限に増加するように見える。しかし、5回の反復を超えると、いくつかの正方形が重なり始めるため、面積は有限となり、6×4の長方形内に収まることになる。 とある。

面積が70368744177664の正方形が25個分になるので、70368744177664*25を計算してフラグゲット。

Reverse Engineering

AP Lab: Computer Science Principles

javaのソースを見ると、入力値inpをshift2(shift(inp))したものが「inagzgkpm)Wl&Tg&io」であればinpがフラグになるらしい。 そのため、これを逆算?するコードを書くと良さそう。 javaは未経験のため開発環境がなかったので、paizaで以下のコードを実行し、フラグゲット。

public class Main
{
    public static void main(String[] args) {
        String st = "inagzgkpm)Wl&Tg&io";
        String flag = shift2(shift(st));
        System.out.println(flag);
    }
    public static String shift(String input) {
        String ret = "";
        for (int i = 0; i<input.length(); i++) {
            ret+=(char)(input.charAt(i)+i);
        }
        return ret;
    }
    public static String shift2(String input) {
        String ret = "";
        for (int i = 0; i<input.length(); i++) {
            ret+=(char)(input.charAt(i)-Integer.toString((int)input.charAt(i)).length());
        }
        return ret;
    }
}

AP Lab: English Language

Computer Science Principlesと同様に、「1dd3|y_3tttb5g`q]^dhn3j」をflagの形に直す。 xor()は変更せず。 transpose()の逆変換をする関数transpose2()を作成し、for文で回すとフラグゲット。

public class Main
{
    public static void main(String[] args) {
        String bf = "1dd3|y_3tttb5g`q]^dhn3j";
        
        for (int i=0; i<3; i++){
            bf = xor(bf);
            bf = transpose2(bf);
        }
        
        System.out.println(bf);
    }
        public static String transpose2(String input) {
        int[] transpose = {11,19,7,20,16,6,9,13,4,22,21,0,8,14,15,2,17,5,1,3,18,10,12};
        String ret = "";
        for (int i: transpose) {
            ret+=input.charAt(i);
        }
        return ret;
    }
    public static String xor(String input) {
        int[] xor = {4,1,3,1,2,1,3,0,1,4,3,1,2,0,1,4,1,2,3,2,1,0,3};
        String ret = "";
        for (int i = 0; i<input.length(); i++) {
            ret+=(char)(input.charAt(i)^xor[i]) ;
        }
        return ret;
    }
}

Crypto

XORed

XORの性質から、A xor B = Cのとき、A xor C = Bが成り立つ。よって、

key3 = key1 ^ 0x9a13ea39f27a12000e083a860f1bd26e4a126e68965cc48bee3fa11b

key4 = key3 ^ 0x996e59a867c171397fc8342b5f9a61d90bda51403ff6326303cb865a

key5 = key1 ^ key4 ^ 0x7b33428eb14e4b54f2f4a3acaeab1c2733e4ab6bebc68436177128eb

key2 = key3 ^ key5 ^ 557ce6335808f3b812ce31c7230ddea9fb32bbaeaf8f0d4a540b4f05

これでkeyが全て求められたので、以下でフラグを計算

flag = key1 ^ key2 ^ key3 ^ key4 ^ key5 ^ 0x306d34c5b6dda0f53c7a0f5a2ce4596cfea5ecb676169dd7d5931139

結果をそのままsubmitしても弾かれたので、Discordを確認してみると、ASCIIに変換するとの事なので、cyberchefで変換してフラグゲット

Unexpected

N=PQ、N=QR、N=PRの時に暗号文C1,C2,C3を復号する問題。

同じ素数を使いまわしてNを生成しているので、Common Factor Attackを使いP、Q、Rを求める。

その後各Nに対応する秘密鍵(d1,d2,d3)を求め、m = cd (mod n)を計算し平文M1,M2,M3を導出する。その後、asciiに変換するとフラグゲット。

※python2にてasciiに変換。

("%x"%m1).decode('hex')

【参考】 picoCTF writeup Low Entropy · GitHub

Misc

Do Stars Spin? 1

discord内で"stars"で検索し、古い順に並び替える。すると、PMPというユーザが2019/05/24にDo stars even spin?といった、本問に関係のありそうな事を発言しているのを発見。

発言内の"dostarsevenspin"でググるredditのページが表示されるも、投稿は全て削除されており、flag{no}とだけある。

web.archive.orgで検索すると、2020/05/27にアーカイブがとられており、内容を見ると削除された投稿が表示され、フラグゲット。

※余談だが、この問題を解いている時archive.orgがダウンしていたため、以下のようなサイトをひたすら調べていた…

www.hongkiat.com

thenextweb.com

Blurry Eyes(Web)

CTFdの紹介ページに飛ぶ。ページ最下部にぼかされた箇所があり、そこがflagっぽい。

開発者ツールで該当箇所のコードを見ると、ランダムな文字列のspan classがあり、展開するとCSS疑似クラスである::afterが出てくるので、クリックするとflagが表示される。

Web

Inspector Gadget

開発者ツールを見るとコメント文にフラグが書いてある

Debt Simulator

ボタンを押すと、ランダムで所持金が増減するゲームが始まる。-1000ドル以下になると負けとなる。

Burp Suiteでボタンを押した時の通信を見ると、 function=getPay

function=getCost

のいずれかの値を送っている事がわかる。

getPayだと所持金が増えるみたいなので全てfunction=getPayでリクエストを送るも、結果は変わらず。

開発者ツールでデバッグ実行してみる。

App.jsの26行目にonClick()の挙動が書かれているので、ここにブレークポイントを置く。27行目をステップ実行すると、35行目に飛ぶ。URLが書かれているので、アクセスしてみると、

{"functions":["getPay","getCost","getgetgetgetgetgetgetgetgetFlag"]}

と書かれている。 よって、先ほどのBurp Suiteで

function=getgetgetgetgetgetgetgetgetFlag

を送るとフラグが表示される。

所持金を増やせば勝ちだと思っていたのでかなり苦戦した…

Very Safe Login

ソースを見るとusernameとpasswordが書かれているので入力してフラグゲット。