Dreamhack 강의를 통해 XS-Search 공격에 대해 알아봅시다.
Differences XSS
웹 브라우저에서 SOP(Same-Origin Policy)정책으로 인하여 일반적으로는 다른 오리진에 요청을 보내고 응답을 받는 것은 불가능합니다.
- XSS는 공격 대상 오리진에 반드시 공격자의 입력이 들어가 스크립트를 삽입해야하고, 피해자가 해당 페이지를 방문해야한다는 전제조건이 필요합니다.
- 반면에 XS-Search는 공격 대상 오리진에 스크립트를 삽입하거나 해당 페이지를 직접 방문하지 않고, 피해자가 공격자가 의도한 서버에만 접속하는 것만으로 SOP를 우회하여 공격 대상 오리진의 비밀 정보를 유출할 수 있는 강력한 공격기법입니다.
XS-Search
Cross-Site Search (XS-Search)는 쿼리 기반 시스템을 이용해 이용자의 비밀 정보를 유출하는 공격 기법입니다.
XS-Search는 부채널 공격의 일종으로 Blind SQL Injection과 비슷한 형태로 공격이 이루어집니다.
XS-Search 공격은 SOP 정책을 위반하지 않는 선에서 다른 오리진에 요청을 보내고 요청에 소요된 시간, 응답 코드, 창의 프레임 개수 등의 요소를 활용해 비밀 정보를 유출합니다.
Example Code
아래와 같이 query 변수를 받아 secret이 일치하면 200, 아니면 404를 리턴합니다.
1
2
3
4
5
6
7
8
9
secret = "this_is_secret_value"
@app.route('/search')
def search_secret():
query = request.args.get("query", "_")
if secret.startswith(query):
return "OK", 200
else:
return "NO", 404
SOP 우회
XMLHttpRequest를 이용하여 응답 값을 받아오면 CORS정책에 위반되어 에러가 발생합니다.
브라우저는 SOP에 구애 받지 않고 외부 출처에 대한 접근을 허용해주는 경우가 존재합니다.
예를 들면, 이미지나 자바스크립트, CSS 등의 리소스를 불러오는 <img>, <style>, <script>
등의 태그는 SOP의 영향을 받지 않습니다.
XS-Search는 이와 같이 SOP에 구애받지 않는 태그를 활용하여 공격합니다.
아래 코드는 script 태그를 이용해 요청의 응답 코드가 200인지 404인지 구분하는 코드입니다.
1
2
3
4
5
6
7
8
9
10
function req(url) {
let script = document.createElement('script');
script.src = url;
script.onload = () => console.log(200);
script.onerror = () => console.log(404);
document.head.appendChild(script);
}
req('http://localhost:8000/search?query=a');
req('http://localhost:8000/search?query=t');
일치하면 200, 아니면 404가 반환되므로 이를 이용하여 secret를 가져올 수 있습니다.