Authentication Bypasses

审计

  • 创建AccountVerificationHelper实例,用于处理账户验证逻辑

parseSecQuestions函数的作用是从请求体中遍历参数名,找到包含secQuestion的参数,将其值存入Map中并返回

这里直接把AccountVerificationHelper整个分析一下


/** Created by appsec on 7/18/17. */
public class AccountVerificationHelper {// simulating database storage of verification credentialsprivate static final Integer verifyUserId = 1223445;private static final Map<String, String> userSecQuestions = new HashMap<>();static {userSecQuestions.put("secQuestion0", "Dr. Watson");userSecQuestions.put("secQuestion1", "Baker Street");}private static final Map<Integer, Map> secQuestionStore = new HashMap<>();static {secQuestionStore.put(verifyUserId, userSecQuestions);}// end 'data store set up'// this is to aid feedback in the attack process and is not intended to be part of the// 'vulnerable' codepublic boolean didUserLikelylCheat(HashMap<String, String> submittedAnswers) {boolean likely = false;if (submittedAnswers.size() == secQuestionStore.get(verifyUserId).size()) {likely = true;}if ((submittedAnswers.containsKey("secQuestion0")&& submittedAnswers.get("secQuestion0").equals(secQuestionStore.get(verifyUserId).get("secQuestion0")))&& (submittedAnswers.containsKey("secQuestion1")&& submittedAnswers.get("secQuestion1").equals(secQuestionStore.get(verifyUserId).get("secQuestion1")))) {likely = true;} else {likely = false;}return likely;}// end of cheating check ... the method below is the one of real interest. Can you find the flaw?public boolean verifyAccount(Integer userId, HashMap<String, String> submittedQuestions) {// short circuit if no questions are submittedif (submittedQuestions.entrySet().size() != secQuestionStore.get(verifyUserId).size()) {return false;}if (submittedQuestions.containsKey("secQuestion0")&& !submittedQuestions.get("secQuestion0").equals(secQuestionStore.get(verifyUserId).get("secQuestion0"))) {return false;}if (submittedQuestions.containsKey("secQuestion1")&& !submittedQuestions.get("secQuestion1").equals(secQuestionStore.get(verifyUserId).get("secQuestion1"))) {return false;}// elsereturn true;}
}

这里直接定义了用户ID和用户的问题关联并将它们存入了secQuestionStore这个变量

  • didUserLikelylCheat函数通过

(用户提交的参数数量)=(参数数量) (此条可能会被后面覆盖,但是由于后面参数不存在,检验跳过,所以这里是有用的

(用户提交参数名包含所需要参数名)and(对应参数名答案正确)

判断用户是否作弊

  • verifyAccount函数和didUserLikelylCheat函数很像,也是通过检查用户参数数量和对应参数答案是否匹配(不同的是这里用的不等于的比较,为后面的绕过留下了余地)

didUserLikelylCheat和verifyAccount两个函数判定过了就能绕过了

这里的核心原理是如果secQuestion0不存在就会跳过检验,所以其实如果包含secQuestion参数名的数量正确之后,剩下的检验就会全部跳过,所以只要构造两个包含secQuestion的参数就行了

靶场

Insecure Login

靶场

这里就是简单的拦截请求再填入

审计

login部分,主要是js


function submit_secret_credentials() {var xhttp = new XMLHttpRequest();xhttp['open']('POST', 'InsecureLogin/login', true);//sending the request is obfuscated, to descourage js readingvar _0xb7f9=["\x43\x61\x70\x74\x61\x69\x6E\x4A\x61\x63\x6B","\x42\x6C\x61\x63\x6B\x50\x65\x61\x72\x6C","\x73\x74\x72\x69\x6E\x67\x69\x66\x79","\x73\x65\x6E\x64"];xhttp[_0xb7f9[3]](JSON[_0xb7f9[2]]({username:_0xb7f9[0],password:_0xb7f9[1]}))
}--->
function submit_secret_credentials() {var xhttp = new XMLHttpRequest();xhttp.open('POST', 'InsecureLogin/login', true);// 发送混淆后的请求xhttp.send(JSON.stringify({username: "CaptianJack", password: "BlackPearl"}))
}

使用了十六进制编码的字符串数组 _0xb7f9,但请求包中仍然是明文

JWT

理论部分:

技术本质

JWT是一种基于RFC 7519标准的轻量级安全凭证格式,采用紧凑的URL-safe字符串形式传输经过数字签名JSON数据。其核心价值在于通过密码学签名机制实现了信息自包含(self-contained)和防篡改(tamper-proof)的特性。

安全机制
  • 数字签名保障:支持两种签名方式
    • 对称加密:使用HMAC算法(HS256/HS384/HS512)+ 服务端密钥
    • 非对称加密:使用RSA/ECDSA算法(RS256/ES256等)+ 公私钥体系
基本结构

Header.Payload.Signature

  • Header (头部):包含令牌类型和签名算法

{"alg": "HS256","typ": "JWT"
}
  • Payload(负载):包含声明(claims),有三种类型:
    • Registered claims:预定义声明如 iss(签发者), exp(过期时间), sub(主题)等
    • Public claims:公开定义的声明
    • Private claims:自定义声明
{"sub": "1234567890","name": "John Doe","admin": true
}
  • Signature (签名):用于验证消息完整性,创建方式:
HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)
令牌
  • 两种令牌类型
    • 访问令牌(Access):用于向服务器发起API请求,有效期较短
    • 刷新令牌(Refresh):用于获取新的访问令牌,有效期较长

