Skip to content

Commit a9d0ad8

Browse files
committed
fix markdown warning
1 parent 83618c0 commit a9d0ad8

File tree

2 files changed

+108
-65
lines changed

2 files changed

+108
-65
lines changed

geetest_offline/README.md

Lines changed: 85 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
## GeeTest滑块验证码offline模式的破解
1+
# GeeTest滑块验证码offline模式的分析
2+
23
GeeTest滑块验证码通过机器学习检查鼠标行为轨迹,识别人工或机器行为。
34
online在线验证的流程,目前最全面的分析文档详见 [https://zhuanlan.zhihu.com/windev](https://zhuanlan.zhihu.com/windev)
45
online模式的验证流程,网站后台与GeeTest后台 [http://api.geetest.com](http://api.geetest.com) 进行通讯验证。浏览器前端仅做数据采集和简单加密传输。
56
offline模式的离线验证,网站后台自行验证,GeeTest后台 [http://static.geetest.com](http://static.geetest.com) 仅提供滑块验证码图片下载功能。浏览器前端做数据采集和本地验证。
67
在安全性上,online模式相对非常可靠,offline模式仅仅是障眼法。
78

8-
### 1. 测试网站
9-
[国家企业信用信息公示系统](http://www.gsxt.gov.cn)为例:
10-
主站使用geetest 5.10.10 online 在线验证模式。各省市站点使用的版本和模块略有差异。
11-
**geetest offline 5.9.0**
9+
### 1. 测试网站
10+
11+
[国家企业信用信息公示系统](http://www.gsxt.gov.cn)为例:主站使用 geetest 5.10.10 online 在线验证模式。各省市站点使用的版本和模块略有差异。
12+
13+
**geetest offline 5.9.0**
14+
1215
+ 上海
1316
+ 河北
1417
+ 内蒙古
@@ -25,76 +28,108 @@ offline模式的离线验证,网站后台自行验证,GeeTest后台 [http://
2528
+ 青海
2629
+ 宁夏
2730

28-
**geetest offline 5.10.10**
31+
**geetest offline 5.10.10**
32+
2933
+ 贵州
3034
+ 陕西
3135

3236
### 2. offline模式验证流程
33-
以上海站点为例 [http://sh.gsxt.gov.cn](http://sh.gsxt.gov.cn)
34-
#### 2.1 GET 首页 http://sh.gsxt.gov.cn/notice/
35-
返回HTML页面,解析得到session.token。
36-
#### 2.2 GET register http://sh.gsxt.gov.cn/notice/pc-geetest/register
37+
38+
[上海站点](http://sh.gsxt.gov.cn)为例。
39+
40+
#### 2.1 GET 首页 http://sh.gsxt.gov.cn/notice/
41+
42+
返回HTML页面,解析得到session.token。
43+
44+
#### 2.2 GET register http://sh.gsxt.gov.cn/notice/pc-geetest/register
45+
3746
返回JSON数据
38-
```
47+
48+
```json
3949
{
40-
"success":0,
41-
"gt":"39134c54afef1e0b19228627406614e9",
42-
"challenge":"d2ddea18f00665ce8623e36bd4e3c7c543"
50+
"success":0,
51+
"gt":"39134c54afef1e0b19228627406614e9",
52+
"challenge":"d2ddea18f00665ce8623e36bd4e3c7c543"
4353
}
4454
```
55+
4556
success = 0 表示启用 offline 验证模式。
46-
#### 2.3 POST http://sh.gsxt.gov.cn/notice/security/verify_ip
47-
返回200 True,表示成功。
48-
#### 2.4 POST http://sh.gsxt.gov.cn/notice/security/verify_keyword
49-
返回200 True,表示成功。
50-
#### 2.5 POST http://sh.gsxt.gov.cn/notice/pc-geetest/validate
57+
58+
#### 2.3 POST http://sh.gsxt.gov.cn/notice/security/verify_ip
59+
60+
返回200 True,表示成功。
61+
62+
#### 2.4 POST http://sh.gsxt.gov.cn/notice/security/verify_keyword
63+
64+
返回200 True,表示成功。
65+
66+
#### 2.5 POST http://sh.gsxt.gov.cn/notice/pc-geetest/validate
67+
5168
上传滑块验证码的本地验证结果数据,简称validate。返回JSON数据
52-
```
69+
70+
```json
5371
{
54-
"status":"success",
55-
"version":"3.3.0"
72+
"status":"success",
73+
"version":"3.3.0"
5674
}
57-
```
58-
offline模式,后台根本不知道浏览器使用哪张滑块验证码图片,只知道浏览器上传了验证结果的数据。所以完全可以省略下载验证码图片,进行图像识别,计算滑块移动位置,模拟鼠标滑动轨迹这些步骤。
59-
**验证数据的格式**
60-
例如:1517aab3f_51aa460f_75555a6a38,其中以_分隔的3段数据是由geetest.5.x.x.js中的distance, rand0, rand1加密混淆得到。
61-
具体加密过程分析详见 [寻找阿登高地——爬虫工程师如何绕过验证码](http://www.jianshu.com/p/5b6fb04ea686)
62-
其实不用关心加密算法的实现细节,只需找到JavaScript调用入口,传入参数执行即可:
6375
```
76+
77+
offline模式,后台根本不知道浏览器使用哪张滑块验证码图片,只知道浏览器上传了验证结果的数据。所以完全可以省略下载验证码图片,进行图像识别,计算滑块移动位置,模拟鼠标滑动轨迹这些步骤。
78+
79+
**验证数据格式**
80+
81+
例如:`1517aab3f_51aa460f_75555a6a38`,其中以 `_` 分隔的3段数据是由 `geetest.5.x.x.js` 中的 distance, rand0, rand1 加密混淆得到。
82+
具体加密过程分析详见 [寻找阿登高地——爬虫工程师如何绕过验证码](http://www.jianshu.com/p/5b6fb04ea686)
83+
其实不用关心加密算法的实现细节,只需找到JavaScript调用入口,传入参数执行即可:
84+
85+
```javascript
6486
function userresponse(a, b) {
65-
for (var c = b.slice(32), d = [], e = 0; e < c.length; e++) {
66-
var f = c.charCodeAt(e);
67-
d[e] = f > 57 ? f - 87 : f - 48
68-
}
69-
c = 36 * d[0] + d[1];
70-
var g = Math.round(a) + c; b = b.slice(0, 32);
71-
var h, i = [ [], [], [], [], [] ], j = {}, k = 0; e = 0;
72-
for (var l = b.length; e < l; e++)
73-
h = b.charAt(e), j[h] || (j[h] = 1, i[k].push(h), k++, k = 5 == k ? 0 : k);
74-
for (var m, n = g, o = 4, p = "", q = [1, 2, 5, 10, 50]; n > 0;)
75-
n - q[o] >= 0 ? (m = parseInt(Math.random() * i[o].length, 10), p += i[o][m], n -= q[o]) : (i.splice(o, 1), q.splice(o, 1), o -= 1);
76-
return p
87+
for (var c = b.slice(32), d = [], e = 0; e < c.length; e++) {
88+
var f = c.charCodeAt(e);
89+
d[e] = f > 57 ? f - 87 : f - 48
7790
}
91+
c = 36 * d[0] + d[1];
92+
var g = Math.round(a) + c; b = b.slice(0, 32);
93+
var h, i = [ [], [], [], [], [] ], j = {}, k = 0; e = 0;
94+
for (var l = b.length; e < l; e++)
95+
h = b.charAt(e), j[h] || (j[h] = 1, i[k].push(h), k++, k = 5 == k ? 0 : k);
96+
for (var m, n = g, o = 4, p = "", q = [1, 2, 5, 10, 50]; n > 0;)
97+
n - q[o] >= 0 ? (m = parseInt(Math.random() * i[o].length, 10), p += i[o][m], n -= q[o]) : (i.splice(o, 1), q.splice(o, 1), o -= 1);
98+
return p
99+
}
78100
```
79-
**3个参数的正确生成**
101+
102+
**3个参数的正确生成**
103+
80104
distance,rand0,rand1,这3个参数都是随机生成,但是如果写代码直接随机生成,会发现验证成功率不高,那么这3个参数之间存在什么隐藏关联关系?后台是如何校验这3个随机数的正确性?
81105
其实它们之间存在什么关系不重要,重要的是能够成功通过验证。
82106
只需人工采样N次,构造足够的样本数组,每次随机选取1个,调用JavaScript加密方法,得到验证数据即可。
83-
#### 2.6 POST http://sh.gsxt.gov.cn/notice/search/ent_info_list
107+
108+
#### 2.6 POST http://sh.gsxt.gov.cn/notice/search/ent_info_list
109+
84110
上传session.token(步骤1获得),challenge(步骤2获得),validate(步骤5计算),keyword(查询关键字),返回HTML页面,解析DOM结构,即可获得查询结果和session.token的更新(用于下一次查询)。
85-
### 3. 源码见GitHub
86-
https://github.com/9468305/python-script/tree/master/geetest_offline, Python 3.6
87-
Install:
88-
```
111+
112+
### 3. 源码
113+
114+
Python 3.6
115+
116+
Install:
117+
118+
```bash
89119
pip install requests # HTTP Request库
90120
pip install PyExecJS # Python调用JavaScript, 配合node.js更佳
91121
pip install beautifulsoup4 # 解析HTML页面
92122
```
123+
93124
Demo:
94-
```
125+
126+
```bash
95127
python ./geetest_offline.py
96128
python ./geetest_offline_nm.py
97129
```
98-
Entry Code:
99-
[geetest_offline.py](/geetest_offline/geetest_offline.py) for 上海,河北。
100-
[geetest_offline_nm.py](/geetest_offline/geetest_offline_nm.py) for 内蒙古,HTTP Request&Response 略有不同。
130+
131+
#### Entry Code
132+
133+
[geetest_offline.py](/geetest_offline/geetest_offline.py) for 上海,河北。
134+
135+
[geetest_offline_nm.py](/geetest_offline/geetest_offline_nm.py) for 内蒙古,HTTP Request&Response 略有不同。

geetest_offline/README_gd.md

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
这次的爬虫换个目标,不仅仅抓取统一社会信用代码(税号),还要抓取企业基础信息。
2-
目标网站设定为 http://gd.gsxt.gov.cn 国家企业信用信息公示系统(广东)。
1+
这次的爬虫换个目标,不仅仅抓取统一社会信用代码(税号),还要抓取企业基础信息。目标网站设定为 http://gd.gsxt.gov.cn 国家企业信用信息公示系统(广东)。
32

4-
首页依然是采用GeeTest滑块验证码Offline模式验证,应对方案详见[《Python破解GeeTest滑块验证码offline V5.10.10》](http://www.jianshu.com/p/7623ff64ee54)
5-
校验过程省略,以搜索关键字“腾讯科技”为例,第一步获得如下数据。
6-
```
3+
首页依然是采用GeeTest滑块验证码Offline模式验证,校验过程内容省略。以搜索关键字“腾讯科技”为例,第一步获得如下数据。
4+
5+
```python
76
[
87
('广州腾讯科技有限公司',
98
'http://gsxt.gzaic.gov.cn/aiccips/GSpublicity/GSpublicityList.html?service=entInfo_nPNw57QPCnL961TNeXO4Gqc/FgBy7ESTwWPrP4zJe5g=-FBrJ/suNwXMupXtmIUvNKg=='),
@@ -27,20 +26,24 @@
2726
'https://www.szcredit.org.cn/GJQYCredit/GSZJGSPTS/QYGS.aspx?rid=6B553DC2860F51DD7501B40D8BFA3C22E27771C25B8DF96FD1F35DF7C350F5A9')
2827
]
2928
```
30-
**吐槽:企业详细信息页面分3种。每种网站又有不同的网页模板,因此解析HTML页面元素需要分别处理。深圳的网页模板是一套,广州和其他的是另一套。所以需要区分2种DOM树进行解析。**
29+
30+
**吐槽:企业详细信息页面分3种。每种网站又有不同的网页模板,因此解析HTML页面元素需要分别处理。深圳的网页模板是一套,广州和其他的是另一套。所以需要区分2种DOM树进行解析。**
3131

3232
+ 深圳 https://www.szcredit.org.cn
3333
+ 广州 http://gsxt.gzaic.gov.cn/aiccips/GSpublicity/GSpublicityList.html
3434
+ 其他 http://gd.gsxt.gov.cn/aiccips/CheckEntContext/../GSpublicity/GSpublicityList.html
3535

3636
使用 BeautifulSoup 解析搜索结果页面后,需要判断URL:
37+
3738
```Python
3839
_url = _company['href']
3940
if _url.startswith('../'):
4041
_url = INDEX + '/aiccips/CheckEntContext/' + _url
4142
```
43+
4244
最终整理得到数据:
43-
```
45+
46+
```python
4447
{
4548
'注册号/统一社会信用代码': '91440101327598294H',
4649
'注册资本': '0',
@@ -55,8 +58,11 @@ if _url.startswith('../'):
5558
'经营范围': '电子、通信与自动控制技术研究、开发;网络技术的研究、开发;计算机技术开发、技术服务;软件服务;软件测试服务;软件批发;软件零售;软件开发;游戏软件设计制作;信息技术咨询服务;数据处理和存储服务;(依法须经批准的项目,经相关部门批准后方可开展经营活动)〓'
5659
}
5760
```
58-
**吐槽+1:〓是什么鬼?**
61+
62+
**吐槽+1:〓是什么鬼?**
63+
5964
由于这些网站性能极差,默认的15秒超时经常失败,因此在每次网络请求之上添加保护,对于可以多次重试的请求,添加循环等待。
65+
6066
```Python
6167
def safe_query_detail(url):
6268
'''Safe query url, handle network timeout and retry multi times.'''
@@ -69,13 +75,15 @@ def safe_query_detail(url):
6975
time.sleep(5)
7076
return None
7177
```
72-
**吐槽+2:降低网站性能也是一种非常有效的反爬技术。**
7378

74-
2017.12.05 记录
75-
http://gd.gsxt.gov.cn 查询“深圳兴腾讯科技有限公司”,跳转链接失败,服务器500错误。
76-
https://www.szcredit.org.cn/GJQYCredit/GSZJGSPTS/QYGS.aspx?rid=6B553DC2860F51DD8179F9821CA72F8094E73CE96BD2D49EC7C4690757FA61D9
79+
**吐槽+2:降低网站性能也是一种非常有效的反爬技术。**
80+
81+
2017.12.05 更新
82+
83+
http://gd.gsxt.gov.cn 查询“深圳兴腾讯科技有限公司”,跳转链接失败,服务器500错误。
84+
> https://www.szcredit.org.cn/GJQYCredit/GSZJGSPTS/QYGS.aspx?rid=6B553DC2860F51DD8179F9821CA72F8094E73CE96BD2D49EC7C4690757FA61D9
85+
7786
https://www.szcredit.org.cn ,查询和跳转正常。
78-
https://www.szcredit.org.cn/web/gspt/newGSPTDetail3.aspx?ID=2e82a6a7aaec419884738d2421e7a838
87+
> https://www.szcredit.org.cn/web/gspt/newGSPTDetail3.aspx?ID=2e82a6a7aaec419884738d2421e7a838
7988
80-
**吐槽+3:这都是什么运维水平?**
81-
最后,[源码见GitHub](https://github.com/9468305/script/blob/master/geetest_offline/geetest_offline_gd.py)
89+
**吐槽+3:这都是什么运维水平?**

0 commit comments

Comments
 (0)