...
 
Commits (3)
    https://gitcode.net/qq_36759224/Python3-Spider-Practice/-/commit/550cad603f9e1cfccee1c96ffbb8d3cae2ce8089 ❌ 应版权方要求删除中烟新商盟【2022.07.22】 2022-07-22T11:00:43+08:00 TRHX admin@itrhx.com https://gitcode.net/qq_36759224/Python3-Spider-Practice/-/commit/32c3c90af830faf96bd085f70f8105e859c141cd ❌ 应版权方要求删除中烟新商盟【2022.07.22】 2022-07-22T11:01:27+08:00 TRHX admin@itrhx.com https://gitcode.net/qq_36759224/Python3-Spider-Practice/-/commit/e0040643e482fd05ba104c1c2818822b166b94af ❌ 应版权方要求删除中烟新商盟【2022.07.22】 2022-07-22T11:12:30+08:00 TRHX admin@itrhx.com
## 中烟新商盟
## XX新商盟
- 目标:中烟新商盟登录
- 主页:http://www.xinshangmeng.com/xsm2/?Version=2021061900
- 接口:http://login.xinshangmeng.com/login/users/dologin/dfaup
- 逆向参数:
- Query String Parameters:
- `jsonp: jQuery999004301464652688636_1626077252402`
- `j_mcmm: 351faaef3ba8f4db2001ec621344dbbf`
- `j_valcode: 5807`
- `_: 1626077333760`
## 分析过程
应版权方要求,已删除本项目
jsonp 这个参数,在登录请求成功或者失败后,会返回一个类似 `jQuery999004301464652688636_1626077252402(xxxxxxxxxxxxxx)` 的东西,也就是你发送的 jsonp 值等于返回内容开头的这一段值,类似于回调函数,在全局搜索里面没有发现可以生成这个参数的地方,观察 `_` 后面 16 开头的 13 位数字,不难发现这是一个时间戳,至于前面的一串数字,随机生成就可以了。同样的还有个 `_` 参数,也是时间戳,`j_valcode` 是验证码,那么就剩下 `j_mcmm` 这个参数了,可以看出这是密码经过一系列处理之后得到的,抓包分析:
![](https://s2.loli.net/2022/07/22/pj12vM9Zg3QyHJh.png)
![01.png](https://i.loli.net/2021/07/12/oN3SlMbpXRGI56A.png)
经过对比,可以发现第 1132 行 `g.j_mcmm = b` 语句中,b 的值就是最终加密后的值,往上找,第 1125 和 1126 行 `var e = b;` `b = F(F(b) + c);`,把明文密码赋值给 b,c 为验证码,经过 F 这个函数的处理后得到加密值,跟进 F 函数:
![02.png](https://i.loli.net/2021/07/12/WPFilYcpAEuqfMO.png)
可以看到其实就是经过以下函数的处理:
```javascript
function d(a) {
return n(e(o(m(a + "{1#2$3%4(5)6@7!poeeww$3%4(5)djjkkldss}")), 32))
}
```
这个函数中,又包含 n, e, o, m 函数,这里不再每个函数去剥离,直接将这个函数往下所有单个字母的函数 copy 下来即可。
## 加密 JS 剥离
关键 JS 加密代码架构:
```javascript
function getEncryptedPassword(a, b, c) {
// a: 用户名, b: 密码, c: 验证码
function d(a) {
return n(e(o(m(a + "{1#2$3%4(5)6@7!poeeww$3%4(5)djjkkldss}")), 32))
}
function e(a, b) {}
function f(a, b, c, d, e, f) {}
function g(a, b, c, d, e, g, h) {}
function h(a, b, c, d, e, g, h) {}
function i(a, b, c, d, e, g, h) {}
function j(a, b, c, d, e, g, h) {}
function k(a, b) {}
function l(a, b) {}
function m(a) {}
function n(a) {}
function o(a) {}
c.hex_md5 = d
b = d(d(b) + c);
return b
}
// 测试样例
// console.log(getEncryptedPassword('123123', '1231234', '6798'))
```
function getEncryptedPassword(a, b, c) {
// a: 用户名, b: 密码, c: 验证码
function d(a) {
return n(e(o(m(a + "{1#2$3%4(5)6@7!poeeww$3%4(5)djjkkldss}")), 32))
}
function e(a, b) {
for (var c = 1732584193, d = -271733879, e = -1732584194, f = 271733878, l = 0; l < a.length; l += 16) {
var m = c
, n = d
, o = e
, p = f;
c = g(c, d, e, f, a[l + 0], 7, -680876936),
f = g(f, c, d, e, a[l + 1], 12, -389564586),
e = g(e, f, c, d, a[l + 2], 17, 606105819),
d = g(d, e, f, c, a[l + 3], 22, -1044525330),
c = g(c, d, e, f, a[l + 4], 7, -176418897),
f = g(f, c, d, e, a[l + 5], 12, 1200080426),
e = g(e, f, c, d, a[l + 6], 17, -1473231341),
d = g(d, e, f, c, a[l + 7], 22, -45705983),
c = g(c, d, e, f, a[l + 8], 7, 1770035416),
f = g(f, c, d, e, a[l + 9], 12, -1958414417),
e = g(e, f, c, d, a[l + 10], 17, -42063),
d = g(d, e, f, c, a[l + 11], 22, -1990404162),
c = g(c, d, e, f, a[l + 12], 7, 1804603682),
f = g(f, c, d, e, a[l + 13], 12, -40341101),
e = g(e, f, c, d, a[l + 14], 17, -1502002290),
d = g(d, e, f, c, a[l + 15], 22, 1236535329),
c = h(c, d, e, f, a[l + 1], 5, -165796510),
f = h(f, c, d, e, a[l + 6], 9, -1069501632),
e = h(e, f, c, d, a[l + 11], 14, 643717713),
d = h(d, e, f, c, a[l + 0], 20, -373897302),
c = h(c, d, e, f, a[l + 5], 5, -701558691),
f = h(f, c, d, e, a[l + 10], 9, 38016083),
e = h(e, f, c, d, a[l + 15], 14, -660478335),
d = h(d, e, f, c, a[l + 4], 20, -405537848),
c = h(c, d, e, f, a[l + 9], 5, 568446438),
f = h(f, c, d, e, a[l + 14], 9, -1019803690),
e = h(e, f, c, d, a[l + 3], 14, -187363961),
d = h(d, e, f, c, a[l + 8], 20, 1163531501),
c = h(c, d, e, f, a[l + 13], 5, -1444681467),
f = h(f, c, d, e, a[l + 2], 9, -51403784),
e = h(e, f, c, d, a[l + 7], 14, 1735328473),
d = h(d, e, f, c, a[l + 12], 20, -1926607734),
c = i(c, d, e, f, a[l + 5], 4, -378558),
f = i(f, c, d, e, a[l + 8], 11, -2022574463),
e = i(e, f, c, d, a[l + 11], 16, 1839030562),
d = i(d, e, f, c, a[l + 14], 23, -35309556),
c = i(c, d, e, f, a[l + 1], 4, -1530992060),
f = i(f, c, d, e, a[l + 4], 11, 1272893353),
e = i(e, f, c, d, a[l + 7], 16, -155497632),
d = i(d, e, f, c, a[l + 10], 23, -1094730640),
c = i(c, d, e, f, a[l + 13], 4, 681279174),
f = i(f, c, d, e, a[l + 0], 11, -358537222),
e = i(e, f, c, d, a[l + 3], 16, -722521979),
d = i(d, e, f, c, a[l + 6], 23, 76029189),
c = i(c, d, e, f, a[l + 9], 4, -640364487),
f = i(f, c, d, e, a[l + 12], 11, -421815835),
e = i(e, f, c, d, a[l + 15], 16, 530742520),
d = i(d, e, f, c, a[l + 2], 23, -995338651),
c = j(c, d, e, f, a[l + 0], 6, -198630844),
f = j(f, c, d, e, a[l + 7], 10, 1126891415),
e = j(e, f, c, d, a[l + 14], 15, -1416354905),
d = j(d, e, f, c, a[l + 5], 21, -57434055),
c = j(c, d, e, f, a[l + 12], 6, 1700485571),
f = j(f, c, d, e, a[l + 3], 10, -1894986606),
e = j(e, f, c, d, a[l + 10], 15, -1051523),
d = j(d, e, f, c, a[l + 1], 21, -2054922799),
c = j(c, d, e, f, a[l + 8], 6, 1873313359),
f = j(f, c, d, e, a[l + 15], 10, -30611744),
e = j(e, f, c, d, a[l + 6], 15, -1560198380),
d = j(d, e, f, c, a[l + 13], 21, 1309151649),
c = j(c, d, e, f, a[l + 4], 6, -145523070),
f = j(f, c, d, e, a[l + 11], 10, -1120210379),
e = j(e, f, c, d, a[l + 2], 15, 718787259),
d = j(d, e, f, c, a[l + 9], 21, -343485551),
c = k(c, m),
d = k(d, n),
e = k(e, o),
f = k(f, p)
}
return new Array(c, d, e, f)
}
function f(a, b, c, d, e, f) {
return k(l(k(k(b, a), k(d, f)), e), c)
}
function g(a, b, c, d, e, g, h) {
return f(b & c | ~b & d, a, b, e, g, h)
}
function h(a, b, c, d, e, g, h) {
return f(b & d | c & ~d, a, b, e, g, h)
}
function i(a, b, c, d, e, g, h) {
return f(b ^ c ^ d, a, b, e, g, h)
}
function j(a, b, c, d, e, g, h) {
return f(c ^ (b | ~d), a, b, e, g, h)
}
function k(a, b) {
var c = (65535 & a) + (65535 & b);
return (a >> 16) + (b >> 16) + (c >> 16) << 16 | 65535 & c
}
function l(a, b) {
return a << b | a >>> 32 - b
}
function m(a) {
for (var b = a.length, c = new Array(b), d = 0; d < b; d++) {
var e = a.charCodeAt(d);
c[d] = 255 & e
}
return c
}
function n(a) {
for (var b = "0123456789abcdef", c = "", d = 0; d < 4 * a.length; d++)
c += b.charAt(a[d >> 2] >> d % 4 * 8 + 4 & 15) + b.charAt(a[d >> 2] >> d % 4 * 8 & 15);
return c
}
function o(a) {
for (var b = 1 + (a.length + 8 >> 6), c = new Array(16 * b), d = 0; d < 16 * b; d++)
c[d] = 0;
for (var e = 0; e < a.length; e++)
c[e >> 2] |= (255 & a[e]) << e % 4 * 8;
return c[e >> 2] |= 128 << e % 4 * 8,
c[16 * b - 2] = 8 * a.length,
c
}
c.hex_md5 = d
b = d(d(b) + c);
return b
}
// 测试样例
// console.log(getEncryptedPassword('123123', '1231234', '6798'))
# ==================================
# --*-- coding: utf-8 --*--
# @Time : 2021-08-02
# @Author : TRHX
# @Blog : www.itrhx.com
# @CSDN : itrhx.blog.csdn.net
# @FileName: xinshangmeng_login.py
# @Software: PyCharm
# ==================================
import time
import random
import execjs
import requests
from PIL import Image
index_url = 'http://www.xinshangmeng.com/xsm2/?Version=2021061900'
login_url = 'http://login.xinshangmeng.com/login/users/dologin/dfaup'
ver_code_url = 'https://login.xinshangmeng.com/login/users/forlogin/img'
headers = {
'Referer': 'http://www.xinshangmeng.com/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36'
}
session = requests.session()
def get_verification_code():
response = session.get(url=ver_code_url, headers=headers)
with open('code.png', 'wb') as f:
f.write(response.content)
image = Image.open('code.png')
image.show()
code = input('请输入验证码: ')
return code
def get_encrypted_password(username, password, code):
with open('xinshangmeng_encrypt.js', 'r', encoding='utf-8') as f:
xinshangmeng_js = f.read()
encrypted_password = execjs.compile(xinshangmeng_js).call('getEncryptedPassword', username, password, code)
return encrypted_password
def login(username, encrypted_password, code):
timestamp = str(round(time.time() * 1000))
jsonp = ''
for _ in range(20):
jsonp += str(random.randint(0, 9))
jsonp = 'jQuery' + jsonp + '_' + timestamp
params = {
'jsonp': jsonp,
'protocol': ' http:',
'loginIndex': index_url,
'j_mmrm': username,
'j_mcmm': encrypted_password,
'j_valcode': code,
'_': timestamp
}
response = session.get(url=login_url, params=params, headers=headers)
response.encoding = 'utf-8'
print(response.text)
def main():
username = input('请输入登录账号: ')
password = input('请输入登录密码: ')
code = get_verification_code()
encrypted_pwd = get_encrypted_password(username, password, code)
login(username, encrypted_pwd, code)
if __name__ == '__main__':
main()
......@@ -309,10 +309,10 @@
</tr>
<tr>
<td>
<a href="https://mp.weixin.qq.com/s/E4pzttU9DvPpCYrAydZ1Rg">【JS 逆向百例】DOM事件断点调试,中烟新商盟登录逆向</a>
【JS 逆向百例】DOM事件断点调试,中烟新商盟登录逆向
</td>
<td>
<a href="https://github.com/TRHX/Python3-Spider-Practice/tree/master/JSReverse/www_xinshangmeng_com">www_xinshangmeng_com</a>
应版权方要求已删除
</td>
</tr>
<tr>
......