获取jwt的流程

在客户端和服务端之间

JWT Claim Misuse

JWT Claim Misuse(JWT声明滥用)指的是对JSON Web Token中的声明(payload)部分进行不当或未经授权的操纵行为。

  • 未经授权的声明添加

攻击者尝试添加未授权的声明以获取不应有的权限

例如:普通用户添加管理员权限声明

  • 声明篡改

修改现有声明的值来操纵身份或权限

例如:修改"user_id"来冒充其他用户

  • 过度声明

添加大量不必要或虚假声明

目的可能是增大令牌体积影响系统性能

  • 过期时间篡改

修改"exp"声明延长令牌有效期

使攻击者能够维持超出预期的访问权限

  • 重放攻击

重复使用已过期的有效JWT

用于冒充原始用户或利用有时限的功能

  • 关键声明操纵

如操纵"kid"(密钥ID)声明

可能使服务器使用错误的密钥进行验证

JKU相关漏洞

JKU是JWT规范的一部分,允许通过URL动态获取验证签名所需的公钥。

  • 漏洞原理
    • 当JWT使用弱密钥签名,且JKU指向外部公钥时
    • 攻击者可制作恶意JWT并控制验证公钥的来源
  • 攻击步骤
    • 识别JKU端点
    • 制作恶意JWT
    • 使用自有私钥签名
    • 发送给服务器
    • 服务器从攻击者控制的URL获取公钥验证
    • 攻击成功
  • 防御措施
    • 白名单机制
    • 静态密钥
    • 增强验证
    • 监控审计
    • 安全测试

实践部分

jwt_decode
靶场

简单的解密之后提取用户名就行了

审计

判断user值是否匹配

jwt_vote
审计

先找到前端触发vote函数

getvoting函数

  • 通过$.get("JWT/votings")从服务端获取投票项列表
  • 使用字符串替换方式构建HTML模板
  • votesList是前端投票面板的id值

vote函数

  • 验证用户是否为"Guest"
  • 通过$.ajax POST请求发送到JWT/votings/{title}端点

(Claims)设置

  • setIssuedAt设置签发时间(10天后),设置admin和user

jwt签名

  • 设置声明(claims)
  • 使用密钥签名, 对JWT_PASSWORD进行HS512对称加密

其中:JWT_PASSWORD = TextCodec.BASE64.encode("victory");//注意密钥

cookie设置

  • 将jwt存入cookie

生成claims,jwt,cookie,并返回200 OK

若validUsers.contains(user)判断没过,则清空Cookie值,并返回401未授权

从cookie中获取access_token,如果存在

try {Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD)  // 使用密钥验证签名.parse(accessToken);         // 解析 JWTClaims claims = (Claims) jwt.getBody();  // 获取 payload(声明)

核心

boolean isAdmin = Boolean.valueOf(String.valueOf(claims.get("admin")));
if (!isAdmin) {return failed(this).feedback("jwt-only-admin").build();} 
else {votes.values().forEach(vote -> vote.reset());return success(this).build();
}

从JWT的payload中获取admin字段,如果为true则成功

靶场

在删除时抓包

对token解码

把admin改成true,再输入密钥为上文提到的victory,再放回去

成功

JWT 破解
审计

成功条件是WEBGOAT_USER.equalsIgnoreCase(user)

但是注意到这里的有效时间只有一分钟,要不就快速的,要不就要最后把时间戳换一下

靶场

用脚本爆破密钥

我这里是business

重新替换之后编码输入就行

refreshing token
审计

  • 检查用户是否是Tom
  • 如果是Tom,额外检查JWT头部的算法是否为none
靶场

让我们让Tom付钱,把token改成tom的

题目给了一个文件,解码发现是Tom的token

拦截一个请求,发现里面有jerry的token

第一反应就是替换,但是肯定没这么简单

果然,认证过期了。

改时间戳,欸嘿,成功了!

JWTHeaderJKUEndpoint
审计

重点在这里生成了一个JWT

