极光行动_流量分析_漏洞复现 1 分析样本数据 2 分析奔溃点 3 OD动态分析 验证 4 EXP实现后台远程连接
1.1 概览样本数据流
分析:
可以观察到样本已经提取得很精炼并没有多少个包,协议只有http、tcp 所以我们不用协议分层、会话、端点等分析,直接流追踪就行
1.2 tcp流追踪
分析:
从上面得图中可以发现以下流程:
分析:
服务端第二次返回了一个html文档,里面包含了这样得内容:
>
分析:
但是上面的脚本里面没有这个函数,所系分析脚本:
那就能解释了,这个解密后是脚本,并且有WisgEgTNEfaONekEqaMyAUALLMYW(event)这个函数。
1.3 提取脚本并调试获取解密脚本
这里我用chrome浏览器调试,我在解密后执行前下一个断点,如下:
分析:
此时的 NqxAXnnXiILOBMwVnKoqnbp 即保存的是 解密后的脚本,我们通过chrome 的数据窗口保存数据到本地:
1.4 查看并分析解密后脚本
}
分析:
我们看到的确在这里面有 WisgEgTNEfaONekEqaMyAUALLMYW() 函数,概览了分析了一下整个脚本(详情请查看上面的注释)。总结如下:
1. gGyfqFvCYPRmXbnUWzBrulnwZVAJpUifKDiAZEKOqNHrfziGDtUOBqjYCtATBhClJkXjezUcmxBlfEX()
此函数填充了 0xd0000个栈溢出跳转地址和堆空间空间150个滑板指令+shellcode
lTneQKOeMgwvXaqCPyQAaDDYAkd
2. 创建了全局的变量事件触发event副本
标签vhQYFCtoDnOzUOuxAflDSzVMIHYhjJojAOCHNZtQdlxSPFUeEthCGdRtiIY
的内容置空
3. 设置一个定时器,发作间隔为50ms,发作响应函数为nayjNuSncnxGnhZDJrEXatSDkpo
猜想这里应该就是触发了崩溃,因为已经置空了还在去访问。
2 分析奔溃点
2.1 获取崩溃点
使用windbg 附加ie 6.0 的进程,然后访问本地搭建的服务器(这里使用phpsudy搭建,根目录下放我们前面提取出的html文档),链接使用 xxx.html?rFfWELUjLJHpP,xxx为你存储的html文档名
分析:
如前面分析脚本中的验证,根据栈回溯分析,是mshtml!CEventObj::get_srcElement导致的崩溃,即脚本中的 lTneQKOeMgwvXaqCPyQAaDDYAkd.srcElement。
2.2 分析上下文 查看奔溃点的来源
u mshtml!CEventObj::get_srcElement
u mshtml!CEventObj::GenericGetElement l0x100
u mshtml!CElement::GetDocPtr
崩溃点环境:
分析:
-
我们可以看到ecx是0x 00000054 所以产生了异常。
-
我往上找(上面第二张贴图)发现 在mshtml!CEventObj::GenericGetElement 中 ecx 源于 ebx,ebx 来源于.......可以追溯到 当前的局部变量 [ebp-0x8] 中。
-
简单的浏览观察到没有哪里有赋值[ebp-0x8],所以开始展开分析。
2.3 展开分析追溯崩溃源
展开 mshtml!CEventObj::GenericGetElement 函数 查看 局部变量 [ebp-8]
7e44c4c8 8b804c010000 mov eax,dword ptr <Unloaded_ud.drv>+0x14b (0000014c)[eax]
分析:
我们可以从上面找到如下语句:
可以看出,调用了GetParam函数,ebp-8是存储的参数
分析 mshtml!CEventObj::GetParam函数:
7e27e26d c20400 ret 4
分析:
可以看出使用ecx调用数据,这大概是一个thiscall类型,ecx存储着一个对象指针。我门回到上面查看调用mshtml!CEventObj::GetParam之前ecx是什么。
可以看到是 mshtml!CEventObj::GenericGetElement 函数的 局部变量 [ebp-0ch]
可以看到 是 mshtml!CEventObj::GenericGetElement() 的 ecx 也就是 同一个对象参数。
2.4 查阅分析相关类和结构体
元素内存已经被释放了。
使用查看相关IDA符号:
2.5 漏洞成因
综合上面的分析可以得出以下结论:
createEventObject创建了event的副本,但是此函数中EVENTPARAM::EVENTPARAM() 复制EVENTPARAM结构时并没有增加CTreeNode中srcElement即原对象的访问计数。所以在原Element被清空的时候,也对该内存进行了释放,造成了event副本中的EVENTPARAM.CtreeNode成了悬空指针。当使用的时候,会依次调用mshtml!CEventObj::get_srcElement()、mshtml!CEventObj::GenericGetElement()、mshtml!CElement::GetDocPtr(),会使得访问已经释放的内存(我们可以有意使用这块内存触发堆喷条件)
3 OD动态分析 验证
3.1 当释放Element的情况
在mshtml!CEventObj::get_srcElement()、mshtml!CEventObj::GenericGetElement()、mshtml!CElement::GetDocPtr()这三个函数下断点
分析:
我们一路跟下来可以看到此时 ecx = ebx = 0x0c0d0c0d是我们的滑板指令了。继续跟进去验证:
分析:
如我们预计的一样,此时已经来到了我们的滑板了
3.2 当没有释放Element的情况
在脚本中注释掉,释放对象的语句:
运行:
分析:
我们可以观察到这里CTreeNode的ECX和EBX恢复了正常
4 EXP实现后台远程连接
4.1 CShellCode 和 UnicodeShellCode的的转换
注意: 此脚本使用python2的环境,因为python3中没有 .encode('hex')
js_shellcode)
4.2 shellcode的编写
这里使用的是vs2017 -32- release,写完后直接放xdbg里面扣取shellcode
}
4.3 自定义js脚本,触发并实现堆喷
/html>
4.4 验证远程连接反弹shell
使用OD附加IE并使用IE 访问服务器 ip/test.html:
到达触发点:
来到堆喷滑板指令:
验证shellcode:
f9 继续运行,并使用物理机telnet虚拟机,成功反弹shell,并且在shellcode中使用exitprocess,增强隐蔽性: