前言
BugKu是一个由乌云知识库(wooyun.org)推出的在线。乌云知识库是一个致力于收集、整理和分享互联网安全信息的社区平台。
BugKu旨在提供一个实践和学习网络安全的平台,供安全爱好者和测试人员进行挑战和练习。它包含了各种不同类型的场景,如Web、系统、密码学等,参与者需要通过解决这些来获取Flag。
BugKu的特点如下:
1. 丰富:BugKu提供了大量的场景供用户挑战,涵盖了常见的Web,如XSS、SQL注入、文件上传等,以及其他类型的,如逆向工程、密码学等。
2. 适合不同水平:BugKu的题目分为不同的难度级别,适合不同水平的参与者。从初学者到专业测试人员,都能在BugKu中找到适合自己的挑战。
3. 学习资源:BugKu提供了丰富的学习资源,包括解题思路、分析、修复建议等。参与者可以通过学习他人的解题思路和经验,提高自己的技术水平。
4. 排行榜竞赛:BugKu设置了排行榜,参与者可以通过解决题目获取积分,竞争排名。这种竞争激励机制可以激发参与者的学习兴趣和动力。
通过参与BugKu,参与者可以在实践中学习到真实的和技术,提高自己的技术水平。同时,BugKu也是一个交流和分享的平台,参与者可以与其他安全爱好者进行讨论和学习,共同成长。
CTF Crypto
密码学(Cryptography)一般可分为古典密码学和现代密码学。
其中,古典密码学,作为一种实用性艺术存在,其编码和破译通常依赖于设计者和敌手的创造力与技巧,并没有对密码学原件进行清晰的定义。古典密码学主要包含以下几个方面:
单表替换加密(Monoalphabetic Cipher)
多表替换加密(Polyalphabetic Cipher)
奇奇怪怪的加密方式
而现代密码学则起源于 20 世纪中后期出现的大量相关理论,1949 年香农(C. E. Shannon)发表了题为《保密系统的通信理论》的经典论文标志着现代密码学的开始。现代密码学主要包含以下几个方面:
对称加密(Symmetric Cryptography),以 DES,AES,RC4 为代表。
非对称加密(Asymmetric Cryptography),以 RSA,ElGamal,椭圆曲线加密为代表。
哈希函数(Hash Function),以 MD5,SHA-1,SHA-512 等为代表。
数字签名(Digital Signature),以 RSA 签名,ElGamal 签名,DSA 签名为代表。
其中,对称加密体制主要分为两种方式:
分组密码(Block Cipher),又称为块密码。
序列密码(Stream Cipher),又称为流密码。
一般来说,密码设计者的根本目标是保障信息及信息系统的
机密性(Confidentiality)
完整性(Integrity)
可用性(Availability)
认证性(Authentication)
不可否认性(Non-repudiation)
其中,前三者被称为信息安全的 CIA 三要素 。
而对于密码破解者来说,一般是要想办法识别出密码算法,然后进行,或者利用密码体制的进行破解。当然,也有可能通过构造虚假的哈希值或者数字签名来绕过相应的检测。
一般来说,我们都会假设已知待破解的密码体制,而攻击类型通常分为以下四种:
类型 | 说明 |
唯密文 | 只拥有密文 |
已知明文 | 拥有密文与对应的明文 |
选择明文 | 拥有加密权限,能够对明文加密后获得相应密文 |
选择密文 | 拥有解密权限,能够对密文解密后获得相应明文 |
一、MaybeEasyRSA
from Crypto.Util.number import * from secret import flag from sympy import nextprime flag = b'' r = getRandomNBitInteger(64) p1 = r ** 5 + r ** 4 - r ** 3 + r ** 2 - r + 2024 q1 = r ** 5 - r ** 4 + r ** 3 - r ** 2 + r + 2024 p = nextprime(p1) q = nextprime(q1) n = p * q def enc(flag, n): m = bytes_to_long(flag) return pow(m, 65537, n) c = enc(flag, n) print(n) print(c) #1058756604181685917958185571746711428601045466594619627088399455470892502310139608978164573773765910533535849969889860275644658086339362201840191861497991951344100284004205747279828567835277683 #643011921358774538378881505518732362708757638007688649119354348647468190640688857686213431516881297805187671774564672497176686191162897918672339254715366498963369868410476737543157157149810569
代码给出了 n、c、e 的值
解题思路:
1. 需要先求出 p 和 q,因为 p 和 q 是 p1 和 q1 的下一个质数,所有去看 p1 和 q1 的值。
每个多项式的最高次项是 r^5
。在大多数情况下,这个最高次项对多项式的值影响最大,又因为 n = p* q,所以我们选择 n
的第10次方根作为 r
的初始猜测值
p1 ≈ r^5 q1 ≈ r^5 n ≈ (r^5) * (r^5) = r^10
2. p 和 q 的值使其等于 n
from gmpy2 import * from sympy import nextprime n = 1058756604181685917958185571746711428601045466594619627088399455470892502310139608978164573773765910533535849969889860275644658086339362201840191861497991951344100284004205747279828567835277683 c = 643011921358774538378881505518732362708757638007688649119354348647468190640688857686213431516881297805187671774564672497176686191162897918672339254715366498963369868410476737543157157149810569 e = 65537 # p1 ≈ r^5 # q1 ≈ r^5 # n ≈ (r^5) * (r^5) = r^10 # iroot(n, 10)[0] 是计算 n 的第10次方根 r_prox = iroot(n, 10)[0] # 循环遍历 for r in range(r_prox - 2000, r_prox + 2000): p1 = r ** 5 + r ** 4 - r ** 3 + r ** 2 - r + 2024 q1 = r ** 5 - r ** 4 + r ** 3 - r ** 2 + r + 2024 p = nextprime(p1) q = nextprime(q1) if p * q == n: # 计算私钥 L = (p - 1) * (q - 1) d = invert(e, L) # 求明文 m = pow(c, d, n) # m.bit_length(): 返回整数 m 的二进制表示中最高位的索引(即,m 的二进制表示的位数)。 # + 7: 这是为了向上取整。如果我们直接除以 8,我们可能会丢失不足一个字节的那些位。例如,9 位实际上需要 2 个字节(9/8 = 1.125 向上取整到 2)。所以我们加上 7 来保证任何非零位数都能向上取整。 # // 8: 整除 8,计算出 m 转换为字节串所需的字节数。每个字节包含 8 位,所以我们需要除以 8。 byte_length = (m.bit_length() + 7) // 8 # m.to_bytes(byte_length, byteorder='big'): 将整数 m 转换为字节串。 # byteorder='big': 表示使用大端序(big-endian)字节顺序存储整数。大端序意味着最高有效字节(最左边的字节)存储在最小的内存地址上。 decrypted_flag = m.to_bytes(byte_length, byteorder='big') print(decrypted_flag) break
运行得到 flag
二、easy_crypto
打开
打开文件内容如下
0010 0100 01 110 1111011 11 11111 010 000 0 001101 1010 111 100 0 001101 01111 000 001101 00 10 1 0 010 0 000 1 01111 10 11110 101011 1111101
只有 0 1 两种字符推测为变形的摩斯密码 ,第三方网站解密
注意提交时转小写
三、黄道十二宫
打开
文件内容如下
这是个很出名的案件,先将图片上的符合转为文字
%.@*>@?==%88%5 @%#@@90-7$^=*@ 17.(>()1@##-$40 ~*6?#%#8#=75+1 (**1%#>,05)%? %*^=1&>=1%.+7&# 8681(+§*@@(¸@@@ #*=#$3*#%,#%%.3 *+7.7+@===+)61
参考网上发布的解密过程进行重排
链接
https://m.thepaper.cn/baijiahao_10580706得到字符如下
%%>%;.@3*.#(#0+ @#+.@)8@7@*7@@1 #5&8=.*9@=)#6#7 >0#7%%8$+@-#5?* 13@?7-+(^(*==$$ 1*=+#==^4~@)8%= %=0.*&*.+8*1*1> @#)8@76%=@%6%.. ?#1(%15@(#>%...
再利用工具 AZdecrypt 解密
flag{alphananke}
四、给你私钥吧
打开
打开 Python 程序内容如下
from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP import base64 from flag import flag f=open(r"pubkey.pem","r") # key = RSA.importKey(f.read()): 读取文件内容并导入 RSA 公钥。RSA.importKey 方法用于将读取的 PEM 格式的公钥转换为可用于加密操作的 RSA key 对象 key=RSA.importKey(f.read()) # cipher = PKCS1_OAEP.new(key): 使用公钥 key 创建一个 PKCS#1 OAEP 加密器对象。PKCS#1 OAEP 是一种填充方案,用于增强 RSA 加密的安全性 cipher=PKCS1_OAEP.new(key) # cipher_txt = base64.b64encode(...): 对加密后的数据进行 Base64 编码,以便将其转换为可读的字符串格式 cipher_txt=base64.b64encode(cipher.encrypt(flag)) with open(r"flag.enc","wb") as f: f.write(cipher_txt) f.close()
给出了私钥和公钥及 flag
解题思路:
1. 先通过 openssl 读取公钥信息
┌──(root㉿kali)-[/home/morant/Crypto] └─# openssl rsa -pubin -in pubkey.pem -text -modulus Public-Key: (2048 bit) Modulus: 00:d1:2b:63:9d:f7:59:a9:9c:9a:db:57:50:0b:bd: 63:50:41:aa:70:f8:e7:3f:6e:a1:58:b2:3b:9a:f5: 75:91:5c:f6:8c:f8:e5:7b:04:5b:be:bc:f7:8a:9b: ca:72:bf:0e:63:cb:6e:c3:53:d6:61:42:04:8c:b6: 9e:b5:f2:0c:dc:6b:af:6c:85:e7:7e:6f:2a:a9:06: dc:58:68:fc:b0:f0:33:0d:eb:55:07:6e:df:1b:22: 6e:f5:49:26:dd:2a:d3:c9:43:c8:eb:35:cb:8c:85: 84:8e:05:ea:86:80:98:8a:18:27:01:b6:a0:dc:54: 96:77:60:ca:c2:81:36:ad:5b:3d:9f:1c:f7:95:2b: 89:8c:fa:af:86:3a:90:bf:d5:8d:f0:fa:3f:35:8a: 7e:b8:bc:be:1b:fc:f1:38:72:bb:b9:fc:c2:b3:30: a3:8f:3f:d6:89:46:7f:ef:22:f0:27:54:9f:53:d4: 60:e9:fe:bb:48:f1:ae:15:f7:bf:ba:93:06:96:41: fd:53:c4:6f:c9:71:56:0f:59:55:d8:f6:e4:19:f5: 98:1a:9b:a3:93:71:8d:78:5f:58:65:96:07:f5:11: f6:cc:40:77:83:4e:05:9f:36:8e:b0:5b:ca:79:64: ea:2d:c8:cd:1b:13:f6:2a:29:ea:24:4a:38:76:ff: 59:67 Exponent: 65537 (0x10001) Modulus=D12B639DF759A99C9ADB57500BBD635041AA70F8E73F6EA158B23B9AF575915CF68CF8E57B045BBEBCF78A9BCA72BF0E63CB6EC353D66142048CB69EB5F20CDC6BAF6C85E77E6F2AA906DC5868FCB0F0330DEB55076EDF1B226EF54926DD2AD3C943C8EB35CB8C85848E05EA8680988A182701B6A0DC54967760CAC28136AD5B3D9F1CF7952B898CFAAF863A90BFD58DF0FA3F358A7EB8BCBE1BFCF13872BBB9FCC2B330A38F3FD689467FEF22F027549F53D460E9FEBB48F1AE15F7BFBA93069641FD53C46FC971560F5955D8F6E419F5981A9BA393718D785F58659607F511F6CC4077834E059F368EB05BCA7964EA2DC8CD1B13F62A29EA244A3876FF5967 writing RSA key -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0StjnfdZqZya21dQC71j UEGqcPjnP26hWLI7mvV1kVz2jPjlewRbvrz3ipvKcr8OY8tuw1PWYUIEjLaetfIM 3GuvbIXnfm8qqQbcWGj8sPAzDetVB27fGyJu9Ukm3SrTyUPI6zXLjIWEjgXqhoCY ihgnAbag3FSWd2DKwoE2rVs9nxz3lSuJjPqvhjqQv9WN8Po/NYp+uLy+G/zxOHK7 ufzCszCjjz/WiUZ/7yLwJ1SfU9Rg6f67SPGuFfe/upMGlkH9U8RvyXFWD1lV2Pbk GfWYGpujk3GNeF9YZZYH9RH2zEB3g04FnzaOsFvKeWTqLcjNGxP2KinqJEo4dv9Z ZwIDAQAB -----END PUBLIC KEY-----
1. openssl rsa
这是 OpenSSL 命令行工具的一个子命令,rsa 子命令用于处理 RSA 密钥。
2. -pubin
指定输入文件包含的是一个公钥。如果不使用这个选项,OpenSSL 会默认认为输入文件包含的是私钥。
3. -in pubkey.pem
指定输入文件名为 pubkey.pem。该文件应该包含 RSA 公钥。
4. -text
以可读的文本格式输出 RSA 公钥的详细信息,包括密钥的各种参数(如模数和公钥指数)。
5. -modulus
显示 RSA 公钥的模数(Modulus)。模数是 RSA 公钥的一部分,是一个大整数,用于加密和解密过程。
得到 e = 65537,Modulus 则是十六进制的 n,转换为十进制得到
26405201714915839490865227813246218372938736243516916108608439705738170543023112509150522274284238701776297205717958250714972924576706985074311737321016048409831557758205687745692399643151467933196930799657476449865271038382866908177517793954543176769652784274788769353482450910551831498252972857285424471782215525406445071432588374802623485148684255853068532820859835479998199886719945699488858505070686919320144576280217196858823521754407597888769668827432569034617434944912323704501156532854074083408527717809315663187405585840074689387865750105223058720511199252150772925124516509254841404742306560035497627834727
2. 利用工具 factordb 将 n 因式分解为 p 和 q 得到
pip install factordb-pycli
157790417717035275943197904823645145281147085252905247447260034051878691034747684303715336348507267921249655103263347914128144476912685213431110454636244692224328066884510063590700506729345331153483633231327359450199822698241355428609085077662488946173655043172957247264543259611018596088670385591091710018977 167343506005974003380506069679607737381940204686173214188860057004909006055220516074283090160430833007424970980655748310232878462615469792561310560310363430669700009093597847018287568821792168143170329382585883857083334915378884054389878477389765792275111293420203613159303898365894897865177093362621517279751
完整脚本实现
from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP import base64 import libnum def decrypt_rsa(): n = 26405201714915839490865227813246218372938736243516916108608439705738170543023112509150522274284238701776297205717958250714972924576706985074311737321016048409831557758205687745692399643151467933196930799657476449865271038382866908177517793954543176769652784274788769353482450910551831498252972857285424471782215525406445071432588374802623485148684255853068532820859835479998199886719945699488858505070686919320144576280217196858823521754407597888769668827432569034617434944912323704501156532854074083408527717809315663187405585840074689387865750105223058720511199252150772925124516509254841404742306560035497627834727 e = 65537 q = 157790417717035275943197904823645145281147085252905247447260034051878691034747684303715336348507267921249655103263347914128144476912685213431110454636244692224328066884510063590700506729345331153483633231327359450199822698241355428609085077662488946173655043172957247264543259611018596088670385591091710018977 p = 167343506005974003380506069679607737381940204686173214188860057004909006055220516074283090160430833007424970980655748310232878462615469792561310560310363430669700009093597847018287568821792168143170329382585883857083334915378884054389878477389765792275111293420203613159303898365894897865177093362621517279751 d = libnum.invmod(e, (p - 1) * (q - 1)) u = libnum.invmod(p, q) private_key = RSA.construct((n, e, d, p, q, u)) with open(r"./tmp/flag.enc", "rb") as f: cipher_txt = f.read() cipher_txt = base64.decodebytes(cipher_txt) decipher = PKCS1_OAEP.new(private_key) flag = decipher.decrypt(cipher_txt) print(flag) if __name__ == "__main__": decrypt_rsa() pass
当然也能直接使用工具解密
┌──(root㉿kali)-[/home/morant/Crypto/RsaCtfTool-master] └─# ./RsaCtfTool.py --publickey pubkey.pem --decryptfile flag.enc private argument is not set, the private key will not be displayed, even if recovered. ['pubkey.pem'] [*] Testing key pubkey.pem. attack initialized... attack initialized... [*] Performing system_primes_gcd attack on pubkey.pem. 100%|██████████████████████████████████████████████████████| 7007/7007 [00:00<00:00, 649979.83it/s] [+] Time elapsed: 0.0349 sec. [*] Performing pastctfprimes attack on pubkey.pem. [+] loading prime list file data/pastctfprimes.txt... 100%|████████████████████████████████████████████████████████| 121/121 [00:00<00:00, 855836.06it/s] [+] loading prime list file data/ti_rsa_signing_keys.txt... 100%|██████████████████████████████████████████████████████████| 34/34 [00:00<00:00, 682326.97it/s] [+] loading prime list file data/visa_emv.txt... 100%|█████████████████████████████████████████████████████████████| 2/2 [00:00<00:00, 61680.94it/s] [+] Time elapsed: 0.0023 sec. [*] Performing lucas_gcd attack on pubkey.pem. 100%|███████████████████████████████████████████████████████| 9999/9999 [00:00<00:00, 67871.33it/s] [+] Time elapsed: 0.1481 sec. [*] Performing nonRSA attack on pubkey.pem. [+] Time elapsed: 0.0058 sec. [*] Performing factordb attack on pubkey.pem. [*] Attack success with factordb method ! [+] Total time elapsed min,max,avg: 0.0023/0.1481/0.0478 sec. Results for pubkey.pem: Decrypted data : HEX : 0x6275676b757b7477305f5469673372735f6c3056335f64346e63316e677e6569217d INT (big endian) : 2918586387313427374648113440268372321293127400371659767444946173589057060433633661 INT (little endian) : 3709215666712012992462466403546646476981044684602414906342022350687712344355075426 utf-8 : bugku{tw0_Tig3rs_l0V3_d4nc1ng~ei!} utf-16 : 畢歧筵睴弰楔㍧獲江嘰弳㑤据渱繧楥紡 STR : b'bugku{tw0_Tig3rs_l0V3_d4nc1ng~ei!}' HEX : 0x00a523cbe10c51ead7e9644a5204cfe9fbdb74563b3eff4ef1bdf6c5cf9f5128147c555280fd5b6c260550bedeb619a18a84a2e7c4848f2eaf44ef18ae5bde25a1444986ad5cd3c1c44bc5856998f687dfc8baa21c38c2889d648b60afb4b348575a9ae3069e418063e01a6516ede865a7387171db096d3e5fb4d42fcccc8ddb05171676de0975ccc15c704b28b1c9918099cc4740c8bead68ca7ca36098b1f13118db82d581a63cb609871879553902d08454498e0831dd2f8a34c94f7df170aa3908935052df5e8c7edb246bdfb81f2a123ae9cf5b5d75d516bf057d33f2e689b065cb04a02e88d67e212dedfeccfe7f7127ec7fa303162bf75b6639dc3d29 INT (big endian) : 81433485091683117729717936813410649682758284541757944860531322121787750361115421764353279099689852790295240315525792403496101981998736337314845081040264709493871780260243922411131472425470840653126631270365069388688762451708248880104115578452340859098453476543481889050970410349911522172736663738291224791218022632374300122455338112493842419557856068570374630901848217097177605910777015383256762468570410207184799429316152372747950704363864014315541311876808261634933982667016332187799092386336784756627013908871613266188424064501047694184376947525813677481081510493140809755158416427169586303606677615190862478633 INT (little endian) : 5206274930219105001030736156940407019146396078141741514464691081689581277672865917806951731042960847517178192163849853569829854258690781682270945872751605855398075664524044609471901382939170928883625021890270958748663017677150717364726957817717856005677923974075749963837599786736805629362260414535598111700646995944739338992623613809901515192240627557496164007918596150245092622914504958809192749246645183137807810350768706858202144168970863590183977369013923196730893204679531292320403692942420736584910376723924582236934958423920266411928101112095072556759450757104144438752332222413227015526297356650380997666048 STR : b"\x00\xa5#\xcb\xe1\x0cQ\xea\xd7\xe9dJR\x04\xcf\xe9\xfb\xdbtV;>\xffN\xf1\xbd\xf6\xc5\xcf\x9fQ(\x14|UR\x80\xfd[l&\x05P\xbe\xde\xb6\x19\xa1\x8a\x84\xa2\xe7\xc4\x84\x8f.\xafD\xef\x18\xae[\xde%\xa1DI\x86\xad\\\xd3\xc1\xc4K\xc5\x85i\x98\xf6\x87\xdf\xc8\xba\xa2\x1c8\xc2\x88\x9dd\x8b`\xaf\xb4\xb3HWZ\x9a\xe3\x06\x9eA\x80c\xe0\x1ae\x16\xed\xe8e\xa78qq\xdb\tm>_\xb4\xd4/\xcc\xcc\x8d\xdb\x05\x17\x16v\xde\tu\xcc\xc1\\pK(\xb1\xc9\x91\x80\x99\xccG@\xc8\xbe\xadh\xca|\xa3`\x98\xb1\xf11\x18\xdb\x82\xd5\x81\xa6<\xb6\t\x87\x18yU9\x02\xd0\x84TI\x8e\x081\xdd/\x8a4\xc9O}\xf1p\xaa9\x08\x93PR\xdf^\x8c~\xdb$k\xdf\xb8\x1f*\x12:\xe9\xcf[]u\xd5\x16\xbf\x05}3\xf2\xe6\x89\xb0e\xcb\x04\xa0.\x88\xd6~!-\xed\xfe\xcc\xfe\x7fq'\xec\x7f\xa3\x03\x16+\xf7[f9\xdc=)"