Jwt jwt =Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() {@Overridepublic byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {final String kid = (String) header.get("kid");try (var connection = dataSource.getConnection()) {ResultSet rs =connection.createStatement().executeQuery("SELECT key FROM jwt_keys WHERE id = '" + kid + "'");while (rs.next()) {return TextCodec.BASE64.decode(rs.getString(1));}} catch (SQLException e) {errorMessage[0] = e.getMessage();}return null;}}).parseClaimsJws(token);
  • @Override public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims):重写方法,根据JWT头部和声明返回签名密钥的字节数组
  • kid从jwt头获得id字段
  • 执行SQL查询,根据kidjwt_keys表获取对应的密钥
  • nTextCodec.BASE64.decode(rs.getString(1));返回base64解码后的密钥字节数组
  • .parseClaimsJws(token);使用配置的解析器解析并验证JWT
靶场

这里是Jerry想删掉Tom的账户,那可能就要构造一个Tom的token

拦截一个请求把它里面的token解码之后得到

讲密钥设为1并在kid中构造联合注入

在webwolf里搞了很久,发现自己拦截没开,哈哈哈

Password reset

Question

审计

就是获取用户名和答案,再根据用户名对密码进行比对

可以对密码进行爆破

SecurityQuestion

前面部分设置了一些问题和答案

  • answer.isPresent():检查是否存在有效答案

这里设置了一个triedQuestion类

就是简单的计数和判断

ResetLink

  • String resetLink = UUID.randomUUID().toString();:使用UUID生成随机重置令牌
  • 将令牌存储在全局集合中
  • 获取主机头信息
  • 判断 host 当中是否存在 WebWlof 服务对应的端口与 Host

抓包改一下host

在wobwolf中找到对应请并访问

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/914231.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/914231.shtml
英文地址,请注明出处:http://en.pswp.cn/news/914231.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

火山引擎:字节跳动的技术赋能初解

火山引擎是字节跳动旗下的企业级智能技术服务平台&#xff0c;于2020年6月正式上线。它通过开放字节跳动在大数据、人工智能、视频云等领域的核心技术&#xff0c;助力企业实现数字化转型与业务增长。火山引擎界面核心能力与技术亮点:1.全栈云服务公有云与混合云&#xff1a;提…

VUE 带有搜索功能的穿梭框(简单demo)

一、template/ 组件代码<el-dialog :title"title" :visible.sync"dialogVisible" width"60%" :before-close"handleClose" class"custom-dialog-line" ><div style"text-align: center ; width: 100%; height…

写个扫雷小游戏

1.test.c&#xff08;测试源文件&#xff09;2.game.c&#xff08;游戏源文件&#xff09;3.头文件

【Linux庖丁解牛】— system V共享内存!

1. 什么是system VSystem V IPC&#xff08;Interprocess Communication&#xff0c;进程间通信&#xff09;是Unix系统中一种经典的进程间通信机制&#xff0c;由AT&T在System V.2版本中引入&#xff0c;并广泛应用于Linux等现代操作系统中。它通过三种核心机制实现进程间…

从输入到路径:AI赋能的地图语义解析与可视化探索之旅(2025空间智能全景)

​​摘要​​在空间智能爆发的2025年&#xff0c;地图系统已从静态导航工具进化为​​实时决策中枢​​。本文深度解析AI如何重构地理信息处理全链路&#xff1a;通过​​多模态语义理解​​&#xff08;文本/语音/图像→空间意图&#xff09;、​​动态路网建模​​&#xff0…

安全运维新趋势:AI 驱动的自动化威胁检测

在数字化浪潮中&#xff0c;网络攻击正从 “单点突破” 进化为 “链状打击”&#xff1a;2024 年某金融机构遭遇供应链攻击&#xff0c;恶意代码通过运维通道潜伏 3 个月&#xff0c;传统规则引擎因未识别 “正常运维指令中的异常参数”&#xff0c;导致数据泄露损失过亿。这背…

数据库复合索引设计:为什么等值查询列应该放在范围查询列前面?

前言作为后端开发工程师&#xff0c;我们经常会遇到数据库查询性能问题。在一次系统优化中&#xff0c;我发现一个简单的索引顺序调整竟然让查询速度提升了10倍&#xff01;这让我意识到复合索引列顺序的重要性。今天&#xff0c;我就来分享一下这个经验&#xff0c;希望能帮助…

【PMP备考】每日一练 - 2

1、一个建筑项目的项目经理发现&#xff0c;他管理的项目所在地附近正在新建一条新的水管线。公司政策要求&#xff0c;在他的团队继续完成这个项目之前&#xff0c;必须先填写一系列有关城市环境变化的表格。这是那两种情况的例子&#xff1f;&#xff08;选2个选项&#xff0…

【三】ObservableCollection 与 List 的区别

