TAMUctf 2017 Writeup

この大会は2017/4/13 9:00(JST)~2017/4/24 14:00(JST)に開催されました。
今回もチームで参戦。結果は3455点で786チーム中14位でした。
自分で解けた問題をWriteupとして書いておきます。

Howdy (Tutorial 5)

問題に書いてあるフラグを投入するだけ。

gigem{H0WDY!}

vinegar (crypto 50)

Vigenere暗号。https://www.guballa.de/vigenere-solverで復号する。

VIGENERESOUNDSALOTLIKEVINEGARWHICHGOESONSALADSSALADSAREHEALTHYFOODSBUTBURGERSAREBETTERITISASHAMETHATBURGERSARENOTHEALTHYFORYOUHEREISYOURFLAGSALADCDAF
SALADCDAF

Hashed md5 (crypto 50)

MD5が706dc2ee585fb5dcb18e3ac08da7ce0cになるものを答える。
Googleで調べるだけ。

it's

onion_duke (crypto 50)

1バイト右の文字はさらに1つずつシフトしていると考え、26パターン復号してみる。

import string

e = 'TSETJJBYDD'
upper = string.uppercase

for i in range(1, 26):
    p = ''
    for j in range(len(e)):
        index = (upper.index(e[j]) + i - j) % 26
        p += upper[index]
    print p

この結果は以下の通り。

USDRGFWSWV
VTESHGXTXW
WUFTIHYUYX
XVGUJIZVZY
YWHVKJAWAZ
ZXIWLKBXBA
AYJXMLCYCB
BZKYNMDZDC
CALZONEAED
DBMAPOFBFE
ECNBQPGCGF
FDOCRQHDHG
GEPDSRIEIH
HFQETSJFJI
IGRFUTKGKJ
JHSGVULHLK
KITHWVMIML
LJUIXWNJNM
MKVJYXOKON
NLWKZYPLPO
OMXLAZQMQP
PNYMBARNRQ
QOZNCBSOSR
RPAODCTPTS
SQBPEDUQUT

単語になっていそうな以下の文字列がフラグ。

CALZONEAED

hail caesar (crypto 50)

http://www.geocachingtoolbox.com/index.php?lang=en&page=caesarCipherで復号する。
わかりにくいが、ROT1の以下の文字列がフラグだった。

DRESSNGFDC

dachshund (crypto 100)

RSA暗号。eが非常に大きいため、Wiener's attackで復号する。

from fractions import Fraction

def egcd(a, b):
    x,y, u,v = 0,1, 1,0
    while a != 0:
        q, r = b//a, b%a
        m, n = x-u*q, y-v*q
        b,a, x,y, u,v = a,r, u,v, m,n
        gcd = b
    return gcd, x, y

def decrypt(p, q, e, c):
    n = p * q
    phi = (p - 1) * (q - 1)
    gcd, a, b = egcd(e, phi)
    d = a
    pt = pow(c, d, n)
    return hex(pt)[2:-1].decode('hex')

def continued_fractions(n,e):
    cf = [0]
    while e != 0:
        cf.append(int(n/e))
        N = n
        n = e
        e = N%e
    return cf

def calcKD(cf):
    kd = list()
    for i in range(1,len(cf)+1):
        tmp = Fraction(0)
        for j in cf[1:i][::-1]:
            tmp = 1/(tmp+j)
        kd.append((tmp.numerator,tmp.denominator))
    return kd

def int_sqrt(n):
    def f(prev):
        while True:
            m = (prev + n/prev)/2
            if m >= prev:
                return prev
            prev = m
    return f(n)

def calcPQ(a,b):
    if a*a < 4*b or a < 0:
        return None
    c = int_sqrt(a*a-4*b)
    p = (a + c) /2
    q = (a - c) /2
    if p + q == a and p * q == b:
        return (p,q)
    else:
        return None

def wiener(n,e):
    kd = calcKD(continued_fractions(n,e))
    for (k,d) in kd:
        if k == 0:
            continue
        if (e*d-1) % k != 0:
            continue
        phin = (e*d-1) / k
        if phin >= n:
            continue
        ans = calcPQ(n-phin+1,n)
        if ans is None:
            continue
        return (ans[0],ans[1])

with open('9b00a4b6f2ba73b4', 'r') as f:
    lines = f.readlines()

c = int(lines[0].strip().split(': ')[1].decode('base64').encode('hex'), 16)
e = int(lines[1].strip().split(': ')[1].decode('base64'))
n = int(lines[2].strip().split(': ')[1].decode('base64'))

p, q = wiener(n, e)

flag = decrypt(p, q, e, c)
print flag
gigem{h0Tdogs_2053124388faee1d}

lowered_expectations (crypto 100)

RSA暗号。nが非常に大きく、eが小さいのでe乗根を取れば復号できる。

import gmpy

with open('b449eea770bd6f3b', 'r') as f:
    lines = f.readlines()

c = int(lines[0].strip().split(': ')[1].decode('base64').encode('hex'), 16)
e = int(lines[1].strip().split(': ')[1].decode('base64'))
n = int(lines[2].strip().split(': ')[1].decode('base64'))

print ('%x' % gmpy.root(c, e)[0]).decode('hex')
gigem{get_L0W__101d935de22a247e}

commonplace (crypto 200)

RSA暗号。nが共通で、e,cのペアが複数あるので、Common Modules Attackで復号する。

import gmpy

def commom_modules_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)
    x = (v*w) % n
    return x

with open('e538338d7671181d', 'r') as f:
    lines = f.readlines()

