[Writeup] Vòng loại WhiteHat Grand Prix 2015: Crypto100 - Crypto200 - Crypto250

Thảo luận trong 'Writeup WhiteHat Grand Prix' bắt đầu bởi KaiO, 17/11/15, 01:11 PM.

  1. KaiO

    KaiO Moderator

    Tham gia: 20/07/15, 09:07 PM
    Bài viết: 7
    Đã được thích: 2
    Điểm thành tích:
    18
    Nguồn: Everping (https://github.com/everping/ctfs/tre...ion-Round-2015)

    Cảm ơn các bạn đã chia sẻ.

    Crypto100 - HoiAn

    http://lab14.grandprix.whitehatvn.com/index.php.s
    http://lab14b.grandprix.whitehatvn.com/index.php.s (Mirror)

    Mã:
    import md5
    import requests
    from decimal import Decimal
    
    URL = "http://lab14b.grandprix.whitehatvn.com/index.php"
    
    
    # https://github.com/twitter/mysql/blob/master/sql/password.c
    # We can calculate the next random value from two previous values
    def my_rnd(s1, s2):
        mv = 0x3FFFFFFFL
        s1 = (s1 * 3 + s2) % mv
        s2 = (s1 + s2 + 33) % mv
        rs = s1 / mv
        return rs
    
    
    def next_rnd(rs1, rs2):
        mv = 0x3FFFFFFFL
        s1 = rs2 * mv
        s1p = rs1 * mv
        s2p = s1 - (s1p * 3) % mv
        s2 = (s1 + s2p + 33) % mv
        return my_rnd(s1, s2)
    
    
    def md5_hash(msg):
        return md5.new(str(msg).strip()).hexdigest()
    
    
    def find_between(s, first, last):
        try:
            start = s.index(first) + len(first)
            end = s.index(last, start)
            return s[start:end]
        except ValueError:
            return ""
    
    
    # Get two random numbers using sql injection vulnerability
    def get_bootstrap():
        payload = {'user': "' union select concat(rand(), '|', rand())-- -", 'sub1': 'Forgot+password+%3F+Reset'}
        r = requests.post(URL, data=payload)
        bootstrap = find_between(r.text, "id ", "...").strip().split("|")
        rand1 = Decimal(bootstrap[0])
        rand2 = Decimal(bootstrap[1])
        return rand1, rand2
    
    
    def get_root():
        r1, r2 = get_bootstrap()
    
        # Calculate the next random value
        r3 = next_rnd(float(r1), float(r2))
        r3 = format(r3, '.16f')
    
        # hash and send request to server
        password = md5_hash(r3)
        payload = {'user': 'admin', 'sub2': 'sa', 'password': password}
        r = requests.post(URL, data=payload)
        return r.text
    
    
    result = ""
    while "flag" not in result:
        result = get_root()
    print result
    

    Crypto200 - BuonMaThuat
    Mã:
    from hashlib import sha1
    import telnetlib
    
    
    def brute_hash(prefix, prefix_hash):
        print 'Breaking the hash... \n',
        for i in xrange(2 ** 35):
            s = str(prefix) + str(i)
            if sha1(str(s)).hexdigest()[:6] == prefix_hash:
                return s
    
    
    def find_between(s, first, last):
        try:
            start = s.index(first) + len(first)
            end = s.index(last, start)
            return s[start:end]
        except ValueError:
            return ""
    
    
    HOST = "lab12b.grandprix.whitehatvn.com"
    PORT = 1337
    tn = telnetlib.Telnet(HOST, PORT)
    
    data = tn.read_until("> ")
    print data
    pre = find_between(data, 's has prefix ', ' and ')
    suf = find_between(data, 'sha1(s) has prefix ', '.')
    
    plain_hash = brute_hash(pre, suf)
    print 'Send plain hash %s' % plain_hash
    
    tn.write(plain_hash + '\n')
    print tn.read_until('\n>')
    print "Breaking admin's password"
    password = ''
    
    for line in reversed(open("/usr/share/dict/words").readlines()):
        password = line.strip()
        tn.write('r admi ' + 'n' + password + '\n')
        data = tn.read_until('.')
        if "just login" in data:
            print 'Found password = ' + password
            break
    
    tn.write('l admin ' + password + '\n')
    tn.write('mm' + '\n')
    print tn.read_until('==\n>')
    Crypto250 - TamDao

    http://lab11.grandprix.whitehatvn.com:1337
    http://lab11b.grandprix.whitehatvn.com:1337 (Mirror)

    Mã:
    import copy
    import requests
    
    BLOCK_SIZE = 16
    HMAC_SIZE = 20
    
    URL = "http://lab11b.grandprix.whitehatvn.com:1337/"
    
    
    def get_msg(ck):
        cookie = dict(wanted=ck)
        r = requests.get(URL, cookies=cookie)
        return r.text
    
    
    def chunks(l, n):
        if n < 1:
            n = 1
        return [l[i:i + n] for i in range(0, len(l), n)]
    
    
    def get_cipher(prefix='', suffix=''):
        url = (URL + '?pre=%s&suf=%s' % (prefix, suffix))
        r = requests.get(url)
        return r.cookies['wanted'].decode('hex')
    
    
    def get_secret_size():
        base_len = len(get_cipher())
        for s in range(1, BLOCK_SIZE + 1):
            prefix = chr(0x42) * s
            trial = len(get_cipher(prefix))
            if trial > base_len: break
        return base_len - BLOCK_SIZE - HMAC_SIZE - s
    
    
    # This challenge is related to a known attack - Poodle Attack
    # I did look into the code of l4w for reference http://l4w.io/2015/01/tetcon-ctf-2015-crypto200-the-poodle-attack/
    # Thanks young guy :)
    def get_secret():
        secret_size = get_secret_size()
        _secret = ""
        for m in range(1, 3):
            for n in range(BLOCK_SIZE - 1, -1, -1):
                if len(_secret) == secret_size:
                    break
    
                prefix = 'B' * (n % BLOCK_SIZE)
                suffix = 'C' * (secret_size - (n % BLOCK_SIZE))
                cookie = get_cipher(prefix, suffix)
                cipher_block = chunks(cookie, 16)
    
                for i in range(256):
                    xor_byte = ord(cipher_block[m - 1][-1])
                    new_block = copy.copy(cipher_block)
                    new_block.append(new_block[m])
                    new_block[len(cipher_block) - 1] = '\xff' * 15 + chr(i)
                    response = get_msg(''.join(new_block).encode('hex'))
                    if "wrong" not in response:
                        c = 31 ^ i ^ xor_byte
                        _secret += chr(c)
                        print 'Secret = ', _secret
                        break
    
        return _secret
    
    
    def get_flag():
        wanted = get_secret()
        message = wanted[:8] + wanted[12:]
        r = requests.get(URL + "test?msg=" + message)
        return get_msg(r.text)
    
    
    print get_flag()
     
    Last edited by a moderator: 17/11/15, 03:11 PM
    Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
    Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan