開源PHPCMS的0day漏洞挖掘及防範筆記

前言市面上,開源的cms有很多,例如:織夢、phpwind、discuz、帝國、phpcms、騎士小說、emlog、zblog、wordpress 等.....他們都有一個共同點,源碼開源、使用的人多、漏洞多;就是很多使用者不一定會和官方同步升級到最新版本,這樣子舊版的漏洞就存在不被修復的可能。那要怎麼去防禦呢?0x01環境搭建:Damn Vulnerable Web App (DVWA)isa PHP/MySQL web application that is damn vulnerable. Its main goals are to bean aid for security professionals to test their skills and tools in a legalenvironment, help web developers better understand the processes of securingweb applications and aid teachers/students to teach/learn web applicationsecurity in a class room environment..htaccessphp_flag magic_quotes_gpcOff//主要是對所有的GET、POST和COOKIE數據自動運行addslashes()。5.3.0以前、if(!get_magic_quotes_gpc()){addslashes($prot);}#php_flag allow_url_fopenon#php_flagallow_url_include onAllowOverride None/All0x02 APMserv,XAMPP,WAMP0x03 PHP 超全局變數$GLOBALS包含一個引用指向每個當前腳本的全局範圍內有效的變數。該數組的鍵標為全局變數的 名稱。從 PHP 3 開始存在 $GLOBALS 數組。$_SERVER變數由 Web 伺服器設定或者直接與當前腳本的執行環境相關聯。類似於舊數組 $HTTP_SERVER_VARS 數組(依然有效,但反對使用)。HTTP頭、$_GET經由 HTTP GET 方法提交至腳本的變數。類似於舊數組 $HTTP_GET_VARS 數組(依然有效,但反對使用)。$_POST經由HTTP POST方法提交至腳本的變數。類似於舊數組 $HTTP_POST_VARS 數組(依然有效,但反對使用)。$_COOKIE經由 HTTP Cookies 方法提交至腳本的變數。類似於舊數組 $HTTP_COOKIE_VARS 數組(依然有效,但反對使用)。$_FILES經由 HTTP POST 文件上傳而提交至腳本的變數。類似於舊數組 $HTTP_POST_FILES 數組(依然有效,但反對使用)。詳細信息請參閱 POST 方法上傳。$_ENV執行環境提交至腳本的變數。類似於舊數組 $HTTP_ENV_VARS 數組(依然有效,但反對使用)。$_REQUEST經由 GET,POST 和 COOKIE 機制提交至腳本的變數,因此該數組並不值得信任。所有包含在該數組中的變數的存在與否以及變數的順序均按照 php.ini 中的 variables_order 配置指示來定義。該數組沒有直接模擬 PHP 4.1.0 的早期版本。參見 。******自 PHP 4.3.0起,$_FILES 中的文件信息不再存在於 $_REQUEST 中。*****$_SESSION當前註冊給腳本會話的變數。類似於舊數組 $HTTP_SESSION_VARS 數組(依然有效,但反對使用)。0x04require_once()語句在腳本執行期間包含並運行指定文件。此行為和require()語句類似,唯一區別是如果該文件中的代碼已經被包含了,則不會再次包含。0x05Sql注入:允許攻擊者從HTTP表單輸入框提交SQL語句,還包括盲注和SQL注入錯誤顯示。過濾:stripslashesPHP刪除反斜線字元函數mysql_real_escape_stringPHP轉義函數下列字元受影響:x00

