首页
社区
课程
招聘
[旧帖] RPC DNS劫持 0.00雪花
发表于: 2014-5-31 03:24 10058

[旧帖] RPC DNS劫持 0.00雪花

2014-5-31 03:24
10058
访问http://www.duba.com/ 会出现乱码或者访问WAP的http://www.duba.com/去了
附件: conig.rar
求大神分析详细过程与原理
小弟不才 只知道一点点

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

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 44
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
求完整源码,求原理
2014-5-31 21:38
0
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
只有样本没有源码,应该是挂接\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);
		}
2014-6-1 15:17
0
雪    币: 135
活跃值: (106)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
4
样本是驱动原理吗?
2014-10-4 17:37
0
雪    币: 65
活跃值: (112)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
你是认为attach了就把句柄表也都attach过去了么
2014-10-4 18:28
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
6
经过测试发现确实关闭了~你如何解释这个事儿呢?
2014-10-4 20:01
0
雪    币: 65
活跃值: (112)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7
你试试这东西能否一直稳定运行就知道了……最简单的,你遍历下系统范围内所有句柄,再对某类或者某几类做类似操作,你看是什么效果。
再者,操作句柄表可以不用lock的么?直接attach一下,然后create handle就会自动lock目标进程的句柄表?
2014-10-5 14:48
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
8
ZwClose貌似很特例~其他操作是不行的。我估计跟Close的过程的实现方式有关~

关闭捣蛋的句柄貌似效果不错。
2014-10-5 21:57
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
有完整的代码吗 我想学习
2014-12-1 21:20
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
给位大神你们qq多少  能就解决的
2014-12-1 21:27
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
00406230  RpcServerUnregisterIf RPCRT4
0040622C  RpcMgmtStopServerListening RPCRT4
00406224  RpcServerRegisterIfEx RPCRT4
我破解的程序 看到代码
2014-12-3 16:20
0
游客
登录 | 注册 方可回帖
返回
//