2025SUCTF
2025SUCTF -WEB
死了
SU_photogallery
可以上传一个zip压缩包
404页面长得像php-s 启动的服务,搜搜相关漏洞
找到了这个,成功读取了代码
源代码如下
1 |
|
简单分析一下上传的逻辑
第一个箭头这里调用了extractTo解压了这个压缩包内的东西
随后对内部的文件进行了检测
我们如果使得让他识别文件出错,但是能够正常保留压缩包中的文件,就可以上传我们的一句话shell
相当于只要过waf就行了
SU_blog
有点离谱
随便注册一个账号密码,登上去
F12看到以下内容
猜测是要先变成admin,然后可以访问file读取东西
然后感觉是要和给出的提示
配合 去算他那个时间戳,然后得到secret
然后才发现可以直接注册admin/aaaaaa 变成admin,都不需要伪造cookies 我糙
双写绕过,可以读取到源码
1 | /article?file=articles/..././app.py |
1 | from flask import * |
注意到有一个waf.py 可以读取一下
1 | /article?file=articles/..././wa../f.py |
1 | key_blacklist = [ |
这里存在原型链污染
找到一篇文章Pydash 原型链污染
通过污染jinja2 编译模板时的包中的参数可以完成rce 这里恰好给了数字2
不过loader没了,需要寻找一下其他的
为咯方便调试,我自己加上了一个shell路由
1 |
|
发现由有个这个
成功找到sys
接下来就直接拿shell即可
调了好久 手慢无
SU_POP
路由里面有一个反序列化路由,明显就是要找链子
先看看destruct方法
在RejectedPromise类的__destruct方法
这里可以触发tostring方法,$handled默认就是false 不需要修改
Response的tostring方法可以触发call方法
接下来就是找可以利用的call方法
vendor\cakephp\cakephp\src\ORM\Table.php下
1 | public function __call(string $method, array $args): mixed |
这里可以调用call($method, $args);调用任意call方法,同时$method和$args均可控,符合我们rce的要求
这里的$_behaviors还是BehaviorRegistry类
现在看看能不能满足判断条件
1 | $this->_behaviors->hasMethod($method) |
指向的是BehaviorRegistry的方法
1 | public function hasMethod(string $method): bool |
判断是不是在这个$_methodMap内,但是这个值我们可以控制,只要把我们执行的函数放到这个array里面就行
走到vendor\cakephp\cakephp\src\ORM\BehaviorRegistry.php的call方法
1 | public function call(string $method, array $args = []): mixed |
一个hasMethod判断如上 一个has判断如下
参数均可控 现在就是找可以执行命令的函数了
找到一个eval函数存在的地方
触发这个即可,链子如下
1 | RejectedPromise#__destruct ==> Response#__toString ==> Table#__call ==> BehaviorRegistry#call ==> MockClass#generate |
exp
1 |
|
SU_PWN
这题dns出网 但是实在是做的太折磨了
/upload路由可以上传文件 然后试图用org.apache.xalan.xslt.Process;去做转换
上网搜,可以找到这两个网页
这个payload在不考虑check的时候是可以直接rce的
但是他这里限制了不能出现Runtime,所以这个payload就失效了,不过我们依然可以寻找其他的方式
import与include标签(失败)
这两个标签的灵感来源于国城杯jelly那题里面,同样可以使用这两个标签去加载外部的文件,尝试直接rce看看
构造本地的xslt标签
1 | <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
尝试一下
本地成功打穿
线上环境应该是不出网,我没办法加载到我服务器上的xlst,这下只能换个办法
编码绕过
想起来xxe里面有一个技巧是可以使用编码绕过,翻来翻去没找到编码的标签,想到试试16进制编码看看
1 | def string_to_hex_escape(input_string): |
成功识别并且rce
下一步就是外带了,这一步发现dns居然是出网的
直接一手dns外带就行
flag名字及其抽象,同时需要切片才能读取到flag里面的内容
和carbofish搓了搓脚本,成功得到flag
1 | import requests |