" " x1a確認字符集//字元型過濾is_numeric — 檢測變數是否為數字或數字字元串 ctype_digit 正則表達式//數字型的過濾addslashes雙位元組會出現漏洞,不需要資料庫連接0x06資料庫報錯信息泄漏漏洞黑客利用SQL注入攻擊,可利用報錯顯示資料庫名,及用戶名Php.ini文件display_errors=On資料庫查詢函數前加@0x07PHP字元編碼繞過漏洞addslash對於字元%BF%27的漏洞單引號被 urlencode兩次以後是 %2527,然後 POST,PHP 內部在生成全局變數 $_POST 的時候會先 urldecode,得到 %27,然後 PHP 會檢查 Magic Quotes 的設置,但是無論是否開啟 Magic Quotes,%27 都不會被addslashes。" and(select 1 from(select count(*),concat((select (select(selectconcat(0x23,cast(concat(username,0x3a,password,0x3a,encrypt) as char),0x23)from v9_admin LIMIT 0,1)) from information_schema.tables limit0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) and "1"="10x08SQL注入漏洞的防範數字型的注入1. is_numeric ctype_digit 正則表達式2. str_length限制輸入的字元長度字元型的注入1.mysql_real_escape_string2.str_length限制輸入的字元長度如何挖掘SQL注入漏洞注意常見獲取變數,資料庫操作函數mysql_querySQL注入攻擊的總體思路·發現SQL注入位置;·判斷後台資料庫類型;·確定XP_CMDSHELL可執行情況·發現WEB虛擬目錄·上傳ASP木馬;·得到管理員許可權;0x09命令執行漏洞常見執行命令函數system() passthru() popen() exec()等函數如何挖掘:搜索exec,system,popen,passthru,proc_open,shell_exec如何利用:管道命令:|%Ping 0|net stat user /addPing 0|dir c:/Echo webshell>a.txt例:ping命令的過濾stripslashes() 函數刪除由addslashes()函數添加的反斜杠。explode() 函數把字元串分割為數組。explode(separator,string,limit)separator必需。規定在哪裡分割字元串。string必需。要分割的字元串。limit可選。規定所返回的數組元素的最大數目。((is_numeric($octet[0]))&& (is_numeric($octet[1])) && (is_numeric($octet[2]))&& (is_numeric($octet[3])) && (sizeof($octet) == 4))EscapeShellArg() EscapeShellcmd()0x10文件包含漏洞常見文件包含函數Include()require() include_once() require_once()Require_once只包含一次默認第一次Require被包含文件有錯誤不在向下執行(主文件)Include 被包含文件有錯誤也可以向下執行(主文件)遠程文件包含漏洞allow_url_fopen allow_url_include如何繞過allow_url_fopen allow_url_includezlib:// ogg:// (獲取媒體文件) data://(獲取post數據) php://相關函數:Include()include_once() require() require_once() fopen() imagecreatefromXXX() file()file_get_contents() copy() delete() unlink() upload_tmp_dir() $_FILESmove_uploaded_file()如何防止文件包含漏洞關閉allow_url_fopen和allow_url_include驗證過濾(判斷文件是否是包含文件,如果不等於,就exit)copy /b 1.gif+2.php 3.gif%00 字元串截斷0x11Csrf漏洞利用及防範(黑客藉助受害者的cookie騙取伺服器的信任)瀏覽器同源策略利用

使受害者訪問網頁Cross-site request forgery跨站請求偽造,也被稱為「oneclick attack」或者sessionriding,通常縮寫為CSRF或者XSRF,是一種對網站的惡意利用。儘管聽起來像跨站腳本(XSS), 但它與XSS非常不同,並且攻擊方式幾乎相左。XSS利用站點內的信任用戶,而CSRF則通過偽裝來自受信任用戶的請求來利用受信任的網站。與XSS攻擊相比,CSRF攻擊往往不大流行(因此對其進行防範的資源也相當稀少)和難以防範,所以被認為比XSS更具危險性。

