身份認證缺陷

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;一.一周工作 本周學習了清華大學張學工汪小我老師的模式識別與…