吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 11588|回复: 35
收起左侧

[其他原创] 钉钉网页版自动登录、捕获消息、发送消息

  [复制链接]
麦田孤望者 发表于 2020-8-10 10:35
本帖最后由 麦田孤望者 于 2020-8-17 11:38 编辑

起因:由于某些奇妙的原因,我需要捕获钉钉聊天内容,但是钉钉官方提供的机器人不包含收消息功能,于是就产生了写这个程序的想法

(本帖不打算帖完整代码,因为我代码写得跟shi一样。。。。。)

还有帖子里插得代码是在class里的有的处理了缩进有的没处理

所以也不能拿来直接用 抱歉啦

演示视频:https://www.bilibili.com/video/BV1zC4y1t7T4/

目录

  1. 登录
  2. 获取是否扫码
  3. 获取消息
  4. 发送消息


一、登录

首先打开钉钉网页版https://im.dingtalk.com/
F12,刷新,寻找登录二维码的链接
0.png
发现url是base64格式的二维码,于是就打算使用草料看看这个二维码包含的内容
保存——上传草料
1.png
可以看到,二维码的链接是由http://qr.dingtalk.com/action/login?code=与code拼成
于是搜索这个code看看能不能找到
2.png
可以看到,这个code是GET https://login.dingtalk.com/user/qrcode/generate.jsonp?callback=angular.callbacks._0得到的,验证发现不用带headers

代码实现:
def getCode():
    r = self.res.get('https://login.dingtalk.com/user/qrcode/generate.jsonp?callback=angular.callbacks._0')
    html = re.findall('\((.*?)\)', r.text, re.S)[0]
    callback = json.loads(html)
    if callback['success'] == True:
        self.Code = callback['result']
        self.QRurl = 'http://qr.dingtalk.com/action/login?code='+self.Code
        return callback['result']
    else:
        print('Error01:返回值为否')


获取到了code,就可以构建二维码了
我用的是qrcode
显示图片用的是PIL
代码实现:
[Python] 纯文本查看 复制代码
import qrcode
from PIL import Image
def makeQRcode():
    img = qrcode.make(self.QRurl)
    with open('test.png', 'wb') as f:
        img.save(f)
    im = Image.open('test.png')
    im.show()


二、获取是否扫码

其实吧,这个借口很容易找到的,毕竟......
3.png
就看这个就知道验证接口是它了
接下来分析

headers没什么好分析的
但是带的参数就得好好看一下了
appKey: 85A09F60A599F5E1867EAB915A8BB07F
callback: angular.callbacks._1
pdmModel: Windows Unknown
pdmTitle: Windows Unknown Web
pdmToken: T2gAC1QTLzX2NkrEj6uqt4pP9l_JG61b1WbiRf8_4zBQ0Tsvn922akdPrMjhhuFKaA5bjcPYLgmluUDpj-f2zlgI
qrcode: B5EEC884-3E1B-4B90-8B9B-119062EF68A5

前四个不用管的,都是字面意思
qrcode就是刚才获得到的code
接下来是pdmToken
搜索它生成的位置(我一般先搜值再搜变量名)
在一堆islogged中,我看到了它:um.json
4.png
返回的值:

{id: "G28828312008958197E5967600805DC78A7409B"
tn: "T2gAC1QTLzX2NkrEj6uqt4pP9l_JG61b1WbiRf8_4zBQ0Tsvn922akdPrMjhhuFKaA5bjcPYLgmluUDpj-f2zlgI"}
我们要的是返回的tn
于是观察这个请求的参数
data: 106!ECMmc0clJFmH/brVHmjz5Frca5nTQmsm5UamzLHtKj7U5xjMYyoj7K1czEH0n+0MwbLJ3inX9RJvfMbxrO9QayhHTWnC422L3+pmZkGzcPQ6Nw11tV+1mw8Z07GJJ1XX3ycRlqLQH56L5FYhELJY4C1mQpegQ0WRcuE1O4rkysaJPfogzBgMs7DUDWLmrY9BSlngjWCryLAZnCM1U0K5S7kUOHELlT/Q4uDj67/Tr8tvyM2XsQt9gpSUxvXs/ysK42Ujx7/QC0I5YR7XxXcLA8sf82q8VGxIpAKa1R3n8aK08vo0VscQie9YR3gu5M3n069EzUwyOLzrx0N8kQcqZyZ8jytWSDVzna1dMmN4p/eQ5RQ99lMKPHRAWJsKBt6+gQ2imXI8NBnY0pM2fWphO1QppIKk17b+ZaqFIf3gdoJAlRxn6SncJkqUgMagYP8CZAbPhK12Ycu9O7PvX3iRlutz7xcO8RIgzp5B99CVCs7RdPaiNetHNnbxarEj7WmDIhJO1Jvheb10tuR/88pAxLXVboka4OH3mKYSMJLIrYJoKP4EbRFHaxP8S6EyqNHyLrNNxpp+41ilrqpmSkIGaUz2LT52cFlmlSrecfsmcN0FOikY98sEscvfs+yn6faNoIuAEY85NqXuGE/H5dK6qpyVK0lQV6tAv6aUcugh+W+1qJ/J9meqDtLnvGmD4nRLQ+LtExRhOa2NxM52kfwR77Ok2swlgSiHVI52sPsREWCvJnKlYJQe9liFVywMUMyLcubG/aLgUG8U6xx1obuQkgKN
xa: dingding
xt:

