看流星社区

 找回密码
 注册账号
查看: 1804|回复: 0

内核提权,任意地址写任意数据/固定数据模型

[复制链接]

该用户从未签到

发表于 2017-6-1 12:56:30 | 显示全部楼层 |阅读模式
实验环境 xp sp3
此实验将一个不常用的内核函数置0,然后R3申请了0地址的指针,将shellcode拷到此内存,内核并没有做ProbeForRead /Write检查
直接对传入的数据进行了修改,造成了任意地址写任意数据漏洞 ,提权了R3程序为system权限


R3代码
主要获得一个函数的地址,将函数地址传入R0
R0将此函数地址置0,然后R3申请了一个0地址,将shellcode拷到了申请的内存中,然后调用被置0的函数,触发了shellcode
  1. /********************************************************************
  2.         created:        2010/12/06
  3.         filename:         D:\0day\ExploitMe\exploitme.c
  4.         author:                shineast
  5.         purpose:        Exploit me driver demo
  6. *********************************************************************/
  7. #include <ntddk.h>
  8. #define DEVICE_NAME L"\\Device\\ExploitMe"
  9. #define DEVICE_LINK L"\\DosDevices\\DRIECTX1"
  10. #define FILE_DEVICE_EXPLOIT_ME 0x00008888
  11. #define IOCTL_EXPLOIT_ME (ULONG)CTL_CODE(FILE_DEVICE_EXPLOIT_ME,0x800,METHOD_NEITHER,FILE_WRITE_ACCESS)
  12. //创建的设备对象指针
  13. PDEVICE_OBJECT g_DeviceObject;
  14. /**********************************************************************
  15. 驱动派遣例程函数
  16.         输入:驱动对象的指针,Irp指针
  17.         输出:NTSTATUS类型的结果
  18. **********************************************************************/
  19. NTSTATUS DrvDispatch(IN PDEVICE_OBJECT driverObject,IN PIRP pIrp)
  20. {
  21.         PIO_STACK_LOCATION pIrpStack;//当前的pIrp栈
  22.         PVOID Type3InputBuffer;//用户态输入地址
  23.         PVOID UserBuffer;//用户态输出地址
  24.         ULONG inputBufferLength;//输入缓冲区的大小
  25.         ULONG outputBufferLength;//输出缓冲区的大小
  26.         ULONG ioControlCode;//DeviceIoControl的控制号
  27.         PIO_STATUS_BLOCK IoStatus;//pIrp的IO状态指针
  28.         NTSTATUS ntStatus=STATUS_SUCCESS;//函数返回值
  29.         //获取数据
  30.         pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  31.         Type3InputBuffer = pIrpStack->Parameters.DeviceIoControl.Type3InputBuffer;
  32.         UserBuffer = pIrp->UserBuffer;
  33.         inputBufferLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
  34.         outputBufferLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
  35.         ioControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
  36.         IoStatus=&pIrp->IoStatus;
  37.         IoStatus->Status = STATUS_SUCCESS;// Assume success
  38.         IoStatus->Information = 0;// Assume nothing returned
  39.         //根据 ioControlCode 完成对应的任务
  40.         switch(ioControlCode)
  41.         {
  42.         case IOCTL_EXPLOIT_ME:
  43.                 if ( inputBufferLength >= 4 && outputBufferLength >= 4 )
  44.                 {
  45.                         *(ULONG *)UserBuffer = *(ULONG *)Type3InputBuffer;//本地提权 //任意地址写任意数据
  46.                         //少调用的
  47.                         //*(ULONG*)(Type3InputBuffer) = 0; //任意地址写固定数据
  48.                         //*(ULONG/)(UserBuffer) = 0;
  49.                         IoStatus->Information = sizeof(ULONG);
  50.                 }
  51.                 break;
  52.         }  
  53.         //返回
  54.         IoStatus->Status = ntStatus;
  55.         IoCompleteRequest(pIrp,IO_NO_INCREMENT);
  56.         return ntStatus;
  57. }
  58. /**********************************************************************
  59. 驱动卸载函数
  60.         输入:驱动对象的指针
  61.         输出:无
  62. **********************************************************************/
  63. VOID DriverUnload( IN PDRIVER_OBJECT  driverObject )
  64. {
  65.         UNICODE_STRING symLinkName;
  66.         KdPrint(("DriverUnload: 88!\n"));
  67.         RtlInitUnicodeString(&symLinkName,DEVICE_LINK);
  68.         IoDeleteSymbolicLink(&symLinkName);
  69.         IoDeleteDevice( g_DeviceObject );
  70. }
  71. /*********************************************************************
  72. 驱动入口函数(相当于main函数)
  73.         输入:驱动对象的指针,服务程序对应的注册表路径
  74.         输出:NTSTATUS类型的结果
  75. **********************************************************************/
  76. NTSTATUS DriverEntry( IN PDRIVER_OBJECT  driverObject, IN PUNICODE_STRING  registryPath )
  77. {
  78.         NTSTATUS       ntStatus;
  79.         UNICODE_STRING devName;
  80.         UNICODE_STRING symLinkName;
  81.         int i=0;
  82.         //打印一句调试信息
  83.         KdPrint(("DriverEntry: Exploit me driver demo!\n"));
  84.         //创建设备
  85.         RtlInitUnicodeString(&devName,DEVICE_NAME);
  86.         ntStatus = IoCreateDevice( driverObject,
  87.                 0,
  88.                 &devName,
  89.                 FILE_DEVICE_UNKNOWN,
  90.                 0, TRUE,
  91.                 &g_DeviceObject );
  92.         if (!NT_SUCCESS(ntStatus))
  93.         {
  94.                 return ntStatus;  
  95.         }
  96.         //创建符号链接  
  97.         RtlInitUnicodeString(&symLinkName,DEVICE_LINK);
  98.         ntStatus = IoCreateSymbolicLink( &symLinkName,&devName );
  99.         if (!NT_SUCCESS(ntStatus))
  100.         {
  101.                 IoDeleteDevice( g_DeviceObject );
  102.                 return ntStatus;
  103.         }
  104.         //设置该驱动对象的卸载函数
  105.         driverObject->DriverUnload = DriverUnload;
  106.         //设置该驱动对象的派遣例程函数
  107.         for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
  108.         {
  109.                 driverObject->MajorFunction[i] = DrvDispatch;
  110.         }
  111.         //返回成功结果
  112.         return STATUS_SUCCESS;
  113. }
