歸納: 從技術角度分析IIS6文件名解析漏洞的原理與IIS7的相關狀況。
a.IIS6錯誤解析文件類型現象
一、當WEB目錄下,文件名以 xxx.asp;xxx.xxx 來進行命名的時候,此文件將送交asp.dll解析(也就是執行腳本)
二、當WEB目錄下,在訪問以 xxx.asp 命名的目錄下的任意文件時,此文件將送交asp.dll解析(也就是執行腳本)
經過對IIS6的核心文件類型解析相關文件的逆向後,整理出下面的核心處理代碼。app
1 //reverse code by golds7n with ida 2 int __thiscall Url(void *this, char *UrlStruct) 3 { 4 void *pW3_URL_INFO; // esi@1 5 int bSuccess; // eax@1 6 const wchar_t *i; // eax@2 7 wchar_t *wcsSlashTemp; // ebx@6 8 int wcsTemp; // eax@6 9 int wcs_Exten; // eax@6 10 int v8; // esi@9 11 int v10; // eax@11 12 int v11; // ST04_4@13 13 int v12; // eax@13 14 int ExtenDll; // eax@19 15 int Extenisa; // eax@20 16 int ExtenExe; // eax@21 17 int ExtenCgi; // eax@22 18 int ExtenCom; // eax@23 19 int ExtenMap; // eax@24 20 int Entry; // [sp+Ch] [bp-148h]@6 21 wchar_t *wcsMaohaoTemp; // [sp+10h] [bp-144h]@6 22 unsigned int dotCount; // [sp+14h] [bp-140h]@1 23 wchar_t *Str; // [sp+18h] [bp-13Ch]@3 24 char *url_FileName; // [sp+1Ch] [bp-138h]@1 25 char Url_FileExtenName; // [sp+20h] [bp-134h]@1 26 char v25; // [sp+50h] [bp-104h]@1 27 28 dotCount = 0; 29 pW3_URL_INFO = this; 30 STRU::STRU(&Url_FileExtenName, &v25, 0x100u); 31 url_FileName = (char *)pW3_URL_INFO + 228; 32 bSuccess = STRU::Copy((char *)pW3_URL_INFO + 228, UrlStruct); 33 if ( bSuccess < 0 ) 34 goto SubEnd; 35 for ( i = (const wchar_t *)STRU::QueryStr((char *)pW3_URL_INFO + 228); ; i = Str + 1 ) 36 { 37 Str = _wcschr(i, '.'); ***********N1************ 38 if ( !Str ) 39 break; 40 ++dotCount; 41 if ( dotCount > W3_URL_INFO::sm_cMaxDots ) 42 break; 43 bSuccess = STRU::Copy(&Url_FileExtenName, Str); 44 if ( bSuccess < 0 ) 45 goto SubEnd; 46 wcsSlashTemp = _wcschr(Str, '/'); ***********N2************ 47 JUMPOUT(wcsSlashTemp, 0, loc_5A63FD37); 48 wcsTemp = STRU::QueryStr(&Url_FileExtenName); 49 wcsMaohaoTemp = _wcschr((const wchar_t *)wcsTemp, ':'); ***********N3************ 50 JUMPOUT(wcsMaohaoTemp, 0, loc_5A63FD51); 51 wcs_Exten = STRU::QueryStr(&Url_FileExtenName); 52 __wcslwr((wchar_t *)wcs_Exten); 53 if ( META_SCRIPT_MAP::FindEntry(&Url_FileExtenName, &Entry) ) 54 { 55 *((_DWORD *)pW3_URL_INFO + 201) = Entry; 56 JUMPOUT(wcsSlashTemp, 0, loc_5A63FDAD); 57 STRU::Reset((char *)pW3_URL_INFO + 404); 58 break; 59 } 60 if ( STRU::QueryCCH(&Url_FileExtenName) == 4 ) 61 { 62 ExtenDll = STRU::QueryStr(&Url_FileExtenName); 63 if ( !_wcscmp(L".dll", (const wchar_t *)ExtenDll) 64 || (Extenisa = STRU::QueryStr(&Url_FileExtenName), !_wcscmp(L".isa", (const wchar_t *)Extenisa)) ) 65 JUMPOUT(loc_5A63FD89); 66 ExtenExe = STRU::QueryStr(&Url_FileExtenName); 67 if ( !_wcscmp(L".exe", (const wchar_t *)ExtenExe) 68 || (ExtenCgi = STRU::QueryStr(&Url_FileExtenName), !_wcscmp(L".cgi", (const wchar_t *)ExtenCgi)) 69 || (ExtenCom = STRU::QueryStr(&Url_FileExtenName), !_wcscmp(L".com", (const wchar_t *)ExtenCom)) ) 70 JUMPOUT(loc_5A63FD89); 71 ExtenMap = STRU::QueryStr(&Url_FileExtenName); 72 JUMPOUT(_wcscmp(L".map", (const wchar_t *)ExtenMap), 0, loc_5A63FD7B); 73 } 74 } 75 if ( *((_DWORD *)pW3_URL_INFO + 201) 76 || (v10 = *((_DWORD *)pW3_URL_INFO + 202), v10 == 3) 77 || v10 == 2 78 || (v11 = *(_DWORD *)(*((_DWORD *)pW3_URL_INFO + 204) + 0xC4C), 79 v12 = STRU::QueryStr(url_FileName), 80 bSuccess = SelectMimeMappingForFileExt(v12, v11, (char *)pW3_URL_INFO + 756, (char *)pW3_URL_INFO + 1012), 81 bSuccess >= 0) ) 82 v8 = 0; 83 else 84 SubEnd: 85 v8 = bSuccess; 86 STRU::_STRU(&Url_FileExtenName); 87 return v8; 88 }
上述代碼中,做星號標記的是N1,N2,N3,分別檢測點號,反斜槓和分號。
大概流程爲:
請求 /aaa.asp;xxxx.jpg
N1:從頭部查找查找 "."號,得到 .asp;xxxx.jpg
N2:查找";"號,若是有則內存截斷
N3:查找"/",若是有則內存截斷
最終,將保留下來 .asp 字符串,從META_SCRIPT_MAP腳本映射表裏與擴展名匹配對比,並反饋給了asp.dll處理this
b.IIS7是否延續了漏洞
IIS7的核心處理代碼:url
1 //reverse code by golds7n with ida 2 const unsigned __int16 *__stdcall MatchPathInUrl(const unsigned __int16 *url_User, unsigned __int32 url_Length, const unsigned __int16 *IIS_MAP_Wizard) 3 { 4 const unsigned __int16 *p; // ebx@1 5 const unsigned __int16 *pUrl; // ecx@4 6 const wchar_t *i; // edi@6 7 signed int isXingHao; // edx@8 8 const unsigned __int16 cWizard; // ax@10 9 const unsigned __int16 *pWizard; // esi@11 10 int cTemp; // eax@17 11 int pCharTemp; // esi@23 12 const unsigned __int16 *pCharUser; // eax@43 13 const unsigned __int16 byteChar; // cx@44 14 const wchar_t cSlash; // ax@50 15 const unsigned __int16 *Str2; // [sp+8h] [bp-8h]@11 16 signed int bFound; // [sp+Ch] [bp-4h]@3 17 18 p = IIS_MAP_Wizard; 19 if ( *IIS_MAP_Wizard != '*' || IIS_MAP_Wizard[1] ) 20 { 21 bFound = 1; 22 if ( *IIS_MAP_Wizard == '/' ) 23 { 24 p = IIS_MAP_Wizard + 1; 25 bFound = 0; 26 ++IIS_MAP_Wizard; 27 } 28 pUrl = url_User; 29 if ( *url_User == '/' ) 30 { 31 pUrl = url_User + 1; 32 ++url_User; 33 } 34 LABEL_6: 35 for ( i = pUrl; ; i += pCharTemp ) 36 { 37 while ( *p == '?' ) 38 { 39 if ( !*i ) 40 return 0; 41 if ( *i == '/' ) 42 goto LABEL_30; 43 ++p; 44 ++i; 45 } 46 isXingHao = 0; 47 if ( *p == '*' ) 48 { 49 ++p; 50 isXingHao = 1; 51 } 52 cWizard = *p; 53 if ( !*p ) 54 break; 55 pWizard = p; 56 Str2 = p; 57 if ( cWizard != '*' ) 58 { 59 do 60 { 61 if ( cWizard == '?' ) 62 break; 63 if ( !cWizard ) 64 break; 65 ++pWizard; 66 cWizard = *pWizard; 67 Str2 = pWizard; 68 } 69 while ( *pWizard != '*' ); 70 } 71 if ( isXingHao ) 72 { 73 if ( !*pWizard ) 74 { 75 cTemp = (int)&i[pWizard - p]; 76 if ( cTemp > (unsigned int)&pUrl[url_Length] ) 77 return 0; 78 while ( *(_WORD *)cTemp != '/' && *(_WORD *)cTemp && *i != '/' && *i ) 79 { 80 ++i; 81 cTemp += 2; 82 } 83 } 84 pCharTemp = pWizard - p; 85 while ( _wcsncmp(i, p, pCharTemp) ) 86 { 87 if ( !*i ) 88 return 0; 89 if ( *i == '/' ) 90 goto LABEL_29; 91 ++i; 92 } 93 } 94 else 95 { 96 pCharTemp = pWizard - p; 97 if ( _wcsncmp(i, p, pCharTemp) ) 98 { 99 LABEL_29: 100 pUrl = url_User; 101 LABEL_30: 102 if ( !bFound ) 103 return 0; 104 while ( *pUrl != '/' ) 105 { 106 if ( !*pUrl ) 107 return 0; 108 ++pUrl; 109 } 110 if ( !*pUrl ) 111 return 0; 112 p = IIS_MAP_Wizard; 113 ++pUrl; 114 url_User = pUrl; 115 goto LABEL_6; 116 } 117 } 118 p = Str2; 119 pUrl = url_User; 120 } 121 if ( isXingHao ) 122 { 123 cSlash = *i; 124 if ( *i == '/' ) 125 return i; 126 do 127 { 128 if ( !cSlash ) 129 break; 130 ++i; 131 cSlash = *i; 132 } 133 while ( *i != '/' ); 134 } 135 if ( *i != '/' && *i ) 136 goto LABEL_30; 137 return i; 138 } 139 pCharUser = url_User; 140 do 141 { 142 byteChar = *pCharUser; 143 ++pCharUser; 144 } 145 while ( byteChar ); 146 return &url_User[pCharUser - (url_User + 1)]; 147 } 148 MatchPathInUrl(const unsigned __int16 *url_User, unsigned __int32 url_Length, const unsigned __int16 *IIS_MAP_Wizard)
參數url_User是用戶提交的路徑參數,相似PHOST/DEFAULT WEB SITE/aa.asp;xxx.jpg,由 服務/站點名稱/請求路徑 構成,IIS_MAP_Wizard是在管理器文件映射裏的每一個表項,譬如*.ASP
比較的結果就是,拿aa.asp;xxx.jpg與*.ASP進行匹配,顯然結果是不匹配的(/xxx.asp/xxx.jpg,是拿xxx.jpg和*.ASP進行匹配)spa
c.總結
IIS6文件映射配置圖設計
IIS7文件映射配置圖code
從上面的關鍵分析和圖中,能夠看出,IIS6存在解析漏洞是因爲其設計上的問題致使,IIS6只簡單地根據擴展名來識別,而IIS7是進行通配符匹配來定奪請求文件是不是某腳本類型,可見IIS7糾正了錯誤機制,更加科學、健壯。blog