Summary: This article analyzes the principle of the IIS6 file name resolution vulnerability and the related information of IIS7 from a technical perspective.
A. IIS6 file type error Parsing
1. When the file name in the WEB directory is named xxx. asp; xxx. xxx, the file will be sent to asp. dll for parsing (that is, executing the script)
2. When accessing any file in the directory named xxx. asp under the WEB directory, this file will be sent to asp. dll for parsing (that is, executing the script)
Sort out the following core processing code after reverse parsing of the IIS6 core file type.
// Reverse code by golds7n with ida
Int _ thiscall Url (void * this, char * UrlStruct)
{
Void * pW3_URL_INFO; // esi @ 1
Int bSuccess; // eax @ 1
Const wchar_t * I; // eax @ 2
Wchar_t * wcsSlashTemp; // ebx @ 6
Int wcsTemp; // eax @ 6
Int wcs_Exten; // eax @ 6
Int v8; // esi @ 9
Int v10; // eax @ 11
Int v11; // ST04_4 @ 13
Int v12; // eax @ 13
Int ExtenDll; // eax @ 19
Int Extenisa; // eax @ 20
Int ExtenExe; // eax @ 21
Int ExtenCgi; // eax @ 22
Int ExtenCom; // eax @ 23
Int ExtenMap; // eax @ 24
Int Entry; // [sp + Ch] [bp-148h] @ 6
Wchar_t * wcsMaohaoTemp; // [sp + 10 h] [bp-144h] @ 6
Unsigned int dotCount; // [sp + 14 h] [bp-140h] @ 1
Wchar_t * Str; // [sp + 18 h] [bp-13Ch] @ 3
Char * url_FileName; // [sp + 1Ch] [bp-138h] @ 1
Char Url_FileExtenName; // [sp + 20 h] [bp-134h] @ 1
Char v25; // [sp + 50 h] [bp-104h] @ 1
DotCount = 0;
PW3_URL_INFO = this;
STRU: STRU (& Url_FileExtenName, & v25, 0x100u );
Url_FileName = (char *) pW3_URL_INFO + 228;
BSuccess = STRU: Copy (char *) pW3_URL_INFO + 228, UrlStruct );
If (bSuccess <0)
Goto SubEnd;
For (I = (const wchar_t *) STRU: QueryStr (char *) pW3_URL_INFO + 228); I = Str + 1)
{
Str = _ wcschr (I, '.'); ************* N1 ************
If (! Str)
Break;
++ DotCount;
If (dotCount> W3_URL_INFO: sm_cMaxDots)
Break;
BSuccess = STRU: Copy (& Url_FileExtenName, Str );
If (bSuccess <0)
Goto SubEnd;
WcsSlashTemp = _ wcschr (Str, '/'); **********n2 ************
JUMPOUT (wcsSlashTemp, 0, loc_5A63FD37 );
WcsTemp = STRU: QueryStr (& Url_FileExtenName );
WcsMaohaoTemp = _ wcschr (const wchar_t *) wcsTemp ,':'); * ********** N3 ************
JUMPOUT (wcsMaohaoTemp, 0, loc_5A63FD51 );
Wcs_Exten = STRU: QueryStr (& Url_FileExtenName );
_ Wcslwr (wchar_t *) wcs_Exten );
If (META_SCRIPT_MAP: FindEntry (& Url_FileExtenName, & Entry ))
{
* (_ DWORD *) pW3_URL_INFO + 201) = Entry;
JUMPOUT (wcsSlashTemp, 0, loc_5A63FDAD );
STRU: Reset (char *) pW3_URL_INFO + 404 );
Break;
}
If (STRU: QueryCCH (& Url_FileExtenName) = 4)
{
ExtenDll = STRU: QueryStr (& Url_FileExtenName );
If (! _ Wcscmp (L ". dll", (const wchar_t *) ExtenDll)
| (Extenisa = STRU: QueryStr (& Url_FileExtenName ),! _ Wcscmp (L ". isa", (const wchar_t *) Extenisa )))
JUMPOUT (loc_5A63FD89 );
ExtenExe = STRU: QueryStr (& Url_FileExtenName );
If (! _ Wcscmp (L ". exe", (const wchar_t *) ExtenExe)
| (ExtenCgi = STRU: QueryStr (& Url_FileExtenName ),! _ Wcscmp (L ". cgi", (const wchar_t *) ExtenCgi ))
| (ExtenCom = STRU: QueryStr (& Url_FileExtenName ),! _ Wcscmp (L ". com", (const wchar_t *) ExtenCom )))
JUMPOUT (loc_5A63FD89 );
ExtenMap = STRU: QueryStr (& Url_FileExtenName );
JUMPOUT (_ wcscmp (L ". map", (const wchar_t *) ExtenMap), 0, loc_5A63FD7B );
}
}
If (* (_ DWORD *) pW3_URL_INFO + 201)
| (V10 = * (_ DWORD *) pW3_URL_INFO + 202), v10 = 3)
| V10 = 2
| (V11 = * (_ DWORD *) (* (_ DWORD *) pW3_URL_INFO + 204) + 0xC4C ),
V12 = STRU: QueryStr (url_FileName ),
BSuccess = SelectMimeMappingForFileExt (v12, v11, (char *) pW3_URL_INFO + 756, (char *) pW3_URL_INFO + 1012 ),
BSuccess> = 0 ))
V8 = 0;
Else
SubEnd:
V8 = bSuccess;
STRU: _ STRU (& Url_FileExtenName );
Return v8;
} In the above Code, the asterisks marked with N1, N2, and N3 respectively check the dot, backslash, and semicolon.
The general process is:
Request/aaa.asp;xxxx.jpg
N1: search for "." In the header and obtain .asp;xxxx.jpg.
N2: search for ";". If yes, the memory is truncated.
N3: search for "/". If yes, the memory is truncated.
Finally, the. asp string will be retained, compared with the extension matching in the META_SCRIPT_MAP script ing table, and fed back to asp. dll for processing.
B. Does IIS7 continue the vulnerability?
IIS7 core processing code:
// Reverse code by golds7n with ida
Const unsigned _ int16 * _ stdcall MatchPathInUrl (const unsigned _ int16 * url_User, unsigned _ int32 url_Length, const unsigned _ int16 * IIS_MAP_Wizard)
{
Const unsigned _ int16 * p; // ebx @ 1
Const unsigned _ int16 * pUrl; // ecx @ 4
Const wchar_t * I; // edi @ 6
Signed int isXingHao; // edx @ 8
Const unsigned _ int16 cWizard; // ax @ 10
Const unsigned _ int16 * pWizard; // esi @ 11
Int cTemp; // eax @ 17
Int pCharTemp; // esi @ 23
Const unsigned _ int16 * pCharUser; // eax @ 43
Const unsigned _ int16 byteChar; // cx @ 44
Const wchar_t cSlash; // ax @ 50
Const unsigned _ int16 * Str2; // [sp + 8 h] [bp-8h] @ 11
Signed int bFound; // [sp + Ch] [bp-4h] @ 3
P = IIS_MAP_Wizard;
If (* IIS_MAP_Wizard! = '*' | IIS_MAP_Wizard [1])
{
BFound = 1;
If (* IIS_MAP_Wizard = '/')
{
P = IIS_MAP_Wizard + 1;
BFound = 0;
++ IIS_MAP_Wizard;
}
PUrl = url_User;
If (* url_User = '/')
{
PUrl = url_User + 1;
++ Url_User;
}
LABEL_6:
For (I = pUrl; I + = pCharTemp)
{
While (* p = '? ')
{
If (! * I)
Return 0;
If (* I = '/')
Goto LABEL_30;
++ P;
++ I;
}
IsXingHao = 0;
If (* p = '*')
{
++ P;
IsXingHao = 1;
}
CWizard = * p;
If (! * P)
Break;
PWizard = p;
Str2 = p;
If (cWizard! = '*')
{
Do
{
If (cWizard = '? ')
Break;
If (! CWizard)
Break;
++ PWizard;
CWizard = * pWizard;
Str2 = pWizard;
}
While (* pWizard! = '*');
}
If (isXingHao)
{
If (! * PWizard)
{
CTemp = (int) & I [pWizard-p];
If (cTemp> (unsigned int) & pUrl [url_Length])
Return 0;
While (* (_ WORD *) cTemp! = '/' & * (_ WORD *) cTemp & * I! = '/' & * I)
{
++ I;
CTemp + = 2;
}
}
PCharTemp = pWizard-p;
While (_ wcsncmp (I, p, pCharTemp ))
{
If (! * I)
Return 0;
If (* I = '/')
Goto LABEL_29;
++ I;
}
}
Else
{
PCharTemp = pWizard-p;
If (_ wcsncmp (I, p, pCharTemp ))
{
LABEL_29:
PUrl = url_User;
LABEL_30:
If (! BFound)
Return 0;
While (* pUrl! = '/')
{
If (! * PUrl)
Return 0;
++ PUrl;
}
If (! * PUrl)
Return 0;
P = IIS_MAP_Wizard;
++ PUrl;
Url_User = pUrl;
Goto LABEL_6;
}
}
P = Str2;
PUrl = url_User;
}
If (isXingHao)
{
CSlash = * I;
If (* I = '/')
Return I;
Do
{
If (! CSlash)
Break;
++ I;
CSlash = * I;
}
While (* I! = '/');
}
If (* I! = '/' & * I)
Goto LABEL_30;
Return I;
}
PCharUser = url_User;
Do
{
ByteChar = * pCharUser;
++ PCharUser;
}
While (byteChar );
Return & url_User [pCharUser-(url_User + 1)];
} MatchPathInUrl (const unsigned _ int16 * url_User, unsigned _ int32 url_Length, const unsigned _ int16 * IIS_MAP_Wizard)
The url_User parameter is the path parameter submitted by the user. Similar to PHOST/default web site/aa.asp;xxx.jpg, it consists of the service/SITE name/Request Path. IIS_MAP_Wizard is each table item in the Manager file ing, for example *. ASP
The result of the comparison is "aa.asp;xxx.jpg" and "*. ASP". Obviously, the result does not match (/xxx. asp/xxx.jpg, which is matched by xxx.jpg and *. ASP ).
C. Summary
IIS6 file ing Configuration
IIS7 file ing Configuration
From the key analysis and diagram above, we can see that the parsing vulnerability in IIS6 is caused by design issues. IIS6 only identifies the vulnerability based on the extension, IIS7 matches wildcards to determine whether the requested file is of a script type. It can be seen that IIS7 has corrected the error mechanism and is more scientific and robust.