A-A+

TX IOA 系统登录加密分析 Python3 RSA PKCS1_OAEP

2022年04月02日 16:24 学习笔记 暂无评论 共2543字 (阅读98 views次)

【注意:此文章为博主原创文章!转载需注意,请带原文链接,至少也要是txt格式!】

images

某天因为需要调用腾讯某产品内部的一些数据,但是无奈没有API接口,那么只有通过类似爬虫的方式进行登录,然后调用相关功能点。

如上图所示,首先就需要登录,然后获取登录态,这里通过抓包发现,密码是被加密然后进行base64编码之后传递到服务端的。那么首先就应该找出密码加密的方式,如下图:

images

登录之前首先获取公钥KEY,通过访问 https://xxxx.xxxx.com/api/global/GetEncryptKey  那么后续应该会用这个KEY来进行加密操作。

这里搜索一下密码关键词,看看在哪里进行加密。其实这里我走了一个弯路,因为登录密码字段是password,所以我搜索的这个关键词,但是就因为搜索的这个关键词,结果导致浪费了很久的时间。可以看到我之前的断点分析,都是浪费时间的结果,如下图:

images

就因为这个关键词太广了,结果导致分析的时间都用在了错误的地方。没有直戳要害!

好,下面开始正式分析。

根据密钥KEY接口返回的信息得到关键‘publicKey’字段:

images

这里直接搜索“publicKey”然后定位到代码如下图:

images

这里关键代码展示出来,如下:

 

t.generateKeys = function() {
                var e = p.generateKeyPairSync("rsa", {
                    modulusLength: 4096,
                    publicKeyEncoding: {
                        type: "pkcs1",
                        format: "pem"
                    },
                    privateKeyEncoding: {
                        type: "pkcs1",
                        format: "pem",
                        cipher: "aes-256-cbc",
                        passphrase: ""
                    }
                })
                  , t = e.publicKey
                  , n = e.privateKey;
                return {
                    publicKey: t,
                    privateKey: n
                }
            }
            ,
            t.encrypt = function(t, n) {
                try {
                    var r = e.from(t, "utf8")
                      , o = p.publicEncrypt(n, r).toString("base64");
                    return o
                } catch (e) {
                    return ""
                }
            }
            ,
            t.decrypt = function(t, n) {
                var r = e.from(t, "base64");
                return p.privateDecrypt({
                    key: n.toString(),
                    passphrase: ""
                }, r).toString("utf8")
            }
            ,
            t.getEncryptKey = function() {
                return b.apply(this, arguments)
            }

从代码中不难发现,它的代码加密类型是pkcs1,用的是rsa加密方式。

images

从图中就已经看的很明确了。var r = e.from(t, "utf8")
, o = p.publicEncrypt(n, r).toString("base64");
对重点代码进行了详细说明。
这里我们跟进publicEncrypt这个函数。

images

跟随是n的值为空,h = e.padding ? e.padding : n ? 1 : 4; 所以这里结果h就是4

也就是说,函数走入了红色圈内。红色圈内说明用的是sha1的方式。

到这里基本也就分析透了,程序使用的是Node.js crypto.publicEncrypt()默认的方式进行的密码加密,通过朋友提示,可以先使用 RSA加密工具 测试一下。这里把KEY还有密码输入后,得出密钥,经过测试没有问题,可以登录系统,如下图:

images

最后一步就是写出Python脚本代码,实现自动登录,这里参考了官方的示例 https://pycryptodome.readthedocs.io/en/latest/src/cipher/oaep.html 最终python代码如下:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def encrypt_password():
    from Crypto.Cipher import PKCS1_OAEP
    from Crypto.PublicKey import RSA
 
    rsa_key = b"""-----BEGIN PUBLIC KEY-----
MIICCgKCAgEAvrOaIR+zQSkEDi4Ac5wrEvYxM68LhHtGTy8pHceyPLKtK0c7PnS1
3VT7oafyXLVpNWR/R+bvFwGrA0URMqRzMQxYtr7T0sgiaZbgXZO+OyQh26005OKj
ydA1oCCb06+v6/qp1d+FXVg847tUK0TqkGOCNXPaCDElNoH/A4B4sikWCVtY87V1
42wBpI4mdPDw33w4+5/uHBuhltOpQRPSTuQlCNP5SaotAIcZNfzw0a0VJ5illxnZ
oGAAjh1Di7xU+TH3PiwyP8pG2jYg4qT9YLbhdMuuCerBnKw6F3cD/qEUsChFQ2d3
14KzCV6/QDLuYadSMdX+cj/k40dCqbyvCfQA8fZAhUXWnBRPqyXQs8PQQSow2Lse
aNiKyTAUW06d93H3DzoPE2NsLQMHTr72b+Hb7eAeXBrrp8o0j/3sNKDspVNtvzdm
nUF4nYmG0u4XsspbXwHpCa6mCTV7hm5F7MffE+RdDOukvNwPdBYRh+T5nunxXZwi
X0mf5eR/9+w3+vJ48liRQ6ToQ0C+jVRnJzXK5ceyNk0Jb+U80v7zHxEugqbfQppW
MvWTiYKadcsFuwsdEDe98x3t2Ml09A8suid5I/Bhk176WUmHOk0+fxJ2ZGNhcwYm
qW+37k5AYOTtVWRnGeC573i9mj6jlDg5T8RGD+htzUSXDLNIGatZA7MCAwEAAQ==
-----END PUBLIC KEY-----
"""
    message = "12345678"  ##登录系统的密码
 
    key = RSA.importKey(rsa_key)
    cipher = PKCS1_OAEP.new(key)
    ciphertext = cipher.encrypt(message.encode('utf-8'))
    return base64.b64encode(ciphertext).decode()

以上就是完整的分析过程。

布施恩德可便相知重

微信扫一扫打赏

支付宝扫一扫打赏

×

给我留言