[HFCTF2020]EasyLogin

文章目錄

  • TRY
  • WP
  • 總結

TRY

注冊admin報錯username wrong。
隨便注冊一個用戶點擊GetFlag,permission deny。
猜測可能是需要admin權限。

看cookie發現有:
sses:aok:eyJ1c2VybmFtZSI6ImEiLCJfZXhwaXJlIjoxNzU2NDU1NjczMTAxLCJfbWF4QWdlIjo4NjQwMDAwMH0=
sses:aok.sig:cPcLr5TdZHkihzRoMmGXTwP_0wM

sses:aok可以base64解碼:{“username”:“a”,“_expire”:1756455673101,“_maxAge”:86400000}
第二個參數表示失效時間,第三個參數表示最大存活時長。sses:aok.sig應該就是簽名。

這種 sses:aok + sses:aok.sig 的組合,是 **“自定義令牌 + 簽名驗證” 的輕量化認證方案 **,核心邏輯是 “用 Base64 編碼攜帶身份與有效期信息,用獨立簽名確保完整性與合法性”。

簽名的編碼方式不清楚,AI說是對Hash編碼的二進制數進行Base64url編碼。

解題方向就兩個,第一,登錄admin賬戶;第二:爆破簽名,偽造cookie認證。

嘗試約束攻擊登錄admin賬戶,不可行。

WP

漏掉了一些線索。
從瀏覽器控制臺中的調試中能看到前端代碼
在這里插入圖片描述
app.js中留下線索:
/**

  • 或許該用 koa-static 來處理靜態文件
  • 路徑該怎么配置?不管了先填個根目錄XD
    */
    在 Koa.js(Node.js 的一個 Web 框架)中,koa-static 是一個常用的中間件(middleware),用于處理靜態文件的訪問請求。
    簡單來說,它能讓服務器直接返回指定目錄中的靜態資源(如 HTML、CSS、JavaScript、圖片、字體等),而無需開發者編寫額外代碼來讀取和返回這些文件。具體功能:

koa-static 的主要功能是:
指定靜態文件目錄:告訴 Koa 服務器 “某個目錄下的文件是靜態資源,可以直接對外提供訪問”。
自動映射請求路徑:當客戶端請求某個路徑時(如 /css/style.css),koa-static 會自動去你指定的靜態目錄中查找對應的文件(如 ./public/css/style.css),并返回給客戶端。
處理 MIME 類型:自動識別文件類型(如 .html、.js、.png),并在響應頭中添加正確的 Content-Type,確保瀏覽器能正確解析文件。

作用就像是Golang中的HTTP.FileServer。根據線索提示將根目錄指定為靜態文件目錄,那源碼就成了可訪問文件了。
于是直接訪問/app.js得到Web 應用程序入口文件:

const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const session = require('koa-session');
const static = require('koa-static');
const views = require('koa-views');const crypto = require('crypto');
const { resolve } = require('path');const rest = require('./rest');
const controller = require('./controller');const PORT = 3000;
const app = new Koa();app.keys = [crypto.randomBytes(16).toString('hex')];
global.secrets = [];app.use(static(resolve(__dirname, '.')));app.use(views(resolve(__dirname, './views'), {extension: 'pug'
}));app.use(session({key: 'sses:aok', maxAge: 86400000}, app));// parse request body:
app.use(bodyParser());// prepare restful service
app.use(rest.restify());// add controllers:
app.use(controller()); //根據路由分發請求到對應業務邏輯處理app.listen(PORT);
console.log(`app started at port ${PORT}...`);

具體業務邏輯處理在controllers文件夾中。但是并不知道文件名。
根據wp,源碼文件是controllers/api.js:

const crypto = require('crypto');
const fs = require('fs')
const jwt = require('jsonwebtoken')const APIError = require('../rest').APIError;module.exports = {'POST /api/register': async (ctx, next) => {const {username, password} = ctx.request.body;if(!username || username === 'admin'){throw new APIError('register error', 'wrong username');}if(global.secrets.length > 100000) {global.secrets = [];}const secret = crypto.randomBytes(18).toString('hex');const secretid = global.secrets.length;global.secrets.push(secret)const token = jwt.sign({secretid, username, password}, secret, {algorithm: 'HS256'});ctx.rest({token: token});await next();},'POST /api/login': async (ctx, next) => {const {username, password} = ctx.request.body;if(!username || !password) {throw new APIError('login error', 'username or password is necessary');}const token = ctx.header.authorization || ctx.request.body.authorization || ctx.request.query.authorization;const sid = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString()).secretid;console.log(sid)if(sid === undefined || sid === null || !(sid < global.secrets.length && sid >= 0)) {throw new APIError('login error', 'no such secret id');}const secret = global.secrets[sid];const user = jwt.verify(token, secret, {algorithm: 'HS256'});const status = username === user.username && password === user.password;if(status) {ctx.session.username = username;}ctx.rest({status});await next();},'GET /api/flag': async (ctx, next) => {if(ctx.session.username !== 'admin'){throw new APIError('permission error', 'permission denied');}const flag = fs.readFileSync('/flag').toString();ctx.rest({flag});await next();},'GET /api/logout': async (ctx, next) => {ctx.session.username = null;ctx.rest({status: true})await next();}
};

代碼中有幾個重要的地方:

  1. 注冊的時候會生成global [secretid=>secret],secretid存儲在jwt的payload中。
  2. 登陸的時候根據secretid取出secret進行簽名驗證。
    const sid = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString()).secretid; 在取出secretid時沒有驗證簽名,我們可以偽造。
  3. if(sid === undefined || sid === null || !(sid < global.secrets.length && sid >= 0)) { throw new APIError('login error', 'no such secret id'); }對secretid進行了過濾。
  4. const user = jwt.verify(token, secret, {algorithm: 'HS256'});在驗證token的時候指定了簽名算法’HS256’,似乎無法通過簽名算法置none繞過。

secretid可偽造 + secretid過濾不徹底 + Node.js 的jsonwebtoken庫低版本存在缺陷:即使指定了驗證簽名時的算法,如果secret為空,會默認用none來驗證

以上三個條件就導致了本題中的漏洞:首先我們偽造secretid為[]即空數組,此時能通過過濾,并且global.secrets[secretid]得到的應該是undefined或者是null,我也沒有驗證過。驗證簽名時就會用none算法,我們只需要構造簽名算法為none的token就能通過驗證。

構造payload:
在這里插入圖片描述
在這里插入圖片描述
成功登錄。直接就能獲取flag了。

總結

這道題首先從前端JS代碼中獲得線索,koa-static處理靜態文件時將工作區根目錄指定為靜態文件目錄,這就導致了工作區所有源碼文件泄露。但是api.js文件名來的就有些奇怪,或許這是Node.js項目中的常規命名?得到源碼后能看到使用的是JWT認證,由于多個條件組合導致了JWT偽造漏洞。漏洞修改建議:對于客戶端傳輸的token,應該遵守 在驗證其正確性之后才能從中獲得任何信息 的規范,避免用戶偽造。用白名單限定secretid的數據類型而不是黑名單。升級jwt模塊版本。另外有一個注意的點是,瀏覽器控制臺中的網絡監視器并不能捕獲所有發送到服務端的請求,例如這道題,由此我漏掉了重要線索,所以下次還是要用bp。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/94768.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/94768.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/94768.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java接口和抽象類的區別,并舉例說明

Java接口和抽象類是面向對象編程中實現抽象的兩種機制&#xff0c;它們在語法、設計目的和使用場景上有顯著區別&#xff1a;一、核心區別?定義方式?抽象類&#xff1a;使用abstract class聲明&#xff0c;可包含抽象方法和具體方法45。接口&#xff1a;使用interface聲明&am…

docker-相關筆記

1: 導入鏡像 docker load -i myimage.tar# 導出鏡像 docker save myimage:latest > myimage.tar # 導入鏡像 docker load -i myimage.tardocker load -i <文件> 功能&#xff1a;用于導入通過 docker save 命令導出的鏡像歸檔文件&#xff08;通常是 .tar 格式&#…

自然語言提取PDF表格數據

自然語言提取PDF表格數據PDF v8.2的文檔解決方案與OpenAI實現了無縫的AI集成&#xff0c;可將非結構化PDF轉換為可用數據。MESCIUS 推出的 PDF 文檔解決方案 (DsPdf) 是一款軟件開發工具包&#xff0c;它提供了 .NET Core 庫和一個 JavaScript PDF 查看器&#xff0c;用于處理和…

飛牛Nas每天定時加密數據備份到網盤,基于restic的Backrest筆記分享

1. 前言 受前輩“RAID≠備份”的經驗&#xff0c;也考慮到硬盤故障時 RAID 重建步驟繁瑣&#xff0c;我干脆放棄陣列&#xff0c;直接單盤運行。 重要數據則加密后上傳至大廠云盤&#xff1a;一方面文件對外不可讀&#xff0c;規避掃描和諧&#xff1b;另一方面依靠大廠的數據安…

C#連接SQL-Server數據庫超詳細講解以及防SQL注入

C#連接SQL Server數據庫完整指南&#xff0c;整合了ADO.NET原生連接與Entity Framework Core兩種實現方式。這篇文件詳細介紹C#代碼連接數據庫的通用操作數據庫鏈接功能 數據庫的增刪改查操作1 配置全局數據庫鏈接字符串 App.config2 獲取數據庫鏈接字符串先在App.config配置連…

Pico2?ICE FPGA 開發板:從開箱到跑通示例的全歷程

FPGA 和 MCU 結合的開發板不多&#xff0c;而 Pico2?ICE 則把小巧、靈活和易上手完美結合。搭載 RP2350 雙核 RISC-V MCU Lattice iCE40UP5K FPGA&#xff0c;配合官方 SDK&#xff0c;你可以一步步跑通各種示例&#xff0c;從 LED 到 VGA&#xff0c;再到 MCU 與 FPGA 協作應…

Java圖形圖像處理【Swing圖像拖拽】【五】

Java圖形圖像處理【Swing圖像拖拽】 18.3.3 Swing圖像對象拖拽功能 18.3.3 Swing圖像對象拖拽功能 上文討論的是java.awt.dnd包中提供的拖拽API接口&#xff0c;也可稱之為AWT組件的拖拽功能。下面我們要討論的是Swing框架的拖拽功能&#xff1a;Swing組件也提供了對拖拽功能的…

狀態模式與幾個經典的C++例子

1. 狀態模式定義與核心思想 狀態模式解決的是當控制一個對象狀態轉換的條件表達式過于復雜時的情況。通過將狀態的判斷邏輯轉移到表示不同狀態的一系列類中,可以把復雜的判斷邏輯簡化。 核心思想: 狀態抽象:將對象的每個狀態都封裝到一個獨立的類中。 委托代替條件判斷:…

SyncBackPro 備份及同步軟件中的腳本功能簡介

腳本提供了一種靈活而簡單的方法來自動執行任務和擴展應用程序的功能。腳本是一個小程序&#xff0c;能夠自定義和控制備份作業。例如&#xff0c;用戶可以編寫腳本來復制、重命名或刪除特定文件、自定義用戶界面或更改配置文件設置。SyncBackPro 的腳本功能類似于 Microsoft O…

部署2.516.2版本的jenkins,同時適配jdk8

&#x1f4cc; 前言 在企業級開發中&#xff0c;我們常常面臨 新老項目并存 的復雜局面&#xff1a; 老項目基于 JDK 8 開發&#xff0c;短期內無法升級&#xff1b; 新項目采用 JDK 17&#xff08;LTS&#xff09;甚至更高版本&#xff1b; 而作為 CI/CD 核心的 Jenkins&#…

Autodesk Maya 2026.2 全新功能詳解:MotionMaker AI 動畫、LookdevX 材質增強、USD 工作流優化

軟件介紹 Autodesk Maya 2026.2是一款專業的3D計算機圖形軟件&#xff0c;它為數字內容創作者提供了豐富的工具集&#xff0c;以實現高質量的建模、動畫、模擬和渲染。該版本帶來了多項性能優化和工作流程改進&#xff0c;特別是針對生成式動畫工具MotionMaker進行了重大升級&…