從上圖可以看出,要完成一次CSRF攻擊,受害者必須依次完成兩個步驟:1.登錄受信任網站A,並在本地生成Cookie。2.在不登出A的情況下,訪問危險網站B。看到這裡,你也許會說:「如果我不滿足以上兩個條件中的一個,我就不會受到CSRF的攻擊」。是的,確實如此,但你不能保證以下情況不會發生:1.你不能保證你登錄了一個網站後,不再打開一個tab頁面並訪問另外的網站。2.你不能保證你關閉瀏覽器了後,你本地的Cookie立刻過期,你上次的會話已經結束。(事實上,關閉瀏覽器不能結束一個會話,但大多數人都會錯誤的認為關閉瀏覽器就等於退出登錄/結束會話了......)3.上圖中所謂的攻擊網站,可能是一個存在其他漏洞的可信任的經常被人訪問的網站。當前防防禦CSRF 的幾種策略在業界目前防禦 CSRF 攻擊主要有三種策略:驗證 HTTP Referer 欄位;在請求地址中添加 token 並驗證;在 HTTP 頭中自定義屬性並驗證。下面就分別對這三種策略進行詳細介紹。驗證HTTP Referer 欄位根據 HTTP 協議,在 HTTP 頭中有一個欄位叫 Referer,它記錄了該 HTTP 請求的來源地址。在通常情況下,訪問一個安全受限頁面的請求來自於同一個網站,比如需要訪問http://bank.example/withdraw?account=bob&amount=1000000& for=Mallory,用戶必須先登陸 bank.example,然後通過點擊頁面上的按鈕來觸發轉賬事件。這時,該轉帳請求的 Referer 值就會是轉賬按鈕所在的頁面的 URL,通常是以 bank.example 域名開頭的地址。而如果黑客要對銀行網站實施 CSRF 攻擊,他只能在他自己的網站構造請求,當用戶通過黑客的網站發送請求到銀行時,該請求的 Referer 是指向黑客自己的網站。因此,要防禦 CSRF 攻擊,銀行網站只需要對於每一個轉賬請求驗證其 Referer 值,如果是以 bank.example 開頭的域名,則說明該請求是來自銀行網站自己的請求,是合法的。如果 Referer 是其他網站的話,則有可能是黑客的 CSRF 攻擊,拒絕該請求。這種方法的顯而易見的好處就是簡單易行,網站的普通開發人員不需要操心 CSRF 的漏洞,只需要在最後給所有安全敏感的請求統一增加一個攔截器來檢查 Referer 的值就可以。特別是對於當前現有的系統,不需要改變當前系統的任何已有代碼和邏輯,沒有風險,非常便捷。然而,這種方法並非萬無一失。Referer 的值是由瀏覽器提供的,雖然 HTTP 協議上有明確的要求,但是每個瀏覽器對於 Referer 的具體實現可能有差別,並不能保證瀏覽器自身沒有安全漏洞。使用驗證 Referer 值的方法,就是把安全性都依賴於第三方(即瀏覽器)來保障,從理論上來講,這樣並不安全。事實上,對於某些瀏覽器,比如 IE6 或 FF2,目前已經有一些方法可以篡改 Referer 值。如果 bank.example 網站支持 IE6 瀏覽器,黑客完全可以把用戶瀏覽器的 Referer 值設為以 bank.example 域名開頭的地址,這樣就可以通過驗證,從而進行 CSRF 攻擊。即便是使用最新的瀏覽器,黑客無法篡改 Referer 值,這種方法仍然有問題。因為 Referer 值會記錄下用戶的訪問來源,有些用戶認為這樣會侵犯到他們自己的隱私權,特別是有些組織擔心 Referer 值會把組織內網中的某些信息泄露到外網中。因此,用戶自己可以設置瀏覽器使其在發送請求時不再提供 Referer。當他們正常訪問銀行網站時,網站會因為請求沒有 Referer 值而認為是 CSRF 攻擊,拒絕合法用戶的訪問。在請求地址中添加在token 並驗證CSRF 攻擊之所以能夠成功,是因為黑客可以完全偽造用戶的請求,該請求中所有的用戶驗證信息都是存在於 cookie 中,因此黑客可以在不知道這些驗證信息的情況下直接利用用戶自己的 cookie 來通過安全驗證。要抵禦 CSRF,關鍵在於在請求中放入黑客所不能偽造的信息,並且該信息不存在於 cookie 之中。可以在 HTTP 請求中以參數的形式加入一個隨機產生的 token,並在伺服器端建立一個攔截器來驗證這個 token,如果請求中沒有 token 或者 token 內容不正確,則認為可能是 CSRF 攻擊而拒絕該請求。這種方法要比檢查 Referer 要安全一些,token 可以在用戶登陸後產生並放於 session 之中,然後在每次請求時把 token 從 session 中拿出,與請求中的 token 進行比對,但這種方法的難點在於如何把 token 以參數的形式加入請求。對於 GET 請求,token 將附在請求地址之後,這樣 URL 就變成http://url?csrftoken=tokenvalue。 而對於 POST 請求來說,要在 form 的最後加上 ,這樣就把 token 以參數的形式加入請求了。但是,在一個網站中,可以接受請求的地方非常多,要對於每一個請求都加上 token 是很麻煩的,並且很容易漏掉,通常使用的方法就是在每次頁面載入時,使用 javascript 遍歷整個 dom 樹,對於 dom 中所有的 a 和 form 標籤後加入 token。這樣可以解決大部分的請求,但是對於在頁面載入之後動態生成的 html 代碼,這種方法就沒有作用,還需要程序員在編碼時手動添加 token。該方法還有一個缺點是難以保證 token 本身的安全。特別是在一些論壇之類支持用戶自己發表內容的網站,黑客可以在上面發布自己個人網站的地址。由於系統也會在這個地址後面加上 token,黑客可以在自己的網站上得到這個 token,並馬上就可以發動 CSRF 攻擊。為了避免這一點,系統可以在添加 token 的時候增加一個判斷,如果這個鏈接是鏈到自己本站的,就在後面添加 token,如果是通向外網則不加。不過,即使這個 csrftoken 不以參數的形式附加在請求之中,黑客的網站也同樣可以通過 Referer 來得到這個 token 值以發動 CSRF 攻擊。這也是一些用戶喜歡手動關閉瀏覽器 Referer 功能的原因。在HTTP 頭中自定義屬性並驗證這種方法也是使用 token 並進行驗證,和上一種方法不同的是,這裡並不是把 token 以參數的形式置於 HTTP 請求之中,而是把它放到 HTTP 頭中自定義的屬性里。通過 XMLHttpRequest 這個類,可以一次性給所有該類請求加上 csrftoken 這個 HTTP 頭屬性,並把 token 值放入其中。這樣解決了上種方法在請求中加入 token 的不便,同時,通過 XMLHttpRequest 請求的地址不會被記錄到瀏覽器的地址欄,也不用擔心 token 會透過 Referer 泄露到其他網站中去。然而這種方法的局限性非常大。XMLHttpRequest 請求通常用於 Ajax 方法中對於頁面局部的非同步刷新,並非所有的請求都適合用這個類來發起,而且通過該類請求得到的頁面不能被瀏覽器所記錄下,從而進行前進,後退,刷新,收藏 等操作,給用戶帶來不便。另外,對於沒有進行 CSRF 防護的遺留系統來說,要採用這種方法來進行防護,要把所有請求都改為 XMLHttpRequest 請求,這樣幾乎是要重寫整個網站,這代價無疑是不能接受的。0x12反射型跨站漏洞XSSJavascript請求,可以盜cookie,掛馬,例:動態頁面向用戶顯示消息error.php?message=sorry%2c+an+error+ocurred判斷error.php?message=如何利用漏洞?會話劫持(cookie截獲)注意$_POST $_GET $_COOKIE如何修補:利用htmlspecialchars函數過濾http://ha.ckers.org/xss.html構造一個getcookie.php內容如下$cookie =$_GET[『c』];$log =fopen(「cookie.txt」,」a」);Fwrite($log,$cookie.」
」);?>利用HTTP/HTTPS Protocol Debuger 可以偽造cookie實現登錄的目的1.支持HTTP和HTTPS(SSL加密)網路協議的跟蹤和調試。2.可以查看到HTTP/HTTPS協議連接的詳細過程和返回結果。3.允許GET/POST/HEAD/PUT四種連接方式。4.支持HTTP的Proxy代理。5.自動處理重定向Redirect功能。6.自動處理Cookie的接收和發送。7.可以自行設置和增加HTTP請求命令的參數。0x13 存儲型跨站漏洞可以進行包含js文件,進行提權。關注我們
推薦閱讀:

Windows內核漏洞利用教程 第7部分:未初始化的堆變數
反引號->命令執行
DedeCMS 漏洞為何屢修不止?
漏洞提交級別說明
Pwn新手應該如何開始挖掘二進位漏洞(如UAF,stack overflow)?

TAG:開源 | 筆記 | 漏洞 | PHPCMS | 漏洞挖掘 | 挖掘 |