复制代码





修复也很简单,使用异常处理块 &#43robeForRead/Write检测传入的userbuff

/********************************************************************
        created:        2010/12/06
        filename:         D:\0day\ExploitMe\exploitme.c
        author:                shineast
        purpose:        Exploit me driver demo
*********************************************************************/
#include <ntddk.h>

#define DEVICE_NAME L"\\Device\\ExploitMe"
#define DEVICE_LINK L"\\DosDevices\\DRIECTX1"
#define FILE_DEVICE_EXPLOIT_ME 0x00008888
#define IOCTL_EXPLOIT_ME (ULONG)CTL_CODE(FILE_DEVICE_EXPLOIT_ME,0x800,METHOD_NEITHER,FILE_WRITE_ACCESS)

//创建的设备对象指针
PDEVICE_OBJECT g_DeviceObject;

/**********************************************************************
驱动派遣例程函数
        输入:驱动对象的指针,Irp指针
        输出:NTSTATUS类型的结果
**********************************************************************/
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;//pIrp的IO状态指针
        NTSTATUS ntStatus=STATUS_SUCCESS;//函数返回值

        //获取数据
        pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
        Type3InputBuffer = pIrpStack-&gtarameters.DeviceIoControl.Type3InputBuffer;
        UserBuffer = pIrp->UserBuffer;
        inputBufferLength = pIrpStack-&gtarameters.DeviceIoControl.InputBufferLength;
        outputBufferLength = pIrpStack-&gtarameters.DeviceIoControl.OutputBufferLength;
        ioControlCode = pIrpStack-&gtarameters.DeviceIoControl.IoControlCode;
        IoStatus=&pIrp->IoStatus;
        IoStatus->Status = STATUS_SUCCESS;// Assume success
        IoStatus->Information = 0;// Assume nothing returned

        //根据 ioControlCode 完成对应的任务
        switch(ioControlCode)
        {
        case IOCTL_EXPLOIT_ME:
                __try
                {

                        if ( inputBufferLength >= 4 && outputBufferLength >= 4 )
                        {
                                //Type3InputBuffer 任意数据
                                //UserBuffer 任意地址
                                //当UserBuffer不是用户态地址 ProbeForRead/Write抛出STATUS_ACCESS_VIOLATION异常
                                ProbeForRead(UserBuffer,sizeof(ULONG),sizeof(ULONG));
                                ProbeForWrite(UserBuffer,sizeof(ULONG),sizeof(ULONG));
                                *(ULONG *)UserBuffer = *(ULONG *)Type3InputBuffer;
                                IoStatus->Information = sizeof(ULONG);
                        }
                }
                __except(EXCEPTION_EXECUTE_HANDLER)
                {
                        ntStatus = GetExceptionCode();  
                        IoStatus->Information = sizeof(ULONG);
                }
               
                break;
        }  

        //返回
        IoStatus->Status = ntStatus;
        IoCompleteRequest(pIrp,IO_NO_INCREMENT);
        return ntStatus;
}
/**********************************************************************
驱动卸载函数
        输入:驱动对象的指针
        输出:无
**********************************************************************/
VOID DriverUnload( IN PDRIVER_OBJECT  driverObject )
{
        UNICODE_STRING symLinkName;
        KdPrint(("DriverUnload: 88!\n"));
        RtlInitUnicodeString(&symLinkName,DEVICE_LINK);
        IoDeleteSymbolicLink(&symLinkName);
        IoDeleteDevice( g_DeviceObject );
}
/*********************************************************************
驱动入口函数(相当于main函数)
        输入:驱动对象的指针,服务程序对应的注册表路径
        输出:NTSTATUS类型的结果
**********************************************************************/
NTSTATUS DriverEntry( IN PDRIVER_OBJECT  driverObject, IN PUNICODE_STRING  registryPath )
{
        NTSTATUS       ntStatus;
        UNICODE_STRING devName;
        UNICODE_STRING symLinkName;
        int i=0;
        //打印一句调试信息
        KdPrint(("DriverEntry: Exploit me driver demo!\n"));
        //创建设备
        RtlInitUnicodeString(&devName,DEVICE_NAME);
        ntStatus = IoCreateDevice( driverObject,
                0,
                &devName,
                FILE_DEVICE_UNKNOWN,
                0, TRUE,
                &g_DeviceObject );
        if (!NT_SUCCESS(ntStatus))
        {
                return ntStatus;  
        }
        //创建符号链接  
        RtlInitUnicodeString(&symLinkName,DEVICE_LINK);
        ntStatus = IoCreateSymbolicLink( &symLinkName,&devName );
        if (!NT_SUCCESS(ntStatus))
        {
                IoDeleteDevice( g_DeviceObject );
                return ntStatus;
        }
        //设置该驱动对象的卸载函数
        driverObject->DriverUnload = DriverUnload;
        //设置该驱动对象的派遣例程函数
        for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
        {
                driverObject->MajorFunction = DrvDispatch;
        }
        //返回成功结果
        return STATUS_SUCCESS;
}





[/code]
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-29 15:17

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表