STM32之DMA詳解

一、DMA 1. DMA的引入 在嵌入式系統或計算機系統中&#xff0c;數據的傳輸和處理是非常重要的操作。以下通過一個簡單的示例來展示傳統數據操作方式與 DMA 引入的必要性&#xff1a; int a 10; int b 20;a b;上述代碼包含了變量定義、初始化以及變量數據賦值操作。在傳統…

鏈表有環找入口節點原理

環形鏈表入口檢測算法數學解釋 數學原理假設定義: 鏈表頭到環入口的距離為 a環入口到相遇點的距離為 b相遇點到環入口的距離為 c環的長度為 b c第一次相遇時: 慢指針走了 s a b 步快指針走了 f a b n(b c) 步&#xff0c;其中 n 是快指針在環內轉的圈數由于快指針速度是…

Java 基本類型與包裝類詳解

Java 基本類型與包裝類詳解 在 Java 開發中&#xff0c;理解 基本數據類型與包裝類、字符串處理、以及高精度計算類是非常核心的能力。這不僅關系到程序性能&#xff0c;還影響代碼的正確性和可維護性。本文將詳細講解這些知識點&#xff0c;并給出常見的使用技巧和陷阱。 1?…

CRYPT32!CryptMsgUpdate函數分析之CRYPT32!PkiAsn1Decode函數的作用是得到pci

第一部分&#xff1a; CryptMsgUpdate( #endifIN HCRYPTMSG hCryptMsg,IN const BYTE *pbData,IN DWORD cbData,IN BOOL fFinal) {ContentInfo *pci NULL;if ((PHASE_FIRST_FINAL pcmi->dwPhase) &&(0 pcmi->dwMsgType)) {if (0 …

華為交換機S5700設置acl

1.、配置ACL1.1、定義允許的ACL規則[sw1]acl number 3001[sw1-acl-adv-3001]rule permit ip source 192.168.20.0 0.0.0.255 destination 192.168.40.1 0[sw1-acl-adv-3001]rule permit ip source 192.168.30.0 0.0.0.255 destination 192.168.40.1 01.2、定義禁止的ACL規則[sw…

在使用spring ai進行llm處理的rag的時候,選擇milvus還是neo4j呢?

在使用spring ai進行llm處理的rag的時候&#xff0c;選擇milvus還是neo4j呢&#xff1f; 對于Spring AI中的RAG&#xff08;Retrieval-Augmented Generation&#xff09;應用&#xff0c;選擇Milvus還是Neo4j&#xff0c;主要取決于你的數據類型以及RAG流程中對數據檢索的側重點…

計算機視覺與深度學習 | 視覺里程計技術全景解析:從原理到前沿應用

視覺里程計技術全景解析:從原理到前沿應用 一、定義與核心價值 二、技術原理與分類體系 2.1 基本工作流程 2.2 主流技術路線對比 2.3 算法范式演進 三、典型應用場景 3.1 地面移動機器人 3.2 自動駕駛領域 3.3 深空探測 3.4 增強現實 四、核心技術挑戰與突破路徑 4.1 主要技術…

Wireshark和USRP捕獲同一信號波形差異原因

一、波形差異 在前面的博客中我對比繪制了同一信號的Wireshark和USRP兩種波形&#xff1a; 可以看出波形差別還是挺大的&#xff0c;尤其是在信號分布間隔方面。 我猜想Wireshark的一條數據包在物理上并不是連續的&#xff1a; 而是分組發送&#xff0c;但在Wireshark中合并在…

Python-GEE遙感云大數據分析、可視化與Satellite Embedding應用

隨著航空、航天、近地空間遙感平臺的持續發展&#xff0c;遙感技術近年來取得顯著進步。遙感數據的空間、時間、光譜分辨率及數據量均大幅提升&#xff0c;呈現出大數據特征。2025年7月&#xff0c;Google DeepMind發布了革命性的AlphaEarth Foundations模型及Satellite Embedd…