CTF解題:[NSSCTF 2022 Spring Recruit]弱類型比較繞過

一、漏洞背景介紹

在 CTF(Capture The Flag)競賽和 Web 安全測試中,PHP 語言的類型比較漏洞是常見的考點。這類漏洞源于 PHP 的弱類型特性,即當使用==進行比較時,PHP 會自動進行類型轉換,從而導致一些不符合預期的比較結果。本文將通過分析一道具體的 PHP 代碼題目,深入探討這類漏洞的原理和利用方法。

二、題目代碼分析

我們先來看一下題目給出的 PHP 代碼:

<?php
highlight_file(__FILE__);
include_once('flag.php');
if(isset($_POST['a'])&&!preg_match('/[0-9]/',$_POST['a'])&&intval($_POST['a'])){if(isset($_POST['b1'])&&$_POST['b2']){if($_POST['b1']!=$_POST['b2']&&md5($_POST['b1'])===md5($_POST['b2'])){if($_POST['c1']!=$_POST['c2']&&is_string($_POST['c1'])&&is_string($_POST['c2'])&&md5($_POST['c1'])==md5($_POST['c2'])){echo $flag;}else{echo "yee";}}else{echo "nop";}}else{echo "go on";}
}else{echo "let's get some php";
}
?>

2.1 條件逐層分析

這段代碼通過四重條件判斷來控制 flag 的輸出,我們需要逐一分析每個條件的要求:
第一層條件:

isset($_POST['a']) && !preg_match('/[0-9]/', $_POST['a']) && intval($_POST['a'])

必須存在 POST 參數a
a的值不能包含任何數字字符
a的值被轉換為整數后必須為真(即非零)
第二層條件:

isset($_POST['b1']) && $_POST['b2']

必須存在 POST 參數b1和b2
第三層條件:

$_POST['b1'] != $_POST['b2'] && md5($_POST['b1']) === md5($_POST['b2'])

b1和b2的值不能相等
但它們的 MD5 哈希值必須嚴格相等(使用===比較)
第四層條件:

$_POST['c1'] != $_POST['c2'] && is_string($_POST['c1']) && is_string($_POST['c2']) && md5($_POST['c1']) == md5($_POST['c2'])

c1和c2的值不能相等
它們都必須是字符串類型
它們的 MD5 哈希值必須寬松相等(使用==比較)

三、漏洞利用原理

3.1 第一層條件繞過:非數字的整數

第一個挑戰是如何讓一個字符串不包含數字,但轉換為整數后卻非零。PHP 的類型轉換規則為我們提供了突破口。當一個字符串被轉換為整數時,PHP 會從字符串的開始處提取數字部分,直到遇到非數字字符為止。如果字符串以非數字字符開頭,則轉換結果為 0。
解決方案:使用科學計數法表示數字。例如,字符串1e0在 PHP 中會被解釋為1 * 10^0 = 1,但它并不包含數字字符0-9,因為e在科學計數法中是合法的指數符號。
驗證代碼:

<?php
var_dump(preg_match('/[0-9]/', '1e0')); // bool(false)
var_dump(intval('1e0')); // int(1)
?>

除了使用科學計數法,還可以利用 PHP 數組的特性繞過第一個條件。當$_POST[‘a’]是一個數組時:

preg_match('/[0-9]/', $_POST['a'])會返回false(即不匹配)

因為preg_match期望的參數是字符串,當傳入數組時會觸發警告,但返回值為0(表示不匹配)

intval($_POST['a'])會返回0

因為數組轉換為整數時結果為0
矛盾點:雖然preg_match檢查通過了,但intval($_POST[‘a’])返回0,而第三個條件要求轉換結果為真(非零)。這看似是一個矛盾,但實際情況中可能存在兩種解釋:
PHP 版本差異:在某些 PHP 版本中,數組轉換為布爾值時可能被視為true
測試代碼:

<?php
$a = array('a');
var_dump((bool)$a); // 通常輸出bool(true)
var_dump(intval($a)); // 輸出int(0)
?>

但在條件表達式中,intval($a)明確返回0,這應該導致條件失敗。因此這種解釋可能不成立。
代碼邏輯漏洞:出題者可能忽略了數組對preg_match的影響
當傳入a[]=a時,雖然intval返回0,但出題者可能誤以為數組轉換為整數會得到非零值
實際測試:在大多數 PHP 環境中,a[]=a會導致第一個條件失敗。但如果題目環境存在特殊配置(如錯誤抑制符@屏蔽了preg_match的警告),這種繞過方式可能有效。
建議:在實際 CTF 題目中,如果遇到類似情況,兩種方法都應該嘗試:

  1. 使用科學計數法a=1e0(通用有效)
  2. 嘗試數組繞過a[]=a(可能在特定環境中有效)

3.2 第二層條件繞過:數組的 MD5 哈希

第二個挑戰是找到兩個不同的值,它們的 MD5 哈希值嚴格相等。PHP 在處理數組的哈希函數(如 md5 ()、sha1 ())時有一個特殊行為:當傳入的參數是數組時,這些函數會返回NULL。
解決方案:使用數組作為參數。例如:

<?php
$b1 = array(1);
$b2 = array(2);
var_dump($b1 != $b2); // bool(true)
var_dump(md5($b1) === md5($b2)); // bool(true),因為md5($b1)和md5($b2)都為NULL
?>

3.3 第三層條件繞過:MD5 碰撞與弱類型比較

第三個挑戰是找到兩個不同的字符串,它們的 MD5 哈希值在寬松比較下相等。這需要利用 PHP 的弱類型特性和特定的 MD5 碰撞字符串。
當使用==比較兩個字符串時,如果它們看起來像科學計數法表示的數字(即0e開頭,后面跟著數字),PHP 會將它們解釋為 0 的冪,因此所有這種形式的字符串在寬松比較下都相等。
解決方案:使用特定的 MD5 碰撞字符串。例如:
QNKCDZO的 MD5 值是0e83040045199349405802421990339
QLTHNDT的 MD5 值是0e40596782540195537254913908420
驗證代碼:

<?php
$c1 = "QNKCDZO";
$c2 = "QLTHNDT";
var_dump($c1 != $c2); // bool(true)
var_dump(is_string($c1) && is_string($c2)); // bool(true)
var_dump(md5($c1) == md5($c2)); // bool(true)
?>

四、完整 POC 與利用

方案一:科學計數法(推薦)

POST / HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 71a=1e0&b1[]=1&b2[]=2&c1=QNKCDZO&c2=QLTHNDT

方案二:數組繞過(特定環境可能有效)

POST / HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 71a[]=a&b1[]=1&b2[]=2&c1=QNKCDZO&c2=QLTHNDT

標題五、擴展知識點

5.1 PHP 弱類型比較總結

PHP 的弱類型比較是一個常見的安全風險點。下表總結了一些常見的弱類型比較陷阱:

表達式結果原因
0 == "0"true字符串 "0" 被轉換為整數 0
0 == "abc"true字符串 "abc" 轉換為整數 0
"10" == "010"false字符串比較不進行類型轉換
10 == "010"true字符串 "010" 被轉換為整數 10
md5("240610708") == md5("QNKCDZO")true兩個 MD5 值都是 0e 開頭的字符串,在寬松比較下相等
sha1("aaroZmOk") == sha1("aaK1STfY")true兩個 SHA1 值都是 0e 開頭的字符串,在寬松比較下相等

5.2 更多 MD5 碰撞字符串

除了前面提到的QNKCDZO和QLTHNDT,還有許多其他的 MD5 碰撞字符串對,例如:

240610708 和 QNKCDZO
aabg7XSs 和 aabC9RqS

這些字符串對的 MD5 值都是0e開頭,因此在 PHP 的寬松比較下相等。

六、總結

通過分析這道 CTF 題目,我們深入了解了 PHP 弱類型比較漏洞的原理和利用方法。這類漏洞雖然在現代 PHP 應用中已經較少見,但在一些老舊系統或代碼中仍然可能存在。理解這些漏洞的工作原理,不僅有助于我們在安全測試中發現問題,也能指導我們寫出更安全的 PHP 代碼。
在實際滲透測試和 CTF 競賽中,遇到類似的多條件驗證題目時,我們需要逐一分析每個條件的繞過方法,結合編程語言的特性和漏洞利用技巧,構造出能夠通過所有驗證的 POC。

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

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

相關文章

【SQL】存儲過程 vs 普通 SQL

一、存儲過程 vs 普通 SQL 的核心區別 先明確兩者的本質&#xff1a; 普通 SQL&#xff1a;是直接執行的查詢 / 操作語句&#xff08;如SELECT、INSERT&#xff09;&#xff0c;每次執行都要編譯&#xff0c;邏輯寫在應用端或直接運行。存儲過程&#xff1a;是預編譯并存儲在…

Vue.js第一節

初識Vue、插值操作、屬性綁定 初識&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>D…

前端打斷點

這個按鈕有個點擊事件&#xff0c;然后點擊這個js 即可進入到代碼中 如果這時想打一些臨時的表達式&#xff0c;可以按esc彈出console控制臺&#xff0c; 右上角有可以使用的變量

Jmeter接口測試與性能測試

&#x1f345; 點擊文末小卡片 &#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快 目前最新版本發展到5.0版本&#xff0c;需要Java7以上版本環境&#xff0c;下載解壓目錄后&#xff0c;進入\apache-jmeter-5.0\bin\&#xff0c;雙擊ApacheJMete…

如何利用大模型搭建本地知識庫

要利用大模型搭建本地知識庫&#xff0c;核心在于&#xff1a;構建高質量知識內容源、使用向量化技術實現語義檢索、部署大語言模型以實現自然語言問答接口、設計本地知識庫的數據更新機制、注重隱私與合規性控制。其中&#xff0c;使用向量化技術實現語義檢索至關重要&#xf…

vscode連接不上服務器問題修復

原因&#xff1a;運維人員修復漏洞&#xff0c;升級了服務器openssh版本&#xff0c;導致無法新建連接連上vscode 操作&#xff1a; 1.刪除云桌面上C:\Users\.ssh 路徑下known_hosts文件&#xff1b; 2.設置免密登錄 1&#xff09;執行 ssh-keygen -t rsa -C "your_em…

架構優化——submodule轉為subtree

文章目錄 背景subtree優勢submodule切換到subtree腳本subtree使用切開發分支推送代碼同步代碼 背景 submodule過多&#xff0c;目前20個submodule需要切出20個分支&#xff0c;查看提交記錄、切分支等使用起來麻煩。 團隊深受困擾&#xff01; subtree優勢 繼承submodule的…

車載軟件架構 --- 汽車中央控制單元HPC軟件架構方案實例

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 做到欲望極簡,了解自己的真實欲望,不受外在潮流的影響,不盲從,不跟風。把自己的精力全部用在自己。一是去掉多余,凡事找規律,基礎是誠信;二是…

零基礎開始的網工之路第二十一天------性能優化

目錄 一、性能優化概述 二、性能監控工具 1. 基礎工具 2. 高級工具 三、子系統優化策略 1. CPU優化 2. 內存優化 3. 磁盤I/O優化 4. 網絡優化 四、資源限制優化 1. ulimit 2. cgroups&#xff08;控制組&#xff09; 五、安全與注意事項 六、綜合案例 案例1&…

【Google Chrome】谷歌瀏覽器歷史版本下載

最新版&#xff1a; Chrome for Testing availability 谷歌瀏覽器 Chrome 最新版離線安裝包下載地址 v137.0.7151.104 - 每日自動更新 | 異次元軟件 歷史版本&#xff1a; Download Google Chrome 105.0.5195.102 for Windows - Filehippo.com chrome瀏覽器,chrome插件,谷…

線性表實訓(頭歌實踐平臺課程答案詳細解說)

