HNCTF-2025-部分web复现
Really_Ez_Rce
源码如下
1 |
|
首先是请求参数Number
,限制其不能含有数字,并且还要利用intval()
转化成整数的返回值要为真,才能继续执行下面的代码,这里可以利用数组绕过,传参时写成Number[]=1
的形式,既满足不是纯数字,又满足转化成整数返回值为真
1 |
|
然后是POST参数cmd
,存在WAF对其内容进行限制,这里可以利用空变量$@
进行绕过
1 |
|
也可以利用变量拼接绕过
1 |
|
然后是读取flag.txt
中的flag,虽然cat
可以利用上面的方法进行绕过,但是这里把点.
也过滤了,这里可以考虑使用base64编码进入绕过
1 |
|
ez_php
源码如下
1 |
|
首先是在GOGOGO
类中有一个__destruct()
魔术方法,会执行下面这个语句,
1 |
|
这里会把$this->dengchao
当作字符串调用,刚好可以触发DouBao
类中的__toString()
魔术方法,在这个方法中会先有个MD5和Sha1强比较,这里可以利用数组绕过,然后执行下面的语句
1 |
|
最后看第三个类HeiCaFei
,存在一个__call
魔术方法,在调用一个不存在的方法会触发,触发后会执行下面这个语句
1 |
|
这里可以利用这个代码执行命令,这使用的是call_user_func_array()
函数,在这个函数中第一个参数是$this->HongCaFei
,会作为函数,这里可以写成system
用于后续执行命令
第二个参数是[0 => $name]
,是将name
作为唯一参数传给函数,最后执行这个函数,这里的name
是传入魔术方法__call
的第一个参数,是不存在的方法名,所以我们要调用的不存在的方法名可以写成要执行的命令
1 |
|
最后还有一个异常函数需要绕过,不绕过代码不会执行,没有回显,可以借鉴文章:https://xz.aliyun.com/news/11289
最后可以得到的绕过方法就是加上下面这个代码
1 |
|
然后将最后运行得到的序列化数据最后末尾的i:1;i:0;
改为i:0;i:0;
最终exp
1 |
|
1 |
|
然后将末尾的i:1;i:0;
改为i:0;i:0;
1 |
|
DeceptiFlag
随便输入内容利用bp抓包,会发现存在三个参数
题目提示两个答案都要拼音
根据页面的背景猜测值是xiyangyang
和huitailang
,POST中第二个参数是Lang
,猜测值为huitailang
,其他俩都是xiyangyang
发送请求后会得到tips.php
路径,放包跳转到该路径
并且会发现有个GET参数file
,可以利用伪协议读取到flag,在cookie中有个base64编码的提示
1 |
|
可以得到flag的路径是/var/flag/flag.txt
1 |
|
1 |
|
进行base64解码
奇怪的咖啡店
所给附件源码如下
1 |
|
在/add
路由中存在原型链污染,具体地方是下面这段代码
1 |
|
这里定义一个merge
的递归函数,可以将一个字典的内容或字典对象合并到另一个对象中
举个例子,有个源字典src
和一个目标对象dst
1 |
|
调用merge(src, dst)
这个函数后,会将目标对象变为
1 |
|
题目提示源码不完全
在本题中可以利用这个函数进行原型链污染,污染 _static_folder
,从而实现任意文件读取,从而获取完整的源码
在 Flask 框架中,static_folder
是应用初始化时的一个参数,指定静态文件的存储路径,默认值为项目根目录下的 static
文件夹,如果将其污染为根目录\
,就相当于将所有静态文件的存储路径改为根目录,从而可以直接通过URL访问到服务器的所有文件,如通过访问http://xxx.com/etc/passwd
直接读取/etc/passwd
文件
在 Flask 框架中,在内部实现上,Flask 会把用户传入的 static_folder
参数赋值给 _static_folder
属性,所以我们可以直接污染_static_folder
exp
1 |
|
访问/add
,随便输入商品名称和价格,利用bp进行抓包
发现污染失败,存在waf过滤,对payload进行unicode 编码,注意使用\u005f
这种,而不是%u005f
,否则不会污染成功
1 |
|
回显 “ 你无法添加商品 ” 是因为以下代码,无论是否污染成功都会回显这句话
1 |
|
回到浏览器就可以通过 URL 直接访问服务器文件,先读完整源码
1 |
|
1 |
|
有个非预期,直接访问下载得到环境变量文件environ
1 |
|
下面是预期解
存在黑名单,可以污染掉
1 |
|
1 |
|
1 |
|
看到有个/aaadminnn
路由
1 |
|
注意其中的这段代码可以打SSTI,设置好permission
为payload即可
1 |
|
要满足session
中的name
为admin
,permission
不为0
,可以看以下这段代码
1 |
|
这里设置了SECRET_KEY
是一个随机数,在/
路由下会把name
设置成customer
,把permission
设置为0
思路:可以将SECRET_KEY
污染成一个具体的固定值,然后利用污染后的SECRET_KEY
伪造session,使name为admin,permission为打SSTI的payload,从而可以访问/aaadminnn
并进行RCE
首先污染SECRET_KEY
为固定值123
1 |
|
1 |
|
利用污染的SECRET_KEY
进行 Flask 框架的伪造session,利用工具
项目地址:https://github.com/noraj/flask-session-cookie-manager
先对原本的session进行解密
1 |
|
伪造session,payload如下
记得引号前加上转义符\
1 |
|
带着session去访问aaadminnn
,这里要GET请求,因为POST请求会执行以下这个代码,直接return结束了
最后就是读4flloog
1 |
|
Watch
提示flag在D盘中(其实是key),带上Token访问赛题环境
可以进行文件读取
1 |
|
尝试直接目录穿越到D盘,不过失败
1 |
|
在所给附件中的go.mod
文件中可知GO版本是1.20,该版本存在一个CVE漏洞:CVE-2023-45283
就是\??\c:\x
会被当作c:\x
,所以可以构造出\??\d:\
,即d:\
,前面进行一次目录穿越从而进入d盘
1 |
|
访问读取key.txt
文件
1 |
|
得到key
1 |
|