在线咨询
有事点这里
有事点这里
看不懂这篇文章?联系我们
("麦洛克菲"长期致力于内核安全的推广与普及,我们更专业!)
求职QQ群:223902435。讨论各种求职笔试面试问题
作者:admin 时间:2015-10-31
标题:任意地址写入任意数据(固定数据)

当R3与R0在进行通信的时候,采用了第三种通信方式(METHOD_NEITHER)直接将R3地址下传到内核,并在内核中,将一个R3地址中的任意数据(固定数据),赋值给R3的任意一个地址,那么就会造成严重的内核任意地址写入任意数据(固定数据)。因为攻击者完全可以在R3地址里构造一个任意的数据和设置一个任意的地址。

 

比如下面的内核代码,在该派遣分发函数中,使用了第三种通信方式(METHOD_NEITHER),直接将R3的内存地址传递到内核中,并在内核中通过:

 

*(ULONG *)UserBuffer = *(ULONG *)Type3InputBuffer;


上面这句代码,将R3任意数据赋值给R3任意地址。因此,造成了任意地址写入任意数据漏洞。

 

NTSTATUS DrvDispatch(IN PDEVICE_OBJECT driverObject,IN PIRP pIrp)

{

       PIO_STACK_LOCATION pIrpStack;//当前的pIrp

       PVOID Type3InputBuffer;//用户态输入地址

       PVOID UserBuffer;//用户态输出地址

       ULONG inputBufferLength;//输入缓冲区的大小

       ULONG outputBufferLength;//输出缓冲区的大小

       ULONG ioControlCode;//DeviceIoControl的控制号

       PIO_STATUS_BLOCK IoStatus;//pIrpIO状态指针

       NTSTATUS ntStatus=STATUS_SUCCESS;//函数返回值

 

       //获取数据

       pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

       Type3InputBuffer = pIrpStack->Parameters.DeviceIoControl.Type3InputBuffer;

       UserBuffer = pIrp->UserBuffer;

       inputBufferLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;

       outputBufferLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;

       ioControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;

       IoStatus=&pIrp->IoStatus;

       IoStatus->Status = STATUS_SUCCESS;// Assume success

       IoStatus->Information = 0;// Assume nothing returned

 

       //根据 ioControlCode 完成对应的任务

       switch(ioControlCode)

       {

       case IOCTL_EXPLOIT_ME:

              if ( inputBufferLength >= 4 && outputBufferLength >= 4 )

              {

                     *(ULONG *)UserBuffer = *(ULONG *)Type3InputBuffer;

                     IoStatus->Information = sizeof(ULONG);

              }

              break;

       } 

 

       //返回

       IoStatus->Status = ntStatus;

       IoCompleteRequest(pIrp,IO_NO_INCREMENT);

       return ntStatus;

}

 

任意地址:R3传入一个内核地址(比如某个表中的函数地址,一般要很少被调用的函数)

任意数据:想办法将该内核地址的值设置为0

R3里分配一个0地址空间(调用ZwAllocateVirtualMemory),并将R0 shellcode拷贝到此内存空间

然后,利用上面代码的漏洞,在R0里完成把这个R0地址(任意地址)设置为0(任意或固定数据),完成设置之后,然后通过调用函数,促发内核执行该内核地址代码,但该地址已经指向了0地址的shell code,因此,造成了恶意代码的执行。

 

shellcode代码可以用来:

1,提升进程的权限到system进程

2,恢复内核hookinlinehook

3,添加调用门,中断门等