DDE通信研究

笑着哭i 提交于 2019-12-25 07:19:43

作为一个安全研究人员来讲,听到最多关于DDE的东西可能就是office DDE 攻击这种钓鱼攻击手法。

  • 为什么只有Office可以进行DDE攻击?
  • 有哪些软件默认支持DDE协议?
  • DDE还可以做什么?

DDE通信还有其他功能命令,如:动态修改Excel表格内容。

本文只针对双击桌面上的xls文件时,Explorer通过DDE将文件路径传给Excel的过程进行研究。

1)研究背景

大部分Office系列软件如Excel、Word等程序默认支持基于Windows消息机制的DDE通信协议。使用DDE的程序,如Excel软件在启动时的命令行参数只有" /dde"

这样Excel就会默认创建一个隐藏的窗口作为DDEServer,并等待接收用户双击桌面xls文件时,DDE Client(Explorer.exe)发来的DDE消息。

2)DDE会话流程

一个程序既可以作为DDE服务器,也可以作为DDE客户端,两者通讯的标识是彼此的窗口句柄HWND。微软建议每次建立会话都应该建立不同的窗口句柄。

第一步:建立会话,客户端必须通过SendMessage广播一条WM_DDE_INITIATE消息给所有窗口,来定位Excel的DDE Server。

如果lParam的LOWORD为NULL,任何DDEServer可以回复这个消息。DDE Server收到一个WM_DDE_INITIATE消息后,如果该消息的lParam的HIWORD为NULL,DDE Server为它支持的所有Topic都回复一个WM_DDE_ACK 消息。

SendMessage((HWND)HWND_BROADCAST,   // 广播消息给所有窗口
WM_DDE_INITIATE,                    // 初始化会话
(WPARAM)g_hHwnd,                    // 当前DDE Client的窗口句柄
MAKELONG(atomApplication,           // application-name atom  (Excel默认是"Excel")
atomTopic));                        // topic-name atom  (Excel默认是"System")

服务端回复WM_DDE_INITIATE消息

DDE Server收到WM_DDE_INITIATE消息后,根据wParam中保存的DDE Client句柄回复消息。服务端必须回复一个WM_DDE_ACK消息,告诉客户端,它收到了建立会话的申请!

回复WM_DDE_ACK消息时,将自己的窗口句柄,作为wParam参数回复给客户端。至此会话建立完成,剩下的消息必须使用根据各种保存的对方窗口句柄,使用PostMessage来通讯

客户端收到握手会话的回复后,在消息处理中保存DDE服务端的窗口句柄

case WM_DDE_ACK:
   {
       // 客户端接收DDE服务器回复,保存DDEServer句柄,删除lParam中的GlobalAtom
       HWND g_hServerHwnd = (HWND)wParam;
   }
break;

第二步:发送命令,告诉Excel打开指定xls文件

// 发送命令给Excel
 
// 服务器数据项内容
CONST wchar_t sCommand[] = L"[open(\"D:\\1.xlsx\" /ou \"\")]";
// 分配DDEDATA格式化的全局共享内存块
HGLOBAL hCommand = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(sCommand));
// 锁定内存块地址
LPWSTR lpCommand = (LPWSTR)GlobalLock(hCommand);
// 填充数据项内容
wcscpy(lpCommand, (WCHAR*)sCommand);
// 解锁内存块
GlobalUnlock(hCommand);
// 获取当前窗口的安全句柄
// 组合消息参数lParam
LONG lDataPack = PackDDElParam(WM_DDE_EXECUTE, 0, (UINT)hCommand);
// 发出远程命令消息
PostMessage(g_hServerHwnd, WM_DDE_EXECUTE, (WPARAM)g_hHwnd, (LPARAM)lDataPack);
// 释放内存
GlobalFree(hCommand);

第三步: 结束会话 WM_DDE_TERMINATE

PostMessage(g_hServerHwnd, WM_DDE_TERMINATE, (WPARAM)g_hHwnd, 0);

3)分析Exploer和Excel的DDE通讯消息

3.1)观察DDE消息通讯

通过Spy++可以查看Explorer和Excel通过DDE通讯的消息类型,打开Spy++,选择Excel进程,消息选项中过滤DDE消息。
在这里插入图片描述

随后双击桌面上的xls文件,可以观察到Explorer发送给Excel的消息由一下3条,下面消息中第三列数据:R、S、P标志,具体含义可以参考Spy++手册。

通过上面可以看到,Explorer给Excel发送了3条消息,分别是:

  • 建立会话WM_DDE_INITATE
  • 执行命令WM_DDE_EXECUTE
  • 结束会话WM_TERMINATE

其中要打开的xls文件路径,就保存在WM_DDE_EXECUTE执行命令消息中,其消息具体格式,参考https://docs.microsoft.com/en-us/windows/win32/dataxchg/wm-dde-execute

3.2)观察发送的命令格式

通过x64dbg调试Explorer,设置PackDDEParam函数断点,命中后,可以查看Explorer发送的WM_DDE_EXECUTE消息的命令内容

在这里插入图片描述

4)补充

DDE已经被应用在IE、Adobe、Office、等软件中,我们可以通过木马程序给目标DDEServer发送消息来控制目标软件的行为。

比如下面宏代码给IE浏览器发送DDE消息,可以控制它访问指定网页

Sub AutoOpen()
On Error GoTo MyErr
lngChannel = DDEInitiate(App:="IExplore", Topic:="WWW_OpenURL")
DDEExecute Channel:=lngChannel, Command:="www.qq.com"
DDETerminate Channel:=lngChannel
MyErr:
End Sub

甚至可以使用DDE消息读取修改指定office文档内容,由于是基于windows消息以及共享内存交互数据,这样不会触发任何读取文件的行为,可以规避安全软件的文件行为防御,可用于高级定向攻击,窃取指定敏感文件内容的APT木马中。

下面来说说为什么DDE攻击只被用到了office中,经过逆向分析,原来Office系列在向外发送DDEInitiate消息的时候,如果目标DDE Server进程不存在,则会尝试创建这个进程。

Sub AutoOpen()
On Error GoTo MyErr
lngChannel = DDEInitiate(App:="c:\\Windows\\system32\\cmd.exe", Topic:="/c calc")
MyErr:
End Sub

但是Office软件也会给用户对应的弹窗提示,这个提示中的路径很明显,这个也有办法绕过,绕过方法可以参考我这篇文章:https://blog.csdn.net/cssxn/article/details/91867028
在这里插入图片描述

5)参考资料

  • https://docs.microsoft.com/en-us/windows/win32/dataxchg/using-dynamic-data-exchange
  • https://www.cnblogs.com/organic/p/9175276.html
  • https://blog.csdn.net/u012252959/article/details/49590827
  • https://docs.microsoft.com/en-us/office/vba/api/word.application.ddeinitiate
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!