魚脳の池

CTF:Little Twoos

TAMUCTF 2019 write-up

チームm1z0r3として参加しました。

自分が手かけた問題のwrite-upを書きます

競技中解いた問題

[Crypro 354pts] RSAaay

(2531257, 43) My super secret message: 906851 991083 1780304 2380434 438490 356019 921472 822283 817856 556932 2102538 2501908 2211404 991083 1562919 38268

solver↓↓

n,e = (2531257, 43)

from Crypto.Util.number import long_to_bytes

'''
factor(2531257) = 509*4973
'''
p,q = (509,4973)

from Crypto.Util.number import inverse

phi = (p-1)*(q-1)
d = inverse(e,phi)
'''
d=58739L
'''
c = '906851 991083 1780304 2380434 438490 356019 921472 822283 817856 556932 2102538 2501908 2211404 991083 1562919 38268'.split(' ')
c = [int(i) for i in c]
import sys
for i in c:
    print pow(i,d,n)
msg = [103, 105, 103, 101, 109, 123, 83, 97, 118, 97, 103, 101, 95, 83, 105, 120, 95, 70, 108, 121, 105, 110, 103, 95, 84, 105,103, 101, 114, 115, 125]
for i in msg:
    sys.stdout.write(chr(i))

最後ちょっとひねって、二文字のasciiを繋いだことに気づき、手動で分離しました。

[Crypro 492pts] Holey Knapsack

My knapsack has a hole in it

Cipher text: 11b90d6311b90ff90ce610c4123b10c40ce60dfa123610610ce60d450d000ce61061106110c4098515340d4512361534098509270e5d09850e58123610c9 Public key: {99, 1235, 865, 990, 5, 1443, 895, 1477}

ちょっとググったら、解説が発見 原理:https://nrich.maths.org/2199
最初はprintableの文字を全部暗号化して辞書から当てようとしたら、うまくいかず。 たぶん昔が出題されたことあると踏んで検索したらありました。
ctfs/solve.py at master · everping/ctfs · GitHub
上記のsolver参考してやってみたけどもうまくいかず、最後ほかのメンバーが解いてくれました。 結局のところ、暗号文を分けないといけないですね。

from sage.all import *
c = '11b90d6311b90ff90ce610c4123b10c40ce60dfa123610610ce60d450d000ce61061106110c4098515340d4512361534098509270e5d09850e58123610c9'
pubKey = [99, 1235, 865, 990, 5, 1443, 895, 1477]
nbit = len(pubKey)
c = [c[i:i+4] for i in range(len(c)-3,4)]
encoded = map(lambda x: int(x,16),c)
print "start"
for j in encoded:
    # create a large matrix of 0's (dimensions are public key length +1)
    A = Matrix(ZZ,nbit+1,nbit+1)
    # fill in the identity matrix
    for i in xrange(nbit):
        A[i,i] = 1
    # replace the bottom row with your public key
    for i in xrange(nbit):
        A[i,nbit] = pubKey[i]
    # last element is the encoded message
    A[nbit,nbit] = -j

    res = A.LLL()
    print "M: "
    M = res.row(8).list()
    print M

あとあと考えたらおそらく暗号化の実装がちょっと間違えたかな、二進数を逆転してから重りを計算したほうが多分ちゃんと辞書も作れると思います。

[Misc 340pts] Hello World

空白がやたら多いcファイルがあって、多分それもコードかなという予想がつきました。検索したら、どうやら空白でもコードをかけるそうで、しかもオンラインIDEもあるということで、そのまま投げました。
Whitelips the Whitespace IDE
最初は↓のような文字しか見えなかった。
Well sweet golly gee, that sure is a lot of whitespace!
右を見たら空白*2はprintcに等しいことがわかりました。
あとはひたすらprintcの数を増やして後ろの文字を吐かせる。
Well sweet golly gee, that sure is a lot of whitespace!}3v4h_u0y_gn1c4ps_t4hw_ym_h0{megig
を逆にしたらフラグでした。

[Android 376pts] Secrets

Android系の問題を初めて触ってみた、とりあえずいろいろググりまくりました。結果以下のような手順に至りました。
* unzip howdy.zip
* d2j-dex2jar.sh classes.dex
* JD-GUIで開くR.classの中にflagというstringが発見
* aapt dump --values resources howdyapp.apk resources.arsc > v.txt
* cat v.txt | grep 0x7f0b0020 --after-context=5

これでstring中のflagの抽出ができました。 flag:gigem{infinite_gigems}

[Android 460pts] Local News

これもたしか一緒のような気がした。 flag:gigem{hidden_81aeb013bea}

[Reversing 100pts] Cheesy

確かにStringして変な文字列があったのでとりあえずbase64にデコードしたらflagでした。
flag:gigem{3a5y_R3v3r51N6!}

[Reversing 100pts] Snakes over cheese

.pycがあったのでそのままimportできそうですので、やってみました、その中変な配列が

In [1]: import reversing2

In [2]: reversing2.Fqaa
Out[2]: [102, 108, 97, 103, 123, 100, 101, 99, 111, 109, 112, 105, 108, 101, 125]

In [3]: print ''.join([chr(i) for i in reversing2.Fqaa])
flag{decompile}

[Reversing 384pts] 042

リバースことがわからないですが、でもちょっと見てみたらasciiっぽいやつが数行あったので、とりあえず変換したらflagでした。

   movb  $65, -16(%rbp)
   movb $53, -15(%rbp)
   movb $53, -14(%rbp)
   movb $51, -13(%rbp)
   movb $77, -12(%rbp)
   movb $98, -11(%rbp)
   movb $49, -10(%rbp)
   movb $89, -9(%rbp)
print ''.join(map(lambda x: chr(x),[65,53,53,51,77,98,49,89]))
A553Mb1Y

gigem{A554Mb1Y}

[Network/Pentest 324pts] Stop and Listen 

指示通りopenVPNで繋いであげて、問題文ようにwiresharkでしばらくlistenして、stopしたら,flagがありました。
flag:gigem{f0rty_tw0_c9d950b61ea83}

write-up見て勉強になったもの(あとで書くはず)

log app

Mike's Marvelous Mystery Curves

chrsow.me

こちらのwrite-upをさんこうしました。当時certificateの確認方法に詰まった、正直にBase64にかけばいいのになといまは思います。
* modulo pの値が小さい → 離散対数問題が突破できる
* sageの中に楕円曲線関数E = EllipticCurve(GF(p), [A, B])
* 離散対数に関する関数d_Alice = G.discrete_log(Q_Alice)