- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
实验环境 xp sp3
此实验将一个不常用的内核函数置0,然后R3申请了0地址的指针,将shellcode拷到此内存,内核并没有做ProbeForRead /Write检查
直接对传入的数据进行了修改,造成了任意地址写任意数据漏洞 ,提权了R3程序为system权限
R3代码
主要获得一个函数的地址,将函数地址传入R0
R0将此函数地址置0,然后R3申请了一个0地址,将shellcode拷到了申请的内存中,然后调用被置0的函数,触发了shellcode
- /********************************************************************
- 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->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;//本地提权 //任意地址写任意数据
- //少调用的
- //*(ULONG*)(Type3InputBuffer) = 0; //任意地址写固定数据
- //*(ULONG/)(UserBuffer) = 0;
- 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[i] = DrvDispatch;
- }
- //返回成功结果
- return STATUS_SUCCESS;
- }
复制代码
修复也很简单,使用异常处理块 +robeForRead/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->arameters.DeviceIoControl.Type3InputBuffer;
UserBuffer = pIrp->UserBuffer;
inputBufferLength = pIrpStack->arameters.DeviceIoControl.InputBufferLength;
outputBufferLength = pIrpStack->arameters.DeviceIoControl.OutputBufferLength;
ioControlCode = pIrpStack->arameters.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] |
|