前言
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=)"