20232307 2025-2026-1 《网络与系统攻防技术》实验八实验报告
20232307 2025-2026-1 《网络与系统攻防技术》实验八实验报告
1.实验内容
(1)Web前端HTML
能正常安装、启停Apache。理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML。
(2)Web前端javascipt
理解JavaScript的基本功能,理解DOM。
在(1)的基础上,编写JavaScript验证用户名、密码的规则。在用户点击登陆按钮后回显“欢迎+输入的用户名”
尝试注入攻击:利用回显用户名注入HTML及JavaScript。
(3)Web后端:MySQL基础:正常安装、启动MySQL,建库、创建用户、修改密码、建表
(4)Web后端:编写PHP网页,连接数据库,进行用户认证
(5)最简单的SQL注入,XSS攻击测试
(6)安装DVWA或WebGoat平台,并完成SQL注入、XSS、CSRF攻击。
2.实验过程
2.1 Web前端HTML
能正常安装、启停Apache。理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML。
2.1.1 能正常安装、启停Apache
Apache(Apache HTTP Server)是世界上使用最广泛的开源Web服务器软件之一,Apache的核心功能是接收客户端,如浏览器的HTTP/HTTPS请求,处理并返回对应的资源。
命令systemctl stop apache2可关闭Apache服务。
使用如下命令启动Kali虚拟机中自带的Apache服务:
systemctl start apache2 #启动Apache服务
systemctl status apache2.service #确认服务状态

打开浏览器输入localhost,如果看到Apache的启动页面,说明安装成功。

2.1.2 理解HTML,理解表单,理解GET与POST方法
HTML:
HTML是超文本标记语言,是用于构建网页结构的标准标记语言,它通过一系列标签定义网页的内容和布局。HTML的核心是标记,用预定义标签包裹内容,让浏览器能解析并渲染出文本、图片、链接、表单等元素。
表单:
HTML 表单是网页中用于收集用户输入并提交到服务器的核心组件,是用户与网站交互的关键入口,如登录、注册、搜索、提交数据等场景。表单通过各类表单控件接收用户输入,常见控件包括文本框、密码框、提交按钮等。表单的核心属性包括指定数据提交的服务器地址和指定提交方式,如 GET/POST,当用户点击提交按钮时,表单会将控件中的数据封装后发送到action指定的地址,由后端处理。
GET与POST方法:
GET方法:数据会附加在URL末尾,格式为?key1=value1&key2=value2,可见性高;传输数据量有限;常用于获取数据,请求可被缓存、收藏,安全性较低,不适合传输敏感数据。
POST方法:数据会被封装在HTTP请求的请求体中,不在URL中显示,隐蔽性好,传输数据量无明确限制,可传输大文件或敏感数据;常用于提交、修改数据,请求不会被缓存,安全性更高。
2.1.3 编写一个含有表单的HTML
进入var/www/html/目录,创建一个HTML文件:
cd /var/www/html/
vim 20232307my.html
我们创建一个用户登录页面,包含用户名、密码两个必填输入框,并通过POST方法将数据提交至login.php后端处理,但是目前还没有后端,样式上通过CSS重置统一默认样式,具备基础的表单交互与数据提交功能。
代码如下:
<!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>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Arial, sans-serif;
}
body {
background-color: #f5f5f5;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.login-container {
background-color: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 400px;
}
.login-container h2 {
text-align: center;
margin-bottom: 1.5rem;
color: #333;
}
.form-group {
margin-bottom: 1rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
color: #555;
}
.form-group input {
width: 100%;
padding: 0.8rem;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 1rem;
}
.form-group input:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}
.submit-btn {
width: 100%;
padding: 0.8rem;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
font-size: 1rem;
cursor: pointer;
transition: background-color 0.3s;
}
.submit-btn:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<div class="login-container">
<h2>用户登录</h2>
<!-- POST方式提交的表单 -->
<form action="login.php" method="POST">
<div class="form-group">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required placeholder="请输入用户名">
</div>
<div class="form-group">
<label for="password">密码:</label>
<input type="password" id="password" name="password" required placeholder="请输入密码">
</div>
<button type="submit" class="submit-btn">登录</button>
</form>
</div>
</body>
</html>
打开浏览器,输入网址http://localhost/20232307my.html访问网站
网站界面如下图所示:

输入账号密码,可以看到使用POST实现安全的数据提交,URL中不显示提交的数据。

2.2 Web前端javascipt
理解JavaScript的基本功能,理解DOM。在2.1的基础上,编写JavaScript验证用户名、密码的规则。在用户点击登陆按钮后回显“欢迎+输入的用户名”,尝试注入攻击:利用回显用户名注入HTML及JavaScript。
2.2.1 理解JavaScript的基本功能,理解DOM
JavaScript的基本功能:
①动态修改网页内容和样式:实时更新文本、切换元素显示状态
②响应用户交互:处理点击、输入、鼠标移动等事件
③数据处理与计算:执行算术运算、字符串操作、数组处理等逻辑
④异步网络请求:通过AJAX/fetch与后端交互获取数据,实现无刷新更新页面
⑤客户端存储:利用localStorage/sessionStorage保存用户数据
⑥控制浏览器行为:跳转页面、操作Cookie、实现定时器等
DOM:
DOM(Document Object Model,文档对象模型)是W3C制定的标准接口,它将HTML/XML文档转换为树形结构的对象模型,把文档中的每个元素、属性和文本都封装成可被脚本操作的对象。通过DOM,JavaScript可以访问、修改、添加或删除网页中的任何节点,例如获取元素内容、修改样式、创建新节点,实现网页内容的动态更新。DOM本质是连接HTML结构与JavaScript行为的桥梁,使静态的网页文档具备可交互的动态特性。
2.2.2 编写JavaScript验证用户名、密码的规则
验证的规则是:用户名不能为空,密码需6-20位且包含字母+数字。
- 用户名验证:通过validateUsername函数检查用户名是否为空,若为空则显示 “用户名不能为空” 的错误提示。
- 密码验证:通过validatePassword函数结合正则表达式/^(?=.[a-zA-Z])(?=.\d).{6,20}$/校验,要求密码长度在6-20位之间,且必须同时包含字母和数字,不符合则显示对应错误提示。
表单提交时会先执行验证逻辑,只有两项输入均符合规则时,才会展示欢迎信息,否则阻止表单提交并显示错误。
完整的HTML文件代码:
点击查看代码
<!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>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Arial, sans-serif;
}
body {
background-color: #f5f5f5;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.login-container {
background-color: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 400px;
}
.login-container h2 {
text-align: center;
margin-bottom: 1.5rem;
color: #333;
}
.form-group {
margin-bottom: 1rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
color: #555;
}
.form-group input {
width: 100%;
padding: 0.8rem;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 1rem;
}
.form-group input:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}
.submit-btn {
width: 100%;
padding: 0.8rem;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
font-size: 1rem;
cursor: pointer;
transition: background-color 0.3s;
}
.submit-btn:hover {
background-color: #0056b3;
}
.error-message {
color: #dc3545;
font-size: 0.875rem;
margin-top: 0.25rem;
display: none;
}
/* 放大欢迎信息区域,让注入内容更显眼 */
.success-message {
font-size: 1.5rem;
text-align: center;
margin-top: 1.5rem;
padding: 1rem;
border-radius: 4px;
background-color: #f8f9fa;
display: none;
}
</style>
</head>
<body>
<div class="login-container">
<h2>用户登录</h2>
<form id="loginForm" action="#" method="POST">
<div class="form-group">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" placeholder="输入任意内容">
<div class="error-message" id="usernameError">用户名不能为空</div>
</div>
<div class="form-group">
<label for="password">密码:</label>
<input type="password" id="password" name="password" placeholder="请输入密码">
<div class="error-message" id="passwordError">密码长度需在6-20位之间,且至少包含字母和数字</div>
</div>
<button type="submit" class="submit-btn">登录</button>
<!-- 欢迎信息区域(使用innerHTML渲染) -->
<div class="success-message" id="welcomeMessage"></div>
</form>
</div>
<script>
const loginForm = document.getElementById('loginForm');
const usernameInput = document.getElementById('username');
const passwordInput = document.getElementById('password');
const usernameError = document.getElementById('usernameError');
const passwordError = document.getElementById('passwordError');
const welcomeMessage = document.getElementById('welcomeMessage');
function validateUsername(username) {
return username.trim() !== '';
}
function validatePassword(password) {
const regex = /^(?=.*[a-zA-Z])(?=.*\d).{6,20}$/;
return regex.test(password);
}
loginForm.addEventListener('submit', function(e) {
e.preventDefault();
let isValid = true;
usernameError.style.display = 'none';
passwordError.style.display = 'none';
welcomeMessage.style.display = 'none';
if (!validateUsername(usernameInput.value)) {
usernameError.style.display = 'block';
isValid = false;
}
if (!validatePassword(passwordInput.value)) {
passwordError.style.display = 'block';
isValid = false;
}
if (isValid) {
const username = usernameInput.value;
// 关键修改:使用innerHTML替代textContent,允许解析HTML/JS
welcomeMessage.innerHTML = `欢迎您:${username}`;
welcomeMessage.style.display = 'block';
}
});
</script>
</body>
</html>
进入浏览器打开用户登录网页:
按要求输入用户名和密码:

如上图所示,通过规则验证,显示“欢迎您:my2307”。
当用户名为空时:

如上图所示,用户名未通过规则验证,显示提示“用户名不能为空”。
当密码不符合要求时:

如上图所示,密码未通过规则验证,显示提示“密码长度需在6-20位之间,且至少包含字母和数字”。
2.2.3 尝试注入攻击,利用回显用户名注入HTML及JavaScript
由于代码中使用innerHTML而非textContent处理用户输入,textContent仅渲染纯文本,会将<、>等符号转义,无法解析HTML/JS;而innerHTML会解析HTML结构并执行内嵌的JavaScript,直接将用户输入作为代码执行,从而导致注入攻击。
(1)注入 HTML
在用户名中输入:
<h1 style="color:red">攻击测试</h1>
攻击者将恶意代码注入到Web页面,当其他用户访问该页面时,代码被浏览器解析执行,当用户输入
<h1 style="color:red">攻击测试</h1>,Web应用未对用户输入做HTML转义,导致攻击者输入的HTML代码被浏览器解析执行,浏览器解析到这段HTML时,会按照<h1>标签的样式渲染 “攻击测试”。
页面会显示红色大标题的 “攻击测试”,如下图所示:

(2)注入JavaScript
在用户名中输入:
<img src='x' onerror='document.body.innerHTML = "JavaScript攻击注入成功!"'>
<img src='x'>是一个图片标签,但src='x'是无效的图片地址,因此浏览器加载图片时会触发标签的onerror事件,onerror事件中嵌入了JavaScript 代码:document.body.innerHTML = "JavaScript injection succeed.",该代码会将整个页面的内容替换为指定文本,实现对页面的篡改。

跳转显示JavaScript攻击注入成功!

2.3 Web后端:MySQL基础
正常安装、启动MySQL,建库、创建用户、修改密码、建表
2.3.1 安装、启动MySQL
systemctl start mysql #启动MySQL
systemctl status mysql #查看MySQL运行状态

2.3.2 建库、创建用户、修改密码、建表
①输入mysql进入数据库管理系统:

②建库、创建用户:
使用以下命令,创建了一个名为db2307的数据库,创建了一个用户,用户名为usermy,初设密码为my123456,授予该用户所有权限,刷新权限。
CREATE DATABASE db2307;#建库
CREATE USER 'usermy' IDENTIFIED BY 'my123456'; #创建用户
GRANT ALL PRIVILEGES ON db2307.* TO 'usermy'; #授予用户所有权限
FLUSH PRIVILEGES; #刷新权限
运行命令如下图所示:

③修改密码:
修改usermy用户密码为my20232307。
ALTER USER 'usermy' IDENTIFIED BY 'my20232307'; #修改用户密码
FLUSH PRIVILEGES; #刷新权限
运行命令如下图所示:

④创建表:
创建一个为test的用户信息表,包含id(主键)、username(50字符非空字符串)、password(100字符非空字符串)三个字段;表通过自增主键确保记录唯一性,用户名和密码字段设为非空保证数据完整性。
CREATE TABLE test (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
password VARCHAR(100) NOT NULL
); #创建表
SHOW TABLES; #查看当前数据库中所有的数据表名称
DESCRIBE test; #查看名为`test`的数据表的详细结构
运行命令如下图所示:

⑤插入数据:
向test表中插入了两条用户记录,具体数据如下:
第一条记录:id为1,username为user1,password为user123
第二条记录:id为2,username为user2,password为user231
INSERT INTO test VALUES (1,'user1', 'user123'),(2,'user2', 'user231'); #插入数据
SELECT * FROM test; #查看表中所有内容
运行命令如下图所示:

2.4 Web后端:编写PHP网页,连接数据库,进行用户认证
还是在var/www/html/目录下,我们新建一个PHP文件,用于接收前端输入的用户名和密码,将输入的信息与数据库中的信息进行比对,验证是否匹配。
PHP代码如下:
<?php
// 设置响应为JSON格式
header('Content-Type: application/json');
// 数据库配置
$db_host = 'localhost';
$db_name = 'db2307';
$db_user = 'usermy';
$db_pass = 'my20232307';
// 初始化响应数据
$response = [
'success' => false,
'message' => '',
'data' => []
];
// 仅允许POST请求
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
$response['message'] = '请使用POST请求';
echo json_encode($response);
exit;
}
// 获取用户输入(不进行过滤)
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
// 基本输入验证(但不过滤特殊字符)
if (empty($username)) {
$response['message'] = '用户名不能为空';
echo json_encode($response);
exit;
}
if (empty($password)) {
$response['message'] = '密码不能为空';
echo json_encode($response);
exit;
}
try {
// 连接数据库
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name;charset=utf8mb4", $db_user, $db_pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 直接拼接SQL语句
$sql = "SELECT id, username, password FROM test WHERE username = '$username' AND password = '$password' LIMIT 1";
// 执行SQL查询
$stmt = $pdo->query($sql);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user) {
// 登录成功 - 直接输出用户输入(存在XSS漏洞)
$response['success'] = true;
$response['message'] = '登录成功';
$response['data'] = [
'user_id' => $user['id'],
'username' => $username, // 直接输出,不进行HTML编码
'raw_username' => $username, // 再次直接输出
'sql_query' => $sql // 泄露SQL查询信息
];
} else {
// 登录失败 - 也直接输出用户输入
$response['message'] = '用户名或密码错误';
$response['data'] = [
'attempted_username' => $username, // 直接输出
'attempted_password' => $password, // 直接输出密码(信息泄露)
'sql_query' => $sql
];
}
} catch(PDOException $e) {
// 向用户暴露详细错误信息(信息泄露)
$response['message'] = '数据库错误:' . $e->getMessage();
$response['data'] = [
'error_details' => $e->getMessage(),
'sql_query' => $sql ?? '未执行'
];
}
// 返回结果 - 不进行任何输出编码
echo json_encode($response, JSON_UNESCAPED_UNICODE);
?>
HTML文件稍做修改,完整代码如下:
点击查看代码
<!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>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Arial, sans-serif;
}
body {
background-color: #f5f5f5;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.login-container {
background-color: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 400px;
}
.login-container h2 {
text-align: center;
margin-bottom: 1.5rem;
color: #333;
}
.form-group {
margin-bottom: 1rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
color: #555;
}
.form-group input {
width: 100%;
padding: 0.8rem;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 1rem;
}
.form-group input:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}
.submit-btn {
width: 100%;
padding: 0.8rem;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
font-size: 1rem;
cursor: pointer;
transition: background-color 0.3s;
}
.submit-btn:hover {
background-color: #0056b3;
}
.error-message {
color: #dc3545;
font-size: 0.875rem;
margin-top: 0.25rem;
display: none;
}
.server-error {
color: #dc3545;
background-color: #f8d7da;
padding: 0.75rem;
border-radius: 4px;
margin-bottom: 1rem;
text-align: center;
display: none;
}
/* 保持原有欢迎信息样式,但使用innerHTML渲染 */
.success-message {
font-size: 1.5rem;
text-align: center;
margin-top: 1.5rem;
padding: 1rem;
border-radius: 4px;
background-color: #f8f9fa;
display: none;
}
</style>
</head>
<body>
<div class="login-container">
<h2>用户登录</h2>
<div class="server-error" id="serverError"></div>
<form id="loginForm">
<div class="form-group">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" placeholder="输入任意内容">
<div class="error-message" id="usernameError">用户名不能为空</div>
</div>
<div class="form-group">
<label for="password">密码:</label>
<input type="password" id="password" name="password" placeholder="请输入密码">
<div class="error-message" id="passwordError">密码长度需在6-20位之间,且至少包含字母和数字</div>
</div>
<button type="submit" class="submit-btn">登录</button>
<!-- 使用innerHTML渲染欢迎信息 -->
<div class="success-message" id="welcomeMessage"></div>
</form>
</div>
<script>
const loginForm = document.getElementById('loginForm');
const usernameInput = document.getElementById('username');
const passwordInput = document.getElementById('password');
const usernameError = document.getElementById('usernameError');
const passwordError = document.getElementById('passwordError');
const welcomeMessage = document.getElementById('welcomeMessage');
const serverError = document.getElementById('serverError');
function validateUsername(username) {
return username.trim() !== '';
}
function validatePassword(password) {
// 放宽密码验证,方便测试
return true;
}
function hideAllMessages() {
usernameError.style.display = 'none';
passwordError.style.display = 'none';
welcomeMessage.style.display = 'none';
serverError.style.display = 'none';
}
loginForm.addEventListener('submit', function(e) {
e.preventDefault();
let isValid = true;
hideAllMessages();
if (!validateUsername(usernameInput.value)) {
usernameError.style.display = 'block';
isValid = false;
}
if (!validatePassword(passwordInput.value)) {
passwordError.style.display = 'block';
isValid = false;
}
if (isValid) {
const formData = new FormData(this);
fetch('20232307.php', {
method: 'POST',
body: formData
})
.then(res => res.json())
.then(data => {
if (data.success) {
// 使用innerHTML渲染,确保XSS代码执行
welcomeMessage.innerHTML = `欢迎您:${data.data.username}`;
welcomeMessage.style.display = 'block';
// 兼容处理:如果是script标签,确保执行
const scripts = welcomeMessage.querySelectorAll('script');
scripts.forEach(script => {
const newScript = document.createElement('script');
newScript.textContent = script.textContent;
document.body.appendChild(newScript).parentNode.removeChild(newScript);
});
} else {
serverError.textContent = data.message;
serverError.style.display = 'block';
}
})
.catch(err => {
serverError.textContent = '网络错误,请重试';
serverError.style.display = 'block';
});
}
});
</script>
</body>
</html>
打开浏览器,输入网址http://localhost/20232307my.html访问网站进行测试,先输入数据库中已有的数据,输入用户名“use1”,密码“user123”,如下图所示:

如上图所示,验证通过,显示“欢迎您:user1”。
当用户名正确,密码错误时

如上图所示,输入的信息错误,提示:用户名或密码错误。
当输入不存在的用户名时:

如上图所示,输入的信息内容不存在,提示:用户名或密码错误。
2.5 最简单的SQL注入,XSS攻击测试
2.5.1 SQL注入
用户名输入:
' OR '1'='1' --
使用最经典的基于布尔盲注的SQL注入payload,当我在用户名输入框填入 ' OR '1'='1' -- 、密码填任意值时,拼接后的SQL会变成:SELECT * FROM users WHERE username = '' OR '1'='1' -- ' AND password = '任意值';密码验证被完全跳过。
密码输入任意,结果如下图所示,可以看到显示欢迎' OR '1'='1' -- ,说明SQL注入成功。

2.5.2 XSS攻击
用户名输入:
<img src=x onerror=alert("XSS攻击成功!")>
攻击者在输入框提交
<img src=x onerror=alert("XSS攻击成功!")>,后台未对输入做任何处理,直接将这段代码作为HTML内容输出到页面,浏览器渲染页面时,解析到标签,尝试加载src=x的图片,但是图片不存在,必然失败,图片加载失败触发onerror事件,浏览器立即执行onerror属性内的alert("XSS攻击成功!");
最终弹出弹窗,证明XSS漏洞存在且可执行任意JS代码。
密码输入任意,结果如下图所示,可以看到跳出一个弹窗,显示XSS攻击成功!

2.6 安装DVWA或WebGoat平台,并完成SQL注入、XSS、CSRF攻击。
2.6.1 环境准备
我使用的是DVWA平台,在kali虚拟机中安装DVWA平台,然后执行以下命令:
sudo service apache2 start # 1. 启动 Apache2 Web 服务
sudo service mysql start # 2. 启动 MySQL 数据库服务
接着在浏览器中输入http://localhost/dvwa/setup.php网址,即可进入DVWA平台,点击创建数据库,然后进入登陆界面,初始默认的用户名是admin,密码是password,点击登录,就进入DVWA平台了,在做实验之前记得选择难度为low.

2.6.2 SQL注入
1.输入User ID为1,显示了对应的name,并且输入的ID值在URL栏中,也说明了是get方法传递参数

输入User ID为1',可以看到出现了一些错误:

由此猜测,存在诸如点,且为字符型注入,单引号闭合。
2.判断字段数
先使用1' order by 1#来尝试一下:
使用列数探测语句, 1'闭合SQL语句中的单引号,触发注入漏洞,order by 1是按第1列排序,#是MySQL 数据库的注释符,注释掉语句后面的所有内容,避免原SQL的剩余字符破坏注入语句的语法。

页面反馈是正常的,接着尝试1' order by 2#

页面反馈依旧是正常的,接着尝试1' order by 3#

页面报错,即可确定表的列数,第三列是不存在的,数据库的表只有两列。
3.查看表中的相关字段
(1)查看当前数据库的版本号,及当前数据库名
使用以下注入语句来查看数据库的版本号及当前数据库名,结果如下图所示:
1' union select version(),database() --

可以当前数据库版本是11.8.3-MariaDB-1+b1 from Debian;当前数据库名是dvwa
(2)查看当前数据库下的所有表名
使用以下注入语句来查看当前数据库下的所有表名:
1' union select version(),group_concat(table_name) from information_schema.tables where table_schema=database() --
结果如下图所示:

可以看到dvwa 数据库有两个数据表:guestbook和users;
(3)查询users表下面的所有字段名
使用以下注入语句来查询users表下面的所有字段名
1' union select version(),group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' --
结果如下图所示:

查询到users表的列名:user_id,first_name,last_name,user,password,avatar,last_login,failed_login
(4)查询users表中的user、password字段数据:
使用注入语句:1' union select user,password from users # 查询users表中的user、password字段数据,结果如下图所示:

如上图所示,查询到了用户名及其密码,返回的密码是MD5哈希值,攻击者可通过哈希破解工具还原为明文,例如查询一下5f4dcc3b5aa765d61d8327deb882cf99对应的明文,查询网站使用了MD5在线解密,解密结果如下图所示:

2.6.2 XSS攻击
(1)XSS(DOM)
观察界面,当选择不同的标签时,URL栏中的default也会发生变化:

default有可能是个传参点,修改default=后面的参数为20232307my,结果如下图所示:

传入xss代码:
<script>alert(20232307)</script>
结果如下图所示:

由上图所示,XSS(DOM)攻击成功。
(2)XSS Reflected
尝试输入值2307:

发现无论我们输入什么值,在页面中都会显示输入的信息,并且url的name传参值就是我们输入的值。
对URL中的name传入xss代码:
<script>alert(20232307)</script>

由上图所示,XSS Reflected攻击成功。
(3)XSS Stored
先尝试输入学号2307,可以看到信息被存储了:

输入xss代码:
<script>alert(2307)</script>
结果如下图所示:

发现name处存在字符限制,使用F12查看前端的代码:

将10个字符的限制修改为100个字符,修改后的代码如下:

重新输入XSS攻击代码<script>alert(2307)</script>

由上图所示,XSS Stored攻击成功。
2.6.2 CSRF攻击
由于这一步骤需要使用Burp Suite工具,我的Burp Suite工具安装在windows主机上面了,所以这一步我是在Windows系统中打开的DVWA平台和Burp Suite工具。
尝试修改密码为12345,

但是能够主要到当我们更改密码成功后url栏的参数是这样的
http://127.0.0.1/DVWA/vulnerabilities/csrf/?password_new=12345&password_conf=12345&Change=Change#
可以分析出password_new是我输入的密码,password_conf是我确认的密码,说明我们在网站上输入的信息是会在url栏这里进行一个传输执行,
使用Burp Suite抓包,如下图所示:

发现url栏的信息和请求的信息是一致的,大胆猜测如果我能控制url栏里传入的参数,就能够不在网站内执行更改密码的操作。
更改url的参数:
http://127.0.0.1/DVWA/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#
只需要在原来的url基础上该新密码和确认密码的参数即可。

如上图所示,页面跳转到了dvwa的更改密码界面,csrf攻击成功。
但是在真实CSRF攻击中,攻击者为了隐藏自己的攻击手段,可能构造一个假的页面,然后放在公网上,诱导受害者访问这个页面,如果受害者访问了这个页面,那么受害者就会在不知情的情况下完成了CSRF攻击。自己测试可以写一个本地页面,也可以利用burpsuit直接生成攻击页面代码。方法如下:
抓取更改密码的数据包,利用engagement tools生成CDRF PoC,访问点击提交之后就可以更改密码。CDRF PoC生成器生成的代码如下图所示:

我最开始在DVWA网站想修改密码为12345,但是在CDRF PoC生成的代码中,我把密码改为了123456,点击用浏览器测试:

复制网址到浏览器中:

点击send request以后发现密码成功修改:

进入DVWA平台的初始登陆界面,使用我刚刚修改的密码123456登录:

可以看到登陆成功:

3.问题及解决方案
- 问题1:在2.4编写PHP网页,连接数据库,进行用户认证的过程中,前端的数据信息并没有传到后端。
- 问题1解决方案:经过检查,发现创建PHP文件时,没有和HTML文件放在同一个目录下,更改到同一个目录下之后运行成功。
- 问题2:windows平台中尝试使用Burp Suite工具,但是Burp Suite工具抓不到DVWA平台的包。
- 问题2解决方案:原因是Firefox默认不代理本地地址(localhost/127.0.0.1)的流量,需要修改配置:在Firefox地址栏输入 about:config,点击 “接受风险并继续”;搜索network.proxy.allow_hijacking_localhost,双击将其值改为True。
4.学习感悟、思考等
通过本次实验我进一步理解了Web安全和相应的攻击手段,在实现一个虽然简单但是完整的前端、数据库、后端处理的整体连接后成就感满满,“实践是检验真理的唯一标准”,通过实践不仅加深了我对知识的理解,更是增强了对代码的理解和整体框架的搭建能力。
在DVWA平台的实践让我觉得十分有趣,通过SQL注入、XSS、CSRF攻击的实践,我进一步理解了攻击的原理和目的,同时也意识到网络攻击不可忽视,不要随意点击陌生链接。
本学期的实验到这里就结束了,经过一学期的网络攻防课程的学习,我对我的专业有了更深刻的认知,非常感谢这一学期以来老师和同学们对我的帮助,未来我将继续精进我的专业能力,继续努力!

浙公网安备 33010602011771号