就继续,写写,记忆记忆,学习学习
还是有所收获的
拒绝服务内核漏洞
这是指能使远程系统崩溃或者资源耗尽的内核程序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上,如下:
我们将下面的看出SMB packet
NETBIOS Header
SMB Base Header
SMB Command Header
SMB DATA
他们协议的字段部分有点长啊
懒,不打字了,
不过看下面攻击数据也能大概看到
首先漏洞发生在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有点问题,
而且用新版ida定位到哪个地址,那又没那个函数,就先将就着看汇编代码吧
这个就是作者截图中的v4,保存在esi中了
跟着就赋值
根据作者的说法,那么开始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太渣,重新下载了个,可以了
该漏洞我们传入得a2是0x18d
至于为啥进入的是else,为啥不是if,没说,不过程序肯定是进入了else,那么肯定是因为
a1是一个句柄,*(_BYTE *)(a1 + 22) & 8的运算结果为0咯
继续v4运算后其实就是v5的值0x18d,小于0x400进入if
进而调用下面的函数
我们看看MessageTable索引是0x18d
向下看可以看到是0x45
那么跟0x3f与的结果是5
那么_gapfnScSendMessage第5个就是
我们去这个函数看看
只要a4不为0,就访问a4+8和a4+4,这个地址执行的DWORD数据
那么MJ0011是传了0x80000000,0x80000000+8,怎么可能给你读取呢
最后运行exp看看会不会蓝屏
没有,应该是我的xp sp3已经修复了
缓冲区溢出内核漏洞
接下来是这个洞
[2009-07-31][ALWIL][avast4.8.1335_Professionnel][aswMon2.sys][本地缓冲区溢出内核漏洞][本地权限提升]
avast是一个杀软哦
漏洞存在于aswMon2.sys驱动对派遣例程的处理中,对IoControlCode为0xb2c8000c的处理中存在缓冲区溢出漏洞。两次调用这个IoControl处理函数,会导致内存的函数指针覆盖成一个固定的DWORD,0x57523c00,
这个是可以在用户态申请分配的,存放Ring0 shellcode就行了,假如那里的没有申请,也是内存非法访问,蓝屏
上ida
看到了设置派遣例程函数
从这我发现其实漏洞分析的时候,直接搜触发漏洞时候的字符就快速定位函数了
直接到达
继续,如果缓冲区长度不等于0x1448,直接返回了
如果相等就复制到dword_18BD8,调用sub_108F0函数,之后返回
我们看看sub_108F0函数
char __cdecl sub_108F0() { const char *v0; // esi@1 const char *v1; // esi@3 const char *v2; // edi@5 int v4; // edi@7 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指向的内存
之前
那我们可以控制0x18BD8-0x1A020的内存
作者说本来那个常量是写到0x18BD8-0x1A01F,结果写到了0x1A021处了,就认为是缓存区溢出
不过硬是要说也是,因为我们可控的0x1448字节最后一个不是'\0',
但这样感觉是溢出一个字节
本来我觉得是常量写在0x1A020的,现在写在0x1A021
因为0x1448字节的最后一个正常应该为'\0'
不知道分析得对不对,瞎说的
就是要赋值给函数指针的,现在偏移1位了,我感觉是这样
继续,而从0x1A020是函数指针
而再sub_1034E中又有调用,
其中sub_1034E在这里面,首先设置了派遣例程函数
一致跟进去就是sub_1034E
直接看sub_1034E吧,确实调用了
byte_1A030需要非空,上次我们将dword_1A024覆盖成0x57523c00了,我们将Ring0 shellcode存于此即可
但是byte_1A030飞空怎么解决呢,跟byte_1A020相差16字节,上次我们只能溢出11割接
那我们就两次溢出啊,
现在我才明白了这溢出啊,不懂的看看书的示意图
可以不断地在后面写<RW>*.FON这个字符
byte_1A030就不是空了,再想办法调用sub_1034E就ko了
那就KO了咯
我们看看发现并利用漏洞作者的exp
确实是两次调用了,为防止太快了,中间还sleep一下,毕竟0x1448字节
AfficherListeFichiers(); 这个函数肯定是触发sub_1034E的了
好像是找数据的,这就不懂如何触发了
还有的话就是之前还申请了内存和复制shellcode,确实是那个显眼的地址
任意地址写任意数据内核漏洞
学习的是下面这个
[2010-01-23][Rising][Antivirus_2008_2009_2010][RsNTGdi.sys][任意地址写任意数据内核漏洞][本地权限提升][37951]
是瑞星的,又是杀软,O(∩_∩)O哈哈~
漏洞存在于RsNTGdi.sys
都是这个规律,越到后面,越是懒得写,这里作者直接上ida了
我们在start那看到了几个派遣例程函数,那个名称可能作者重命名了
可以看到处理了6个IoControlCode,(我复制到编辑器,方便代码折叠)
看看0x83003C0B这个流程
首先输入输出缓冲区长度都要大于等于4
但我这里f5将InputBuffer作为VidSetTextColor的参数
只是这里ida识别不出来,eax就是Type3InputBuffer,那么[eax]就是*Type3InputBuffer
解决一个小问题,继续
VidSetTextColor在下面这个文件中,看蓝色标题处
会将输入保存到一个全局变量中
并返回旧的全局变量的值并赋值给UserBuffer
那这样我们就要两次调用才行啦,
首先将要写入的值放在第一次调用,
第二次就可以写到要写到的UserBuffer中的
就是任意位置写任意数据了
我们看看exp,确实调用了两次
但看下面实际上就执行了多次写操作
第一次是将0xc3写到Gdt_Addr
第二次是CallGateData[eax]循环写到Gdt_Addr+0x3e0+eax
其中eax是循环变量,暂时不懂什么意思,慢慢消化
循环4次
任意地址写固定数据内核漏洞
最后一个啦
[2009-07-30][Microsoft][NtUserConsoleControl][win32k.sys][任意地址写固定数据内核漏洞][本地权限提升]
是xp的sp2和sp3中的系统服务函数NtUserConsoleControl,实现是在win32k.sys
首先在ida找到这个函数
通过PsGetCurrentProcess获取进程的PEPROCESS跟csrss进程的相比
不同就将返回值设置为下面的转化为16进制就是0xC0000022u(STATUS_ACCESS_DENIED)
相同就继续调用xxxConsoleControl
跟进xxxConsoleControl
首先对a1进行检查
如果大于9,返回0xC0000003(STATUS_INVALID_INFO_CLASS)
跟着就判断0-9哪种情况
我们看看7时的情况:
将Object[3] = 0; 即将Object第四个句柄置为0
整个过程又没对Object进行检查
那么Ring3传过来的Object,经过这个函数就可以将Object第四个句柄置0,即可以向任意地址写入固定数值(数值0)
我们看看利用代码
不过我感觉这位置有点问题,框住的是我添加的注释
a1为7才对
感觉这样才对
好的就先这样,继续前行