C 和 C 支持 4 種基本數據類型&#xff08;整型、浮點型、字符型、布爾型&#xff09;和 3 種復合型數據類型&#xff08;數組、指針、結構&#xff09;。復合類型的數據對于數據結構至關重要&#xff0c;因為從某種程度上來說數據量的多少和數據結構的好壞決定了程序的復雜程度…

【前端】threeJS學習(長期更新)

簡介 Three.js是用JavaScript編寫的第三方庫&#xff0c;用于實現3D功能&#xff0c;基于WebGL進行封裝。 一個3D模型的建立主要由以下幾個部分組成&#xff08;基本版&#xff09;&#xff1a; * 創建場景scene--相機camera--渲染器renderer--(燈光light)&#xff1b; *…

Linux系統--權限

大家好&#xff0c;上一次我們學習了關于Linux中的基礎指令&#xff0c;那么我們今天來繼續學習Linux的新的內容&#xff1a;權限。那么話不多說&#xff0c;我們開始今天的學習&#xff1a; 目錄 Linux權限 1. Linux權限的概念 2. Linux權限管理 3. ?件權限值的表??法…

論文筆記 <交通燈> <多智能體>DERLight雙重經驗回放燈機制

今天看的論文是這篇 主要提出了傳統優先級經驗回放&#xff08;PER&#xff09;在復雜交通場景中效率低下&#xff0c;使用二叉樹存儲樣本&#xff0c;導致大規模樣本時計算復雜度高。而且不丟棄樣本&#xff0c;造成存儲空間浪費。 雙重經驗池&#xff1a; 為了解決以上問題…

Chromium 136 編譯指南 macOS篇:環境準備與系統配置(一)

1. 引言 在瀏覽器技術的星空中&#xff0c;Chromium 猶如一顆最亮的明星&#xff0c;照亮了整個互聯網的發展軌跡。作為推動現代 Web 技術革命的核心引擎&#xff0c;Chromium 不僅是 Google Chrome 的技術基石&#xff0c;更是 Microsoft Edge、Opera、以及眾多定制瀏覽器的共…

linux機器間無密碼如何傳輸文件

1. scp傳輸時的問題 $ scp deepseek_r1_distill_qwen1.5b_content_audit_fp16_20250613_2_Q4_K_M.gguf xxx192.168.xxx:/home/xxx/pretrained_model/output The authenticity of host 192.168.xxx (192.168.xxx) cant be established. ED25519 key fingerprint is SHA256:deOs…

PySpark 使用pyarrow指定版本

背景說明 在 PySpark 3.1.3 環境中&#xff0c;當需要使用與集群環境不同版本的 PyArrow (如 1.0.0 版本)時&#xff0c;可以通過以下方法實現&#xff0c;而無需更改集群環境配置 完整操作說明 去pyarrowPyPI下載對應版本的whl文件后綴whl直接改成zip解壓后有兩個文件夾&am…

安卓APP投屏調試工具使用教程

安卓APP投屏調試工具使用教程 一、準備工作&#xff08;一&#xff09;下載ADB工具&#xff08;二&#xff09;配置ADB的環境變量&#xff08;三&#xff09;檢查是否成功安裝&#xff08;四&#xff09;adb核心命令說明 二、無線調試流程&#xff08;一&#xff09;環境要求&a…

huggingface網站里的模型和數據集

直接下載肯定是不太行&#xff0c;平時訪問都不容易&#xff0c;更別提下載東西了&#xff0c;但是我們可以通過國內鏡像進行快速下載。 鏡像網址&#xff1a; hf-mirror地址&#xff1a;HF-Mirror 進入網站之后&#xff0c;在搜索框里搜索你想下載的內容&#xff0c;接下來…

Node.js 路由請求方式大全解:深度剖析與工程實踐

文章目錄 &#x1f310; Node.js 路由請求方式大全解&#xff1a;深度剖析與工程實踐一、&#x1f4dc; HTTP 請求方法全景圖&#x1f3c6; 核心方法深度對比HTTP 請求方法概念對比表&#x1f6e0;? 特殊方法應用場景 二、&#x1f3a8; 各方法深度解析1. GET - 數據查看器&am…