IE安全系列之——RES Protocol

res Protocol用于从一个文件里面提取指定资源。语法为:res://sFile[/sType]/sID
各Token含义:
sfile:百分号编码。包含资源的文件路径。
sType:可选的,字符串或者数字,表明资源类型。可以是任意亿一个FindResource可以识别的预定义类型。如果指定了数字类型的值,则需要跟随一个#字符。未指定时默认RT_HTML或RT_FILE。
sID:字符或数字类型。资源标识符。如果指定了数字值,需要跟随一个#。
具体的可见参考资料1,不翻译了……
0x01 新窗口中Res Protocol的加载
在新窗口打开res protocol的时候,res Protocol的dll会被载入内存。Res protocol加载的dll使用LoadLibraryExW读入,一些常见的res protocol,例如res://ieframe.dll/的读入时并没有使用完整的路径。虽然可以考虑DLL劫持问题,但program files和system32均为administrator权限,所以还是不要想了……
在新窗口加载res protocol URL时,最终解析、加载资源并绑定的工作由CResProtocol类的CResProtocol::DoParseAndBind完成。
0:009> kvn 1
# ChildEBP RetAddr  Args to Child             
00 072fa464 664b2ad5 0f806814 00000000 00000060 KERNEL32!LoadLibraryExWStub (FPO: [Non-Fpo])
 
0:009> dds esp
072fa468  664b2ad5 MSHTML!CResProtocol::DoParseAndBind+0x103
072fa46c  0f806814
 
0:009> du 0f806814
0f806814  "ieframe.dll"
代码1:CResProtocol::DoParseAndBind正在使用LoadLibraryEx加载ieframe.dll
DoParseAndBind处理ResProtocol时的具体做法:
a、Crack Res URL。
Res URL格式如我们之前所述。另外,res protocol的第一个path部分不允许有“/”。因为微软在crack URL时hardcode直接wcschr搜索的L'/'。解析字符串时遇到的第一个“/”(除了res://的//)后面只能是restype,或者id。

b、传入的res protocol 路径长度大于MAX_PATH时,返回E_FAIL,所以Fuzz这里意义也不是多大了。Win95+IE4.0时候这里有漏洞,这个判断也是自那个漏洞之后补上的。

c、LoadLibraryEx载入资源DLL,Flag为DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE。所以也不要考虑重复利用载入的DLL了,因为DLL被映射到了只读内存中。并不会被执行。

0:009> !address 67370000  
Usage:                  Image
Base Address:           67370000
End Address:            67371000
Region Size:            00001000
State:                  00001000    MEM_COMMIT
Protect:                00000002    PAGE_READONLY
Type:                   01000000    MEM_IMAGE
Allocation Base:        67370000
Allocation Protect:     00000080    PAGE_EXECUTE_WRITECOPY
Image Path:             F:\WINDOWS\SYSTEM32\IEFRAME.dll
Module Name:            IEFRAME
Loaded Image Name:      F:\WINDOWS\SYSTEM32\IEFRAME.dll
Mapped Image Name:     
More info:              lmv m IEFRAME
More info:              !lmi IEFRAME
More info:              ln 0x67370000
More info:              !dh 0x67370000
代码2:分配在只读页上的ieframe.dll
0x02 曾经的可行方法:new Image判断res

确实迟了一些,不过为了弥补,我接下来会分析为什么用不了了

曾经在Angler Exploit Kit中,攻击者用Res Protocol玩出了一堆花样。使用如下代码,可以判断本地文件是否存在。

function my_onError(){alert("file not exists!!");}
function Check(s) {
    x = new Image();
    x.onerror=my_onError;
    x.src = s;
    document.body.appendChild(x);
    return 0;
}
Check("res://f:\\node\\asoehook2.dll/#2/#102")
代码3:使用Res Protocol检查本地文件(不过在最新的IE11中,这个判断并不能在http/https/ftp下进行,也不能在任何网络相关的protocol打开的about:blank或者iframe 的about:blank中进行。下节说)

为啥Image可以做到这个呢?让我们仔细看一下。猜也能猜得到,new Image事实上创建了一个CImgElement。
Breakpoint 10 hit
eax=11fe3bc0 ebx=662016f0 ecx=11fe3bc0 edx=000001bc esi=65eb2270 edi=072fa3c8
eip=66201739 esp=072fa3a4 ebp=072fa3b4 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200206
MSHTML!CImgElement::CImgElement:
66201739 8bff            mov     edi,edi
0:009> kvn
 # ChildEBP RetAddr  Args to Child             
00 072fa3a0 66201718 0000003d 06a08000 662016f0 MSHTML!CImgElement::CImgElement (FPO: [Non-Fpo])
01 072fa3b4 6625110b 072fa440 06a08000 072fa3ec MSHTML!CImgElement::CreateElement+0x28 (FPO: [Non-Fpo])
02 072fa3f0 663aa61a 06a08000 11fe8a00 00000000 MSHTML!CreateElement+0xab (FPO: [Non-Fpo])
03 072fa500 664c4bb9 0000003d 072fa524 00000000 MSHTML!CMarkup::CreateElement+0xee (FPO: [Non-Fpo])
04 072fa548 664c49a0 06a7ee10 06920000 0bb24420 MSHTML!CImageElementFactory::create+0x49 (FPO: [Non-Fpo])
05 072fa5b8 664c48e4 00000001 11fe8a00 072fa5d8 MSHTML!CImgElement::Var_create+0x89 (FPO: [Non-Fpo])
06 072fa5e0 552f3b7e 189114e0 01000001 163c3d20 MSHTML!CFastDOM::CHTMLImageElement::DefaultEntryPoint+0x44 (FPO: [Non-Fpo])
07 072fa648 552f8f53 189114e0 01000001 163c3d20 jscript9!Js::JavascriptExternalFunction::ExternalFunctionThunk+0x18e (FPO: [Non-Fpo])
代码4: CImgElement的创建
然后,为Image指定src后,整个流程如下:
1
CImgElement::OnPropertyChange ---> CImgHelper::SetImgSrc ---> CImgHelper::FetchAndSetImgCtx
在早期的IE中,这一套流程下来并没有认为res是不让加载的,所以能够触发onerror事件。但是,使用file:///的src不可判断本地文件是否存在。这就使得res判断成为比较独特的存在。
就像http下并不能通过file protocol或者UNC访问本地文件(例如上述代码Check("file:///f:/yy.jpg")不会抛出onerror事件),而如果在非http/https/ftp网站打开的about:blank中还是可以使用的。
上述描述在不过在最新的IE中无效了,那是因为微软的LMZL策略。
0x03 Local Machine Zone Lockdown
我也就不贴到最后的参考连接里面了,直接贴这儿好了:https://technet.microsoft.com/en-us/library/cc782928(v=ws.10).aspx
LMZL是微软搞出来的一个安全策略,简单的说就是阻止互联网内容访问本地内容,照理来说,在Windows XP SP2的时候就已经有这个功能了,但是直到多年以后,我在IE8上实验,还是能用RES访问本地资源。
微软的行踪一向很谜。这个举动也相当的谜。RES Protocol的当作本地文件处理的逻辑为什么没加?观察IE8和IE11处理相同本地数据的代码可以得出一个基础结论——应该是忘了。
0x04 IE11下的RES Protocol(IMG src中)为什么失效了?
首先,在IE中我输入了下面的代码。不出意外地,document.body.appendChild(iii)之后,元素添加成功,但是图片没显示出来,同时,onerror也没有触发。我开始以为是因为f:\asoehook2.dll存在的缘故。结果换了个随便打的地址加上Res Protocol,还是没有触发onerror。

同比在IE8下的Res Protocol,则既能显示图片,又能触发onerror。

于在IE11下,Img SRC指定为RES Protocol时,Img显示的是一个透明的方块,所以先怀疑这些点:下载是否出问题了?在跟踪下载栈之后,发现下载和IE8的几乎一模一样。
ChildEBP RetAddr 
039e85a4 764c14a2 urlmon!CBSCHolder::OnProgress(
            unsigned long ulProgress = 0x338,
            unsigned long ulProgressMax = 0x338,
            unsigned long ulStatusCode = 4,
            wchar_t * szStatusText = 0x0bbc2ce8 "res://f:\asoehook2.dll/#2/#102")+0x50 [d:\blue\inetcore\urlmon\mon\mpxbsc.cxx @ 807]

上一页       

039e85dc 764c46e1 urlmon!CBinding::OnTransNotification(
            tagBINDSTATUS NotMsg = ,
            unsigned long dwCurrentSize = 0x338,
            unsigned long dwTotalSize = 0x338,
            wchar_t * pwzStr = 0x00000000 "",
            HRESULT hrINet = 0x00000000)+0x35b [d:\blue\inetcore\urlmon\trans\cbinding.cxx @ 2676]
039e8610 764c4458 urlmon!CBinding::ReportData(
            unsigned long grfBSCF = 0xd,
            unsigned long ulProgress = 0x338,
            unsigned long ulProgressMax = 0x338)+0xa1 [d:\blue\inetcore\urlmon\trans\cbinding.cxx @ 5451]
039e8638 764c43ec urlmon!COInetProt::ReportData(
            unsigned long grfBSCF = 0xd,
            unsigned long ulProgress = 0x338,
            unsigned long ulProgressMax = 0x338)+0x54 [d:\blue\inetcore\urlmon\trans\prothndl.cxx @ 1863]
039e8674 764c4303 urlmon!CTransaction::DispatchReport(
            tagBINDSTATUS NotMsg = BINDSTATUS_ENDDOWNLOADDATA (0n6),
            unsigned long grfBSCF = 0xd,
            unsigned long dwCurrentSize = 0x338,
            unsigned long dwTotalSize = 0x338,
            wchar_t * pwzStr = 0x00000000 "",
            HRESULT hresult = 0x00000000)+0x19e [d:\blue\inetcore\urlmon\trans\transact.cxx @ 3153]
(Inline) -------- urlmon!CTransaction::DispatchPacket+0x23 [d:\blue\inetcore\urlmon\trans\transact.cxx @ 3278]
(Inline) -------- urlmon!CTransaction::OnINetCallback+0x116 [d:\blue\inetcore\urlmon\trans\transact.cxx @ 3356]
二者都成功地获取到了所需的资源,看来这里可以先排除。
然后,让我们再追踪一下事件。给MSHTML!CImgHelper::Fire_onerror下断点,为了确认下我下的对不对,我修改了iii.src=“aa”,这时,Fire_onerror成功触发。

图:给iii的src传入非res Protocol时,onerror事件就能成功触发。
而在IE11下指定Res Protocol时,Fire_onerror却始终无法断到。这可以证明一个猜想:如果IE禁止RES Protocol用在IMG中,那么这个禁止逻辑可能不是在事件里面去处理的。
对比在IE8下,即使使用Res Protocol,Fire_onerror仍然可以断到:

目标放在Fire_onerror的前后两层。上一层OnDwnChan看起来并不是多相关,再向上一层,CImgHelper::SetImgCtx里首先有了一些不一样的地方。
0:008>
eax=00000000 ebx=071b2930 ecx=039e9cb0 edx=00000000 esi=00000000 edi=00000000
eip=639c17ce esp=039e9c9c ebp=039e9cd0 iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000216
MSHTML!CImgHelper::SetImgCtx+0x11:
639c17ce e868feffff      call    MSHTML!CImgHelper::CScriptCalloutProtection::CScriptCalloutProtection (639c163b)
0:008>
eax=039e9cb0 ebx=071b2930 ecx=071b2934 edx=071b2930 esi=00000000 edi=00000000
eip=639c17d3 esp=039e9ca0 ebp=039e9cd0 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
MSHTML!CImgHelper::SetImgCtx+0x16:
639c17d3 33f6            xor     esi,esi
0:008>
eax=039e9cb0 ebx=071b2930 ecx=071b2934 edx=071b2930 esi=00000000 edi=00000000
eip=639c17d5 esp=039e9ca0 ebp=039e9cd0 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246

上一页       

MSHTML!CImgHelper::SetImgCtx+0x18:
639c17d5 397314          cmp     dword ptr [ebx+14h],esi ds:002b:071b2944=031a8e00
0:008>
eax=039e9cb0 ebx=071b2930 ecx=071b2934 edx=071b2930 esi=00000000 edi=00000000
eip=639c17d8 esp=039e9ca0 ebp=039e9cd0 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
MSHTML!CImgHelper::SetImgCtx+0x1b:
639c17d8 0f857b090000    jne     MSHTML!CImgHelper::SetImgCtx+0x217 (639c2159) [br=1]
0:008>
eax=039e9cb0 ebx=071b2930 ecx=071b2934 edx=071b2930 esi=00000000 edi=00000000
eip=639c2159 esp=039e9ca0 ebp=039e9cd0 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
MSHTML!CImgHelper::SetImgCtx+0x217:
639c2159 397344          cmp     dword ptr [ebx+44h],esi ds:002b:071b2974=00000000
CImgHelper::CScriptCalloutProtection::CScriptCalloutProtection在IE8中并不存在,不过很不幸,CImgHelper::CScriptCalloutProtection::CScriptCalloutProtection 并不是我们要找的目标。

但是目标也不遥远了,继续往下看一点代码,就可以发现IE11在设置IMG元素的上下文时,做了一个CMarkup::CheckForLMZLLoad(v8, 1);的判断。

LMZL还有印象不?就是上一节说的Local Machine Zone Lockdown,名字看起来有点中二病,微软具体让这个东西覆盖了多少代码量也是个谜。
记住第二个参数1。
跟入CheckForLMZLLoad之后,我们看到了if(a4 == 1){v8 = &FCK::FEATURE_BLOCK_LMZ_IMG;}
看起来很明显了,微软在IMG设置上下文的时候,限制了Local Machine Zone的图片资源加载。

设置上下文?差点忘了,获取图片和设置上下文的函数就是这个:CImgHelper::FetchandSetImgCtx。

既然上下文设置失败,那么事件绑定和触发也必然没着落,更惨的是图片也不让显示,RES Protocol判断本地文件是否存在的功能自此宣告灭亡。
0x05 网络诊断
也许你最近一年根本就没有用过IE,不要紧,IE里面有个无法显示此页还是一直在那里的。当访问一个无法处理的网站时,IE会展示res://ieframe.dll/dnserror.htm#http://xxx,在这个页面上有一个“修复连接问题”。

点击一下这个东西,就会蹦出来一个网络修复程序,比较神奇。那么这里会不会也有安全问题呢,这个修复程序IE是怎么定位到的?
跟踪一下,可以发现发现IE实际调用了ndfapi的LaunchMSDT函数,该函数启动system32下的msdt.exe。调用时使用的是完整路径,所以无需考虑exe劫持之类的问题。
0:009> kvn
 # ChildEBP RetAddr  Args to Child             
00 072fa2cc 54f3c7ec 08085978 004bdf80 00000000 KERNEL32!CreateProcessWStub (FPO: [Non-Fpo])
01 072fa5b0 54f3cb1c 07fff5a8 fedbc665 54f32b80 ndfapi!LaunchMSDT+0x201 (FPO: [Non-Fpo])
02 072fa688 54f3c5d8 00000001 54f30000 072fa6bc ndfapi!CNetDiagClient::LaunchScriptedDiagnostics+0x143 (FPO: [Non-Fpo])
03 072fa6a0 54f377a2 00000001 072fa6dc 67654b7d ndfapi!NdfExecuteDiagnosisEx+0x53 (FPO: [Non-Fpo])
04 072fa6ac 67654b7d 069d37e0 00040c94 00000000 ndfapi!NdfExecuteDiagnosis+0x12 (FPO: [Non-Fpo])
05 072fa6dc 675ee143 072fa72c 07b3f7cc 07ffec54 IEFRAME!DiagnoseConnectionProblems+0xa9 (FPO: [Non-Fpo])
06 072fa9bc 7732b0ff 07ff4ff8 072faa0c 07ffec54 IEFRAME!CShellUIHelper::DiagnoseConnection+0x2d3 (FPO: [Non-Fpo])
07 072fa9d4 7730c807 07ff4ff8 00000070 00000004 OLEAUT32!DispCallFunc+0x16f
看起来一切都是那么严谨,不过谁知道呢,IE总是在最意想不到的地方出各种小问题。
0x06 参考资料
【1】:https://msdn.microsoft.com/en-us/library/aa767740(v=vs.85).aspx

上一页      

IE安全系列之——RES Protocol的更多相关文章

  1. Kafka系列之-Kafka Protocol实例分析

    本文基于A Guide To The Kafka Protocol文档,以及Spark Streaming中实现的org.apache.spark.streaming.kafka.KafkaClust ...

  2. Android系列:res之shape制作

    大家好,pls call me francis. nice to me you. 本文将介绍使用在Android中使用shape标签绘制drawable资源图片. 下面的代码是shap标签的基本使用情 ...

  3. highlight高亮

    玩转正则之highlight高亮 2013-10-07 05:16 by 靖鸣君, 584 阅读, 3 评论, 收藏, 编辑 程序员在编写代码的时候少不了和字符串以及“查询”打交道,两者的交集中有一个 ...

  4. 玩转正则之highlight高亮

    程序员在编写代码的时候少不了和字符串以及“查询”打交道,两者的交集中有一个叫做正则表达式的的东西,这家伙用好了可以提高编程效率,用不好的话...你可以先去好好学一学. 关于正则的使用,举个简单的例子: ...

  5. 如何往IE工具条添加按钮(转载)

    如何往IE工具条添加按钮 问题提出:金山词霸.网络蚂蚁等软件安装后会向IE的工具条添加自己的按钮.按下按钮后还会作出相应的动作,这种功能是如何实现的呢?读完本文,您也可以将自己应用程序的按钮添加到IE ...

  6. 在AD09中查找元件和封装

    在AD09中查找元件和封装 Altium Designer 软件方法/步骤 Altium下Miscellaneous Devices.Intlib元件库中常用元件有: 电阻系列(res*)排组(res ...

  7. Python3 与 C# 并发编程之~ 进程篇

      上次说了很多Linux下进程相关知识,这边不再复述,下面来说说Python的并发编程,如有错误欢迎提出- 如果遇到听不懂的可以看上一次的文章:https://www.cnblogs.com/dot ...

  8. copy other

    DELPHI基础开发技巧 ◇[DELPHI]网络邻居复制文件 uses shellapi; copyfile(pchar('newfile.txt'),pchar('//computername/di ...

  9. node中转换URL字符串与查询字符串

    一个完整的URL字符串中,从"?"(不包括?)到"#"(如果存在#)或者到该URL字符串结束(如果不存在#)的这一部分称为查询字符串. 可以使用Query St ...

随机推荐

  1. 通过ClientDataSet复制表的结构及数据

    1.  需要2个ClientDataSet组件: 2.  clientDataSet1连接目标表,clientDataSet2连接源表,如果无法直接连接,使用DataSetProvider进行桥接: ...

  2. 时空KSOA之CS表单工具说明

    CS表单工具说明 1.调用: 1.1.单据事件调用 runbill_表单sn 调用无窗口表单 loadbill_表单sn 调用窗口表单 1.2.功能调用 功能号:LOADCSBILL 参数表单名称 1 ...

  3. 关于#pragma comment

    #pragma comment(lib,"ws2_32.lib") #pragma comment(lib,"ws2_32.lib")表示连接Ws2_32.li ...

  4. 题解 P1208 【[USACO1.3]混合牛奶 Mixing Milk】

    其实根本没有一楼dalao描述的那么麻烦...... 一楼dalao其实吧,采用了一种纯属模拟的方式. 下面是我的大跃进思想 但是一个个地做减法是不是太慢了?(大跃进思想) 于是我们是不是可以直接进行 ...

  5. Android中View绘制优化

    1.优化布局层次 http://www.2cto.com/kf/201209/154108.html 2.使用<include />标签复用布局文件 http://www.2cto.com ...

  6. 2018.10.20 2018-2019 ICPC,NEERC,Southern Subregional Contest(Online Mirror, ACM-ICPC Rules)

    i207M的“怕不是一个小时就要弃疗的flag”并没有生效,这次居然写到了最后,好评=.= 然而可能是退役前和i207M的最后一场比赛了TAT 不过打得真的好爽啊QAQ 最终结果: 看见那几个罚时没, ...

  7. SDOI 2019 Round1 游记

    \(SDOI~2019 ~ Round1\) 游记 \(Day ~0\) 报道.骑车子去的,好热.到了之后看到好几个同校神仙,还从那里莫名其妙的等了一会,然后交了钱签了名就拿挂牌走人了.现在居然还有受 ...

  8. HDU 6249

    Alice’s Stamps Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  9. Docker多主机网络 OpenvSwitch

    一.Open vSwitch    Open vSwitch(以下简称为OVS),英文全称:OpenVirtual Switch,顾名思义,Open vSwitch就是开放虚拟交换.我们可以把他理解成 ...

  10. python的if条件语句的语法和案例

    1.条件语句 缩进用4个空格 if条件: #条件成功, else: #条件不成功 if条件:{ #条件成功, #条件成功, }else{ #条件不成功, #条件不成功, } if的语法就是这样或者是用 ...