20222420 2024-2025-1 《网络与系统攻防技术》实验八实验报告

1.实验内容

1.1 近期学习内容简述

(1)学习了Web前后端的语言的简介
(2)学习了SQL注入的多个实例,知道了SQL注入的原理
(3)学习了XSS跨站脚本攻击的原理和示例
(4)了解了CSRF的原理和防范方法
(5)了解了Burpsuite等工具

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.实验过程

2.1 Web前端HTML(能正常安装、启停Apache。理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML)

(1)正常安装、启停Apache

  • 使用sudo apt install apache2命令自动安装配置Apache(由于kali自带,这里就不展示了)

  • 使用sudo systemctl start apache2命令启动Apache,使用sudo systemctl status apache2命令查看Apache状态
    可知已经启动

  • 浏览器浏览localhost
    可再次确定Apache启动成功

  • 使用sudo systemctl stop apache2命令关闭Apache,使用sudo systemctl status apache2命令查看Apache状态
    可知已经关闭

(2)理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML

  • /var/www/html/创建文件Get_method.html

    • 创建一个html文件在桌面,然后使用命令sudo mv Get_method.html /var/www/html/Get_method.html将其移动到/var/www/html/
    • Get_method.html中写入Get方法的html代码
    • 访问http://localhost/Get_method.html并提交数据
      可知,Get方法提交后,数据在URL中可见

  • /var/www/html/创建文件Post_method.html

    • 创建一个html文件在桌面,然后使用命令sudo mv Post_method.html /var/www/html/Post_method.html将其移动到/var/www/html/

    • Post_method.html中写入Post方法的html代码

    • 访问http://localhost/Post_method.html并提交数据
      可知,Post方法提交后,数据在URL中不可见,因为数据放在HTTP请求的主体部分(body),不会显示在URL中。

    • 但是抓包还是能抓到明文数据,使用https就会安全很多

(3)总结 GET 方法和 POST 方法

区别 GET 方法 POST 方法
请求目的 从指定的资源请求数据 向指定的资源提交数据以进行处理(例如,创建/更新资源)
请求参数位置 参数附加在URL的末尾(查询字符串) 参数包含在HTTP请求的主体中
数据可见性 参数在URL中可见,可能会被缓存和记录在服务器日志中 参数在HTTP请求主体中,相对不那么容易被直接访问或记录
数据大小限制 通常受限于URL长度和服务器配置(较短) 无严格限制,取决于服务器配置(较长)
安全性 不太安全,因为参数在URL中可见 相对更安全,因为参数不在URL中,但需要使用HTTPS来确保数据传输的安全性
浏览器书签 可以将请求URL书签化 无法直接书签化POST请求的URL
缓存 浏览器和某些中间件可能会缓存GET请求的响应 POST请求的响应通常不会被缓存
使用场景 适用于请求数据而不改变服务器状态的操作(例如,搜索查询) 适用于提交数据以改变服务器状态的操作(例如,表单提交)

2.2 Web前端javascipt(理解JavaScript的基本功能,理解DOM;在(1)的基础上,编写JavaScript验证用户名、密码的规则。在用户点击登陆按钮后回显“欢迎+输入的用户名”;尝试注入攻击:利用回显用户名注入HTML及JavaScript)

  • /var/www/html/创建文件Post_JS.html

  • Post_JS.html中写入Post方法的html代码

点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Register: POST JS 20222420</title>
    <style>
        /* 简单的样式,用于显示欢迎信息 */
        #welcomeMessage {
            color: green;
            font-weight: bold;
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <h1>Register: POST JS 20222420 </h1>
    <form id="myForm" action="/submit" method="post">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" required>
        <br><br>
        <label for="password">Password:</label>
        <input type="password" id="password" name="password" required>
        <br><br>
        <button type="submit">Submit</button>
    </form>
    <p id="welcomeMessage"></p> <!-- 用于显示欢迎信息的元素 -->

    <script>
        // 获取表单元素
        const form = document.getElementById('myForm');
        const usernameInput = document.getElementById('username');
        const passwordInput = document.getElementById('password');

        // 添加事件监听器
        form.addEventListener('submit', function(event) {
            // 阻止表单的默认提交行为
            event.preventDefault();

            // 获取用户输入
            const username = usernameInput.value.trim();
            const password = passwordInput.value.trim();

            // 验证用户名和密码
            const usernameValid = username.length >= 5;
            const passwordValid = password.length >= 8 && /\d/.test(password);

            // 如果验证通过
            if (usernameValid && passwordValid) {
                // 显示欢迎信息
                document.write('欢迎' + username);

            } else {
                // 如果验证失败
                alert('用户名必须至少包含5个字符,密码必须至少包含8个字符且包含至少一个数字。');
            }
        });
    </script>
