​《0day安全》——内核漏洞案例分析

就继续,写写,记忆记忆,学习学习

还是有所收获的

拒绝服务内核漏洞

这是指能使远程系统崩溃或者资源耗尽的内核程序bug或缺陷

下面学习的是这个,影响vista和server 2008

[2009-09-08][Microsoft][SMB2][SRV2.SYS][远程拒绝服务内核漏洞][36299]

跟实现SMB协议相关的SRV2.SYS驱动没有正确处理包含畸形SMB头结构数据的NEGOTIATE PROTOCOL REQUEST

即SMB报文中的Process Id High字段中包含畸形数据,就会触发SRV2.SYS中的函数越界内存引用,导致以内核态执行任何指令或发生系统崩溃

只要开放了端口并允许远程访问就会受影响

SMB运行在TCP/IP协议之上

也在NET Header上,如下:

blob.png

我们将下面的看出SMB packet

NETBIOS Header

SMB Base Header

SMB Command Header

SMB DATA

他们协议的字段部分有点长啊

懒,不打字了,

不过看下面攻击数据也能大概看到

blob.png

首先漏洞发生在Command为0x72的磋商协议

上面也看到了

"\x72" # Negociate Protocol

而且PIDHigh是畸形的,就是不是正常值,正常是\x00\x00

"\x00\x26" # PIDHigh: –> 🙂 normal value should be "\x00\x00" 

我们去ida看看,由于作者的是ida5.5,ida6.6或6.8已经打不开那个idb了,所以看不到符号

只能去一个比较旧的,但是f5有点问题,

blob.png

而且用新版ida定位到哪个地址,那又没那个函数,就先将就着看汇编代码吧

这个就是作者截图中的v4,保存在esi中了

blob.png

跟着就赋值

blob.png

根据作者的说法,那么开始DestinationBuffer进行一系列运算后,就指向了SMB Base Header

SMB Base Header+12刚好指向PIDHigh字段,就是说我们可以任意控制这个WORD大小的值

从而控制数组_ValidateRoutines的索引

只要PIDHigh的值足够大,就可以_ValidateRoutines[PIDHigh]成为非法地址,导致数组越界,甚至引用非法内存或执行任意代码

不过不明白为什么可以执行任意代码

本地拒绝服务内核漏洞

跟作者看看下面这个

[2010-04-22][Microsoft][SfnINSTRING][Win32k.sys][本地拒绝服务内核漏洞]

这是mj0011公布的作者说

Win32k.sys 在DispatchMessage时,会最后调用到xxxDefWindowProc,这个函数在处理某些消息时,会调用gapfnScSendMessage这个函数表中的函数来处理,其中2000/xp/2003下在处理0x18d号消息时,会有一个名为SfnINSTRING的函数,这个函数当lParam不为空时,直接认为lParam是内存指针,并直接从地址中取出数据,尽管函数内使用了SEH,但是只要传递错误的内核地址,仍然会引发系统崩溃

我们看看ida,不用那个魔鬼训练营xp里面的ida,f5太渣,重新下载了个,可以了

blob.png该漏洞我们传入得a2是0x18d

blob.png

至于为啥进入的是else,为啥不是if,没说,不过程序肯定是进入了else,那么肯定是因为

a1是一个句柄,*(_BYTE *)(a1 + 22) & 8的运算结果为0咯blob.png

继续v4运算后其实就是v5的值0x18d,小于0x400进入if

blob.png

进而调用下面的函数

blob.png

我们看看MessageTable索引是0x18d

blob.png

向下看可以看到是0x45

blob.png

那么跟0x3f与的结果是5

blob.png

那么_gapfnScSendMessage第5个就是

blob.png我们去这个函数看看

只要a4不为0,就访问a4+8和a4+4,这个地址执行的DWORD数据

blob.png

那么MJ0011是传了0x80000000,0x80000000+8,怎么可能给你读取呢

blob.png

最后运行exp看看会不会蓝屏

blob.png

没有,应该是我的xp sp3已经修复了

缓冲区溢出内核漏洞

接下来是这个洞

[2009-07-31][ALWIL][avast4.8.1335_Professionnel][aswMon2.sys][本地缓冲区溢出内核漏洞][本地权限提升]

avast是一个杀软哦

漏洞存在于aswMon2.sys驱动对派遣例程的处理中,对IoControlCode为0xb2c8000c的处理中存在缓冲区溢出漏洞。两次调用这个IoControl处理函数,会导致内存的函数指针覆盖成一个固定的DWORD,0x57523c00,

这个是可以在用户态申请分配的,存放Ring0 shellcode就行了,假如那里的没有申请,也是内存非法访问,蓝屏

上ida

看到了设置派遣例程函数

blob.png

从这我发现其实漏洞分析的时候,直接搜触发漏洞时候的字符就快速定位函数了

blob.png

直接到达

blob.png

继续,如果缓冲区长度不等于0x1448,直接返回了

blob.png

如果相等就复制到dword_18BD8,调用sub_108F0函数,之后返回

我们看看sub_108F0函数

char __cdecl sub_108F0()
{
  const char *v0; // [email protected]
  const char *v1; // [email protected]
  const char *v2; // [email protected]
  int v4; // [email protected]
  v0 = &byte_18BF4;
  if ( byte_18BF4 )
  {
    do
    {
      sub_143EC(v0);
      v0 += strlen(v0) + 1;
    }
    while ( *v0 );
  }
  v1 = &byte_1900C;
  if ( byte_1900C )
  {
    do
    {
      sub_143EC(v1);
      v1 += strlen(v1) + 1;
    }
    while ( *v1 );
  }
  v2 = &byte_19418;
  if ( byte_19418 )
  {
    do
    {
      sub_143EC(v2);
      v2 += strlen(v2) + 1;
    }
    while ( *v2 );
  }
  *v2 = *"<RW>*.FON";
  v4 = (v2 + 4);
  *v4 = *&aRw_fon[4];
  v4 += 4;
  *v4 = *&aRw_fon[8];
  *(v4 + 2) = aRw_fon[10];
  sub_12374(0, 1);
  return 1;
}