c1 = int(lines[0].strip().split(': ')[1])
c2 = int(lines[2].strip().split(': ')[1])
e1 = int(lines[4].strip().split(': ')[1])
e2 = int(lines[6].strip().split(': ')[1])
n = int(lines[8].strip().split(': ')[1])
 
m = commom_modules_attack(c1, c2, e1, e2, n)
flag = ('%x' % m).decode('hex')
print flag
gigem{c0mm0nly_knOwn_AS__a8b575875b4594cf}

siamese (stego 50)

$ strings 083643f9a8f5e192
           :
083643f9a8f5e192.txtUT	
Z2lnZW17dGhlX2NhdF9nb2VzX21lb3dfMWE5MjU2MGVkOWYyMTFkOH0=PK
083643f9a8f5e192.txtUT
$ echo Z2lnZW17dGhlX2NhdF9nb2VzX21lb3dfMWE5MjU2MGVkOWYyMTFkOH0= | base64 -d
gigem{the_cat_goes_meow_1a92560ed9f211d8}
gigem{the_cat_goes_meow_1a92560ed9f211d8}

jpeg ocean (stego 100)

Stegsolveで開き、Red plane 0にフラグがある。
f:id:satou-y:20170504080715p:plain

gigem{water_w0rld_99bc48af5a15e348}

chunky (stego 100)

PNGマジックナンバーの前に以下の文字列が入っている。

Z2lnZW17dGhlX2ZsYWdfdGhhdF9lYXRzX2xpa2VfYV9tZWFsX2ViNWNjNGM5ZmQzNjJkZGN9
$ echo Z2lnZW17dGhlX2ZsYWdfdGhhdF9lYXRzX2xpa2VfYV9tZWFsX2ViNWNjNGM5ZmQzNjJkZGN9 | base64 -d
gigem{the_flag_that_eats_like_a_meal_eb5cc4c9fd362ddc}
gigem{the_flag_that_eats_like_a_meal_eb5cc4c9fd362ddc}

ghost busters (stego 100)

$ file d5d148ea132cf63d 
d5d148ea132cf63d: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, mono 44100 Hz

Sonic Visualiserでスペクトログラムを見る。
f:id:satou-y:20170504081250p:plain

gigem{now_you_see_me_ed34a1a931347170}

least important (stego 100)

$ file 12bc35c08727e99d 
12bc35c08727e99d: PC bitmap, Windows 3.x format, 2988 x 1573 x 24

StegsolveでData Extractを確認し、RGBの0ビットのところだけフィルタリングすると、先頭部分にフラグが入っている。

58:gigem{this_is_pretty_significant_success_83d4d343df042166}
gigem{this_is_pretty_significant_success_83d4d343df042166}

What to call me? (forensics 10)

$ ping ctf.tamu.edu
PING ctf.tamu.edu (52.33.57.247) 56(84) bytes of data.
      :
52.33.57.247

Who do I trust? (forensics 15)

証明書を確認する。

USERTrust RSA Certification Authority

Where am I... (forensics 50)

EXIF情報を見る。

GPS Latitude                    : 30 deg 36' 44.51" N
GPS Longitude                   : 96 deg 20' 29.34" W
GPS Position                    : 30 deg 36' 44.51" N, 96 deg 20' 29.34" W

Google Mapで調べる。

Memorial Student Center

Web Detective on the Scene (web 10)

HTMLソースにコメントが入っている。

<!-- Key = GigEm{TAMUctf_Web_a8ba90d7d8efeaf298cda418a2ab7073} -->
GigEm{TAMUctf_Web_a8ba90d7d8efeaf298cda418a2ab7073}

Web Detective Obtains Some Clues (web 15)

HTMLソース内のコメントに次のように書いてある。

<!-- This part is a header and doesn't offer you any flag -->
<!-- There is no key here!  Not even Google can help you now! -->

http://detective2.ctf.tamu.edu/robots.txtにアクセスすると、次のように書いてある。

User-agent: *
Disallow: /192492397fd616d47c5ff84b2d12d1df0da57d992f5fe95d/

http://detective2.ctf.tamu.edu/192492397fd616d47c5ff84b2d12d1df0da57d992f5fe95d/にアクセスすると、インデックスが見えて、user_file.txtがある。この中に次のように書いてあった。

#
#	TAMUctf web exploit challenges
#	Name:	user_file.txt
#	Course:	CSCE 491
#	Prof:	Dr. Daniel Ragsdale
#

#	Username : Password
Alice : TexasAggies2016!
Bob : BeatTheHell0utta_t.u.
Eve	: *H0meOfThe12thMan*
Key	: gigem{TAMUctf_Web_b304dc25b50afc611541e7ae1cb77ed2}
Sully : Br!gadierGenera1C$A
Rudder : GreaterL0veH@athNoM@n
gigem{TAMUctf_Web_b304dc25b50afc611541e7ae1cb77ed2}

SQL: The Injectioning (web 25)

Usernameに ' or 1=1 # と入れてログインすると、ログイン後のメッセージにフラグが入っている。
Huh. We really should gigem{S@niTIz3_Th0se_InpUTs}!

gigem{S@niTIz3_Th0se_InpUTs}

threads (reversing 100)

$ strings 229a70e76d99687e | grep gigem
gigem{stringy_lasagna_ec5a1e530491638f}
gigem{stringy_lasagna_ec5a1e530491638f}

Who am I? (recon 50)

Googleの画像検索を使う。

Brad Brekke, FBI