zoukankan      html  css  js  c++  java
  • CTF之crpto练习三

    DES弱加密之easy_BlockCipher

    下载附件得到2个文件:
    https://adworld.xctf.org.cn/media/task/attachments/5b8bcb28546b4423b481b13149abc99f.zip

    分析题目,题目中给出了加密时的代码。

    des-ofb.py:

    from Crypto.Cipher import DES
    
    f = open('key.txt', 'r')
    key_hex = f.readline()[:-1] # discard newline
    f.close()
    KEY = key_hex.decode("hex")
    IV = '13245678'
    a = DES.new(KEY, DES.MODE_OFB, IV)
    
    f = open('plaintext', 'r')
    plaintext = f.read()
    f.close()
    
    ciphertext = a.encrypt(plaintext)
    f = open('ciphertext', 'w')
    f.write(ciphertext)
    f.close()

    可知加密时采用了DES算法,并且在OFB模式下对明文进行加密。

    因此在已知 IV = ‘12345678’ 的情况下,只需要知道Key,即可对密文进行破解。

    根据已知信息,仅有IV以及未知的Key,所以想到DES加密种存在弱密钥。在 DES 的计算中,56bit 的密钥最终会被处理为 16 个轮密钥,每一个轮密钥用于 16 轮计算中的一轮,DES 弱密钥会使这 16 个轮密钥完全一致,所以称为弱密钥。

    其中四个弱密钥为:

    0x0000000000000000
    0xFFFFFFFFFFFFFFFF
    0xE1E1E1E1F0F0F0F0
    0x1E1E1E1E0F0F0F0F

    利用四组若密钥尝试对密文进行破解。

    from Crypto.Cipher import DES
    
    f = open('ciphertext', 'r')
    ciphertext = f.read()
    f.close()
    IV = '13245678'
    KEY=b'\x00\x00\x00\x00\x00\x00\x00\x00'
    a = DES.new(KEY, DES.MODE_OFB, IV)
    plaintext = a.decrypt(ciphertext)
    print plaintext
    
    KEY=b'\x1E\x1E\x1E\x1E\x0F\x0F\x0F\x0F'
    a = DES.new(KEY, DES.MODE_OFB, IV)
    plaintext = a.decrypt(ciphertext)
    print plaintext
    
    KEY="\xE1\xE1\xE1\xE1\xF0\xF0\xF0\xF0"
    a = DES.new(KEY, DES.MODE_OFB, IV)
    plaintext = a.decrypt(ciphertext)
    print plaintext
    
    KEY="\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
    a = DES.new(KEY, DES.MODE_OFB, IV)
    plaintext = a.decrypt(ciphertext)
    print plaintext

    从得到的结果中得到明文为莎士比亚的一首诗。

    或者脚本:
    #coding:utf-8
    from Crypto.Cipher import DES
    import libnum
    ct=open('ciphertext','rb').read()
    KEY=libnum.n2s(0xe0e0e0e0f1f1f1f1)
    IV='13245678'
    a=DES.new(KEY,DES.MODE_OFB,IV)
    print a.decrypt(ct)
    最终得到flag:
    flag{_poor_single_dog_has_found_an_echo_from_it}


    RSA算法之special-rsa

    题目描述:在学习RSA算法时,我发现了一种和RSA具有同等安全性的算法。 对msg.txt加密得到了msg.enc。 $ python special_rsa.py enc msg.txt msg.enc 你能从flag.enc中恢复flag.txt么?
    下载附件,里面包含了4个文件,如下: 
    https://adworld.xctf.org.cn/media/task/attachments/7a407f44a073442c91fd395b20594f01.zip
    flag.enc
    special_rsa.py
    msg.enc
    msg.txt  
    

    题目的思路是用隐藏的key解密flag.enc文件,阅读special_rsa.py文件加密和解密过程后,我做了简单的公式来找到隐藏的key。
    v4
    伪代码如下:

    flag.sage:

    N = 23927411014020695772934916764953661641310148480977056645255098192491740356525240675906285700516357578929940114553700976167969964364149615226568689224228028461686617293534115788779955597877965044570493457567420874741357186596425753667455266870402154552439899664446413632716747644854897551940777512522044907132864905644212655387223302410896871080751768224091760934209917984213585513510597619708797688705876805464880105797829380326559399723048092175492203894468752718008631464599810632513162129223356467602508095356584405555329096159917957389834381018137378015593755767450675441331998683799788355179363368220408879117131L
    
    c1 = 14548997380897265239778884825381301109965518989661808090688952232381091726761464959572943383024428028270717629953894592890859128818839328499002950828491521254480795364789013196240119403187073307558598496713832435709741997056117831860370227155633169019665564392649528306986826960829410120348913586592199732730933259880469229724149887380005627321752843489564984358708013300524640545437703771424168108213045567568595093421366224818609501318783680497763353618110184078118456368631056649526433730408976988014678391205055298782061128568056163894010397245301425676232126267874656710256838457728944370612289985071385621160886
    c2 = 12793942795110038319724531875568693507469327176085954164034728727511164833335101755153514030256152878364664079056565385331901196541015393609751624971554016671160730478932343949538202167508319292084519621768851878526657022981883304260886841513342396524869530063372782511380879783246034751883691295368172069170967975561364277514063320691930900258017293871754252209727301719207692321798229276732198521711602080244950295889575423383308099786298184477668302842952215665734671829249323604032320696267130330613134368640401070775927197554082071807605399448960911234829590548855031180158567578928333030631307816223152118126597
    
    m1 = 8246074182642091125578311828374843698994233243811347691229334829218700728624047916518503687366611595562099039411430662968666847086659721231623198995017758424796091810259884653332576136128144958751327844746991264667007359518181363522934430676655236880489550093852524801304612322373542296281962196795304499711006801211783005857297362930338978872451934860435597545642219213551685973208209873623909629278321181485010964460652298690058747090298312365230671723790850998541956664376820820570709272500330966205578898690396706695024001970727864091436518202414166919020415892764617055978488996164642229582717493375419993187360
    m2 = 15575051453858521753108462063723750986386093067763948316612157946190835527332641201837062951012227815568418309166473080588354562426066694924364886916408150576082667797274000661726279871971377438362829402529682825471299861814829463510659258586020732228351258291527965822977048954720558973840956731377322516168809373640494227129998871167089589689796024458501705704779109152762373660542684880052489213039920383757930855300338529058000330103359636123251274293258
    
    r1 = 12900676191620430360427117641859547516838813596331616166760756921115466932766990479475373384324634210232168544745677888398849094363202992662466063289599443
    r2 = 7718975159402389617924543100113967512280131630286624078102368166185443466262861344357647019797762407935675150925250503475336639811981984126529557679881059
    
    _, a, b = xgcd(r1, r2)
    k = pow((c1/m1 % N), a, N) * pow((c2/m2 % N), b, N)
    print (k)
    

    得到key:

    175971776542095822590595405274258668271271366360140578776612582276966567082080372980811310146217399585938214712928761559525614866113821551467842221588432676885027725038849513527080849158072296957428701767142294778752742980766436072183367444762212399986777124093501619273513421803177347181063254421492621011961  
    

    得到key,解密flag.enc,得到答案:

    port msgpack

    def egcd(a, b):
        if a == 0:
            return (b, 0, 1)
        else:
            g, y, x = egcd(b % a, a)
            return (g, x - (b // a) * y, y)

    def modinv(a, m):
        g, x, y = egcd(a, m)
        assert g == 1
        return x % m

    def pad_even(x):
        return ('', '0')[len(x)%2] + x

    def decrypt(c, k):
        out = ''
        for r_s, c_s in msgpack.unpackb(c):
            r = int(r_s.encode('hex'), 16)
            c = int(c_s.encode('hex'), 16)
            k_inv = modinv(k, N)
            out += pad_even(format(pow(k_inv, r, N) * c % N, 'x')).decode('hex')
        return out

    N = 23927411014020695772934916764953661641310148480977056645255098192491740356525240675906285700516357578929940114553700976167969964364149615226568689224228028461686617293534115788779955597877965044570493457567420874741357186596425753667455266870402154552439899664446413632716747644854897551940777512522044907132864905644212655387223302410896871080751768224091760934209917984213585513510597619708797688705876805464880105797829380326559399723048092175492203894468752718008631464599810632513162129223356467602508095356584405555329096159917957389834381018137378015593755767450675441331998683799788355179363368220408879117131
    k = 175971776542095822590595405274258668271271366360140578776612582276966567082080372980811310146217399585938214712928761559525614866113821551467842221588432676885027725038849513527080849158072296957428701767142294778752742980766436072183367444762212399986777124093501619273513421803177347181063254421492621011961
    print decrypt(open("flag.enc").read(), k)

    最终得到flag:

    Flag: BCTF{q0000000000b3333333333-ju57-w0n-pwn20wn!!!!!!!!!!!!}



    题目描述:It seems easy, right?Tip: openssl rsautl -encrypt -in FLAG -inkey public.pem -pubin -out flag.enc


    题目给了一个flag.enc,还有一个public.pem,附件下载地址:

    https://adworld.xctf.org.cn/media/task/attachments/9244cc370caa43f491636f8c4670fe7d.zip

    安装openssl可以读取到n和e,因为n不大,可以在yafu或者factordb.com上分解得到n = p * q * r

    根据flag.enc,可以得到密文m

    根据中国剩余定理,我们要求得m在p,q,r下的余数,不妨设为pmod,qmod,rmod

    然后根据模三次剩余,即:proot ^ 3 ≡ pmod ( mod p),求得:proot,同理求得qroot,rroot

    利用网页工具可以直接计算得到:

    http://www.wolframalpha.com/input/?i=x%5E3+%3D+19342563376936634263836075415482+(mod+27038194053540661979045656526063)

    我们从openssl命令行得到一个似乎是通过RSA加密的密文。我们还可以访问公钥,因此我们像使用标准RSA密码一样,通过恢复参数来执行以下操作:

    e = 3

    n = 23292710978670380403641273270002884747060006568046290011918413375473934024039715180540887338067

    使用YAFU,我们将模量分为:

    p = 26440615366395242196516853423447

    q = 27038194053540661979045656526063

    r = 32581479300404876772405716877547

    我们得到三个质数。这仍然是好的,这可能只是多质RSA。这一点也不奇怪,总的来说很简单(p-1)(q-1)(r-1),其余的计算照常进行。但它不存在,因为我们发现模乘逆不存在。原因很明显:gcd(e,to客户端)=3,应该是1。这不是我们第一次遇到类似的情况(如https://github.com/p4-team/ctf/tree/master/2015-10-18-hitcon/crypto 314-u rsabin-35;eng版本),所以我们对如何处理这个问题有了一些想法。

    在应用RSA解码之前,我们需要去掉这3个。这意味着加密是:

    ciphertext = plaintext^e mod n = (plaintext^e')^3 mod n

    所以如果我们能形成方程两边的模三次根(mod n),我们就可以用e'=e/3进行RSA译码。因为e=3,所以e'=e/3=1,所以这里并不容易,这意味着我们的加密是简单的:

    ciphertext = plaintext^3 mod n

    所以整个解密过程需要密文中的模立方根(mod n)。

    一些关于模根的阅读使我们得出结论,这是可能的,但只有在有限的领域。所以它不能对n做,这是一个复合数,我们知道它是,因为它是pqr。

    这个问题让我们想起了中文提醒定理( https://en.wikipedia.org/wiki/Chinese_remainder_theorem ),我们考虑了一会儿,我们想到了一个想法,如果我们能从密文(mod prime)中计算出3个素数的三次模根,我们就能计算出合并根。我们可以用高斯算法(http://www.di-mgt.com.au/crt.html#gaussalg)来实现这一点。

    所以我们继续计算:

    pt^3 mod p = ciperhtext mod p = 20827907988103030784078915883129

    pt^3 mod q = ciperhtext mod q = 19342563376936634263836075415482

    pt^3 mod r = ciperhtext mod r = 10525283947807760227880406671000

    然后我们花了一段时间来解决pt的这个方程,最后我们发现wolframalpha实现了这个功能,例如:

    http://www.wolframalpha.com/input/?i=x^3+%3D+20827907988103030784078915883129+%28mod+26440615366395242196516853423447%29

    这给了我们一套可能的解决方案:

    roots0 = [5686385026105901867473638678946, 7379361747422713811654086477766, 13374868592866626517389128266735]

    roots1 = [19616973567618515464515107624812]

    roots2 = [6149264605288583791069539134541, 13028011585706956936052628027629, 13404203109409336045283549715377]

    我们对这些根应用高斯算法:

    # -*- coding:utf-8 -*-
    # 0CTF 2016: RSA? (Crypto 2pt)

    '''
    # openssl rsa -in public.pem -pubin -text -modulus
    Public-Key: (314 bit)
    Modulus:
    02:ca:a9:c0:9d:c1:06:1e:50:7e:5b:7f:39:dd:e3:
    45:5f:cf:e1:27:a2:c6:9b:62:1c:83:fd:9d:3d:3e:
    aa:3a:ac:42:14:7c:d7:18:8c:53
    Exponent: 3 (0x3)
    Modulus=2CAA9C09DC1061E507E5B7F39DDE3455FCFE127A2C69B621C83FD9D3D3EAA3AAC42147CD7188C53
    writing RSA key
    -----BEGIN PUBLIC KEY-----
    MEEwDQYJKoZIhvcNAQEBBQADMAAwLQIoAsqpwJ3BBh5Qflt/Od3jRV/P4Seixpti
    HIP9nT0+qjqsQhR81xiMUwIBAw==
    -----END PUBLIC KEY-----
    '''

    # Chinese Remainder Theorem
    def chinese_remainder(n, a):
    sum = 0
    prod = reduce(lambda a, b: a*b, n)
    for n_i, a_i in zip(n, a):
    p = prod / n_i
    sum += a_i * mul_inv(p, n_i) * p
    return sum % prod

    def mul_inv(a, b):
    b0 = b
    x0, x1 = 0, 1
    if b == 1: return 1
    while a > 1:
    q = a / b
    a, b = b, a%b
    x0, x1 = x1 - q * x0, x0
    if x1 < 0: x1 += b0
    return x1


    e = 3
    n = 0x2CAA9C09DC1061E507E5B7F39DDE3455FCFE127A2C69B621C83FD9D3D3EAA3AAC42147CD7188C53

    # Factorize n using factordb.com
    p = 26440615366395242196516853423447
    q = 27038194053540661979045656526063
    r = 32581479300404876772405716877547

    assert p * q * r == n

    ct = int(open("flag.enc", "rb").read().encode("hex"), 16)
    # ct = 2485360255306619684345131431867350432205477625621366642887752720125176463993839766742234027524

    # pt^3 mod p = ct mod p = 20827907988103030784078915883129
    # pt^3 mod q = ct mod q = 19342563376936634263836075415482
    # pt^3 mod r = ct mod r = 10525283947807760227880406671000

    # Calculate possible cube-root
    # using wolflam alpha (or using modified Tonelli-Shanks algorithm)
    # like this: "x^3 = 20827907988103030784078915883129 (mod 26440615366395242196516853423447)"
    p_root = [5686385026105901867473638678946, 7379361747422713811654086477766, 13374868592866626517389128266735]
    q_root = [19616973567618515464515107624812]
    r_root = [6149264605288583791069539134541, 13028011585706956936052628027629, 13404203109409336045283549715377]

    # For every compination of roots, mix them using Chinese Remainder Theorem
    for x in p_root:
    for y in q_root:
    for z in r_root:
    m = chinese_remainder([p, q, r], [x, y, z])
    pt = hex(m)[2:-1]
    if len(pt) % 2 != 0:
    pt = "0"+pt
    pt = pt.decode("hex")
    if pt.find("0ctf{") >= 0:
    # Get the flag
    print pt.strip()
    break
    最终flag:
    0ctf{HahA!Thi5_1s_n0T_rSa~}

    RSA解密之babyRSA1

    1.下载附件,发现有3个文件:

    https://adworld.xctf.org.cn/media/task/attachments/5a456b6a66c04c02bf754d540e5b531d.zip

    在挑战中,我们获得代码,公钥和结果。

    加密相当简单:

    R.<a> = GF(2^2049)
    
    def encrypt(m):
        global n
        assert len(m) <= 256
        m_int = Integer(m.encode('hex'), 16)
        m_poly = P(R.fetch_int(m_int))
        c_poly = pow(m_poly, e, n)
        c_int = R(c_poly).integer_representation()
        c = format(c_int, '0256x').decode('hex')
        return c

    看来n这是GF(2)上的PolynomialRing的多项式。加密基本上将消息更改为GF(2 ^ 2049)的元素,然后将其表示为环P的元素,然后将该消息的多项式表示形式提高为emod多项式的幂n。

    所以,它真的可以归结为经典的RSA,与小搓那m和n现在是多项式,一切都在PolynomialRing在GF(2)calcualted。

    我们发现了一篇很好的论文,描述了这个想法:www.diva-portal.se/smash/get/diva2:823505/FULLTEXT01.pdf(Izabela Beatrice Gafitoiu的理学学士学位论文)。

    如果遵循此论点,我们会发现在这种情况下,d解密指数可以计算为emod的模乘逆s。特殊值s是等效的phi,从经典RSA,并且基本上是(2^p_d-1)(2^q_d-1)其中p_d和q_d正度多项式的p和q,使得p*q == n。

    所以这个想法很简单:

    1、因子多项式n成p和q 2、计算 s 3、计算 d 4、解密标志

    def decrypt(m, d):
        m_int = Integer(m.encode('hex'), 16)
        m_poly = P(R.fetch_int(m_int))
        c_poly = pow(m_poly, d, n)
        c_int = R(c_poly).integer_representation()
        c = format(c_int, '0256x').decode('hex')
        return c
    
    if __name__ == '__main__':
        p,q = n.factor()
        p,q = p[0],q[0]
        s = (2^p.degree()-1)*(2^q.degree()-1)
        d = inverse_mod(e,s)
        with open('flag.enc', 'rb') as f:
            ctext = f.read()
            print(decrypt(ctext,d))

    最终得到flag:flag{P1ea5e_k33p_N_as_A_inTegeR~~~~~~}


    AES解密之in-plain-sight

    题目描述:这次的挑战并不难:你只需要对隐藏的密文进行解密。为了让解密更加简单,我会给你除了HiddenCiphertext以外你需要的所有东西,你要做的就是自己将密文找出来! 你需要: 算法:AES-256-CBC 密钥:c086e08ad8ee0ebe7c2320099cfec9eea9a346a108570a4f6494cfe7c2a30ee1 IV:0a0e176722a95a623f47fa17f02cc16a



    通过网站,https://morsecode.world/international/decoder/audio-decoder-adaptive.html(音频解密器)得到C1和C2的值

    C1:4314251881242803343641258350847424240197348270934376293792054938860756265727535163218661012756264314717591117355736219880127534927494986120542485721347351
    C2:485162209351525800948941613977942416744737316759516157292410960531475083863663017229882430859161458909478412418639172249660818299099618143918080867132349
    利用openssl对两个公钥进行解密,得到n1n2和e1e2:

    import gmpy2
    import libnum

    n1 = gmpy2.mpz(10285341668836655607404515118077620322010982612318568968318582049362470680277495816958090140659605052252686941748392508264340665515203620965012407552377979)
    n2 = gmpy2.mpz(8559553750267902714590519131072264773684562647813990967245740601834411107597211544789303614222336972768348959206728010238189976768204432286391096419456339)
    e1 = 41221
    e2 = 41221
    p = gmpy2.gcd(n1,n2)
    q1 = n1 / p
    q2 = n2 / p
    c1 = 4314251881242803343641258350847424240197348270934376293792054938860756265727535163218661012756264314717591117355736219880127534927494986120542485721347351
    c2 = 485162209351525800948941613977942416744737316759516157292410960531475083863663017229882430859161458909478412418639172249660818299099618143918080867132349
    phin1 = (p - 1)*(q1 - 1)
    phin2 = (p - 1)*(q2 - 1)
    d1 = gmpy2.invert(e1,phin1)
    d2 = gmpy2.invert(e2,phin2)

    print(libnum.n2s(pow(c1,d1,n1))+libnum.n2s(pow(c2,d2,n2)))
    最终得到flag:
    UNCTF{ac01dff95336aa470e3b55d3fe43e9f6}


    题目描述:安全分析人员截获间谍发出的秘密邮件,该邮件只有一个mp3文件,安全人员怀疑间谍通过某种private的方式将信息传递出去,尝试分析该文件,获取藏在文件中的数据。 flag形式为 flag{}


    题目附件连接:

    https://adworld.xctf.org.cn/media/task/attachments/206c0533300340b19c3a18d82d806a98.mp3
    解题步骤:

    题目提示文件使用了private加密信息,在010Editor中打开mp3文件,发现存在private bit,因此,只需要提取每一个mf组中的该字节,组合起来,就是答案。可以从图中看到 ms 开始位为1 C1B8H,即第115128字节,如图所示:,如图所示:

    uint32 frame_sync : 12
        uint32 mpeg_id : 1
        uint32 layer_id : 2
        uint32 protection_bit : 1
        uint32 bitrate_index : 4
        uint32 frequency_index : 2
        uint32 padding_bit : 1
        uint32 private_bit : 1
        uint32 channel_mode : 2
        uint32 mode_extension : 2
        uint32 copyright : 1
        uint32 original : 1
        uint32 emphasis : 2
    

    12+1+2+1+4+2+1+1+2+2+1+1+2=32,即总共4字节,private_bit 为24,所在的字节为第3个字节因此要从前一个,即第二个字节开始提取内容,该字节对应的地址为 115130观察每一个mf组,大小都为414h,即1044字节,因此可以得到以下脚本:

    # coding:utf-8
    import re
    import binascii
    n = 115130
    result = ''
    fina = ''
    file = open('flag-woody.mp3','rb')
    while n < 2222222 :
        file.seek(n,0)
        n += 1044
        file_read_result = file.read(1)
        read_content = bin(ord(file_read_result))[-1]
        result = result + read_content
    textArr = re.findall('.{'+str(8)+'}', result)
    textArr.append(result[(len(textArr)*8):])
    for i in textArr:
        fina = fina + hex(int(i,2))[2:].strip('\n')
    fina = fina#.decode('hex')
    print (fina)
    

    将得到的字符串
    464c41477b707231763474335f6269377d25a1cedc3e69888894dac4dd3a87c5e1c5276fa6d626832148d39288a0c596c95abaac3f09f9f524647595ae4894f9b82b3f4c1b47537c365d8d69d84a353c1a93ae436761d430e666e4111752d479746d1828f9c07c27ab1c3eaf1948f8a9e839b280a4342f321e89eb73b237a2b55d5310b77811c0975cfc1365e146f6c9212e244751398f73c17ee1a6664b4fd712d4b0a297275fa471fb65e440bc7bdc12fb0a39d81a1d374f2d55b8faabf9bf2c342f1046fbab7e66ac7896ffac672d277b89f8606759a8ac21a58fbb4b9b51d45f126a7f67c1a297e1fcb638356ec739b89555568816
    转换对应的ASCII码,得到Flag:

    最终 flag:
    flag{pr1v4t3_bi7}

  • 相关阅读:
    开发细节
    html
    java学习
    Promise对象
    强制转换和隐式转换
    借助防抖解决输入框的非空校验
    setTimeout
    Symbol类型
    js API
    vue 使用mixin
  • 原文地址:https://www.cnblogs.com/backlion/p/15693608.html
Copyright © 2011-2022 走看看