介紹邏輯漏洞
邏輯漏洞就是指攻擊者利用業務的設計缺陷,獲取敏感信息或破壞業務的完整性。一般出現在密碼修改、越權訪問、密碼找回、交易支付金額等功能處。其中越權訪問又有水平越權和垂直越權兩種,如下所示。
- 水平越權:相同級別(權限)的用戶或者同一角色中不同的用戶之間,可以越權訪問、修改或者刪除其他用戶信息的非法操作。如果出現此漏洞,可能會造成大批量數據的泄露,嚴重的甚至會造成用戶信息被惡意篡改。
- 垂直越權:就是不同級別之間的用戶或不同角色之間用戶的越權,比如普通用戶可以執行管理員才能執行的功能。
邏輯缺陷表現為設計者或開發者在思考過程中做出的特殊假設存在明顯或隱含的錯誤。精明的攻擊者會特別注意目標應用程序采用的邏輯方式,並設法了解設計者與開發者可能做出的假設,然后考慮如何攻破這些假設,黑客在挖掘邏輯漏洞時有兩個重點:業務流程和HTTP/HTTPS請求篡改。
常見的邏輯漏洞有以下幾類。 - 支付訂單:在支付訂單時,可以篡改價格為任意金額;或者可以篡改運費或其他費用為負數,導致總金額降低。
- 越權訪問:通過越權漏洞訪問他人信息或者操縱他人賬號。
- 重置密碼:在重置密碼時,存在多種邏輯漏洞,比如利用session覆蓋重置密碼、短信驗證碼直接在返回的數據包中等。
- 競爭條件:競爭條件常見於多種攻擊場景中,比如前面介紹的文件上傳漏洞。還有一個常見場景就是購物時,例如用戶A的余額為10元,商品B的價格為6元,商品C的價格為5元,如果用戶A分別購買商品B和商品C,那余額肯定是不夠的。但是如果用戶A利用競爭條件,使用多線程同時發送購買商品B和商品C的請求,可能會出現以下這幾種結果。
- 有一件商品購買失敗。
- 商品都購買成功,但是只扣了6元。
- 商品都購買成功,但是余額變成了-1元。
越權訪問攻擊
頁面實現的功能是,當用戶登錄系統后,可以通過該頁面查看自己的密碼,該URL中存在一個參數username=zhangsan,當我們把參數username改為lisi之后,則可看到用戶lisi的信息。
數據庫是這樣滴:
越權訪問代碼分析
服務端處理用戶查詢個人信息的代碼如下,程序設計的思路如下所示
<html>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title>個人信息</title>
</head>
<body>
<?php
$con=mysqli_connect("localhost","root","qwer","test");
if (mysqli_connect_errno())
{
echo "連接失敗: " . mysqli_connect_error();
}
if (isset($_GET['username'])) {
$result = mysqli_query($con,"select * from users where `username`='".addslashes($_GET['username'])."'");
$row = mysqli_fetch_array($result,MYSQLI_ASSOC);
exit(
'用 戶:<input type="text" name="username" value="'.$row['username'].'" > <br />'.
'密 碼:<input type="password" value="'.$row['password'].'" > <br />'.
'郵 箱:<input type="text" value="'.$row['email'].'" > <br />'.
'地 址:<input type="text" value="'.$row['address'].'" > <br />'
);
}else{
$username = $_POST['username'];
$password = $_POST['password'];
$result = mysqli_query($con,"select * from users where `username`='".addslashes($username)."' and `password` = '".($password)."'");
$row = mysqli_fetch_array($result);
if ($row) {
exit("登錄成功"."<a href='login.php?username=".$username."' >個人信息</a>");
}else{
exit("登錄失敗");
}
}
?>
</body>
</html>
- 在else語句中獲取POST的參數username和參數password,然后到數據庫中查詢,如果正確,則登錄成功,然后跳轉到login.php?username=$username處(if語句)。
- if語句中是登錄成功后的代碼,獲取GET的參數username,然后到數據庫中查詢參數username的所有信息,並返回到頁面上。但是此處沒有考慮的是,如果直接訪問login.php?username=admin, 那么將直接執行if語句中的代碼,而沒有執行else語句中的代碼,所以此處不需要登錄就可以查看admin的信息,通過這種方式,就可以越權訪問其他用戶的信息。
修復建議
越權訪問漏洞產生的主要原因是沒有對用戶的身份做判斷和控制,防護這種漏洞時,可以通過session來控制。例如在用戶登錄成功后,將username或uid寫入到session中,當用戶查看個人信息時,從session中取出username, 而不是從GET或POST取username,那么此時取到的username就是沒有被篡改的。