XCTF 2018 - Easy Fs

Masalah

Berkas.

==============================
   Welcome to Nu1L Easy FS    
==============================
   1. File list               
   2. Read encrypted file     
   3. Custom encryption       
   4. Quit                    
==============================
   Input your choice:         
==============================

Penyelesaian

Alur program berjalan dengan membangkitkan nilai N secara acak, kemudian meminta input untuk nilai E. Kelemahan ada pada fungsi Custom Encryption. Jika dimasukkan nilai 0x3 terus menerus sampai benar pada nilai E maka opsi Read encrypted file akan menggunakan nilai E=0x3 sehingga dapat menyebabkan Broadcast Message yang bisa diselesaikan dengan Hastad Broadcast Message Attack.

$ apt install python-openssl &&
apt install python-gmpy &&
apt install python-gmpy2
# solver.py
from pwn import * 
import re
import gmpy2
import binascii

r = lambda x: log.info(s.recv(2**x))

exactly = 0

while exactly != True:

    n = []
    c = []

    while len(n) != 3 and len(c) != 3:
        s = remote('47.52.195.203', 2333)

        r(12)

        s.sendline('3')

        z = s.recv(2**12)
        z += s.recv(2**12)
        log.info(z)
        o = re.findall(r'N = 0x([0-9a-fA-F]+)', z)
        log.info(o)

        if not o:
            z += s.recv(2**12)
            log.info(z)
            o = re.findall(r'N = 0x([0-9a-fA-F]+)', z)
            log.info(o)

        check1 = False
        while check1 != True:

            s.sendline('3')

            z = s.recv(2**12)
            log.info(z)

            s.sendline('X')

            z = s.recv(2**12)
            log.info(z)
            x = re.findall(r'C = 0x([0-9a-fA-F]+)', z)
            log.info(x)
            if x:
                if '10001' not in z:
                    pass
            else:
                z += s.recv(2**12)
                log.info(z)
                x = re.findall(r'C = 0x([0-9a-fA-F]+)', z)
                log.info(x)
                if '10001' not in z:
                    pass

            log.info('Struktur Kondisi 1')
            if len(x[0]) < 16:
                s.sendline('n')
                check1 = True

            else:
                s.sendline('y')

                z = s.recv(2**12)
                log.info(z)

        z = s.recv(2**12)
        log.info(z)

        s.sendline('2')

        z = s.recv(2**12)
        log.info(z)

        s.sendline('flag')

        z = s.recv(2**12)
        log.info(z)

        o = re.findall(r'N = 0x([0-9a-fA-F]+)', z)
        log.info(o)

        if not o:
            z += s.recv(2**12)
            log.info(z)
            o = re.findall(r'N = 0x([0-9a-fA-F]+)', z)
            log.info(o)

        s.sendline('3')
        z = s.recv(2**12)
        log.info(z)
        x = re.findall(r'C = 0x([0-9a-fA-F]+)', z)
        log.info(x)
        if x:
            if '10001' not in z:
                n.append(o[0])
                c.append(x[0])
        else:
            z += s.recv(2**12)
            log.info(z)
            x = re.findall(r'C = 0x([0-9a-fA-F]+)', z)
            log.info(x)
            if '10001' not in z:
                n.append(o[0])
                c.append(x[0])

        print len(n), len(c)

        s.close()

    print n, c

    N = [gmpy2.mpz(str(int(x,16))) for x in n]
    C = [gmpy2.mpz(str(int(x,16))) for x in c]

    e = 3
    m = [0, 0, 0]
    M = N[0]*N[1]*N[2]
    m[0] = M/N[0]
    m[1] = M/N[1]
    m[2] = M/N[2]

    t = [ccc*mmm*gmpy2.invert(mmm,nnn) for ccc, mmm, nnn in zip(C, m, N)]

    xxx = (t[0] + t[1]+  t[2]) % M # Chinese reminder theorem
    p, exactly = gmpy2.iroot(xxx,e) # recover m
    print exactly
    raw_input('debug?')
    print hex(p).lstrip('0x')
    try:
        print hex(p).lstrip('0x').decode('hex')
    except:
        pass
    raw_input('debug?')
    if exactly:
        print hex(p).lstrip('0x')
        print hex(p).lstrip('0x').decode('hex')

Referensi

results matching ""

    No results matching ""