IIS文件名解析漏洞扼要分析

歸納: 從技術角度分析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

相關文章
相關標籤/搜索