- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
A.NtTerminateProcess
B.涂改内存 //内存清0
C.卸载模块 //free ntdll.dll或主模块
D.窗口攻击 //发close quit 洪水 或 SetParant
这里演示SetParant R3 如果要这么做的话最好在内核中使用更底层的函数
这里提一下枚举窗口 使用EnumWinodws是调用内核中NtUserBuildHwndList 这个函数最后2个参数必须是R3的地址
不然会返回0xC0000008错误,并且如果使用控制台窗口测试,这时ETHREAD下的win32Thread是NULL 也会返回0xC0000008错误
#include <stdio.h>
#include <Windows.h>
HWND g_CurrWdHwnd = 0;
BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam )
{
CHAR str[MAX_PATH] = {0};
DWORD dwPid = 0;
GetWindowTextA( hwnd, str, MAX_PATH-1 );
/*if(*str != '\0')
printf("Hwnd:0x%p----%s\n",hwnd,str);*/
GetWindowThreadProcessId( hwnd, &dwPid );
if( dwPid == *(DWORD*)lParam && *str != ' ')
{
*(HWND*)lParam = hwnd;
printf("Hwnd:0x%p\nPid:%d\n%s\n", hwnd, dwPid, str);
return FALSE;
}
return TRUE;
}
BOOL CALLBACK EnumWindowsProc_Ex( HWND hwnd, LPARAM lParam )
{
CHAR str[MAX_PATH] = {0};
DWORD dwPid = 0;
GetWindowTextA( hwnd, str, MAX_PATH-1 );
GetWindowThreadProcessId( hwnd, &dwPid );
if(*str != '\0')
printf("Hwnd:0x%p--Pid:%d--%s\n", hwnd, dwPid, str);
return TRUE;
}
BOOL CALLBACK EnumWindowsProc_Attack( HWND hwnd, LPARAM lParam )
{
CHAR str[MAX_PATH] = {0};
DWORD dwPid = 0;
GetWindowTextA( hwnd, str, MAX_PATH-1 );
/*if(*str != '\0')
printf("Hwnd:0x%p----%s\n",hwnd,str);*/
GetWindowThreadProcessId( hwnd, &dwPid );
if( dwPid == lParam && *str != '\0')
{
SetParent(hwnd,g_CurrWdHwnd);
printf("Hwnd:0x%p\nPid:%d\n%s\n", hwnd, dwPid, str);
}
return TRUE;
}
HWND GetWindowHwnd(DWORD Pid)
{
DWORD* pOutBuf = 0;
pOutBuf = &id;
if(!EnumWindows( EnumWindowsProc, (LPARAM)pOutBuf) )
{
return *(HWND*)pOutBuf;
}
return NULL;
}
BOOL SetParent_Attack()
{
DWORD tagPid = 0;
//HWND tagHwnd = 0;
printf("input tag pid\n");
scanf_s("%d", &tagPid);
printf("tagPid:%d\n", tagPid);
/*tagHwnd = GetWindowHwnd(tagPid);
if(tagHwnd != NULL)
printf("0x%p\n", tagHwnd);
else
{
printf("getcurrent hwnd faild!\n");
return 0;
}*/
DWORD dwPid = GetCurrentProcessId();
HWND hCurrWnd = GetWindowHwnd(dwPid);
if(hCurrWnd != NULL)
{
printf("0x%p\n", hCurrWnd);
g_CurrWdHwnd = hCurrWnd;
}
else
{
printf("getcurrent hwnd faild!\n");
return 0;
}
//if(SetParent(tagHwnd,hCurrWnd))
//{
// printf("SetParent success ! Now You Can Close Current Window !\n");
// //DestroyWindow(hCurrWnd);
//}
EnumWindows(EnumWindowsProc_Attack,tagPid);
return TRUE;
}
int main(int argc, char* argv[])
{
//EnumWindows(EnumWindowsProc_Ex,NULL);
SetParent_Attack();
getchar();
getchar();
getchar();
return 0;
}[/code]
E. CreateJobObject/AssignProcessToJobObject/TerminateJobObject 或设置关闭时结束(TerminateOnClose 这个没有找到 但文件的有)
文件
CreateFile("要删的文件",FILE_DELETE_ON_CLOSE);
CloseHandle();//删除文件[/code]
参考:http://www.bccn.net/paste/458/
本地备份下:
#include "stdio.h"
#include "windows.h"
#define MEM_LIMIT 4096*1000
int main(int argc, char* argv[])
{
HANDLE hjob;
char *job_name="J1",*pro_name="notepad";
int err;
JOBOBJECT_EXTENDED_LIMIT_INFORMATION joeli;
JOBOBJECT_BASIC_LIMIT_INFORMATION jbii={0};
STARTUPINFOA si ={sizeof(si)};
PROCESS_INFORMATION pi;
if((hjob=CreateJobObjectA(NULL,job_name))==NULL)
{
printf("Cannot create job!\n");
return 1;
}
joeli.BasicLimitInformation.LimitFlags=JOB_OBJECT_LIMIT_PROCESS_MEMORY;
joeli.ProcessMemoryLimit=MEM_LIMIT;
if(SetInformationJobObject(hjob,JobObjectExtendedLimitInformation,&joeli,sizeof(joeli))==0)
{
err=GetLastError();
printf("Fail to set job attributes, Error Code:%d\n",err);
return 1;
}
if(CreateProcessA(NULL,pro_name,/*JOB_OBJECT_ALL_ACCESS*/NULL,/*JOB_OBJECT_ALL_ACCESS*/NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&si,&pi)==0)
{
err=GetLastError();
printf("Cannot create Process %s, Error Code:%d\n",pro_name,err);
return 1;
}
if(!AssignProcessToJobObject(hjob,pi.hProcess))
{
err=GetLastError();
printf("Fail to assign process to job Eror Code:%d\n",err);
}
ResumeThread(pi.hThread);
WaitForSingleObject(pi.hProcess,INFINITE);
return 0;
}[/code]
结束进程测试:
#include "stdio.h"
#include "windows.h"
int main(int argc, char* argv[])
{
HANDLE hjob;
char *job_name="djwow";
int err;
if((hjob=CreateJobObjectA(NULL,job_name))==NULL) //如果创建成功 会返回一个具有JOB_OBJECT_ALL_ACCESS的句柄
{
printf("Cannot create job!\n");
return 1;
}
HANDLE hProcess = OpenProcess(PROCESS_SET_QUOTA | PROCESS_TERMINATE,FALSE,2040);//打开进程需要有这两个权限 见MSDN
if(!AssignProcessToJobObject(hjob,hProcess))
{
err=GetLastError();
printf("Fail to assign process to job Eror Code:%d\n",err);
}
CloseHandle(hProcess);
TerminateJobObject(hjob,0);
return 0;
}
[/code]
F.注入代码,ExitProcess
G. SetThreadContext 改EIP 改到非法地址取
H.调试器附加,退出
I.对每个线程(GetNextProcessThread)PspTerminateThreadByPointer //可以看我的另一篇文章
51055018
J.插APC杀进程
#include <ntddk.h>
#include <windef.h>
#include <stdlib.h>
#include <devioctl.h>
#define DEVICE_NAME L"\\Device\\InsertApcDrv" //Driver Name
#define LINK_NAME L"\\DosDevices\\InsertApcDrv" //Link Name
#define IOCTL_BASE 0x800
#define MY_CTL_CODE(i) CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_PsKillProcess64 MY_CTL_CODE(6)
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString);
NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp);
NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
VOID DriverUnload(PDRIVER_OBJECT pDriverObj);
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(IN HANDLE ProcessId,OUT PEPROCESS *Process);
NTKERNELAPI NTSTATUS PsLookupThreadByThreadId(IN HANDLE ThreadId,OUT PETHREAD *Thread);
NTKERNELAPI NTSTATUS MmUnmapViewOfSection(IN PEPROCESS Process, IN ULONG BaseAddress);
NTKERNELAPI PEPROCESS IoThreadToProcess(IN PETHREAD Thread);
ULONG32 idTarget=0;
PEPROCESS epTarget=NULL;
typedef enum _KAPC_ENVIRONMENT {
OriginalApcEnvironment,
AttachedApcEnvironment,
CurrentApcEnvironment,
InsertApcEnvironment
} KAPC_ENVIRONMENT;
typedef
VOID
(*PKNORMAL_ROUTINE) (
IN PVOID NormalContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
);
typedef
VOID
(*PKKERNEL_ROUTINE) (
IN struct _KAPC *Apc,
IN OUT PKNORMAL_ROUTINE *NormalRoutine,
IN OUT PVOID *NormalContext,
IN OUT PVOID *SystemArgument1,
IN OUT PVOID *SystemArgument2
);
typedef
VOID
(*PKRUNDOWN_ROUTINE) (
IN struct _KAPC *Apc
);
VOID KeInitializeApc (
PKAPC Apc,
PETHREAD Thread,
KAPC_ENVIRONMENT Environment,
PKKERNEL_ROUTINE KernelRoutine,
PKRUNDOWN_ROUTINE RundownRoutine,
PKNORMAL_ROUTINE NormalRoutine,
KPROCESSOR_MODE ProcessorMode,
PVOID NormalContext
);
BOOLEAN KeInsertQueueApc(PKAPC Apc,PVOID SystemArg1,PVOID SystemArg2,KPRIORITY Increment);
typedef NTSTATUS (__fastcall *PSPTERMINATETHREADBYPOINTER)
(
IN PETHREAD Thread,
IN NTSTATUS ExitStatus,
IN BOOLEAN DirectTerminate
);
typedef NTSTATUS (__fastcall *PSPEXITTHREAD)
(
IN NTSTATUS ExitStatus
);
PSPTERMINATETHREADBYPOINTER PspTerminateThreadByPointer=NULL;
PSPEXITTHREAD PspExitThread=NULL;
VOID GetPspTerminateThreadByPointerAddr()
{
ULONG32 callcode=0;
ULONG64 AddressOfPspTTBP=0,AddressOfPsTST=0,i=0; //保存导出PsTerminateSystemThread函数的地址
ULONG64 AddressOfPsTSTHigh32=0;
UNICODE_STRING UniCodeFunctionName;
RtlInitUnicodeString(&UniCodeFunctionName, L"sTerminateSystemThread");
AddressOfPsTST=(ULONG64)MmGetSystemRoutineAddress(&UniCodeFunctionName);
DbgPrint("AddressOfPsTSTAddr:%llx\n",AddressOfPsTST);
if(PspTerminateThreadByPointer==NULL)
{
if(AddressOfPsTST==0)
return;
//根据特征码寻找 特征码 01 e8
for(i=1;i<0xff;i++)
{
if(MmIsAddressValid((PVOID)(AddressOfPsTST+i))!=FALSE)
{
if(*(BYTE *)(AddressOfPsTST+i)==0x01 && *(BYTE *)(AddressOfPsTST+i+1)==0xe8) //目标地址-原始地址-5=机器码 ==> 目标地址=机器码+5+原始地址
{
RtlMoveMemory(&callcode,(PVOID)(AddressOfPsTST+i+2),4);
AddressOfPsTSTHigh32=AddressOfPsTST&0xFFFFFFFF00000000;
AddressOfPspTTBP=(ULONG64)(callcode + 5 + (ULONG32)AddressOfPsTST+i+2)+AddressOfPsTSTHigh32;
}
}
}
PspTerminateThreadByPointer=(PSPTERMINATETHREADBYPOINTER)AddressOfPspTTBP;
DbgPrint("spTerminateThreadByPointerAddr:%llx\n",PspTerminateThreadByPointer);
}
}
VOID GetPspExitThreadAddr()
{
ULONG32 callcode=0;
ULONG64 AddressOfPsTSTHigh32=0;
ULONG64 AddrPspExitThread=0,AddrPspTerminateThreadByPointer=0,i=0;
AddrPspTerminateThreadByPointer = (ULONG64)PspTerminateThreadByPointer; //保存PspTerminateThreadByPointer地址
DbgPrint("spTerminateThreadByPointer:%llx\n",AddrPspTerminateThreadByPointer);
if(PspExitThread==0)
{
if(AddrPspTerminateThreadByPointer == 0)
return;
//根据特征码寻找 特征码 8b cd e8
for(i=1;i<0xff;i++)
{
if(MmIsAddressValid((PVOID)(AddrPspTerminateThreadByPointer+i))!=FALSE)
{
if(*(BYTE *)(AddrPspTerminateThreadByPointer+i)==0x8b && *(BYTE *)(AddrPspTerminateThreadByPointer+i+1)==0xcd && *(BYTE *)(AddrPspTerminateThreadByPointer+i+2)==0xe8) //目标地址-原始地址-5=机器码 ==> 目标地址=机器码+5+原始地址
{
RtlMoveMemory(&callcode,(PVOID)(AddrPspTerminateThreadByPointer+i+3),4);
DbgPrint("callcode:%llx\n",(ULONG64)callcode);
AddressOfPsTSTHigh32=AddrPspTerminateThreadByPointer&0xFFFFFFFF00000000;
AddrPspExitThread=(ULONG64)(callcode + 5 + (ULONG32)AddrPspTerminateThreadByPointer+i+2)+AddressOfPsTSTHigh32;
}
}
}
PspExitThread=(PSPEXITTHREAD)AddrPspExitThread;
DbgPrint("spExitThread:%llx\n",PspExitThread);
}
}
VOID KillThreadRoutine(IN PKAPC Apc,
IN OUT PKNORMAL_ROUTINE *NormalRoutine,
IN OUT PVOID *NormalContext,
IN OUT PVOID *SystemArgument1,
IN OUT PVOID *SystemArgument2)
{
ExFreePool(Apc); //释放APC
PspExitThread(STATUS_SUCCESS);//根据PspTerminateThreadByPointer定位PspExitThread地址
}
VOID KillProcessWithApc(ULONGLONG epro)
{
BOOLEAN status;
PKAPC ExitApc=NULL;
//PEPROCESS eprocess;
PETHREAD ethread;
ULONGLONG i;
ULONG num; //线程数量
ULONGLONG Head; //链表头
ULONGLONG address;//地址
num=(ULONG)*(ULONGLONG *)(epro+0x328); //x64 win7下ActiveThreads偏移是0x328, x86 xp下是 0x1a0
DbgPrint("[RecordThreadAddress] num: 0x%llx\n",num); //打印线程数量
Head=epro+0x308; //x64 win7下List_entry偏移是0x308,x86 xp下是 0x190
for(i=0;i<num;i++)
{
//记录线程地址
Head=(ULONGLONG)((PLIST_ENTRY)Head)->Flink;
address=Head-0x428; //win7 x64下是0x428,x86 xp下是 0x22c
DbgPrint("[ThreadAddress] address: 0x%llx\n",address); //打印线程地址
ethread=(PETHREAD)address; //转换成线程指针
ExitApc=(PKAPC)ExAllocatePoolWithTag(NonPagedPool,sizeof(KAPC),'YM');
if(ExitApc==NULL)
{
DbgPrint("[KillProcessWithApc] malloc memory failed \n");
return;
}
KeInitializeApc(ExitApc,
ethread,
OriginalApcEnvironment,
KillThreadRoutine,
NULL,
NULL,
KernelMode,
NULL);//为线程初始化APC
status=KeInsertQueueApc(ExitApc,ExitApc,NULL,2); //插入Apc到线程队列
}
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING ustrLinkName;
UNICODE_STRING ustrDevName;
PDEVICE_OBJECT pDevObj;
//DbgBreakPoint();
pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
pDriverObj->DriverUnload = DriverUnload;
RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
status = IoCreateDevice(pDriverObj, 0,&ustrDevName, FILE_DEVICE_UNKNOWN,0,FALSE,&pDevObj);
//DbgPrint("[x64Drv] Device Name %S",ustrDevName.Buffer);
if(!NT_SUCCESS(status))
{
DbgPrint("[x64Drv] IoCreateDevice = 0x%llx\n", status);
return status;
}
RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
if(!NT_SUCCESS(status))
{
DbgPrint("[x64Drv] IoCreateSymbolicLink = 0x%llx\n", status);
IoDeleteDevice(pDevObj);
return status;
}
DbgPrint("[x64Drv] SymbolicLink:%S",ustrLinkName.Buffer);
GetPspTerminateThreadByPointerAddr(); //获取 PspTerminateThreadByPointerAddr 地址
GetPspExitThreadAddr(); //获取 PspExitThread 地址
return STATUS_SUCCESS;
}
VOID DriverUnload(PDRIVER_OBJECT pDriverObj)
{
UNICODE_STRING strLink;
RtlInitUnicodeString(&strLink, LINK_NAME);
IoDeleteSymbolicLink(&strLink);
IoDeleteDevice(pDriverObj->DeviceObject);
DbgPrint("[x64Drv] Unloaded\n");
}
NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
DbgPrint("[x64Drv] IRP_MJ_CREATE\n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
DbgPrint("[x64Drv] IRP_MJ_CLOSE\n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
PIO_STACK_LOCATION pIrpStack;
ULONG uIoControlCode;
PVOID pIoBuffer;
ULONG uInSize;
ULONG uOutSize;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
uIoControlCode = pIrpStack->arameters.DeviceIoControl.IoControlCode;
pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
uInSize = pIrpStack->arameters.DeviceIoControl.InputBufferLength;
uOutSize = pIrpStack->arameters.DeviceIoControl.OutputBufferLength;
switch(uIoControlCode)
{
case IOCTL_PsKillProcess64:
{
__try
{
memcpy(&idTarget,pIoBuffer,sizeof(idTarget));
DbgPrint("[x64Drv] PID: %ld",idTarget);
status = PsLookupProcessByProcessId((HANDLE)idTarget, &epTarget);
if(!NT_SUCCESS(status))
{
DbgPrint("[x64Drv] Cannot get target! Status: %llx; EPROCESS: %llx",status,(ULONG64)epTarget);
break;
}
else
{
DbgPrint("[x64Drv] Get target OK! EPROCESS: %llx\n", (ULONG64)epTarget);
KillProcessWithApc((ULONGLONG)epTarget);
//ObDereferenceObject(epTarget);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
;
}
break;
}
}
if(status == STATUS_SUCCESS)
pIrp->IoStatus.Information = uOutSize;
else
pIrp->IoStatus.Information = 0;
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}[/code]
顺便说说线程的结束:
1.NtTerminateThread
2.PspTerminateThreadByPointer
3.Insert APC杀线程 自行百度看雪的帖子 “【原创】一段蛮古老的杀线程代码”
插APC杀线程需要注意 结束的的时候需要设置线程为系统线程
因为PspTerminateSystemThread(STATU_SUCCESS)里面会检验这个
只需要将SystemThread 设为1即可或调用更底层的函数 见上面的APC杀进程
这是设置的地方
CrossThreadFlags::SystemThread win7
KernelStackResident::SystemThread win10
最后说一说TerminateProcess 返回0xC0000022 用户层返回0x5 拒绝访问的事
一般是OpenProcess中没有PROCESS_TERMINTE标志
只需要在ObReferenceObjectByHandle或ObReferenceObjectByHandleWithTag中进程Path即可
HANDLE hProcess = OpenProcess(PROCESS_VM_WRITE,FALSE,5876);[/code]if(!TerminateProcess(hProcess,0))//NT5 在ObReferenceObjectByHandle中判断 NT6在ObReferenceObjectByHandleWithTag中判断
{
err=GetLastError();
printf("Fail to Terminate process to job Eror Code:%d\n",err);
}[/code]
结果是 只要有句柄 结束这个进程不需要有PROCESS_TERMINTE标志 |
|