文章目录前言一、核心概念简介ObservableCollectionList二、关键差异对比三、典型使用场景ObservableCollection 的适用场景List 的适用场景四、在Community Toolkit MVVM中使用ObservableCollection<Data>和List<Data>场景1&#xff1a;动态列表&#xff08;Obser…

网安-SSRF-pikachu

目录 SSRF:Server-Side Request Forgery PHP curl PHP 可能引起SSRF的函数 PHP其他函数 CURL其他协议 SSRF利用&#xff1a; SSRF的发现 工具 SSRF的防御 pikachu-SSRF 一&#xff1a;curl 1.访问连接&#xff1a; 2.读取本地文件 3.dict协议扫描主机端口 二&…

在Centos系统上如何有效删除文件和目录的指令汇总

CentOS系统是一款开源的类Unix操作系统&#xff0c;极其亲和程序员和技术人员。这个系统最大的优势就是其高度自由化的特性&#xff0c;世界各地的开发者可以依照实际需求去修改和运行。在这个操作系统中&#xff0c;如果你想删除文件和目录&#xff0c;你可以使用各式各样的命…

Spring(四) 关于AOP的源码解析与思考

Spring&#xff08;四&#xff09; 关于AOP的源码解析与思考 每种语言都有其独特的机制和特点&#xff0c;那么说到Java你可能会首先想到反射&#xff0c;反射是Java语言提供的一种能够在程序运行时动态操作类或对象的能力&#xff0c;比如获取某个对象的类定义、获取类声明的属…

Android 15 Settings 搜索框:引入关键字过滤功能

在日常使用 Android 手机时,我们经常会用到“设置”应用中的搜索功能来快速定位所需选项。然而,有时搜索结果可能会包含一些我们不希望看到或者过于宽泛的条目。 本文将深入探讨这一变化,通过分析 SearchResultsAdapter.java 文件中的代码修改,揭示 Android 如何实现对特定…

Python-魔术方法-创建、初始化与销毁-hash-bool-可视化-运算符重载-容器和大小-可调用对象-上下文管理-反射-描述器-二分-学习笔记

序 欠4前年的一份笔记 &#xff0c;献给今后的自己。 魔术方法 特殊属性查看属性如果dir&#xff08;lobji&#xff09;参数obj包含方法 __dir__()&#xff0c;该方法将被调用。如果参数obj不包含__dir__()&#xff0c; 该方法将最大限度地收集参数信息。 dir()对于不同类型的对…

redis的一些疑问

spring集成redisCacheEvict(value "commonCache", key "#uniqueid_userInfo")什么时候会执行缓存移除呢&#xff1f;如果方法执行异常是否移除&#xff1f;如果缓存不存在还会移除么&#xff1f;这个移除会在redis的执行历史命令中监控到么&#xff1f;.…

3.检查函数 if (!CheckStart()) return 的妙用 C#例子

在桌面/WPF 开发中&#xff0c;我们经常需要在按钮事件里先判断“能不能做”&#xff0c;再决定“怎么做”。如果校验不过&#xff0c;就直接返回&#xff1b;校验通过&#xff0c;才继续执行业务逻辑。 今天分享一个极简写法&#xff1a;if (!CheckStart()) return;&#xff0…

炎热工厂救援:算法打造安全壁垒

高温天气下智慧工厂&#xff1a;算法赋能&#xff0c;安全救援无忧背景&#xff1a;极端高温下工厂的严峻挑战近年来&#xff0c;极端高温天气频发&#xff0c;部分地区气温接近甚至超过50℃。在这样酷热的环境中&#xff0c;工厂面临着诸多严峻问题。一方面&#xff0c;高温容…

pgsql模板是什么?

查找所有的数据库 select datname from pg_database运行该命令后&#xff0c;我们会发现其中出现了一些其它的数据库接下来&#xff0c;我们分析 template0 和 template1 的作用。template1 template1 是 PostgreSQL 默认用于创建新数据库的模板。当执行 CREATE DATABASE new_d…

LLM 不知道答案,但是知道去调用工具获取答案?

思考&#xff1a; LLM 自己“不知道”某个事实性问题的答案&#xff0c;但仍然能“知道”去调用工具获取正确答案&#xff0c;这听起来确实有点像个悖论该内容触及了大型语言模型&#xff08;LLM&#xff09;的核心局限性以及&#xff08;Agents&#xff09;的智能所在。实际上…

2025年7月11日学习笔记一周归纳——模式识别与机器学习

2025年7月11日学习笔记&一周归纳——模式识别与机器学习一.一周工作二.我的一些笔记汇总三.发现的一些新的学习资料和爱用好物1.百度网盘AI笔记&#xff1a;2.b站资料&#xff1a;3.听说的一些好书&#xff1a;一.一周工作 本周学习了清华大学张学工汪小我老师的模式识别与…