2015-10-05 57 views
0

因此,我有一個我自己沒有設計但具有已知安全漏洞的PHP腳本。有一個管理面板,管理員可以爲每個用戶更改各種配置文件設置,包括他們的電子郵件地址。這個安全漏洞使得任何知道正確URL的人都可以通過簡單計算他們想要的新電子郵件地址的MD5哈希值來更改任何註冊用戶的電子郵件地址,包括管理員,只要他們知道相應的用戶ID即可更改爲併發出GET請求,而無需以管理員身份登錄。例如,輸入以下網址到瀏覽器:在Apache/PHP中阻止GET請求

admin.php的用戶id = 1 & md5hash = c59152a77c0bc073fe6f2a3141b99010 & [email protected]

會與ID成功更新的用戶的電子郵件地址「? 1「發送至[email protected]

現在從我到目前爲止所做的研究看來,拋棄MD5哈希以獲得稍微更專有/安全的加密形式將是實現這一目標的最佳/最安全的方式。但是,雖然我覺得自己對PHP有很好的理解,並且自己編寫了一些基本腳本,但由於我沒有設計特定的腳本,因此我不確定這是否可行和/或是否合理。此外,人們在實踐中仍然使用MD5哈希值,所以必須存在另一種同樣可行的方法來保護這種攻擊,這導致我尋找Apache的mod_rewrite模塊來阻止特定類型的GET請求:

[因爲不相關的編輯原因的2對新用戶的最大鏈接限制]

所以我的問題是:

1)不考慮它是否會實際上是可行的,但改變PHP腳本使用的加密一些其他形式除了MD5哈希是最好的方式去做這件事?還是有一些簡單的功能,我可以添加到PHP腳本本身以防止這種漏洞?

2)如果我去使用Apache的mod_rewrite的路線,如上面的URL描述,這將是最好的方法(出THE_REQUEST,HTTP_REFERER,HTTP_COOKIE,REQUEST_URI,HTTP_USER_AGENT,QUERY_STRING的,和/或REMOTE_ADDR,其中REQUEST_METHOD是「GET」)?或者甚至有可能做我想要這樣做的事情?

3)有人還建議可以通過.htaccess文件做我想做的事情嗎?這是否可能,並且這種方法會比其他提到的方法更安全嗎?

唯一要考慮的是,通過我最終使用的任何方法,服務器必須仍能夠在管理員想要合法更改用戶的電子郵件地址時發出請求。我只需要對其進行更新,以便普通公衆無法通過在瀏覽器中輸入正確的URL來更改用戶的電子郵件地址,因爲他們知道正確的用戶ID。提前致謝。

--->編輯:對不起,我忽略了命名特定的腳本,因爲它是一個公共可用的,我不知道這個特定的漏洞是否是已知的,但事實證明它是,所以我猜在這裏發佈並沒有什麼壞處。該腳本是TorrentTrade(v2.08) - 您可以在SourceForge上下載整個腳本(https://sourceforge.net/projects/torrenttrader/)。

我也複製並粘貼了account-ce的全部內容。PHP:

<?php 
// 
// TorrentTrader v2.x 
//  $LastChangedDate: 2012-09-28 20:35:06 +0100 (Fri, 28 Sep 2012) $ 
//  $LastChangedBy: torrenttrader $ 
// 
//  http://www.torrenttrader.org 
// 

require_once("backend/functions.php"); 
dbconn(); 

$id = (int) $_GET["id"]; 
$md5 = $_GET["secret"]; 
$email = $_GET["email"]; 

if (!$id || !$md5 || !$email) 
    show_error_msg(T_("ERROR"), T_("MISSING_FORM_DATA"), 1); 

$res = SQL_Query_exec("SELECT `editsecret` FROM `users` WHERE `enabled` = 'yes' AND `status` = 'confirmed' AND `editsecret` != '' AND `id` = '$id'"); 
$row = mysql_fetch_assoc($res); 

if (!$row) 
    show_error_msg(T_("ERROR"), T_("NOTHING_FOUND"), 1); 

$sec = $row["editsecret"]; 

if ($md5 != md5($sec . $email . $sec)) 
    show_error_msg(T_("ERROR"), T_("NOTHING_FOUND"), 1); 

SQL_Query_exec("UPDATE `users` SET `editsecret` = '', `email` = ".sqlesc($email)." WHERE `id` = '$id' AND `editsecret` = " . sqlesc($row["editsecret"])); 

header("Refresh: 0; url=account.php"); 
header("Location: account.php"); 

?> 

帳戶ce.php在以下幾個已知漏洞列表(第一個漏洞是唯一一個我看現在)引用的PHP文件:

https://www.exploit-db.com/exploits/21396/

我想,不要坐在等待TorrentTrader發佈新更新,我會嘗試主動修復一些漏洞。

+4

最好的方法就是以修復腳本,檢測呼叫者是否有權調用腳本首先 – DarkBee

+0

'而不必登錄作爲admin'爲什麼?不應該admin.php檢查他們是否像任何其他網頁的管理員? –

+0

你應該使用某種會話。因此,如果用戶登錄並且是管理員,或者信息屬於正在訪問它的登錄用戶,則可以完成更新。這是授權/管理權限的常用方式。 –

回答

0

您需要包含在會話處理程序中。我想假定用戶在被允許訪問任何管理頁面之前需要登錄,並且某種登錄憑證或用戶標識被保存到會話變量中。要實現,你就需要有一個這樣的腳本包含在每一頁上:

<?php 
session_start(); 
if(!isset($_SESSION['uid'])){ 
    $redirect_url='login.php'; 
    if(isset($_SERVER['HTTP_REFERER'])){ 
     $redirect_url.='?target='.urlencode($_SERVER['HTTP_REFERER']); 
    } 
    header('Location: '.$redirect_url); 
} 
?> 

$ _SESSION [「UID」]是有點任意的,可能是你認爲足夠滿足您的應用程序的安全性有任何會話變量。注意:會話變量連接到用戶並在頁面之間保存,直到通過調用session_destroy()銷燬會話。

如果上面的腳本是在每次頁面加載之前執行的,那麼當某些惡意黑客試圖在未登錄的情況下觸發腳本時,它們將在腳本/頁面的其餘部分執行前被重定向到login.php /加載。

+0

呃,沒有。在執行其餘代碼之前,腳本確實會**發出**重定向到login.PHP,但在調用header()之後沒有退出語句時,它仍然會執行代碼的其餘部分。 – symcbean

+0

好的,你有兩個選擇來處理:(如你所提到的)在頭重定向之後調用exit()或die()(假設其餘部分不應該被執行,如果達到的話),或者,你可以把其餘的代碼放在一個else語句中。如果還有其他問題,提供相關代碼的副本可能會有所幫助。 – Andrew

+0

調用header()不會立即重定向用戶,它會在發送處理後的頁面時提交頭部請求。另外,需要注意的是,如果在調用header()之前有文本,可能會阻止設置頭文件 – Andrew

0

當前腳本非常不安全,但不安全不是由使用md5散列產生的。僅僅使用Apache配置就可以將安全機制鎖定在這樣的系統上真的很難。

您可能希望通過在session securitycross site request forgery.

你需要編寫一些代碼讀取趕快下手。由於您沒有發佈任何代碼,也沒有提出具體的解決方案,所以您的問題在這裏非常關鍵。

+0

你對腳本如何工作的分析是非常錯誤的。您可能不希望對此進行任何更改,直到您至少了解其當前的工作方式並知道更多關於安全編程的更多內容。 – symcbean

0

好的傢伙,我覺得現在適度愚蠢,但感謝你的提示使用會話處理器因爲這是最終指向我在正確的方向和正確的地方去尋找。周圍挖之後好像那個特定的管理文件(帳戶ce.php),無論出於何種原因,只是缺少這樣的:

loggedinonly(); 

這是在後端/ functions.php中定義爲:

function loggedinonly() { 
    global $CURUSER; 
    if (!$CURUSER) { 
     header("Refresh: 0; url=account-login.php?returnto=" . urlencode($_SERVER["REQUEST_URI"])); 
     exit(); 
    } 
} 

另外,我打算爲你的建議,所以我可以更好地與會話如何用於此目的自己熟悉的會話安全讀了。再次感謝! :)