看流星社区

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

ARK之杀进程这点小事-有线程补充

[复制链接]

该用户从未签到

发表于 2017-6-1 12:52:00 | 显示全部楼层 |阅读模式
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 = &ampid;
        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&quotsTerminateSystemThread");
        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(&quotspTerminateThreadByPointerAddr:%llx\n",PspTerminateThreadByPointer);
       
        }


}


VOID GetPspExitThreadAddr()
{
        ULONG32 callcode=0;
        ULONG64 AddressOfPsTSTHigh32=0;        
        ULONG64 AddrPspExitThread=0,AddrPspTerminateThreadByPointer=0,i=0;
       
        AddrPspTerminateThreadByPointer = (ULONG64)PspTerminateThreadByPointer; //保存PspTerminateThreadByPointer地址
        DbgPrint(&quotspTerminateThreadByPointer:%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(&quotspExitThread:%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-&gtarameters.DeviceIoControl.IoControlCode;
        pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
        uInSize = pIrpStack-&gtarameters.DeviceIoControl.InputBufferLength;
        uOutSize = pIrpStack-&gtarameters.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标志
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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

GMT+8, 2024-3-19 17:19

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

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