Lab: Reflected XSS into attribute with angle brackets HTML-encoded | Web Security Academy
목적:
- 이 실험의 목적은 웹 애플리케이션에서 사용자 입력이 HTML 속성(attribute) 내에 반영되는 경우에 발생할 수 있는 XSS 취약점을 이해하고, 이를 공격하는 방법을 학습하는 것이다. 특히, 각괄호 (
<
,>
)가 HTML 인코딩되어 있어도 XSS 공격이 가능한 상황을 탐색한다.
- 이 실험의 목적은 웹 애플리케이션에서 사용자 입력이 HTML 속성(attribute) 내에 반영되는 경우에 발생할 수 있는 XSS 취약점을 이해하고, 이를 공격하는 방법을 학습하는 것이다. 특히, 각괄호 (
시나리오:
웹 애플리케이션에서 사용자의 입력을 받아 HTML 속성 내에 반영하는 페이ㅊ지가 있다고 가정한다.
이 페이지는 각괄호를 HTML 인코딩하여 출력한다. 예를 들면,
<
는<
로,>
는>
로 변환된다.
공격 방법:
공격자는 각괄호를 사용하지 않고 다른 특수 문자나 이스케이프 시퀀스를 사용하여 XSS 페이로드를 구성한다.
예를 들어, 속성 값 내에서 따옴표(
"
)를 사용하여 속성을 종료하고, 새로운 속성 또는 이벤트 핸들러를 추가할 수 있다.페이로드 예:
onmouseover=alert(1)
방어 방법:
사용자 입력을 속성 내에 직접 삽입하기 전에 완전히 검증하고 이스케이프한다.
콘텐츠 보안 정책 (CSP)를 적용하여 인라인 스크립트의 실행을 제한한다.
이 실험은 웹 보안 연구자나 웹 개발자들이 XSS 취약점에 대한 이해를 높이기 위한 연습으로 사용될 수 있다. 실제 환경에서는 이러한 취약점을 악용하지 않도록 주의해야 한다.
burp suite 에서 intercept 를 완료하기 위해서는 forward를 해주어야 한다.
솔루션
검색 상자에 임의의 영숫자 문자열을 제출한 다음 Burp Suite를 사용하여 검색 요청을 가로채서 Burp Repeater로 보낸다.
임의의 문자열이 인용된 속성 내에 반영되었는지 확인하는 것이 좋다.
인용된 속성을 이스케이프하고 이벤트 핸들러를 삽입하려면 입력을 다음 페이로드로 바꾼다.
"onmouseover="alert(1)
마우스 오른쪽 버튼을 클릭하고 "URL 복사"를 선택한 다음 브라우저에 URL을 붙여넣어 기술이 작동하는지 확인한다. 삽입된 요소 위로 마우스를 이동하면 경고가 트리거되어야 한다.
여기서 ‘123’ 부분에 검사하기를 눌러서 sript를 삽입할 곳을 찾아내야 한다.
element 를 copy해서 붙여넣기 해보면 모두 escaping이 된 것을 볼 수 있다.
교수님이 설명을 하시는데 다음에서 첫번째는 escaping이 되어있는 것이고 두번째 것은 ecaping이 되어있지 않다고 한다. 이게 무슨 말이지? 하 <h1>0 search results for '<script>alert(1)</script>'</h1>
<input type="text" placeholder="Search the blog..." name="search" value="<script>alert(1)</script>">
교수님의 설명은 HTML 인코딩(escaping)에 관한 것이다. HTML 인코딩은 특정 문자들을 안전한 형태로 변환하는 과정을 의미한다. 이를 통해 웹 페이지에서 악의적인 스크립트 실행을 방지할 수 있다.
두 예제를 살펴보겠다:
<h1>0 search results for '<script>alert(1)</script>'</h1>
이 예제에서는
<script>alert(1)</script>
문자열이<script>alert(1)</script>
로 인코딩되어 있다.<
는<
를,>
는>
를 나타내는 HTML 엔터티이다.이렇게 인코딩된 문자열은 브라우저에서 안전하게 표시됩니다. 즉,
<script>alert(1)</script>
코드가 실행되지 않고 그대로 화면에 표시된다.
<input type="text" placeholder="Search the blog..." name="search" value="<script>alert(1)</script>">
이 예제에서는
<script>alert(1)</script>
문자열이 그대로 사용되었습니다. 이 문자열은 인코딩되지 않았다.이렇게 인코딩되지 않은 문자열은 웹 페이지에서 로드될 때 스크립트로 실행될 위험이 있습니다. 즉,
alert(1)
이 실행되어 경고창이 표시될 수 있다.
따라서, 첫 번째 예제는 안전한 방식으로 문자열을 처리한 것이며, 두 번째 예제는 XSS (Cross-Site Scripting) 공격에 취약한 방식으로 문자열을 처리한 것이다.
위에 설명을 보았듯이 이 것은 저 블로그 사이트에서 위에 reflect?를 해주는 0 search ~ 이쪽은 인코딩이 되어있고 아래 입력 부분에는 인코딩이 되어있지 않기 때문에 아래의 인코딩이 되지 않은 부분에 스크립트를 삽입하여 공격을 하는 것이다.
''<>""\ 를 넣으면 다음과 같이 결과가 나온다.
따라서 인풋 부분에 스크립트를 삽입해서 alert를 뜨도록 하는 작업을 하려고 하는데
123" onmouseover=alert(1);
이 스크립트는 alert가 뜨지 않지만
123" onmouseover=alert(1);"
이 스크립트는 alert가 작동을 한다. 왜 그럴까?
두 스크립트 페이로드를 살펴보면, 두 번째 페이로드에 추가적인 따옴표("
)가 포함되어 있다. 이 차이가 결과에 영향을 미치는 것이다.
HTML에서 속성 값은 대개 따옴표("
)로 묶입니다. 예를 들면, value="something"
과 같은 형태이다.
첫 번째 페이로드:
123" onmouseover=alert(1);
이 페이로드를 삽입하면, HTML은 다음과 같이 해석된다:
htmlCopy code <input type="text" ... value="123" onmouseover=alert(1);" ...>
여기서
value
속성의 값은123
이며,onmouseover
이벤트 핸들러는alert(1);"
로 해석된다.이 경우,
;"
부분 때문에onmouseover
이벤트 핸들러가 올바르게 닫히지 않아서 스크립트는 실행되지 않다.
두 번째 페이로드:
123" onmouseover=alert(1);"
이 페이로드를 삽입하면, HTML은 다음과 같이 해석된다:
htmlCopy code <input type="text" ... value="123" onmouseover=alert(1);" ...>
여기서
value
속성의 값은123
이며,onmouseover
이벤트 핸들러는alert(1);
로 해석된다.추가된 따옴표(
"
) 때문에onmouseover
이벤트 핸들러가 올바르게 닫히게 되어, 마우스를 해당 요소 위로 이동하면alert(1);
스크립트가 실행된다.
따라서, 두 번째 페이로드에서 추가된 따옴표는 onmouseover
이벤트 핸들러를 올바르게 닫아주어 스크립트가 실행되게한다.
그럼 방금 그 예제에서 <script>alert(1)</script>를 사용하여 alert를 뜨게 하려면 어떻게 해야 할까?
<script>alert(1)</script>
를 사용하여 alert
를 뜨게 하려면, 해당 스크립트가 웹 페이지의 HTML에서 실행되도록 삽입해야 한다. 그러나, 이전의 예제에서는 <input>
태그의 value
속성 내에 스크립트를 삽입하려고 했기 때문에, 이 방식은 직접적으로 적용하기 어렵다. value
속성 내에서는 <script>
태그를 사용하여 스크립트를 실행할 수 없다.
그러나 다른 방식으로 접근하면 가능합니다:
외부에서 스크립트 삽입: 웹 페이지의 다른 부분, 예를 들면 댓글이나 게시판에
<script>alert(1)</script>
를 직접 삽입하여 실행시킬 수 있다. 이 방식은 저장형 (Stored) XSS 공격에 해당합니다.이벤트 핸들러 사용: 이전에 언급한 것처럼, HTML 태그의 이벤트 핸들러 (예:
onmouseover
,onclick
등)를 사용하여 스크립트를 실행할 수 있다. 이 방식은 반영형 (Reflected) XSS 공격에 해당할 수 있다. 예를 들면:htmlCopy code <input type="text" placeholder="Search the blog..." name="search" value="" onmouseover="alert(1)">
스크립트 태그 직접 삽입: 만약 웹 애플리케이션의 취약점을 통해 전체 HTML 내용을 수정할 수 있다면,
<script>alert(1)</script>
를 웹 페이지 어디든지 직접 삽입하여 실행시킬 수 있다.
이러한 방법들은 웹 애플리케이션의 XSS 취약점을 테스트하거나 연구할 때 사용될 수 있다. 실제 환경에서는 이러한 취약점을 악용하지 않도록 주의해야 한다.
이런 스크립트를 파싱하는 역할은 브라우저에서 하는 것인가?
맞다. 웹 브라우저는 HTML, CSS, JavaScript 등의 웹 콘텐츠를 파싱하고 렌더링하는 역할을 한다.
브라우저가 웹 페이지를 로드할 때 다음과 같은 과정을 거친다:
HTML 파싱: 브라우저는 웹 서버로부터 받은 HTML 문서를 파싱하여 DOM (Document Object Model) 트리를 생성한다. DOM은 웹 페이지의 구조화된 표현을 제공하며, JavaScript에서 이를 사용하여 웹 페이지의 요소에 접근하고 조작할 수 있다.
CSS 파싱: 브라우저는 외부 CSS 파일과 HTML 내의 인라인 스타일을 파싱하여 CSSOM (CSS Object Model) 트리를 생성한다.
렌더 트리 생성: DOM과 CSSOM 트리를 결합하여 렌더 트리를 생성한다. 렌더 트리는 화면에 실제로 표시되는 요소들만을 포함한다.
레이아웃: 렌더 트리를 기반으로 브라우저는 각 요소의 크기와 위치를 계산한다.
페인팅: 브라우저는 렌더 트리의 각 요소를 화면에 그린다.
JavaScript 실행: 브라우저는
<script>
태그를 만나면 HTML 파싱을 일시 중지하고 JavaScript를 실행한다. 이는 JavaScript가 DOM을 조작할 수 있기 때문이다.
악의적인 스크립트가 HTML에 포함되어 있을 경우, 브라우저는 이를 정상적인 스크립트로 간주하고 실행한다. 이러한 특성 때문에 XSS (Cross-Site Scripting)와 같은 웹 보안 취약점이 발생할 수 있다. 따라서 웹 개발자는 사용자 입력을 안전하게 처리하여 이러한 취약점을 방지해야 한다.
edited by 조준형