data很长 但是经过我大量验证,发现106!是固定的,剩下的一直在变
搜索未果,于是我想知道这个data是不是定值
python重发请求,成功返回数据
于是尝试改变106!后数据,发现只要有106!都可以返回数据
那么就好办了
构造请求um.json
     def makedata(self):
        data = {
            'data':'106!woxiangqiaoni',
            'xa':'dingding',
            'xt':''
        }
        r = self.res.post('https://ynuf.aliapp.org/service/um.json',data=data)
        _ = r.json()

获得tn
再循环请求https://login.dingtalk.com/user/qrcode/is_logged.jsonp
    def checkIfLogined(self):
        url = 'https://login.dingtalk.com/user/qrcode/is_logged.jsonp'
        params = {
            'appKey': '85A09F60A599F5E1867EAB915A8BB07F',
            'callback': None,
            'pdmModel': 'Windows Unknown',
            'pdmTitle': 'Windows Unknown Web',
            'pdmToken': self.tn,
            'qrcode': self.Code
        }
        headers = {
            'accept': '*/*',
            'accept-encoding': 'gzip, deflate, br',
            'accept-language': 'zh-CN,zh;q=0.9',
            'referer': 'https://im.dingtalk.com/',
            'sec-fetch-dest': 'script',
            'sec-fetch-mode': 'no-cors',
            'sec-fetch-site': 'same-site',
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36'
        }
        while True:
            r = self.res.get(url,params = params,headers=headers)

            _ = json.loads(re.findall('\((.*?)\)',r.text,re.S)[0])

            if _['success'] == True:
                break
            time.sleep(2)

        os.remove('test.png')


扫码后获取到了一个json,包含了大量的数据
5.png
记住这个json,里面的许多数据后续都很重要


三、获取信息


既然收到消息network页面没有变化,那么应该就是一个websocket连接
连接在long里
前两个请求卡了我一天半
就在求助讨论区发了个贴https://www.52pojie.cn/thread-1240673-1-1.html
(摘要:第一个请求复制message发一遍就行了第二个请求复制下来的message需要手动在headers里补上ua,did,sid,appjey)
did是在long之前的那个请求
6.png
那么再看这个请求,带的参数:
code: 127103489********(码一下不确定是不是隐私)********58DE2658appkey: 85A09F60A599F5E1867EAB915A8BB07F
isSession: true
callback: __jp0
搜索code值
7.png
那么就在这个json里搜索值
8.png
是tmpcode的值

那么至此,did的值就很容易得到了

接下来是sid,sid其实在第一次send信息的时候就返回了,那个在同一个websocket里应该是定值
然后appkey不用讲了吧,定值
搜索token的值,是之前json里的accessToken
ua我复制到的是
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 OS(windows/10.0) Browser(chrome/84.0.4147.89) DingWeb/3.8.10 LANG/zh_CN

放到headers里就可以了

接下来的内容应该可以更加简单但是我不知道那些是必要的哪些是不必要的
于是我就全部发了一遍.....就这样咯(摊手.jpg)
9.png

然后就可以获取信息了
(之前的方法放弃了 我用了一个更简单的方法)接着点开一个群聊,观察数据情况
13.png
这个红框部分可以说是相当显眼啊
14.png
可以确定,它返回的就是最近的14条消息,0为最新,13为最旧
15.png
通过openid可以反推出发送者的信息
过程就不放了 有兴趣的自己尝试(提示:你本人要获取一个人的信息你会怎么操作?)能获取的个人信息很多

{"lwp":"/r/Adaptor/UserMixI/getUserProfileExtensionByUid","headers":{"mid":Mid},"body":[待查openid,null]}

如何识别是否被@
16.png
如果被@,则返回数据里会多一个atOpenIds,是个字典,keys就是openid,获取到所有openid后逐个与自己的openid比较即可

再没什么了吧......有的话再问就行

(小声逼逼:不给个币或者给个热心吗,好狠心啊嘤嘤嘤)
写成模块了  见https://github.com/gongxi-cn-ln-dl/DingTalk(留个star再走吧......)
10.png

免费评分

参与人数 5吾爱币 +7 热心值 +5 收起 理由
寒墨轩 + 3 + 1 用心讨论,共获提升!
喜子12131 + 2 + 1 鼓励转贴优秀软件安全工具和文档!
hqwl1985 + 1 + 1 谢谢@Thanks!
Menguy + 1 + 1 谢谢@Thanks!
涛行 + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

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

 楼主| 麦田孤望者 发表于 2020-8-10 12:11
辉夜年华 发表于 2020-8-10 11:51
https://www.cnblogs.com/shaocf/p/10898790.html   看看这个

看了一眼,它使用的是dingtalkchatbot 我翻github了它用的还是钉钉群机器人不支持获取消息
 楼主| 麦田孤望者 发表于 2020-8-10 11:38
辉夜年华 发表于 2020-8-10 11:29
感觉可以借鉴一下wechat  看看python的那个是怎么实现的,应该两个大差不差

我网页微信被限制登录了......不然我也不会来搞钉钉
毕竟需要一边读代码一边复现分析过程啊
额微粒波地 发表于 2020-8-10 10:37
lsy_loren 发表于 2020-8-10 10:51
膜拜大神
sensMe 发表于 2020-8-10 10:54
前排支持,感谢分享。。
winkle 发表于 2020-8-10 10:59
感谢分享
李辉! 发表于 2020-8-10 11:00
感谢分享
黄色土豆 发表于 2020-8-10 11:01
感谢分享
QingYi. 发表于 2020-8-10 11:02
学习一下
者零 发表于 2020-8-10 11:06
好东西,厉害了
gcj8 发表于 2020-8-10 11:09
厉害
拜膜大佬
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2025-1-13 13:50

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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