CSAW2018_Lowe

作者: SEVEN_9e53 | 来源:发表于2018-09-22 01:36 被阅读10次

    I personally prefer Home Depot.

    XOR Passes are the easiest way to use numbers to encrypt!

    By Kris Kwiatkowski, Cloudflare

    题目提供了三个文件:file.enc, key.enc, pubkey.pem 可以在我的GitHub中找到。

    TL;DR

    运用了RSA公钥中的小公钥指数e,如果明文m的e次方小于n,则用e开方密文m可以得到明文。参考:https://ctftime.org/writeup/11328


    关于RSA加密和破解的参考:https://bitsdeep.com

    因式分解数据库:http://factordb.com

    先查看三个文件的内容,pubkey.pem 明显是RSA的公钥,用openssl的命令解析它:

    sunhaiwendeMacBook-Pro:LoweCrypto sun$ openssl rsa -inform PEM -text -noout -pubin < pubkey.pem

    Public-Key: (1536 bit)

    Modulus:

        00:cf:70:7e:ed:97:90:17:b7:f6:f4:76:ff:3b:a6:

        55:59:ad:b1:82:e0:7c:fa:23:33:b1:ec:05:6b:7f:

        7b:96:12:40:54:f1:f5:74:8b:04:c3:69:4e:90:f0:

        d9:9f:ee:05:84:a8:7a:70:81:75:80:d4:93:93:32:

        1b:b2:08:07:ff:de:25:a4:c8:ab:d4:6d:95:c1:e3:

        74:0d:9e:64:1f:e7:7f:9b:96:ce:ca:e9:18:e6:7a:

        24:89:52:b5:da:81:ae:77:42:bd:ae:51:b1:29:24:

        59:73:41:50:57:ae:75:df:b7:5a:78:e8:24:37:9e:

        52:50:65:92:c3:75:0e:9a:1c:7e:70:1b:ee:8d:df:

        c7:a9:ca:72:53:4c:d3:b0:95:79:f8:7a:4e:b3:76:

        f9:26:7c:d1:a1:6e:1e:57:90:95:c5:b8:6f:4b:8f:

        24:fb:61:3f:08:a7:e0:e4:75:d2:55:56:ae:41:c8:

        ce:e2:48:e9:0d:ac:96:5d:c4:7d:db:b4:c5

    Exponent: 3 (0x3)

    可以看到这个公钥用了一个很小的指数e,根据Wikipedia对于攻击RSA的描述,我们可以将密文用e开方来得到明文。

    文件file.enc内容如下:

    kStoynmN5LSniue0nDxli9csSrBgexZ/YOo5e+MUkfJKwvht8hHsYyMGVYzMlOp9sAFBrPCbm4UA4n7oMr2zlg==

    用Base64解码:

    其内容肯定加密过,将加码后的内容存在file.bin中。

    文件key.enc的内容如下:

    219135993109607778001201845084150602227376141082195657844762662508084481089986056048532133767792600470123444605795683268047281347474499409679660783370627652563144258284648474807381611694138314352087429271128942786445607462311052442015618558352506502586843660097471748372196048269942588597722623967402749279662913442303983480435926749879440167236197705613657631022920490906911790425443191781646744542562221829319509319404420795146532861393334310385517838840775182

    这是一个大整数,可能是RSA中的某个数。

    因为公钥指数是3,如果密文c的e次方小于大数n,我们可以对c开e次方来得到明文。尝试对key.enc中的数进行开方。用python的gmpy2库来做大数的开方运算:

    >>> import gmpy2

    >>> e=gmpy2.mpz(3)

    >>> c=gmpy2.mpz(219135993109607778001201845084150602227376141082195657844762662508084481089986056048532133767792600470123444605795683268047281347474499409679660783370627652563144258284648474807381611694138314352087429271128942786445607462311052442015618558352506502586843660097471748372196048269942588597722623967402749279662913442303983480435926749879440167236197705613657631022920490906911790425443191781646744542562221829319509319404420795146532861393334310385517838840775182)

    将密文和公钥指数以mpz的格式存储。mpz是Multiple-precision Integers,用来存储任意精度整数。对c进行开方:

    >>> gmpy2.iroot(c, e)

    (mpz(6028897571524104587358191144119083924650151660953920127739581033174354252210219577997969114849529704172847232120373331804620146706030387812427825026581462), False)

    第二个返回值false代表这个结果不是精确的,说明c被e开方不是整数。

    回忆RSA加密公式:c=m^e mod n. 如果m^e比n大,那么就会进行mod n的计算。 我们尝试把密文c加上一个n的大小再次开方:

    >>> n=gmpy2.mpz(0x00cf707eed979017b7f6f476ff3ba65559adb182e07cfa2333b1ec056b7f7b96124054f1f5748b04c3694e90f0d99fee0584a87a70817580d49393321bb20807ffde25a4c8abd46d95c1e3740d9e641fe77f9b96cecae918e67a248952b5da81ae7742bdae51b129245973415057ae75dfb75a78e824379e52506592c3750e9a1c7e701bee8ddfc7a9ca72534cd3b09579f87a4eb376f9267cd1a16e1e579095c5b86f4b8f24fb613f08a7e0e475d25556ae41c8cee248e90dac965dc47ddbb4c5) #导入公钥中的n

    >>> gmpy2.iroot(c+n,e)

    (mpz(12950973085835763560175702356704747094371821722999497961023063926142573092871510801730909790343717206777660797494675328809965345887934044682722741193527531), True)

    开方得到的结果是整数!说明解密成功!

    把整数转换为hex:

    >>> plain = int(gmpy2.iroot(c + n, e)[0])

    >>> hex(plain)

    '0xf74709ad02fe85d8d3f993d5ff5716eabb5829df0d12624a048e0a4bd726a6c428a3cd5ac6248900113733effdf1dc4b8837209c92a9a3e161d0478d04dbd0eb'

    但这依然不是flag。

    题目中有提示运用XOR运算。尝试将我们得到的结果和file.binXOR:

    >>> key = bytes.fromhex(hex(plain)[2:])

    >>> data = open("file.bin", "rb").read()

    >>> bytes([ k ^ d for (k, d) in zip(key, data) ])

    b'flag{saltstacksaltcomit5dd304276ba5745ec21fc1e6686a0b28da29e6fc}'

    得到flag!!!

    相关文章

      网友评论

        本文标题:CSAW2018_Lowe

        本文链接:https://www.haomeiwen.com/subject/curtoftx.html