返回顶部

cryptohack wp (CRYPTO ON THE WEB篇)(持续更新)

Token Appreciation

import jwt

jwt_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmbGFnIjoiY3J5cHRve2p3dF9jb250ZW50c19jYW5fYmVfZWFzaWx5X3ZpZXdlZH0iLCJ1c2VyIjoiQ3J5cHRvIE1jSGFjayIsImV4cCI6MjAwNTAzMzQ5M30.shKSmZfgGVvd2OSB2CGezzJ3N6WAULo3w9zCl_T47KQ"

decoded_jwt = jwt.decode(jwt_token, options={"verify_signature": False})

print(decoded_jwt)

JWT Sessions


浏览器用于将JWT发送到服务器的HTTP头名称可能因应用程序的实现方式而异。然而,最常用的名称是“Authorization”。

在大多数情况下,头将采用以下格式:

Authorization: Bearer
其中是JWT令牌本身,而“Bearer”关键字指示该令牌是一个承载令牌,或者说是一种授权任何拥有者的令牌。
所以flag就是:authorization

No Way JOSE


进入一个API交互页面:
根据代码,先试试admin:
当把这一串token传上去,显示:
并没有flag。。。。试着去解码以下他:

JWT由3部分组成:标头(Header)、有效载荷(Payload)和签名(Signature)。在传输的时候,会将JWT的3部分分别进行Base64编码后用.进行连接形成最终传输的字符串:
JWTString = Base64(Header).Base64(Payload).HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
将admin:的值改为true:![(https://img2023.cnblogs.com/blog/2698491/202305/2698491-20230525012835926-62050817.png)]
得到:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiYWRtaW4iOnRydWV9.CxKAPL3ryUMNCisd3UUDFzI8UtMugBH-luvnO8zwxck,但是,这还不行,因为仅修改了有效负载部分,JOSE 标头仍表示算法为HS256. 然而,由于 JWT 只是 Base64url 编码的,我们可以创建我们自己的 JOSE 标头,利用“none”算法绕过。

import base64

JOSE_header = '{"typ":"JWT","alg":"none"}'

JOSE_bytes = JOSE_header.encode('ascii')
base64_bytes = base64.b64encode(JOSE_bytes)
JOSE_header_encoded = base64_bytes.decode('ascii')

print(JOSE_header_encoded)

得到:eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0=,=可以忽略,然后我们得到一个完整的token
eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJ1c2VybmFtZSI6ImFkbWluIiwiYWRtaW4iOnRydWV9.CxKAPL3ryUMNCisd3UUDFzI8UtMugBH-luvnO8zwxck
提交后:

JWT Secrets


最常用的JWT签名算法是HS256和RS256。前者是使用带有SHA256哈希函数的HMAC的对称签名方案。后者是基于RSA的非对称签名方案。

许多网上的指南都建议使用HS256,因为它更为简单。用于签名令牌的密钥与用于验证它的密钥相同。

然而,如果签名密钥泄露,攻击者可以签署任意令牌并伪造其他用户的会话,可能导致Web应用程序的完全妥协。与非对称密钥对的RS256相反,HS256使保护密钥更难,因为必须在验证HS256令牌的所有服务器上都有该密钥(除非建立具有单独的令牌验证服务的更好基础设施,但通常不是这样的情况)。

总之,HS256是一种更简单的签名算法,但它确实有一些安全方面的影响。RS256是一种使用不同密钥进行签名和验证的非对称算法。验证密钥通常是公开的,从而更易于分发和管理。因此,即使签名密钥泄露,验证密钥仍然安全,仍然可以验证令牌的真实性。
挑战说代码包含关于密钥的奇怪注释。那么让我们来看看吧。

我们注意到“SECRET_KEY = ? # TODO: PyJWT readme key, change later”,那么可以假设此代码的开发人员使用 PyJWT 文档中提到的默认密钥,即secret.
因为我们知道密钥是什么,所以我们可以生成自己的令牌以便以管理员身份登录。
使用如下代码生成令牌:

import jwt 

key = "secret"
encoded = jwt.encode({ "username" : "admin" , "admin" : True }, key, algorithm= "HS256" )

print(encoded)

得到:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiYWRtaW4iOnRydWV9.DuSXAPzL1erb7bIPPyenfl22Q23vgKOLkgY2J2ddELk
提交这串token:

RSA or HMAC?


如果允许攻击者指定他们自己的算法,但是没有仔细验证这些算法,就会出现另一个问题。攻击者可以混合和匹配用于签名和验证数据的算法。当其中一个是对称算法,而另一个是非对称算法时,这会造成漂亮的漏洞。

服务器正在运行PyJWT,并进行了一些小的补丁,以启用在PyJWT版本<= 1.5.0存在的漏洞。为了创建恶意签名,您需要对PyJWT库进行补丁。如果您想进行补丁,请查看漏洞修复中添加的行。使用pip show pyjwt查找您计算机上PyJWT库的位置,并进行编辑。对于版本大于2.4.0的PyJWT,代码已更改,因此您需要编辑jwt/utils.py,而不是jwt/algorithms.py。

posted @ 2023-05-25 01:39  Cryglz  阅读(143)  评论(0编辑  收藏  举报
1 2 3 1