20222423 2024-2025-1 《网络与系统攻防技术》实验八实验报告
1. 实验内容
1.1 学习内容回顾
-
本周主要聚焦于Web安全,复习了Web中前后端的概念,并且了解了前端(如html,css,js等)和后端(java,c,c++,python等常用语句),算是整体对Web技术和概念做了一个回顾
-
回顾了SQL语法,了解了基本的SQL注入原理,知道SQL注入大体分为普通注入和盲注入,可以利用一些字符插入到原本后端的执行SQL语句中,比如利用
--
字符将后面的语句注释掉,可以利用其完成绕过登录等 -
学习了XSS攻击,由于现在好多网页都有安全保障措施,实现起来变得困难,所以在这部分了解了一些常用的web靶场,比如WebGoat或者 “皮卡丘”等,了解了基本攻击形式。
-
了解了CSRF漏洞、知道了其背后的原理和影响。
-
通过对常见WEb攻击的学习,反过来提升安全意识,做到从攻击中学习怎么进行安全保护。
1.2 实验内容
(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.实验过程
Apache HTTP Server(简称Apache)是Apache软件基金会的一个开放源码的网页服务器,可以在大多数计算机操作系统中运行。由于其跨平台和安全性被广泛使用,是最流行的Web服务器端软件之一。
2.1 正常安装、启停Apache。理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML
2.1.1 使用、启动Apache
在java里面自带Apache服务器
查看服务器状态
systemctl status apache2
可以看到最初apache状态是未启动的
启动apache服务
systemctl start apache2
随后打开火狐浏览器,输入127.0.0.1
看到这样的界面说明服务成功启动了
停止apache服务
systemctl stop apache2
看到apache2服务成功停止
2.1.2 编写一个表单HTML,做到理解HTML,理解表单,理解GET与POST方法
记得关掉后打开apahce2服务
启动apache2服务,进入火狐浏览器,输入127.0.0.1
在win主机,端使用sublime
工具编写了简单地表单界面(非常好用,十分推荐),文件名为form20222423.html
,结果如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>简单表单测试</title>
<style>
form {
width: 300px;
margin: 20px auto;
}
label {
display: block;
margin-top: 10px;
}
input {
width: 100%;
padding: 5px;
}
input[type = "submit"] {
margin-top: 15px;
background - color: #fff;
color: green;
border: none;
padding: 8px 12px;
}
</style>
</head>
<body>
<form name="myForm" action = "lpy2423.php" method = "get" id="myForm" onsubmit="return check()">
<label for = "name">姓名:</label>
<input type = "text" id = "name" name = "name">
<label for = "password">密码:</label>
<input type = "password" id = "password" name = "password">
<input type = "submit" value = "提交">
<p>made by 20222423lpy</p>
</form>
</body>
将文件复制到kali中,并将网页传到 /var/www/html
之下
随后再url输入传入的html文件名即可访问网站
可以看到制作了一份简单表单网页,需要用户输入账号密码
使用get请求
在表单中随意输入一些内容点击提交,看看有什么反映
可以看到,提交之后,表单中用户输入的内容是以明文方式传递的
和win中一样,按住Fn + F12
打开控制台界面
可以看到后台解析出了使用的方法为get方法
post方法使用
随后将表单提交中的method改为 post方法
再次打开这个网站
随便在表单中输入内容,点击提交
可以看到提交后的URL是没有显示用户输入的数据的
打开控制台界面
可以看到使用了post方法,请求头中传递的信息是不可见的
总结post方法和get方法
特点 | GET方法 | POST方法 |
---|---|---|
数据传输方式 | 将数据附加到URL的查询字符串中 | 将数据放在HTTP请求的消息体中 |
安全性 | 数据在URL中可见,不适合传输敏感信息 | 数据不在URL中暴露,相对更安全 |
缓存机制 | 请求可以被缓存,并且可以被保存在浏览器历史记录中 | 请求不会被缓存,也不会被保存在浏览器历史记录中 |
默认方法 | 是Form的默认方法 | 暂无 |
2.2 Web前端javascipt,理解JavaScript的基本功能,理解DOM。在(1)的基础上,编写JavaScript验证用户名、密码的规则。在用户点击登陆按钮后回显“欢迎+输入的用户名”
JavaScript是一种高级的、解释执行的编程语言,广泛应用于Web开发中,主要用于增强网页的交互性和动态性。它是一种轻量级的、跨平台的脚本语言,能够使网页可交互,例如拥有复杂的动画、可点击的按钮、弹出菜单等。JavaScript还可以用于服务器端开发,如Node.js,允许为网站添加更多功能,而不仅仅是下载文件
2.2.1 利用Javascript,编写验证用户名、密码的规则。在用户点击登陆按钮后回显“欢迎+输入的用户名”
这里我设置的规则比较简单,也就是用户名不为空,密码输入的时候不能为空,此外密码长度不能小于8位。如果像将密码或用户名的验证功能更复杂,可以使用 正则表达式 完成这一工作
在body标签后添加了script标签
代码如下:
<script>
function check() {
var name = document.getElementById('name').value;
var password = document.getElementById('password').value;
// 验证姓名不为空
if (name === "") {
alert('姓名不能为空');
return false;
}
// 验证密码不为空
if (password === "") {
alert('密码不能为空');
return false;
}
// 验证密码长度不小于8位
if (password.length < 8) {
alert('密码长度必须不小于8位');
return false;
}
document.write('欢迎' + name);
return true;
}
</script>
随后将内容添加到form20222423.html
中,保存
再次打开网页,进入自己编写的html文件,测试是否完成了简单表单验证功能
1.当用户名为空时
2.当密码为空时
3.当密码长度较短的时候
4.当成功登录后
可以看到在登录成功后在网页端回显了“你好”和自己提交的用户名
2.2.2 利用该网站,尝试注入攻击:利用回显用户名注入HTML及JavaScript。
DOM(Document Object Model,文档对象模型)是一种跨平台、语言中立的接口,它表示HTML或XML文档的内容和结构。DOM将网页中的元素(如文本、图像、链接等)表示为一个树形结构,开发者可以通过JavaScript等编程语言来访问和操作这些元素。DOM树是一种层次结构,网页中的每个元素都是一个节点,节点之间有着父子关系。
下面根据这个网页进行简单地注入攻击攻击,在用户名中添加入以HTML文本和脚本
<h1>attacked by 20222423</h1>
<script>alert('你被攻击了! by 20222423');</script>
点击提交,就会出现下面的结果
这说明script
部分的功能起作用了。
在网页回显部分,可以看到用到的字体就是<h1>
格式的字体,说明简单的注入攻击成功实现了!
2.3 Web后端:MySQL基础:正常安装、启动MySQL,建库、创建用户、修改密码、建表
由于我上学期刚好选修了 数据库应用 这门课,所以对SQL语句相对比较熟悉
MariaDB是一个开源的关系型数据库管理系统(RDBMS),它是MySQL的一个分支,由MySQL的创始人之一Michael "Monty" Widenius领导的团队创建和维护。MariaDB旨在继承MySQL的优良传统,并在此基础上提供更多的功能和改进。
2.3.1 启动停止MYSQL数据库
kali里面默认自带数据库,先查看一下状态,没启动就输入命令直接启动
systemctl status mysql
/ 查看数据库状态 /
systemctl start mysql
/ 启动mysql服务 /
mysql -u root -p
/ SQL语句,连接数据库 /
kali里面mysql数据库默认是root的密码是root
systemctl stop mysql
/ 停止数据库服务 /
2.3.2 新建数据库
连接到数据库后,输入\h
查看一下帮助
use mysql;
/ 切换数据库 /
show databases;
/ 查看有哪些数据库 /
使用mysql
查看当前数据库有那些
建立新的数据库db20222423
create database db20222423;
2.3.3 创建新用户,修改密码
创建新用户 lpy20222423
create user 'lpy20222423'@'%' IDENTIFIED BY '20222423';
/ '@‘符号后面表示允许连接的IP,%’符号表示连接任意主机都可以 /
grant all privileges on db20222423.* to 'lpy20222423'@'%';
/ .*表示将对于数据库db20222423的所有权限全部授予用户lpy20222423 /
flush privileges;
/ 刷新全新阿彪,让修改生效 /
show grants for 'lpy20222423'@'%';
/ 查看用户首选信息 /
修改用户密码
alter user 'lpy20222423'@'%' identified by '123456';
/ 重新修改密码 /
select host,user,password from user;
/ 查看用户 /
测试修改后的用户能否连接到数据库
可以看到用户lpy20222423
只能看到自己的数据库,应为他只有对db20222423
的所有权限,这里就是数据库中权限管理部分的知识,要深挖的话内容还是很多的,这里不再介绍
2.3.4 新建表
show tables;
/ 查看数据库中有哪些表 /
可以看到这个新数据库中还没有表
创建登录用户表userLogin
CREATE TABLE userLogin (
userID INT PRIMARY KEY, //PRIMARY KEY表示主键
userNAME VARCHAR(255),
userPW VARCHAR(255)
);
可以看到成功创建了新表userLogin
下来在表中插入一些测试数据
INSERT INTO userLogin (userID, userNAME, userPW)
VALUES
(1, '20222423lpy', '20222423'),
(2, 'liupinyuan', '123456'),
(3, 'manbo', '114514'),
(4, 'jinkela', 'sdyg'),
/ 表中插入一些数据 /
select * from userLogin;
/ 测试数据是否成功插入表中 /
可以看到我们成功在数据库db20222423
中创建了一张新表lpy20222423
,并且在其中插入了一些测试数据
2.4 Web后端:编写PHP网页,连接数据库,进行用户认证
2.4.1 编写php网页文件
还是使用sublime
工具,编写php文件lpy2423.php
,结果如下
<?php
// 数据库连接信息
$servername = "localhost"; // 通常为localhost,如果是远程数据库则为相应的IP地址$
$username = "lpy20222423"; // 替换为你的数据库用户名
$password = "123456"; // 替换为你的数据库密码
$dbname = "db20222423"; // 替换为实际的数据库名
// 创建连接
$conn = new mysqli($servername, $username,$password, $dbname);
// 检查连接是否成功
if ($conn->connect_error) {
die("连接失败: ". $conn->connect_error);
}
//获取前端发来的数据
$name = $_POST['name'];
$password = $_POST['password'];
//查询用户密码
$sql = "select * from userLogin where userNAME = '$name' and userPW = '$password' ";
$result = $conn->query($sql);
//查询,判断用户是否在表中
if($result->num_rows > 0)
{
header("Location:Login_success.html");//登陆成功跳转到Login_success.html
exit();
}
else
{
header("Location:Login_failed.html");//登录失败跳转到Login_failed.html
exit();
}
$conn->close();
//关闭连接
?>
前端页面表单代码也需要改一下
这里的action``改为跳转到刚才编写的lpy2423.php
网页
创建了成功连接的网页Login_success.html
和不成功的Login_failed.html
;
将上面的文件都放在/var/www/html文件夹下
2.4.2 测试连接数据库,进行认证
PS:由于在原本的form20222423.html中提交数据后会将数据
document.write()
显示网页中,这和我的页面跳转有一定的冲突,所以这里我将原本<script>
中的document.write()
修改为了alert()
弹窗,利用界面跳转更好的展示登录成功和失败的结果
测试用户:20222423lpy 密码:20222423
当输入userLogin表
中存在的用户和密码时候,结果如下
测试登录失败的结果
用户:liupinyuan 密码:11111
这是里的密码是随便输入的,和数据库中的条目匹配不上,无法登录,结果如下:
可以看到成功实现了简单的表单提交和页面跳转功能!
2.5 最简单的SQL注入,XSS攻击测试
2.5.1 简单SQL注入
这里在用户名中输入'or1=1#
,用户名任意即可,都可以的登录成功
由于之前在php文件中,查询语句的逻辑是
select * from userLogin where userNAME = '$name' and userPW = '$password'
而这里如果将用户名改为 ' or 1=1 #
那么前端提交数据后,查询语句就会变成
select * from userLogin where userNAME = '' or 1 = 1 #' and userPW = '$password'
能够看到密码部分的查询就被注释掉了
然后前面的语句相当于 或 运算了一个 1=1(永真式)
回顾下离散数学的知识,一个逻辑式 or
一个永真式后,那么这整个式子是也是永真的
也就意味着上面的查询结果永远返回true
,意味着能够查询到对应的用户
由此就跨过了验证这一步,直接不需要密码登录成功
2.5.2 简单XSS注入
PS:由于之前编写php文件实现登录时候,我将form20222423.html进行了一点小改动,我将原本的
<script>
中的回显方式doucment.write()
改为了弹窗alert()
,经过测试使用alert()
的时候注入的HTML或者是script脚本时无法识别执行的,所以这里又换回了document.write()
方式,详细内容见后面的问题及解决部分
依旧是回到登录界面,在用户名中输入
<script>alert('你被攻击了! by 20222423');</script>
点击提交,出现下面的弹窗说明注入成功!
2.6 安装DVWA或WebGoat平台,并完成SQL注入、XSS、CSRF攻击。
WebGoat是由OWASP(开放式Web应用程序安全项目)维护的一个故意不安全的Web应用程序,旨在教授Web应用程序安全课程。它演示了常见的服务器端应用程序缺陷,这些练习旨在供人们学习应用程序安全和渗透测试技术
2.6.1 安装WebGoat平台
我选择靶场为WebGoat,下载链接
注意,下载的时候挂上加速器下载,国内是对github官网的访问是限速的
注意,这种jar包下载配置的方式需要安装jdk,并且需要根据自己安装的jdk版本选择适合的jar包
由于我kali中的jdk版本比较新,所以直接安装最新版本的WebGoat即可
下载webgoat,新建文件夹,专门放jar包
然后使用命令行启动
java -jar weboat-2023.8.jar
随后打开浏览器,输入http://localhost:8080/WebGoat
由于没有账户,这里要点击注册
进入注册界面,这里我使用的是学号注册账户密码
注册后进入的结果如下
这样就成功安装配置了WebGoat靶场
2.6.2 完成SQL注入
SQL注入(SQL Injection)是一种常见的网络攻击技术,攻击者通过在用户输入字段中插入恶意的SQL语句,欺骗数据库执行这些命令,从而达到窃取、篡改或破坏数据库中敏感数据的目的。这种攻击方式利用了Web应用程序对用户输入数据验证不足的漏洞
首先学习SQL注入
找到A3 -> SQL Injection
这里就可以从入门到入狱,学习SQL注入相关知识
然后开始实战
这里和前面自己搭建网站实现SQL注入形式很相似,也是根据查询语句注入SQL语言完成跳过验证
有了前面的经验,这里就不难选择了,这里选择Smith'
、or
和'1'='1
,提交后成功界面如下
测试所用的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'
和前面的逻辑一样,相当于在整个语句后面加上了or '1' = '1'
这一条永真式,让整个SQL语句结果变为永真
趁热打铁,再测试一个,选择第10关
这里在Authenciation Tan部分输入'or '1' = '1
可以看到成功攻击
原理还是老样子,想办法将整个SQL语句变为永真式就行
2.6.3 XSS注入
XSS(跨站脚本攻击)是一种常见的网络攻击方式,攻击者通过在目标网站中注入恶意脚本,当用户访问该网站时,恶意脚本会在用户的浏览器中执行,从而达到窃取用户信息、篡改页面内容等目的
找到A3 -> Cross Site Scripting
在这里学习XSS注入相关内容
然后来实践一下,找到第7关
在card number 部分输入
<script>alert('Attacked by 20222423');</script>
<p>attacked by 20222423</p>
可以看到成功实现了弹窗,并且在页面中显示了attacked by 20222423
<div id="a">this is hacker</div>
<script> document.getElementById("a").innerHTML="attcaked by 20222423";</script>
也可以利用回显写入的方式,在页面中添加黑客信息
2.6.4 CSRF攻击
CSRF(Cross-Site Request Forgery)攻击,称为跨站请求伪造,是一种常见的Web应用程序攻击方式。攻击者通过诱使用户访问恶意网站,利用用户在其他网站已登录的身份信息,隐式发送敏感操作的请求。由于用户已登录该网站,请求会自动携带用户的身份信息,服务器接收到请求后,由于身份信息正确,会执行相应的敏感操作。整个过程中,用户在访问恶意网站时通常不需要进行任何操作,攻击行为在用户不知情的情况下发生
找到A10 -> Cross-Site Request Forgeries
,进行CSRF攻击的学习
下面开始实践
先点击一下Submit Query
按钮,之后会跳转到一个页面
可以看到flag的值是null
根据前面测试网页的信息不难知道,这里需要得到flag的值,完成攻击
回到测试界面,打开控制台界面,查看网页代码
在提交页面找到这一部分form表单
代码
(太难找了。。。)
将需要的代码拷贝出来
保存在一个html文件中,这里我保存在20222423_web.html中
结果如下,注意这里需要将action部分添加一些内容,在前面添加上
http://localhost:8080/
打开结果是个这个
点击Submit Query
的按钮,会跳转到这个页面
可以看到flag的值是37411
回到训练页面,输入flag的值,出现下面的结果说明成功了
至此实践内容完成!
3. 问题及解决方案
- 不同回显方式使用时候的理解问题
其实这个不能算问题,应该叫拓展更合适点
在使用javaScript编写表单验证的时候,最初我以为的回显就是使用alert()弹窗弹出需要的内容
但是如果使用alert()时候,发现XSS注入无法实现,如下
20222423<script>alert('你被攻击了!');</script>
网站会将内容原原本本的呈现出来,而不是解析为脚本语言
使用Html的注入也不行
20222423<h1>你被攻击了</h1>
也不会将其识别为html语言
所以在实验中回显方式基本使用的是document.write()
这样才能实现XSS简单注入
所以这就引发了我的思考,alert方式和document.write()方式数据解析和呈现方式有什么不同?
搜集了大量介绍,可以总结出两个函数以下的特点和不同之处
alert()函数:用于在浏览器中弹出一个警告框,通常用于向用户显示一条消息或提示。当alert()函数被调用时,它会阻塞代码的执行,直到用户点击警告框中的“确定”按钮。这种函数通常用于提供用户反馈或确认信息。
document.write():用于将文本或HTML代码直接写入到网页的文档流中。这意味着它会在网页中显示指定的内容。与alert()不同,document.write()不会阻塞代码的执行,而是立即将内容写入到网页中。这种函数通常用于动态生成网页内容或在网页中插入信息。
简单总结一下,有以下不同:
对比 | alert() | document.write() |
---|---|---|
功能 | 弹出警告框 | 写入网页内容 |
阻塞执行 | 是 | 否 |
使用场景 | 用户反馈、确认信息 | 动态生成内容、插入信息 |
输出位置 | 弹出框 | 网页文档流 |
内容类型 | 纯文本 | 文本或HTML代码 |
这下就更加清晰了,alert()
使用的时候,是将内容作为纯文本信息传递执行的,所以并不会对其进行深入解析,但document.write()
函数是会将内容写入网页的,所以如果在写入的内容中注入Script或者html语言是会被解析识别出来
那这下就不奇怪为什么使用alert()
的时候S简单的XSS注入无法实现,而document.write()
就可以解析出来,而且alter()函数会阻断代码的执行,但是document.write()
不会阻断,而是接续执行,那就意味着如果我使用document.write()
回显信息的时候,如果XSS攻击中注入了真的有威胁的攻击语句,那么是很难做到拦截的。
4. 学习感悟、思考等
-
通过手动实践完成web网页搭建,JavaScript编写,php编写,mysql使用等内容,算是整个对web知识进行了一个系统回顾,之前上web设计课程时候有些没搞懂的地方反而通过亲自实践理解了,所以真的是纸上得来终觉浅,绝知此事要躬行。Web技术光靠讲解和书本上的理论是远远不够的,有时候亲手实践一下获得的东西能更多。
-
此外就是对XSS、CSRF攻击、SQL注入等常见基本Web攻击有了一定了解和体会,原来可以基于基本语句,巧妙插入一些字符,巧妙构造想要的攻击语句,就能直接实现Web攻击。所以对于安全设计,要细致考虑,有时候一些看上去没有问题的设计背后就存在着可以被利用的漏洞,就比如此次XSS攻击,没想到可以直接在表单中写入Html语言或者Script脚本就能够直接实现攻击,而究其原因就来自于网页编写的时候一些看似短小不起眼的代码行(
比如document.write()
)。