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
同上,多了些过滤,把f
ban了,通配符绕过即可:
表白墙
回显和输入相同,疑似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 |