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())。

5. 参考资料

posted on 2024-12-04 08:16  云烟飘渺PM  阅读(88)  评论(0编辑  收藏  举报