- UID
- 852722
|
最近通过看LocalAlloc的问题结合之前研究如何用AP去读写CE6的物理地址的过程,发现CE6的内核存在巨大安全隐患。
如果说CE5是蜗牛壳,那么CE6就是鸡蛋壳了,骚味动点脑筋,CE6的核心就能马上被你控制,下面简述几个CE6设计上的败笔。
败笔1:KDataStuct位置固定
稍微了解一点wince的都知道这个结构体吧,这个结构体在wince初始化的最早期的时候会由OAL先去初始化放置于一个“kernel才有特权”的专属地址,以CE6为例,它位于虚拟地址0xffffc800,此结构体放置大量关键内核信息,此败笔在于此地址固定,而且只需要得到“kernel特权”就可以访问此结构体。
败笔2:CE6的OAL和NK的global结构体
CE6和CE5最重要的区别之一就算OAL和kernel正式分家了,以前CE5因为OAL和Kernel打包成一个exe,外界很难进入和破坏里面的链接关系。但是CE6为了把OAL和kernel.dll分开而又要考虑让它们之间可以建立一些必要的联系,创造性的设计了两个新结构体:_NKGLOBAL和_OEMGLOBAL(nkglobal.h/oemglobal.h)。在新的设计中,kernel只提供和平台无关的一些内核算法,OAL只提供和平台相关的函数接口,kernel提供的API在被上层调用后如果需要访问硬件就必须要透过oemglobal去调用oal的函数,反过来OAL需要做一些关键调用比如entercriticalsection的时候,又要依赖kernel提供的nkglobal来调用kernel的函数。但是如果这两个结构体暴露到外部就非常危险,因为结构体上面的函数指针如果被篡改,那么kernel和oal就会被牵着鼻子走了。
败笔3:Kdatastruct结构体包含了oal和nk的global结构体
微软为了方便启动过程中oal找到nkglobal,把nkglobal和oalglobal的指针都挂在了Kdatastruct中,只要具有内核权限的代码都可以找到它们。
败笔4:用户态名存实无
虽然微软规定了所有AP都是用户态,但是AP却可以自己挂载一个内核态的驱动,这个驱动可以作为内鬼去帮助用户态的AP做任何事情。通过ARMCE兄弟们前期的探索,我们已经知道,我们可以用一个AP去读写CE6的物理地址。
综合上述败笔,我们可以做如下想象:
1.我们先写一个AP和一个傀儡内核态驱动,AP动态注册和加载这个自己的内核驱动。
2.在内核态驱动里面去fetch那个位于0xffffc800的Kdata结构体。
3.内核态驱动从Kdata结构体里面拿到NKglobal和Oemglobal结构体
4.撰写傀儡函数于内核态驱动
5.篡改oemglobal或者nkglobal的相关函数指针指向傀儡函数
6.傀儡函数提供数据给AP
这就实现了对CE6的一个简单破*解。
哈哈,是不是很有意思啊,CE6大门洞开啊。
打个浅显一点的比方,只针对实际应用,大体过程参考1楼。
比如你想监视M8上面的所有的kerneliocontrol的调用。
你可以这样偷梁换柱。
用傀儡内核驱动找到pOemglobal->pfnOEMIoctl指针,先存下来。
然后自己实现一个傀儡OEMIoctl,接口要和kerneliocontrol一致,做的事情就是先得到调用参数记录下来,然后再去call实际的pfnOEMIoctl指针。
然后把傀儡OEMIoctl的地址写到pOemglobal->pfnOEMIoctl
万事大吉了。 |
|
|