2024年JWT渗透姿势一篇通,腾讯移动客户端开发面试

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

“name”: “John Doe”,
“iat”: 1516239022
}


其中sub表示主题,name表示名称,iat表示JWT的签发时间


##### Signature


Signature是使用指定算法对Header和Payload进行签名生成的,用于验证JWT的完整性和真实性,Signature的生成方式通常是将Header和Payload连接起来然后使用指定算法对其进行签名,最终将签名结果与Header和Payload一起组成JWT,Signature的生成和验证需要使用相同的密钥,下面是一个示例Signature



HMACSHA256(base64UrlEncode(header) + “.” +base64UrlEncode(payload),secret)


其中HMACSHA256是使用HMAC SHA256算法进行签名,header和payload是经过Base64编码的Header和Payload,secret是用于签名和验证的密钥,最终将Header、Payload和Signature连接起来用句点(.)分隔就形成了一个完整的JWT,下面是一个示例JWT,其中第一部分是Header,第二部分是Payload,第三部分是Signature,注意JWT 中的每一部分都是经过Base64编码的,但并不是加密的,因此JWT中的信息是可以被解密的



eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c


##### 在线平台


下面是一个JWT在线构造和解构的平台:  
 https://jwt.io/


![](https://img-blog.csdnimg.cn/img_convert/76b407f8c8af9d3f89b63f2b2c5ccc92.png)


#### 工作原理


##### JWT工作原理


JWT的工作流程如下:


* 用户在客户端登录并将登录信息发送给服务器
* 服务器使用私钥对用户信息进行加密生成JWT并将其发送给客户端
* 客户端将JWT存储在本地,每次向服务器发送请求时携带JWT进行认证
* 服务器使用公钥对JWT进行解密和验证,根据JWT中的信息进行身份验证和授权
* 服务器处理请求并返回响应,客户端根据响应进行相应的操作


##### JKU工作原理


Step 1:用户携带JWS(带有签名的JWT)访问应用


![](https://img-blog.csdnimg.cn/img_convert/3c36f57013fbe8a98b7c9531a691df5a.png)


Step 2:应用程序解码JWS得到JKU字段


![](https://img-blog.csdnimg.cn/img_convert/77d305eb7187cecce52f1ca86a42c374.png)


Step 3:应用根据JKU访问返回JWK的服务器


![](https://img-blog.csdnimg.cn/img_convert/041cd10e5bbe74d3f1cc8f44285d485b.png)


Step 4:应用程序得到JWK


![](https://img-blog.csdnimg.cn/img_convert/d56a1134b1c397d38b0f81ef8f10b0f9.png)


Step 5:使用JWK验证用户JWS


![](https://img-blog.csdnimg.cn/img_convert/799177b9633377bb9d92f6671d0887a3.png)


Step 6:验证通过则正常响应


![](https://img-blog.csdnimg.cn/img_convert/24848253d6b480ce4b5032c569ec9ba5.png)


#### 漏洞攻防


##### 签名未校验


###### 验证过程


JWT(JSON Web Token)的签名验证过程主要包括以下几个步骤:


* 分离解构:JWT的Header和Payload是通过句点(.)分隔的,因此需要将JWT按照句点分隔符进行分离
* 验证签名:通过使用指定算法对Header和Payload进行签名生成签名结果,然后将签名结果与JWT中的签名部分进行比较,如果两者相同则说明JWT的签名是有效的,否则说明JWT的签名是无效的
* 验证信息:如果JWT的签名是有效的则需要对Payload中的信息进行验证,例如:可以验证JWT中的过期时间、发行者等信息是否正确,如果验证失败则说明JWT是无效的


下面是一个使用JAVA进行JWT签名验证的示例代码:



import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

public class JWTExample {

private static final String SECRET\_KEY \= "my\_secret\_key";  

public static void main(String\[\] args) {  
    // 构建 JWT  
    String jwtToken \= Jwts.builder()  
            .setSubject("1234567890")  
            .claim("name", "John Doe")  
            .setIssuedAt(new Date())  
            .setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1 hour  
            .signWith(SignatureAlgorithm.HS256, SECRET\_KEY)  
            .compact();  

    // 验证 JWT  
    try {  
        // 分离 Header, Payload 和 Signature  
        String\[\] jwtParts \= jwtToken.split("\\\\.");  
        String header \= jwtParts\[0\];  
        String payload \= jwtParts\[1\];  
        String signature \= jwtParts\[2\];  

        // 验证签名  
        String expectedSignature \= Jwts.parser()  
                .setSigningKey(SECRET\_KEY)  
                .parseClaimsJws(jwtToken)  
                .getSignature();  
        if (!signature.equals(expectedSignature)) {  
            throw new RuntimeException("Invalid JWT signature");  
        }  

        // 验证 Payload 中的信息  
        Claims claims \= Jwts.parser()  
                .setSigningKey(SECRET\_KEY)  
                .parseClaimsJws(jwtToken)  
                .getBody();  
        System.out.println("Valid JWT");  
    } catch (Exception e) {  
        System.out.println("Invalid JWT: " + e.getMessage());  
    }  
}  

}


在上面的示例代码中使用jwt库进行JWT的签名和验证,首先构建了一个JWT,然后将其分离为Header、Payload和Signature三部分,使用parseClaimsJws函数对JWT进行解析和验证,从而获取其中的Payload中的信息并进行验证,最后如果解析和验证成功,则说明JWT是有效的,否则说明JWT是无效的,在实际应用中应该将SECRET\_KEY替换为应用程序的密钥


###### 漏洞案例


JWT库会通常提供一种验证令牌的方法和一种解码令牌的方法,比如:Node.js库jsonwebtoken有verify()和decode(),有时开发人员会混淆这两种方法,只将传入的令牌传递给decode()方法,这意味着应用程序根本不验证签名,而我们下面的使用则是一个基于JWT的机制来处理会话,由于实现缺陷服务器不会验证它收到的任何JWT的签名,如果要解答实验问题,您需要修改会话令牌以访问位于/admin的管理面板然后删除用户carlos,您可以使用以下凭据登录自己的帐户:wiener:peter  
 靶场地址:https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-unverified-signature


![](https://img-blog.csdnimg.cn/img_convert/20355e4272c87d07e4a74ab4f1afc8cd.png)


演示步骤:  
 Step 1:点击上方的"Access the Lab"访问靶场并登录账户


![](https://img-blog.csdnimg.cn/img_convert/49c6f10359a5db5a3b95aaad42f31234.png)


Step 2:进入到Web界面并登录靶场账户



wiener:peter


![](https://img-blog.csdnimg.cn/img_convert/a32c93fe2d3a1e7aed4cb90726899640.png)


![](https://img-blog.csdnimg.cn/img_convert/30fb4b8b7d03db8ab8992338d5db6cd0.png)


登录之后会看到如下一个更新邮箱的界面


![](https://img-blog.csdnimg.cn/img_convert/8da2529ff678e6b1be73b02b9cf43813.png)


Step 3:此时在我们的burpsuite中我们可以看到如下的会话信息


![](https://img-blog.csdnimg.cn/img_convert/a15e902f952b23670940fcc947377df7.png)


此时查询当前用户可以看到会显示当前用户为wiener:


![](https://img-blog.csdnimg.cn/img_convert/6a98e1a516edbfab6ec30c25b763be56.png)


截取上面中间一部分base64编码的部分更改上面的sub为"administrator"



eyJpc3MiOiJwb3J0c3dpZ2dlciIsInN1YiI6IndpZW5lciIsImV4cCI6MTY4Nzc5MDA4M30


![](https://img-blog.csdnimg.cn/img_convert/db4ca7eca8eed48ce7afaeeede335a0c.png)


构造一个sub为"administrator"的载荷并将其进行base64编码处理:



eyJpc3MiOiJwb3J0c3dpZ2dlciIsInN1YiI6ImFkbWluaXN0cmF0b3IiLCJleHAiOjE2ODc3OTAwODN9


![](https://img-blog.csdnimg.cn/img_convert/5dadb68a3eb08211c2bc086158decd0d.png)


替换之后重新发送请求:


![](https://img-blog.csdnimg.cn/img_convert/172f8db34a26cf6383beedf1582a8555.png)


按照题目要求访问/admin路径,发现两个删除用户的调用接口:


![](https://img-blog.csdnimg.cn/img_convert/55194108526f7db6b92b67e89db8a892.png)


请求敏感链接——删除用户carlos



GET /admin/delete?username=carlos HTTP/1.1


![](https://img-blog.csdnimg.cn/img_convert/255c441915f339fc9e46869cd336b061.png)


完成靶场的解答:


![](https://img-blog.csdnimg.cn/img_convert/270f599ca8c96cd54c18b94533acad45.png)


##### 签名用None


###### 场景介绍


在JWT的Header中alg的值用于告诉服务器使用哪种算法对令牌进行签名,从而告诉服务器在验证签名时需要使用哪种算法,目前可以选择HS256,即HMAC和SHA256,JWT同时也支持将算法设定为"None",如果"alg"字段设为"None",则标识不签名
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值