</body>
</html>

  • 验证“JavaScript验证用户名、密码格式”的功能。验证在用户点击按钮后回显“欢迎+输入的用户名”的功能。

    • 用户名符合,但密码未含数字
      我只设置了一个提示信息,所以用户名和密码均提醒了
    • 用户名长度不够,密码符合
      我只设置了一个提示信息,所以用户名和密码均提醒了
    • 用户名、密码格式均符合,回显“欢迎+输入的用户名”
  • 注入攻击:利用回显用户名注入HTML及JavaScript
    用户名输入<script>alert('你被20222420攻击了!')</script> <h1>你被20222420攻击了</h1>

    • JavaScript效果
    • HTML效果

2.3 Web后端(MySQL基础:正常安装、启动MySQL,建库、创建用户、修改密码、建表)

(1)安装

使用sudo apt install mariadb-server命令自动安装配置即可,mariadb-server适用于需要存储和管理大量数据的场景。由于kali自带了mariadb,这里就不展示了

(2)启动并验证,并登录

  • 使用systemctl start mysql启动,systemctl status mysql验证
    disable是指未设置开机自启动,但其是启动了的、在运行的

  • 登录,使用sudo mysql -uroot -p,输入mysql的密码时直接输入“回车”

(3)建库并验证

使用create database test;创建名为test的数据库实例,然后使用show databases;验证

(4)创建用户并验证

使用CREATE USER 'test'@'%' IDENTIFIED BY 'test';,还可以将test数据库实例的权限授予test用户

(5)修改密码

使用ALTER USER 'test'@'%' IDENTIFIED BY 'change';

