(bWAPP)XSS - Reflected (AJAX/JSON)
Level - Low
- 이전 실습과 동일하게 JSON 형태의 검색 사이트가 존재한다.
- 해당 환경에서는 AJAX 를 사용하여 새로고침 없이 입력값이 즉시 반영되는 구조이다.
- 일반적인 스크립트 태그를 가지고 XSS는 통하지 않는다.
<script>
// Stores the reference to the XMLHttpRequest object
var xmlHttp = createXmlHttpRequestObject();
// Retrieves the XMLHttpRequest object
function createXmlHttpRequestObject()
{
// Stores the reference to the XMLHttpRequest object
var xmlHttp;
// If running Internet Explorer 6 or older
if(window.ActiveXObject)
{
try
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
xmlHttp = false;
}
}
// If running Mozilla or other browsers
else
{
try
{
xmlHttp = new XMLHttpRequest();
}
catch (e)
{
xmlHttp = false;
}
}
// Returns the created object or displays an error message
if(!xmlHttp)
alert("Error creating the XMLHttpRequest object.");
else
return xmlHttp;
}
// Makes an asynchronous HTTP request using the XMLHttpRequest object
function process()
{
// Proceeds only if the xmlHttp object isn't busy
if(xmlHttp.readyState == 4 || xmlHttp.readyState == 0)
{
// Retrieves the movie title typed by the user on the form
// title = document.getElementById("title").value;
title = encodeURIComponent(document.getElementById("title").value);
// Executes the 'xss_ajax_1-2.php' page from the server
xmlHttp.open("GET", "xss_ajax_2-2.php?title=" + title, true);
// Defines the method to handle server responses
xmlHttp.onreadystatechange = handleServerResponse;
// Makes the server request
xmlHttp.send(null);
}
else
// If the connection is busy, try again after one second
setTimeout("process()", 1000);
}
// Callback function executed when a message is received from the server
function handleServerResponse()
{
// Move forward only if the transaction has completed
if(xmlHttp.readyState == 4)
{
// Status of 200 indicates the transaction completed successfully
if(xmlHttp.status == 200)
{
// Extracts the JSON retrieved from the server
JSONResponse = eval("(" + xmlHttp.responseText + ")");
// Generates HTML output
// var result = "";
// Obtains the value of the JSON response
result = JSONResponse.movies[0].response;
// Iterates through the arrays and create an HTML structure
//for (var i=0; i<JSONResponse.movies.length; i++)
// result += JSONResponse.movies[i].response + "<br/>";
// Obtains a reference to the <div> element on the page
// Displays the data received from the server
document.getElementById("result").innerHTML = result;
// Restart sequence
setTimeout("process()", 1000);
}
// A HTTP status different than 200 signals an error
else
{
alert("There was a problem accessing the server: " + xmlHttp.statusText);
}
}
}
- 해당 소스코드에 나와있는 부분이며, 이번 문제도 DOM Based XSS에 좀 더 가깝다.
- 코드를 보게되면, 이전과 동일하게 json 형태로 입력값을 출력하며
// Executes the 'xss_ajax_1-2.php' page from the server
xmlHttp.open("GET", "xss_ajax_2-2.php?title=" + title, true);
// Defines the method to handle server responses
- 해당 부분을 보게되면 GET 형식으로 xss_ajax_2-2.php로 보내며 title 파라미터로 입력값을 보내게 된다.
- 하지만 사이트 내에서는 AJAX 형식을 사용하므로 보이지 않는다.
- 그대로 URI에 해당 경로와 파라미터에 스크립트 태그를 사용하여, 입력값을 보내게 되면
- XSS 취약점이 발생하는 것을 확인할 수 있다.
Level - Medium & High
if($_COOKIE["security_level"] == "2")
{
// Generates the JSON output
header("Content-Type: text/json; charset=utf-8");
- medium Level의 필터링을 확인하면 Content-Type 을 json 형식으로 지정하는 걸 볼 수 있다.
- 이를 통해 Javascript 태그는 허용되지 않는다.
- 하지만 img, iframe 과 같은 HTML 태그를 사용하면 이를 우회할 수 있다.
- High Level에서는 htmlsepcialchars 함수를 사용하여, 각각의 특수문자에 대한 HTML 엔터티 인코딩을 통한 필터링을 적용하여, XSS 에 대한 대응이 이루어지고 있다.
Leave a comment