我们看看第一个框,其实差不多是让v2指向byte_19418的结尾+1的地方,v2最终是指向字符串结束符'\0'下一个位置,因为+1了嘛

那么第二个框是将一个常量赋值到v2指向的内存

blob.png

之前

blob.png

那我们可以控制0x18BD8-0x1A020的内存

作者说本来那个常量是写到0x18BD8-0x1A01F,结果写到了0x1A021处了,就认为是缓存区溢出

blob.png

不过硬是要说也是,因为我们可控的0x1448字节最后一个不是'\0',

但这样感觉是溢出一个字节

本来我觉得是常量写在0x1A020的,现在写在0x1A021

因为0x1448字节的最后一个正常应该为'\0'

不知道分析得对不对,瞎说的

就是要赋值给函数指针的,现在偏移1位了,我感觉是这样

继续,而从0x1A020是函数指针

blob.png

而再sub_1034E中又有调用,

其中sub_1034E在这里面,首先设置了派遣例程函数

blob.png

一致跟进去就是sub_1034E

blob.png

直接看sub_1034E吧,确实调用了

blob.png

byte_1A030需要非空,上次我们将dword_1A024覆盖成0x57523c00了,我们将Ring0 shellcode存于此即可

但是byte_1A030飞空怎么解决呢,跟byte_1A020相差16字节,上次我们只能溢出11割接

那我们就两次溢出啊,

现在我才明白了这溢出啊,不懂的看看书的示意图

可以不断地在后面写<RW>*.FON这个字符

byte_1A030就不是空了,再想办法调用sub_1034E就ko了

那就KO了咯

我们看看发现并利用漏洞作者的exp

确实是两次调用了,为防止太快了,中间还sleep一下,毕竟0x1448字节

blob.png

 AfficherListeFichiers(); 这个函数肯定是触发sub_1034E的了

好像是找数据的,这就不懂如何触发了

blob.png

还有的话就是之前还申请了内存和复制shellcode,确实是那个显眼的地址

blob.png

任意地址写任意数据内核漏洞

学习的是下面这个

[2010-01-23][Rising][Antivirus_2008_2009_2010][RsNTGdi.sys][任意地址写任意数据内核漏洞][本地权限提升][37951]

是瑞星的,又是杀软,O(∩_∩)O哈哈~

漏洞存在于RsNTGdi.sys

都是这个规律,越到后面,越是懒得写,这里作者直接上ida了

我们在start那看到了几个派遣例程函数,那个名称可能作者重命名了

blob.png可以看到处理了6个IoControlCode,(我复制到编辑器,方便代码折叠)

blob.png

看看0x83003C0B这个流程

首先输入输出缓冲区长度都要大于等于4

但我这里f5将InputBuffer作为VidSetTextColor的参数

blob.png

只是这里ida识别不出来,eax就是Type3InputBuffer,那么[eax]就是*Type3InputBuffer

解决一个小问题,继续

blob.png

VidSetTextColor在下面这个文件中,看蓝色标题处

会将输入保存到一个全局变量中

并返回旧的全局变量的值并赋值给UserBuffer

blob.png

那这样我们就要两次调用才行啦,

首先将要写入的值放在第一次调用,

第二次就可以写到要写到的UserBuffer中的

就是任意位置写任意数据了

我们看看exp,确实调用了两次

blob.png

但看下面实际上就执行了多次写操作

第一次是将0xc3写到Gdt_Addr

第二次是CallGateData[eax]循环写到Gdt_Addr+0x3e0+eax

其中eax是循环变量,暂时不懂什么意思,慢慢消化

blob.png

循环4次

blob.png

任意地址写固定数据内核漏洞

最后一个啦

[2009-07-30][Microsoft][NtUserConsoleControl][win32k.sys][任意地址写固定数据内核漏洞][本地权限提升]

是xp的sp2和sp3中的系统服务函数NtUserConsoleControl,实现是在win32k.sys

首先在ida找到这个函数

通过PsGetCurrentProcess获取进程的PEPROCESS跟csrss进程的相比

不同就将返回值设置为下面的转化为16进制就是0xC0000022u(STATUS_ACCESS_DENIED)

相同就继续调用xxxConsoleControl

blob.png

跟进xxxConsoleControl

首先对a1进行检查

如果大于9,返回0xC0000003(STATUS_INVALID_INFO_CLASS)

跟着就判断0-9哪种情况blob.png

我们看看7时的情况:

将Object[3] = 0; 即将Object第四个句柄置为0

整个过程又没对Object进行检查

那么Ring3传过来的Object,经过这个函数就可以将Object第四个句柄置0,即可以向任意地址写入固定数值(数值0)blob.png

我们看看利用代码

不过我感觉这位置有点问题,框住的是我添加的注释

a1为7才对

blob.png

感觉这样才对

blob.png

好的就先这样,继续前行

打赏作者
喜欢本博客,打赏让博客永久运行,多少你说了算

您的支持将鼓励我们继续创作!

[微信] 扫描二维码打赏

[支付宝] 扫描二维码打赏

发表评论

电子邮件地址不会被公开。 必填项已用*标注