* 당신의 피해자는 당신이 사용하기 위해 활성화 키를 받는 시스템입니다.
* 당신은 활성화 단추를 사용할 수 있도록 시도 해야합니다.
* 그 키 확인이 작동하는 지에 대한 과정을 이해하기 위해 HTML 소스를 보는데 시간을 할애하세요.
풀이
난이도가 올라가기 시작했어요…ㅠㅠ...
Licene Key에 아무거나 입력하면 Wrong license key. 라고 뜨네요.
뭐…HTML 소스를 보라고 했으니…보죠 뭐
대신 Input box나 Activate 버튼에서 우클릭 -> 요소 검사로 좀 지능적으로 보겠습니다. ㅎㅎ
HTML은 항상 태그들로 둘러쌓여진 형태(트리 구조)를 가지죠. 우리가 확인한 위치는 FORM 태그에 의해 둘러쌓여져 있습니다.
태그의 내용은 이렇구요.
Form 태그는 여러 정보를 한번에 서버로 전송할 때 유용하게 사용되는 태그입니다. 맨 위에 Method 속성에 적힌 대로 POST 방식을 주로 사용합니다.
위 내용을 알려드리자면 input box의 id는 "key"이고 여기에 입력된 내용은 Activate 버튼을 누르면 "#attack/156/400"으로 보내지게 됩니다. 그 전에 onkeyup 속성에 의해 validate('#attack/156/400'); 가 실행됩니다. 이 함수는 위에 있는 dom_injection.js에서 찾을 수 있으며, 원래 다 그렇다기 보다는 개발자 도구 –> 네트워크에서 직접 찾았습니다.
즉, 노가다.
아래는 dom_injection.js의 내용입니다.
function validate(url) { var keyField = document.getElementById('key'); var url = url + "&from=ajax&key=' + encodeURIComponent(keyField.value)"; if (typeof XMLHttpRequest != 'undefined') { req = new XMLHttpRequest(); } else if (window.ActiveXObject) { req = new ActiveXObject('Microsoft.XMLHTTP'); } req.open('GET', url, true); req.onreadystatechange = callback; req.send(null); function callback() { if (req.readyState == 4) { if (req.status == 200) { var message = req.responseText; var messageDiv = document.getElementById('MessageDiv'); try { eval(message); messageDiv.innerHTML = 'Correct licence Key.' } catch (err) { messageDiv.innerHTML = 'Wrong license key.' } } } } }
여기서 3번째 줄에 url 이 있는 데 오타입니다.
var url = url + "&from=ajax&key=" + encodeURIComponent(keyField.value);
이와 같이 고쳐주세요. 고치는 방법은 역시…서버에서 직접…
위치는 <WebGoat 디렉토리>/WebGoat/webgoat-container/target/webgoat-container-7.0-SNAPSHOT/plugin_extracted/plugin/DOMInjection/js
(주말에 크롬 설치하는 방법 올릴 거에요…꼭…)
4~7 번째 줄의 내용은 Ajax를 사용하기 위한 XMLHttpRequest 객체를 준비하는 코드입니다. Ajax를 사용하기 위한 기본이라고 하네요.
if (typeof XMLHttpRequest != 'undefined') { req = new XMLHttpRequest(); } else if (window.ActiveXObject) { req = new ActiveXObject('Microsoft.XMLHTTP'); }
그 아래 9 ~ 11번 째 줄은 수정된 url로 GET요청을 보냅니다.
(이게 Ajax)
req.open('GET', url, true); req.onreadystatechange = callback; req.send(null);
그 아래의 callback 함수는 위의 Request에 대한 Response를 받아 페이지를 수정하는 부분입니다. 여기서 중요하게 봐야할 부분은 19번째 줄의
eval(message);
입니다. eval 함수는 문자열로 넘어온 JavaScript를 실행하는 함수입니다.
여기서 message가 문자열에 해당하며 이는 16번 째 줄에서 Response Page를 문자열로 전환한 변수입니다.
function callback() { if (req.readyState == 4) { if (req.status == 200) { var message = req.responseText; var messageDiv = document.getElementById('MessageDiv'); try { eval(message); messageDiv.innerHTML = 'Correct licence Key.' } catch (err) { messageDiv.innerHTML = 'Wrong license key.' } } } }
즉, url을 수정하여 Ajax로 요청한 후 그에 대한 Response Page를 받아 javascript를 실행시키고 그에 대한 결과에 따라 페이지의 내용을 수정하는 스크립트 입니다.
우리는 이 Response Page를 Proxy Tool로 중간에서 Activate 버튼을 사용할 수 있게만 해주면 됩니다. 방법은 다음과 같습니다.
우선, Input Box의 값을 변경할 때 보내지는 Request를 Proxy Tool로 잡습니다.
이 Request는 위에서 보신 대로 Ajax가 보내는 패킷입니다. 여기서 URI가 #뒤로 보이지 않는 데, 이유는 모르겠습니다. burpsuite에서도 마찬가지…
이에 대한 Response를 보면 페이지 내용들이 잔뜩 있는 데, 이를
document.form.SUBMIT.disabled = false;
로 바꿉니다. eval 함수에 의해 실행되는 스크립트로 SUMBIT의 disabled 속성을 false로 바꾸는 역할을 합니다.
그러면 Correct licence Key. 가 나타나면서 버튼을 누를 수 있습니다.
버튼을 누르면 Complete!
Ajax
근래에 대화형, 반응형 웹을 많이 접하고 계시죠?? 이게 가능하도록 도와주는 것이 Ajax라고 생각하시면 될 거 같습니다.
기존의 웹은 페이지의 내용 변경을 위해 항상 전체 페이지를 다시 받아와야 했습니다.
하지만, Ajax를 이용하면 필요한 데이터만 웹 서버에 요청해서 받아 Client에서 처리할 수 있습니다. 웹 서버의 응답을 처리하기 위해 Client에서는 JavaScript를 사용합니다.
Ajax 에서 사용하는 eval() 함수에 의해 DOM Based XSS가 가능한 경우입니다.