m0becのメモ帳

いろいろ書いてきます

SECCON2017 writeup

JPEG file

1bitだけ壊れたJPEGが渡される.JPEGのファイルフォーマットはこちらのサイトを参考にした.
FFで始まる箇所を重点的に調べていくとFF FC となっている箇所があった.FF FCJPEGの拡張のための予備となっているがFE FC に書き換えるとフラグの書いてある画像が出てくる.

Powerful Shell

文字コードをひたすら$ECCONに代入しているps1のソースコードが渡された.実行すると鍵盤が出てきてPlay the secret melodyと言われる.$ECCONに格納された文字列をファイル出力すると、なんとか読めるソースコードが手に入る.secret melodyは

$secret=@(440,440,493,440,440,493,440,493,523,493,440,493,440,349)

となっており、鍵盤に対応する数値は

ForEach($k in ('w','s','e','d','f','t','g','y','h','u','j','k')){
    $keytone+=@{$k=$keytone[$pk]*[math]::pow(2,1/12)};$pk=$k    
}

で決まっている.h,h,j,h,h,j,h,j,k,j,h,j,h,fで次のステージに進める.
次はパスワードを求められる. [System.Text.Encoding]::ASCII.GetString($plain)をファイル出力すると記号まみれのソースコードが手に入る.やり方は変えずに処理の中身をファイル出力していくとパスワードと入力を比べている箇所を見つけられる.

$ECCON=Read-Host -Prompt 'Enter the password'
If($ECCON -eq 'P0wEr$H311'){
    Write-Host 'Good Job!';
    Write-Host "SECCON{$ECCON}"
}

Run me!

以下のコードが渡される.

import sys
sys.setrecursionlimit(99999)
def f(n):
    return n if n < 2 else f(n-2) + f(n-1)
print "SECCON{" + str(f(11011))[:32] + "}"

実行してみても終わる気配がない.再帰が深すぎるのが原因.なので再帰しないプログラムにする.

s1 = 1
s2 = 2
numb = 3
ans = 0
while(1):
    if numb < 11011:
        ans = s1+s2
        s1 = s2
        s2 = ans
        numb += 1
    else:
        break
print s1
print s2
print numb
print str(ans)[:32]

SHA-1 is dead

SHA1衝突を利用する問題.73spica様のサイトを参考に解いてみた.とりあえずSHA-1が同じになるpdfをこちらのサイトで入手し、末尾に同じデータを追加して2017KiB以上になるようにしてから提出するとフラグがもらえた.

Simon and Speck Block Ciphers

Simon and Speck Block Ciphersを使って鍵を見つける問題.Simon and Speck Block CiphersはこちらのGithubのプログラムを利用した.鍵でわからない部分は4文字だけなので総当たりで調べるとcipherとplainが一致する鍵が手に入る.

from speck import SpeckCipher
from simon import SimonCipher

plain = 0x6d564d37426e6e71
cipher= 0xbb5d12ba422834b5

s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz_"

for i1 in s:
    for i2 in s:
        for i3 in s:
            for i4 in s:
                key = "SECCON{" + i1+i2+i3+i4 + "}"
                tiny_cipher = SimonCipher(int(key.encode('hex'), 16), key_size=96, block_size=64)
                ans = tiny_cipher.encrypt(plain)
                if ans == cipher:
                    print key

Vigenere3d

ヴィジュネル暗号を二回行っている.鍵は14文字だが一回目と二回目のカギは文字列を反対にしただけであり、abcdefggfedcbaのような鍵で一回変換するのと同じである.また、平文の最初の7文字はわかっているので複合できる.

s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz_{}"

p = "SECCON{"
q = "POR4dnyTLHBfwbxAAZhe}}ocZR3Cxcftw9"
key = []

for i in range(len(p)):
    st = s.find(p[i]) - s.find(q[i])
    if st < 0:
        st = st+len(s)
    key.append(st)
for i in range(7):
    key.append(key[6-i])
    
ans = ""
key_num = 0
for i in q:
    n = s.find(i)+key[key_num]
    if n >= len(s):
        n -= len(s)
    ans += s[n]
    key_num = (key_num+1)%14
print ans