萌新賽 sprintf漏洞

WSssSW發表於2024-08-16

首先是個.git原始碼原始碼洩露,用githack回覆一下原始碼

原始碼
<?php
$pass=sprintf("and pass='%s'",addslashes($_GET['pass']));
$sql=sprintf("select * from user where name='%s' $pass",addslashes($_GET['name']));
?>


這題用了兩次sprintf函式可以在這裡做文章

sprintf用法:

%% - 返回一個百分號 %
%b - 二進位制數
%c - ASCII 值對應的字元
%d - 包含正負號的十進位制數(負數、0、正數)
%e - 使用小寫的科學計數法(例如 1.2e+2)
%E - 使用大寫的科學計數法(例如 1.2E+2)
%u - 不包含正負號的十進位制數(大於等於 0)
%f - 浮點數(本地設定)
%F - 浮點數(非本地設定)
%g - 較短的 %e 和 %f
%G - 較短的 %E 和 %f
%o - 八進位制數
%s - 字串
%x - 十六進位制數(小寫字母)
%X - 十六進位制數(大寫字母)

點選檢視程式碼
<?php
$number = 123;
$txt = sprintf("%f",$number);
echo $txt;
?>
//結果是:123.000000
點選檢視程式碼
<?php
$number = 123;
$txt = sprintf("帶兩位小數:%1\$.2f
<br>不帶小數:%1\$u",$number);
echo $txt;
?>
//當一個變數要同時被多個地方引用的時候就需要 %1\$u 的操作
//%1的意思是引用的是第一個變數$u是
//執行結果:如圖

image

那麼bug就來了
如果我們輸入"%"或者"%1$",他會把反斜槓當做格式化字元的型別,然而找不到匹配的項那麼"%","%1$"就因為沒有經過任何處理而被替換為空。
簡單來說就是當sprintf解析時,如果出現 "%"或者"%1$" 會將這兩個變為空
當%1$' 他會直接返回 '

構造payload
name=admin&pass=%$' or 1=1--+

重點過了接下來回跳轉到wjbh.php,就不細講了,他應該是include()了cookie的內容
直接php://filter/convert/resource=/flag 進行16進位制編碼傳入cookie就拿到flag了

image

相關文章