
利用工具 + Burp靶场 + CVE案例 + 攻击技巧 + 其他场景案例
0X01JWT是什么?
JWT,全称是 JSON Web Token,是一种用于身份验证和信息传递的令牌。简单来说,它就像是一个“通行证”,用户登录后,服务器会生成一个JWT返回给用户,用户之后访问其他资源时只需带上这个令牌,服务器验证通过后即可放行。
简单讲,JWT 如同特殊 “房卡”。入住酒店用身份证(账号密码)办房卡,JWT 就是访问网站资源的通行证。每次访问资源出示 “房卡”(携带 JWT),网站服务器验证其签名等有效性后,确认身份便允许访问。要是没有“房卡”想进去耍“刘忙”,别慌,请翻至《 0X04 JWT安全问题 》阅读。
具体而言,完整的 JWT 由三部分组成:第一部分是头部(Header),第二部分是载荷(Payload),第三部分是签名(Signature)。它们之间通过三个点(.)分隔。每一部分都经过 Base64 编码。注意,JWT 的前两部分未加密,可直接解码查看,第三部分签名需密钥验证。
0X02 JWT名称:
JWS(JSON Web Signature):JWS是指使用加密方法保护和验证 JSON 格式的签名数据。它常用于对 JWT 进行签名(第三段:Signature),确保 JWT 的完整性和真实性。JWS 由三部分组成:受保护的头部、有效载荷和签名。
JWT(JSON Web Token):JWT是一种用于在网络应用之间安全传输信息的开放标准。它由三部分组成:头部(Header)、载荷(Payload)和签名(Signature),这三部分之间通过点(.)分隔。
JWE(JSON Web Encryption):JWE是指使用加密方法保护 JSON 格式的加密数据。它用于对 JWT 进行加密,以确保其机密性。JWE 由受保护的头部、加密的有效载荷和加密密钥等部分组成。
JWK(JSON Web Key):JWK是一个 JSON 对象(公/私 密钥),用于表示加密密钥。它可以包含公钥或私钥的信息,用于 JWT 的签名和验证。
JKU(JSON Web Key Set URL):JKU是指一个指向 JSON Web Key Set 的 URL,该 Key Set 包含用于验证 JWT 的公钥。
X5U(X.509 URL):X5U是指一个指向 X.509 公钥证书或证书链的 URL,用于验证 JWT 的签名。
KID(Key ID):kid是 JWT 头部中的一个字段,用于标识用于签名或加密的密钥。
ALG(Algorithm):alg是 JWT 头部中的一个字段,用于指定签名或加密算法。
HMAC(Hash-based Message Authentication Code):HMAC是一种基于哈希的消息认证码,是一种常用的签名算法,用于确保消息的完整性和真实性。
0X03 JWT工具列举:
JWT 工具趣味 “吐槽”:
0X03 哭诉:别问我是谁、咋用啦,我真不知道哇!
读者不依:我有事请教,咋就不行嘛!
0X03 回怼:哎呀,没事瞎折腾啥!快往下看正文!
读者懵圈:折腾 “四” 是谁呀?
0X04 接话:瞅我瞅我,答案在下面呢!
https://github.com/portswigger/jwt-editor
https://www.jsongj.com/ede/jwt
https://github.com/hashcat/hashcat
https://github.com/ticarpi/jwt_tool
https://github.com/wallarm/jwt-secrets
https://github.com/openssl/openssl
0X04 JWT安全问题:
一、有缺陷的JWT签名验证:
(一)案例一:接受任意签名
原理:JWT库通常提供两种方法来处理令牌:一种是验证令牌,另一种只是解码令牌。例如,在Node.js的jsonwebtoken库中,有verify()和decode()方法。
verify() 方法:用于验证令牌的签名是否有效,同时解码令牌内容。如果签名无效,该方法会抛出错误。
decode() 方法:仅用于解码令牌内容,不解密或验证签名。
有时,开发人员可能会混淆这两个方法,错误地只将传入的令牌传递给decode()方法。这样做实际上意味着应用程序没有验证签名,从而可能引入安全风险。
Burp实验靶场 (注意:此关需将 Payload 中的 wiener更改为administrator):
(1)在实验室中,登录到您自己的帐户。
账号:密码 --> wiener:peter
(2)在Burp中,转到Proxy > HTTP history选项卡并查看登录后GET /my-account请求。请注意,您的会话cookie是JWT。
(3)双击令牌的有效负载部分以在“检查器”面板中查看其解码的JSON表单。请注意,子声明包含您的用户名。将此请求发送到Burp Repeater。
(4)在Burp Repeater中,将路径更改为/admin并发送请求。请注意,只有以管理员用户身份登录时,才能访问管理面板。
(5)再次选择JWT的有效负载。在Inspector面板中,将子声明的值从wiener更改为administrator,然后单击Apply changes。
(6)再次发送请求。观察您是否已成功访问管理面板。
(7)在响应中,找到用于删除carlos的URL(/admin/delete?username=carlos)。将请求发送到此端点以解决实验。
(二)案例二:接受空(none)签名(CVE-2015-9235)
原理:在JWT的Header中,alg的值会告诉服务器用哪种算法对令牌签名(可变为客户端决定),这样服务器在验证签名时就知道该用哪种算法。
第一个示例:alg被设置为"HS256",表示使用HMAC和SHA256算法对令牌进行签名。服务器在验证签名时会使用相同的算法和密钥。
{ "alg": "HS256", "typ": "JWT" }
第二个示例:alg被设置为"None",表示不使用签名。这意味着任何令牌都会被服务器视为有效,因为没有签名需要验证。这种设置在生产环境中非常危险,因为它允许攻击者伪造令牌。
{ "alg": "None", "typ": "JWT" }
如果在生产环境中没有关闭这个功能,攻击者就可以利用它,把alg设为"None",然后伪造出想要的令牌,用这个伪造的令牌冒充任意用户登录网站。
Burp实验靶场(注意:攻击手法与上一关卡一致,唯一区别在于,此关需将 header 中的 alg 参数值设为 none )
(1)登入,并获取普通用户权限,抓包获取流量
(2)流程与第一次一致,只不过变为修改 header 中的 alg 参数值设为 none ?你确定?不对,请继续看下文
(3)然后使用Inspector将alg参数的值更改为none。单击应用更改。在消息编辑器中,从JWT中删除签名,但请记住在有效负载之后留下尾随的点。
把“wiener”改成“administrator”,这等于直接告诉全世界“我是管理员”。把“alg”参数值设为“none”,就像对服务器说“嘿兄弟,我今天穿了丝袜”,结果服务器还真信了,不再验证签名。至于是否删除第三部分(Signature),这得看实际情况,不能一概而论。
(3)在响应中,找到用于删除carlos的URL(/admin/delete?username=carlos)。将请求发送到此端点以解决实验。
KID(Key ID):在 JWT 头部中,kid(Key ID)字段用于标识用于签名或加密的密钥。它的主要作用是帮助服务器快速找到正确的密钥,便于密钥管理和提高安全性。虽然 kid 字段不是 JWT 规范中强制要求的,但它是一个推荐使用的字段,特别是在需要管理多个密钥的场景下。
第二种:利用jwt_tool工具
python3 jwt_tool.py JWT_HERE -X a 【不再演示】
(三)案例三:敏感信息泄露
原理:JWT的header头base64解码(可泄露敏感数据)如:密钥文件或者密码
eyJraWQiOiJrZXlzLzNjM2MyZWExYzNmMTEzZjY0OWRjOTM4OWRkNzFiODUxIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ
其中认证类型为JWT,加密算法为RS256,kid指定加密算法的密钥,密钥KID的路径为:keys/3c3c2ea1c3f113f649dc9389dd71b851k,则在 Web 根目录中查找 /key/3c3c2ea1c3f11
3f649dc9389dd71b851k 和 /key/3c3c2ea1c3f113f649dc9389dd71b851k.pem
密钥文件后缀:.cer、 .crt、.jwk、.p8、.keystore、.pfx、.p12、.pem、.jks、.der
二、暴力破解密钥:
原理:HS256(对称加密算法)签名算法使用任意独立字符串作为密钥,此秘密必须难以被攻击者猜到或暴力破解。否则,攻击者可利用此密钥,以任意头部和载荷值创建并重新签名 JWT。
开发人员在实现 JWT 应用时易犯错误,如未更改默认值(过于简单)或占位符密码(类似${db.password}的占位符),甚至直接使用从网上复制的代码片段中的示例硬编码秘密。此时,攻击者使用已知秘密的单词列表,可轻松暴力破解服务器秘密。
Burp实验靶场
(一)案例一:使用hashcat暴力强制密钥
(1)在实验中,登录到您自己的帐户并将登录后GET /my-account请求发送到Burp Repeater。
(2)JWT字典:https://github.com/wallarm/jwt-secrets
(3)hashcat工具:https://github.com/hashcat/hashcat
(4)复制JWT并暴力破解秘密。使用hashcat来实现:
针对如下JWT进行暴力破解:
eyJraWQiOiI2N2JjNWQwYi05NDZjLTQ5ZjItYjg4MS0yM2IxMTUzMTcxNTAiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTc0MjQwMTkyNywic3ViIjoid2llbmVyIn0.Zi26POtZrsxBPDgEv98X-jNpEkq091Q17JHYPEz-Sfc
hashcat -m 16500 -a 0 /root/JWT/jwt.txt /root/JWT/jwt_secrets_list.txt --force
-m 16500:指定哈希类型为 JWT。
-a 0:指定攻击模式为字典攻击。
jwt.txt:包含 JWT 令牌的文件。
rockyou.txt:包含可能的密钥的字典文件。
--force:强制运行,即使 hashcat 提示某些警告或错误。
(5)生成伪造的签名密钥:secret1
(6)修改并签署JWT
(二)案例二:使用jwt_tool暴力强制密钥
(1)在实验中,登录到您自己的帐户并将登录后GET /my-account请求发送到Burp Repeater。
(2)JWT字典:https://github.com/wallarm/jwt-secrets
(3)jwt_tool工具:https://github.com/ticarpi/jwt_tool
(4)复制JWT并暴力破解秘密。使用jwt_tool来实现:
针对如下JWT进行暴力破解:
eyJraWQiOiI2N2JjNWQwYi05NDZjLTQ5ZjItYjg4MS0yM2IxMTUzMTcxNTAiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTc0MjQwMTkyNywic3ViIjoid2llbmVyIn0.Zi26POtZrsxBPDgEv98X-jNpEkq091Q17JHYPEz-Sfc
python3 jwt_tool.py JWT_HERE -C -d jwt_secrets_list.txt
python3:指定使用 Python 3 解释器来运行脚本。
jwt_tool.py:这是一个用于分析和破解 JWT 令牌的 Python 脚本。
JWT_HERE:这是你要分析或破解的 JWT 令牌的具体内容。你需要将 JWT_HERE 替换为实际的 JWT 令牌字符串。
-C:这个选项通常用于指定破解模式(Crack mode),即尝试使用字典攻击来破解 JWT 的密钥。
-d jwt_secrets_list.txt:这个选项指定一个字典文件,其中包含可能的密钥列表。jwt_secrets_list.txt 是字典文件的路径。
(5)生成伪造的签名密钥:secret1
(6)修改并签署JWT
三、JWT头参数注入:
自行回顾:0X02 JWT名称
简提:根据JWS规范,只有alg头参数是强制性的【也可出现空(none)签名漏洞情况】
jwk(JSON Web Key)-JSON 对象(公/私 密钥),用于表示加密密钥,用于 JWT 的签名和验证。
jku(JSON Web Key Set URL)-提供一个URL,服务器可以从中获取包含正确密钥的一组密钥。
kid(密钥ID)-提供一个ID,在有多个密钥可供选择的情况下,服务器可以使用该ID来标识正确的密钥。根据键的格式,匹配对应的kid参数。
此漏洞的本质在于,用户能够操控JWT中参数,将这些参数告知接收方服务器(未经过充分的审核与判断便直接使用),在验证签名时在验证签名时采用由用户决定的密钥并注入经过修改的 JWT(JSON Web Token),这些 JWT 使用你自定义的任意密钥而非服务器的密钥进行签名。
(一)案例一:JWK参数注入自签名JWT(CVE-2018-0114)
原理:服务器理应仅借助预先设定的有限公钥白名单(例如:keys数组)来验证 JWT 签名,以此确保验证过程的安全性与可控性。然而,部分服务器由于配置失误,有时会直接采用 jwk 参数里嵌入的任意密钥进行验证,这无疑为系统埋下了安全隐患。
keys数组:keys 数组包含了两个公钥。每个公钥都有一个唯一的 kid(密钥标识符),以及 kty(密钥类型)、n(模数)和 e(指数)等参数,这些参数用于标识和验证公钥。
{
"keys": [
{
"kid": "key1",
"kty": "RSA",
"n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
"e": "AQAB"
},
{
"kid": "key2",
"kty": "RSA",
"n": "m8d65sLkO3G5n67fWzR0C6c2m1Z9g2C6Z0u2W3q0F5J7y7x9L8r0R6c0t1Q",
"e": "AQAB"
}
]
}
举例:利用公钥PEM格式,转换为 JWT(JSON Web Token)所使用的 JWK(JSON Web Key)格式
openssl pkey -in public_key.pem -out public_key.json -inform PEM -outform JSON
openssl下载地址:https://github.com/openssl/openssl
JWK格式 - 例如:
{
"kid": "0cbb10ae-e7ec-42d0-8d31-4de77764d079",
"typ": "JWT",
"alg": "RS256",
"jwk": {
"kty": "RSA",
"e": "AQAB",
"kid": "0cbb10ae-e7ec-42d0-8d31-4de77764d079",
"n": "4XfFD85aeJMOgKPpgfsqUKSwwWBE9dMML79dWbwQMxw_DeA6r7As7gQa9NiUIx5IhPPa6Bbqql5kTgV2O-SBM-1WrhWMbsF946U2wi96LUuI53_o9Rto5dRvEAHhQAuPet1x9359k9dIopqPLsmKoN6g9AO7h_fkCt0Km41f90JM6A_cFZPy5fbhOhA1Y4-phLJgHPtxljkvuHuf--qSUXhb-p9xT5tu13iw65V1frJMIchswPGfoz-l2YQ8Jz2udlHS7yL-wr8CZ1tbMCFkmzR92k2Yis76-j5r9xRGiH5l--n5kfniENKuSMRQ_6IhfoTJql71vsyPvvTGVQ6Yxw"
}
}
Burp实验靶场 (注意:此关需将 Header中的jwk参数添加到JWT的头部来嵌入JWK):
(1)登入用户,获取普通用户权限的JWT
(2)利用插件jwt enditor
安装并创建KID JWK格式:
(3)注意修改内容:
读者:(一脸崩溃,双手抱头)不是,我说老天爷啊,这什么什么格式,谁能记得住啊!这是要把我的脑子变成浆糊嘛!你是不是跟我前世有仇,故意来刁难我这个无辜小可怜的!
0X04:(吓得一哆嗦,双手乱摇)别别别,大哥大姐饶命!马上马上,这就给您呈上答案,可千万别动手,我这小身板可禁不住打呀 !
(4)在JWT的头文件中,可以看到添加了一个包含公钥的jwk参数,修改"sub":
"wiener"为"sub": "administrator",注意:修改路径为/admin/delete?username=carlos
第二种:利用jwt_tool工具
python3 jwt_tool.py JWT_HERE -X i 【不在演示】
(二)案例二:JKU参数注入自签名JWT
原理:有些服务器不直接使用jwk头参数嵌入公钥,而是允许您使用jku(或者x5u)头参数来引用包含密钥的JWK Set。当验证签名时,服务器从该URL获取相关密钥。
在这种攻击手法里,攻击者巧妙地利用了“jku”和“x5u”这两个标头值。这俩标头值就像一把钥匙,指向的是用于验证非对称签名令牌的 JWKS 文件,或者是 x509 证书(通常这 x509 证书本身也是放在 JWKS 文件里的)对应的 URL 。
JWK格式 - 例如:
Burp实验靶场(注意:此关需将 Header中的jwu参数添加到JWT的头部来嵌入恶意URL)
(1)登入用户,获取普通用户权限的JWT
(2)利用插件jwt enditor
安装并创建KID JWK格式:
(3)在浏览器中,转到漏洞利用服务器。
https://exploit-0adc003403db3d1582a2aad801a90009.exploit-server.net/
(4)将Body部分的内容替换为空的JWK Set,如下所示:
{
"keys": [
]
}
(5)回到JWT编辑器的Keys选项卡,右键单击刚刚生成的键的条目,然后选择Copy Public Key as JWK。
(6)将JWK粘贴到漏洞服务器上的密钥数组中,然后存储漏洞。结果应该如下所示:
得到服务器url:
https://exploit-0adc003403db3d1582a2aad801a90009.exploit-server.net/donpo.json
(7)在JWT的头文件中添加一个新的jku参数。将其值设置为漏洞利用服务器上JWK Set的URL。
(8)成功(注意:攻击服务器点击“ store ” 保存否则失败)
如果服务器把验证密钥存储于数据库中,那么 kid 头参数也有可能成为 SQL 注入攻击的目标
(三)案例三:JWT通过kid头路径(目录遍历)造成空密钥签名或者SQL注入或者命令注入
原理:密钥 ID (kid) 是一个可选header,是字符串类型,用于表示文件系统或数据库中存在的特定密钥,然后使用其中内容来验证签名。如果有多个用于签署令牌的密钥,则此参数很有帮助,但如果它是可注入的,则可能很危险,因为攻击者可以指向内容可预测的特定文件。
思考:可遍历存在危害(空密钥签名)、存储在数据库危害(SQL注入)
补充知识点:
①对称加密中的 k 值在对称加密算法(如 HMAC-SHA256)中,k 值是对称密钥,用于生成和验证 JWT 的签名。
例如:
{
"kty": "oct",
"k": "AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"
}
在这个例子中,k 是一个 Base64 URL 编码的对称密钥,用于 HMAC-SHA256 算法。
②非对称加密中的 k 值在非对称加密算法(如 RSA 或 ECDSA)中,通常使用公钥和私钥对,而不是单一的 k 值。非对称加密的 JWK 会包含不同的参数,例如 n(模数)、e(指数)等,而不是 k 值。
例如:
{
"kty": "RSA",
"n": "0vx7agoebGcQSuuPiCAxXbJnweR4xGWGLmE12ocLZGypr9B28S71RuV6k1A6FhYH5cX0W9luPxhT06qZ6FtAHg",
"e": "AQAB"
}
Burp实验靶场(注意:dev/null文件默认为空文件、k 值修改为AA==也就是 null、k值)
(1)登入,获取JWT
(2)利用jwt enditor生成对称密钥,并修改“k”值 为 “AA==”
(3)修改jwt中的kid为“../../../../../../../dev/null”并点击sign进行空签名
(4)完成任务
(四)案例四:其他有趣的 JWT 头参数
cty(内容类型)攻击实现:
假设攻击者找到了绕过签名验证的方法,他们可能会尝试注入一个cty头,将内容类型更改为text/xml或application/x-java-serialized-object,以利用解析库的漏洞进行攻击。【可能会为XXE和匿名化攻击提供新的载体】例如:
{
"alg": "HS256",
"typ": "JWT",
"cty": "application/x-java-serialized-object"
}
x5c(X.509证书链)攻击实现:
攻击者可能会利用x5c参数注入自签名证书,以欺骗服务器使用该证书进行签名验证。【header参数可以用来注入自签名证书,类似于上面讨论的jwk header注入攻击。由于X.509格式及其扩展的复杂性,解析这些证书也可能引入漏洞】例如:
{
"alg": "RS256",
"typ": "JWT",
"x5c": [
"MIIDxTCCAq2gAwIBAgIITZbf5m...(自签名证书内容)"
]
}
但有关更多细节,请查看CVE-2017-2800和CVE-2018-2633
四、JWT算法混淆:
案例:(CVE-2016-5431/CVE-2016-10555)
对称与非对称算法:
可以使用一系列不同的算法对JWT进行签名。其中一些,如HS 256(HMAC + SHA-256)使用“对称”密钥。这意味着服务器使用单个密钥来签名和验证令牌。显然,这需要保密,就像密码一样。
其他算法,如RS 256(RSA + SHA-256)使用“非对称”密钥对。它由一个私钥和一个与数学相关的公钥组成,服务器使用私钥对令牌进行签名,公钥可用于验证签名。
原理:
算法混淆漏洞通常是由于JWT库的有缺陷的实现引起的。尽管实际的验证过程因所使用的算法而异,但许多库都提供了一种与算法无关的方法来验证签名。这些方法依赖于令牌头中的alg参数来确定它们应该执行的验证类型。
1.下面的伪代码显示了一个简化的示例,说明了这个泛型verify()方法的声明在JWT库中可能是什么样子:
function verify(token, secretOrPublicKey){ algorithm = token.getAlgHeader(); if(algorithm == "RS256"){ // Use the provided key as an RSA public key } else if (algorithm == "HS256"){ // Use the provided key as an HMAC secret key } }
2.开发人员的错误假设
publicKey = <public-key-of-server>; token = request.getCookie("session"); verify(token, publicKey);
开发人员假设所有传入的 JWT 都是使用非对称算法(如 RS256)签名的,因此总是传入一个固定的公钥(publicKey)。
(一)案例一:逻辑混淆绕过JWT算法(暴露公钥情况)
详细的攻击步骤 攻击者构造恶意 JWT:
1、创建一个 JWT,将 alg 设置为 HS256。
2、使用服务器的公钥(publicKey)作为 HMAC 的秘密密钥对 JWT 进行签名。
服务器验证恶意 JWT:
1、服务器接收到 JWT 后,调用 verify(token, publicKey)。
2、由于 alg 是 HS256,服务器将 publicKey 视为 HMAC 的秘密密钥。 攻击者使用相同的公钥作为 HMAC 密钥签名,服务器会错误地认为签名是有效的。
(思考:为什么不随便使用自己生成的密钥?回答:如果攻击者使用随机生成的密钥进行签名,服务器在验证时会使用自己的公钥进行验证,这会导致签名验证失败)
Burp实验靶场(注意:主要在于alg参数,提醒URL/jwks. json每次的不一样)
(1)在浏览器中,转到标准端点/jwks. json并观察服务器公开了包含单个公钥的JWK Set。 从keys数组中复制JWK对象。确保您不会意外地从周围的数组中复制任何字符。
(2)在Burp中,转到Burp主选项卡栏中的JWT编辑器插键。 单击新建RSA密钥。 在对话框中,确保选中了JWK选项,然后粘贴刚刚复制的JWK。单击“确定”保存密钥。 右键单击刚刚创建的密钥的条目,然后选择复制公钥作为PEM。 使用Decoder模块对PEM键进行Base64编码,然后复制结果字符串。
(3)在 JWT Editor Keys 处,生成新的对称加密 Key,用之前保存的 base64 编码去替换 k 的值。修改“alg ” 为 “HS256”,修改 “sub” 为“ administrator”。再进行 Sign 操作,最后发包即可。
(二)案例二:JWT令牌中导出公钥(未暴露公钥情况)
补充:
(1)X.509
(1.1)定义:X.509是一种国际标准(ITU-T X.509)定义的公钥证书格式,广泛应用于公钥基础设施(PKI)中,用于验证公钥的合法性。
(1.2)内容:X.509证书包含多个字段,如版本号、序列号、签名算法、颁发者名称、有效期、主体名称、公钥信息、扩展等。
PEM格式举例:
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIITZbf5mFck0IwDQYJKoZIhvcNAQELBQAw
CjELMAkGA1UEBhMCQVUxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAU
BgNVBAcTDVNhbiBGcmFuY2lzY28xFTATBgNVBAoTDE1ha2V0R3Jvd
...(省略部分内容)
-----END CERTIFICATE-----
(1.3)用途:X.509证书用于验证公钥的合法性,确保通信双方的身份真实可信,广泛应用于SSL/TLS、电子邮件加密、代码签名等场景。
(2)PKCS#1
(2.1)定义:PKCS#1是RSA加密算法的标准,定义了RSA密钥的表示方法和加密、解密的运算过程。
(2.2)内容:PKCS#1格式的公钥主要包含模数(n)和指数(e),私钥则包含更多的参数,如私钥指数(d)、素数因子(p和q)等。
PEM格式举例:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdP47Y99R33m27G84z7nW7j2W2
d9m8z4L5g8v7g9k7z8v7G8v9W7j2W2d9m8z4L5g8v7g9k7z8v7G8v9W7j2W2d9m8z
...(省略部分内容)
-----END PUBLIC KEY-----
(2.3)用途:PKCS#1主要用于RSA加密和解密操作,确保数据的安全传输,常用于数字签名、加密通信等场景。
示例(该过程是计算而不是爆破):
假设你有两个 JWT 令牌 token1 和 token2,你可以运行以下命令:
docker run --rm -it portswigger/sig2n token1 token2
工具会输出一个或多个潜在的派生公钥,你可以使用这些公钥来构造和验证 JWT。
原理:RSA算法基于大素数的乘积难以分解的数学特性。给定两个不同的JWT签名,可以通过它们的签名值和消息内容来推导出可能的公钥参数(如模数n和指数e)
Burp实验靶场(现有的token【令牌】值派生出公钥)
(1)注销并重新登录,复制新的JWT会话cookie并保存它。服务器生成了两个有效的JWT。
(2)在终端中,运行以下命令,将两个JWT作为参数传入。请注意,第一次运行此命令时,可能需要几分钟的时间才能从Docker Hub中提取映像。
docker run --rm -it portswigger/sig2n <token1> <token2>
(3)验证X.509和PKCS1 格式的jwt 哪种有效,并利用该格式的公钥进行JWT混淆案例一的流程,进行混淆则成功。
0X05 JWT补充知识点:
Tip1 - JWT重放:
如果希望特定令牌只能使用一次,该如何操作呢?设想这样一个场景:用户利用生成的令牌来调用我们 API 中的 DELETE 方法。然而,在一天之后(此时理论上用户已不再具备相应权限),他试图再次使用该令牌,即实施所谓的重播攻击。
Tip2 - sql注入:
Tip3 - 命令执行:
如果服务器后端使用的是Ruby,并且在读取密钥文件时使用了open函数,那么可能会存在命令注入的风险。这是因为Ruby的open函数在处理某些输入时,可能会将输入作为命令执行,尤其是在输入中包含管道符 | 或其他特殊字符时。
令牌的安全故事圆满收官!要是没有“房卡”想进去耍“刘忙”,就翻进去,是违法!
练习JWT安全:https://oz-web.com/jwt/
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)