(6)建表并使用、验证

  • 使用CREATE TABLE testTable (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(255) NOT NULL);可以创建一个表并设置了主键

  • 添加数据到表,只需要添加到name,主键会自动递增添加
    INSERT INTO testTable (name) VALUES ('Alice');
    `INSERT INTO testTable (name) VALUES ('Bob');``

  • 查看、验证表
    使用select * from testTable;,可知表创建成功并成功添加了数据

2.4 Web后端:编写PHP网页,连接数据库,进行用户认证

  • root用户创建user_auth数据库实例,并创建表users、插入数据

    • 创建user_auth数据库实例

    • 进入实例,创建表usersCREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL,password VARCHAR(50) NOT NULL);

    • 修改root密码,使其不为空(否则后续连不上),并给予其user_auth的权限(虽然默认root创建者有权限)

    • 插入数据,INSERT INTO users (username, password) VALUES ('testuser', 'testpassword');

  • 编写PHP网页

点击查看代码
<?php
session_start();
 
// 数据库连接参数
$servername = "localhost";
$dbusername = "root";
$dbpassword = "root";
$dbname = "user_auth";
 
// 创建数据库连接
$conn = new mysqli($servername, $dbusername, $dbpassword, $dbname);
 
// 检查连接是否成功
if ($conn->connect_error) {
    die("连接失败: " . $conn->connect_error);
}
 
// 如果表单已提交
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $inputUsername = $_POST['username'];
    $inputPassword = $_POST['password'];
 
    // 查询数据库中的用户
    $result = $conn->query("SELECT * FROM users WHERE username = '$inputUsername' AND password = '$inputPassword'");
 
    if ($result->num_rows > 0) {
    
    
        // 如果用户存在,获取其信息
        $row = $result->fetch_assoc();

        $_SESSION['loggedin'] = true;
        $_SESSION['username'] = $inputUsername;
        echo "登录成功!";
            // 这里可以重定向到其他页面
            // header("Location: protected_page.php");
            // exit();
        
    } else {
        echo "用户名不存在,或密码错误。";
    } 
 
    // 关闭结果集
    $result->close();
}
 
// 关闭数据库连接
$conn->close();
?>
 
<!DOCTYPE html>
<html>
<head>
    <title>用户登录</title>
</head>
<body>
    <h2>登录 made by 20222420</h2>
    <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
        用户名: <input type="text" name="username" required><br>
        密码: <input type="password" name="password" required><br>
        <input type="submit" value="登录">
    </form>
</body>
</html>

  • 登录,验证“用户认证”功能
    • 用户不存在或密码错误示例
      我没有区分具体是用户不存在还是密码错误

    • 验证,登录成功示例

2.5 最简单的SQL注入,XSS攻击测试

使用2.4中的数据库和php网页

  • SQL注入
    使用' or 1=1; -- 作为用户名,注意一定要在--后添加空格否则会卡死在相关语句。密码可以随便填
    这样sql语句变为SELECT * FROM users WHERE username = '' or 1=1; -- AND password = '$inputPassword'。WHERE中一定为真,并且-- 后的语句被注释掉了导致不需要密码

  • XSS攻击

    • 首先需要修改一下php网页,使其可以回显用户输入的账户名,否则攻击语句无法执行
      如图,修改代码,使其可以在登录失败时回显输入的用户名

    • 验证,输入<script>alert("20222420XSS")</script>
      如图,利用网站没有对用户提交数据进行转义处理或者过滤的缺点,添加了html代码,嵌入到web页面中去

2.6 安装DVWA或WebGoat平台,并完成SQL注入、XSS、CSRF攻击

(1)DVWA平台

  • 完成SQL注入

    • 首先输入' or 1=1; -- 进行测试
      可以,SQL注入已经成功,输出了全表的内容。还可知显示的id并不是表中的id而是直接返回了我输入的内容。
    • 进一步进行SQL注入,获取更多信息
      使用' or 1=1 union select version(),database(); --
      如下图,可知,不仅显示了人名,还通过union显示了数据库的版本号为“5.7.26”,及当前数据库名“dvwa”
  • 完成XSS攻击

    • 题目如图

    • 这一题中,只能选择语言并提交。通过仔细观察和反复尝试,可知点击提交后会在URL中出现default=并显示所选择的语言。
      可以分析出,该网页使用的是GET来传递参数

    • 改变default=后的内容,实现XSS攻击
      改为<script>alert("20222420XSS")</script>,由下图可知成功

  • 完成CSRF攻击

    • 分析该题
      该题可以更改自己的密码,然后可以验证修改后的密码

    • 测试后发现,参数直接通过URL传递

    • 准备CSRF攻击
      通过burp拦截,我就得到了一个发送的包,然后通过burp中的工具直接便捷得生成CSRF攻击用的html

    • 修改一下生成的html中的密码的值,使其变为我想要攻击他人时使其密码改变为的值,如6666,然后复制生成的URL

    • 这样,当他人在登陆着http://127.0.0.1/DVWA-master/vulnerabilities/csrf/时,若点击了我的危险网站(即上面生成的URL,或包含该URL的其他看似正常的网站),他的密码就会被我改变
      如下图所示

    • 测试
      由下图可知,成功了

(2)WebGoat平台

  • 完成SQL注入

    • Login_Count输入1 or 1=1; -- 进行测试
      但显示无法解析我的输入到一个数字

    • 查看题目得知,只有一个空对于SQL注入是脆弱的,看来应该是下面一个空
      User_Id输入1 or 1=1,在Login_Count输入正常的数字。如下可知注入成功。

  • 完成XSS攻击
    直接输入<script>alert("20222420XSS")</script>

  • 完成CSRF攻击

    • 这道题需要从发送评论,但必须从其他地方发送
      只需要用burp拦截获取包的格式,然后生成CSRF的html,再修改一下生成的html即可,如下图,我想发送的评论是test星级为4

    • 复制得到的URL

    • 验证
      当登陆着http://127.0.0.1:8080/WebGoat/csrf/review的人点击了该URL,就会发送该评论(test,星级为4
      验证过程如下面三图,可知我(即被攻击者)已经成功从其他位置发送了该评论


3.问题及解决方案

  • 问题1:无法将创建的文件放入/var/www/html/
  • 问题1解决方案:利用sudo mv命令就有权限了
  • 问题2:SQL注入时一直不成功
  • 问题2解决方案:询问AI,本来AI是不会给相关的答案的。但换一种方式问,问我这样能否通过,AI就给出了回答。然后我就得知原来--后需要空格才能起到注释的效果,这样我就解决了问题。
  • 问题3:我写的网页先用SQL语句验证了用户名,然后用$row['password'] === $inputPassword验证密码。但只有用户名能使用SQL注入,这导致我无法用SQL注入登录。
  • 问题3解决方案:更改代码,像课件里的一样用SQL语句同时验证用户名和密码即可直接通过SQL注入登录。
  • 问题4:php连接不上数据库
  • 问题4解决方案:经过检查,代码是没问题的,数据库也没问题。可能是因为数据库的root用户没有设置密码,且$dbpassword = "";不代表没有密码,导致连接不上数据库。设置密码后便解决了。

4.学习感悟、思考等

在这次实验中,我体会了Web开发中的前端与后端技术是如何协同工作的。通过安装和配置Apache服务器以及MySQL数据库,我学会了如何在服务器端搭建一个Web环境。编写HTML表单和JavaScript验证逻辑,让我对前端技术有了更深入的理解,特别是在处理用户输入和表单提交方面。同时,我也认识到了前端验证的重要性,但它并不能替代后端验证,因为前端验证可以被绕过。此外,通过编写PHP网页和进行用户认证,我进一步了解前端和后端mysql的协同。在测试SQL注入、XSS攻击、CSRF攻击的过程中,我也深刻认识到了Web安全的复杂性。

参考资料

posted @ 2024-12-06 21:23  SAltria  阅读(11)  评论(0编辑  收藏  举报