├── data
└── config.sample.json
├── config.py
├── README.md
├── common.py
├── __main__.py
├── .gitignore
├── es_dialer_gd.py
├── LICENSE
└── payload.py
/data/config.sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "user_id": "",
3 | "passwd": "",
4 | "client_id": ""
5 | "cdc_domain": "szpt",
6 | "cdc_area": "0755",
7 | "cdc_school_id": "113",
8 | "host_name": "MacBookPro",
9 | "ostag": "macOS10.12.6",
10 | "user_agent": "CCTP/mac1/5007",
11 | "algo_id": "54EB0E0D-58FE-46E2-8629-0A517E2785F4",
12 | }
13 |
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 |
4 | class Config:
5 | data_directory = './data'
6 |
7 | @staticmethod
8 | def load_data(file, default):
9 | try:
10 | with open('%s/%s' % (Config.data_directory, file), 'r', encoding='utf8') as io:
11 | result = json.load(io)
12 | return result
13 | except:
14 | return default
15 |
16 | @staticmethod
17 | def dump_data(file, data):
18 | try:
19 | with open('%s/%s' % (Config.data_directory, file), 'w', encoding='utf8') as io:
20 | json.dump(data, io, ensure_ascii=False, indent=4)
21 | return True
22 | except:
23 | return False
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PyEsDialerGD
2 |
3 | 广东天翼校园三方客户端(登陆器)(Python3版)
4 |
5 | ## 简介
6 |
7 | 抄袭自[EsDialerGD](https://github.com/claw6148/EsDialerGD)。
8 |
9 | * 因客户端协议更新,本项目已无法工作。
10 |
11 | * 不知道哪个**小人**把原作者项目拿去卖了,原作者不再更新,而本人又没能力逆向分析,所以这个抄袭的项目也就没法更新了。(问候卖project的小人全家)
12 |
13 | ## 使用方法
14 |
15 | 需要**requests**模块。
16 |
17 | ~~~shell
18 | pip3 install requests
19 | ~~~
20 |
21 | * client_id请自行抓包!!!
22 |
23 | 复制```data/config.sample.json```为```data/config.json```,填写账号密码,运行。
24 |
25 | ## 关于Project
26 |
27 | 请通过**wireshark**抓取官方客户端的特征(cdc_开头的字段),自行修改sample文件。
28 |
29 | 在本项目的研究过程中,本人依然遵守“一人一号”规则(即本人所在宿舍是每人一个宽带账号的),本项目的研究目的是为了本人的设备在 Linux 平台(官方未提供 Linux 平台的软件)下能够正常接入校园网。
30 |
31 | 本项目遵循 GNU GPLv3 开源协议,这意味着:
32 | 你可以免费使用、引用和修改本项目的代码以及衍生代码,但不允许将修改后和衍生的代码做为闭源的商业软件发布和销售。
33 |
--------------------------------------------------------------------------------
/common.py:
--------------------------------------------------------------------------------
1 | import hashlib
2 | import time
3 |
4 |
5 | def md5(data: bytes):
6 | return hashlib.md5(data).hexdigest()
7 |
8 |
9 | def md5_str(data: str):
10 | return md5(data.encode('utf8'))
11 |
12 |
13 | def now_str():
14 | return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
15 |
16 |
17 | def str_extract(data_str: str, start_str: str, end_str: str):
18 | result = ''
19 | offset_start = data_str.find(start_str)
20 | if offset_start != -1:
21 | offset_end = data_str.find(end_str, offset_start)
22 | if offset_end != -1:
23 | result = data_str[offset_start + len(start_str):offset_end]
24 |
25 | return result
26 |
27 |
28 | def get_tag_content(data_str: str, tag: str):
29 | result = str_extract(data_str, '<%s>' % tag, '%s>' % tag)
30 | if result[:9] == '':
31 | result = result[9:-3]
32 | return result
33 |
--------------------------------------------------------------------------------
/__main__.py:
--------------------------------------------------------------------------------
1 | import time
2 | import traceback
3 |
4 | from es_dialer_gd import EsDialerGD
5 |
6 | client = EsDialerGD()
7 | if client.init():
8 | print('init success.')
9 | if client.auth():
10 | print('auth success.')
11 | k = 0
12 | while True:
13 | try:
14 | expires = -1
15 | for i in range(3):
16 | expires = client.keep()
17 | if expires != -1:
18 | expires -= 30
19 | k += 1
20 | print('[%s]keep success. %ds' % (k, expires))
21 | break
22 | else:
23 | print('[%s][%s]keep failed.' % (k, i + 1))
24 | if expires > 0:
25 | time.sleep(expires)
26 | except KeyboardInterrupt:
27 | break
28 | except:
29 | traceback.print_exc()
30 | break
31 | else:
32 | print('auth failed.')
33 | else:
34 | print('init failed.')
35 |
36 | client.term()
37 | print('term completed.')
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Python template
3 | # Byte-compiled / optimized / DLL files
4 | __pycache__/
5 | *.py[cod]
6 | *$py.class
7 |
8 | # C extensions
9 | *.so
10 |
11 | # Distribution / packaging
12 | .Python
13 | build/
14 | develop-eggs/
15 | dist/
16 | downloads/
17 | eggs/
18 | .eggs/
19 | lib/
20 | lib64/
21 | parts/
22 | sdist/
23 | var/
24 | wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .coverage
44 | .coverage.*
45 | .cache
46 | nosetests.xml
47 | coverage.xml
48 | *.cover
49 | .hypothesis/
50 | .pytest_cache/
51 |
52 | # Translations
53 | *.mo
54 | *.pot
55 |
56 | # Django stuff:
57 | *.log
58 | local_settings.py
59 | db.sqlite3
60 |
61 | # Flask stuff:
62 | instance/
63 | .webassets-cache
64 |
65 | # Scrapy stuff:
66 | .scrapy
67 |
68 | # Sphinx documentation
69 | docs/_build/
70 |
71 | # PyBuilder
72 | target/
73 |
74 | # Jupyter Notebook
75 | .ipynb_checkpoints
76 |
77 | # pyenv
78 | .python-version
79 |
80 | # celery beat schedule file
81 | celerybeat-schedule
82 |
83 | # SageMath parsed files
84 | *.sage.py
85 |
86 | # Environments
87 | .env
88 | .venv
89 | env/
90 | venv/
91 | ENV/
92 | env.bak/
93 | venv.bak/
94 |
95 | # Spyder project settings
96 | .spyderproject
97 | .spyproject
98 |
99 | # Rope project settings
100 | .ropeproject
101 |
102 | # mkdocs documentation
103 | /site
104 |
105 | # mypy
106 | .mypy_cache/
107 |
108 | data/
--------------------------------------------------------------------------------
/es_dialer_gd.py:
--------------------------------------------------------------------------------
1 | import requests
2 |
3 | import common
4 | import payload
5 | from config import Config
6 |
7 |
8 | def build_headers(
9 | cdc_domain=None, cdc_school_id=None, cdc_area=None,
10 | user_agent=None, algo_id=None, client_id=None,
11 | cdc_checksum=None):
12 | headers = {}
13 |
14 | if cdc_domain is not None:
15 | headers['CDC-Domain'] = cdc_domain
16 | if cdc_school_id is not None:
17 | headers['CDC-SchoolId'] = cdc_school_id
18 | if cdc_area is not None:
19 | headers['CDC-Area'] = cdc_area
20 | if user_agent is not None:
21 | headers['User-Agent'] = user_agent
22 | if client_id is not None:
23 | headers['Client-ID'] = client_id
24 | if algo_id is not None:
25 | headers['Algo-ID'] = algo_id
26 | if cdc_checksum is not None:
27 | headers['CDC-Checksum'] = cdc_checksum
28 |
29 | return headers
30 |
31 |
32 | class EsDialerGD:
33 | def __init__(self):
34 | self._info = Config.load_data('info.json', {})
35 | self._config = Config.load_data('config.json', None)
36 | if self._config is None:
37 | raise Exception('Can not load config.')
38 | else:
39 | print(self._config)
40 |
41 | def init(self):
42 | config = self._config
43 | info = self._info
44 |
45 | headers = build_headers(user_agent=config.get('user_agent'))
46 | try:
47 | resp = requests.get('http://baidu.com', headers=headers, timeout=3)
48 | resp_str = resp.content.decode('gbk', errors='ignore')
49 |
50 | index_url = resp.url
51 | if 'index.cgi' in index_url:
52 | info['index_url'] = index_url
53 | elif info.get('index_url') is not None:
54 | resp = requests.get(info['index_url'], headers=headers, timeout=3)
55 | resp_str = resp.content.decode('gbk', errors='ignore')
56 |
57 | ticket_url = common.get_tag_content(resp_str, 'ticket-url')
58 | auth_url = common.get_tag_content(resp_str, 'auth-url')
59 |
60 | result = ticket_url != '' and auth_url != ''
61 | if result:
62 | info['ticket_url'] = ticket_url
63 | info['auth_url'] = auth_url
64 |
65 | ipv4_addr = common.str_extract(resp_str, 'wlanuserip=', '&')
66 | if ipv4_addr == '':
67 | ipv4_addr = common.str_extract(resp_str, 'wlanuserip=', '"')
68 |
69 | info['ipv4_addr'] = ipv4_addr
70 | Config.dump_data('info.json', self._info)
71 | except Exception as e:
72 | print('[init] %s' % e)
73 | result = False
74 |
75 | return result
76 |
77 | def _update_time(self):
78 | info = self._info
79 | info['local_time'] = common.now_str()
80 |
81 | def _build_headers(self, cdc_checksum=None):
82 | config = self._config
83 | headers = build_headers(
84 | cdc_domain=config.get('cdc_domain', "szpt"),
85 | cdc_school_id=config.get('cdc_school_id', "113"),
86 | cdc_area=config.get('cdc_area', "0755"),
87 | user_agent=config.get('user_agent', "CCTP/mac2/5009"),
88 | algo_id=config.get('algo_id', "54EB0E0D-58FE-46E2-8629-0A517E2785F4"),
89 | client_id=config.get('client_id', "2CDEABEA-BA33-5C55-9DCA-C8F0337897EA"),
90 | cdc_checksum=cdc_checksum
91 | )
92 |
93 | return headers
94 |
95 | def _get_ticket(self):
96 | config = self._config
97 | info = self._info
98 |
99 | data = payload.build_ticket_payload(
100 | config.get('host_name'),
101 | config.get('user_agent'),
102 | config.get('client_id'),
103 | info['ipv4_addr'],
104 | '',
105 | config.get('mac_addr'),
106 | config.get('ostag'),
107 | info['local_time']
108 | )
109 | cdc_checksum = common.md5_str(data)
110 | headers = self._build_headers(cdc_checksum)
111 |
112 | resp = requests.post(info['ticket_url'], data.encode('utf8'), headers=headers, timeout=3)
113 | resp_str = resp.content.decode('utf8')
114 | resp_str_raw = payload.payload_decode(resp_str)
115 |
116 | info['ticket'] = common.get_tag_content(resp_str_raw, 'ticket')
117 |
118 | result = info['ticket'] != ''
119 | if result:
120 | print('[ticket] %s' % info['ticket'])
121 |
122 | return result
123 |
124 | def auth(self):
125 | config = self._config
126 | info = self._info
127 |
128 | self._update_time()
129 | result = self._get_ticket()
130 | if result:
131 | self._update_time()
132 |
133 | data = payload.build_auth_payload(
134 | config.get('user_id'),
135 | config.get('passwd'),
136 | info['ticket'],
137 | config.get('client_id'),
138 | config.get('host_name'),
139 | config.get('user_agent'),
140 | info['local_time']
141 | )
142 | cdc_checksum = common.md5_str(data)
143 |
144 | headers = self._build_headers(cdc_checksum)
145 |
146 | resp = requests.post(info['auth_url'], data.encode('utf8'), headers=headers, timeout=3)
147 | resp_str = resp.content.decode('utf8', errors='ignore')
148 | resp_str_raw = payload.payload_decode(resp_str)
149 |
150 | keep_url = common.get_tag_content(resp_str_raw, 'keep-url')
151 | term_url = common.get_tag_content(resp_str_raw, 'term-url')
152 |
153 | info['keep_url'] = keep_url
154 | info['term_url'] = term_url
155 |
156 | result = keep_url != '' and term_url != ''
157 | print(self._info)
158 | if result:
159 | Config.dump_data('info.json', self._info)
160 | else:
161 | print('[auth] %s' % resp_str_raw)
162 |
163 | return result
164 |
165 | def keep(self):
166 | try:
167 | config = self._config
168 | info = self._info
169 |
170 | self._update_time()
171 | data = payload.build_keep_payload(
172 | config.get('user_agent'),
173 | info['local_time'],
174 | info['ticket'],
175 | config.get('host_name'),
176 | config.get('client_id')
177 | )
178 | cdc_checksum = common.md5_str(data)
179 | headers = self._build_headers(cdc_checksum)
180 |
181 | resp = requests.post(info['keep_url'], data.encode('utf8'), headers=headers, timeout=3)
182 | resp_str = resp.content.decode('utf8')
183 | resp_str_raw = payload.payload_decode(resp_str)
184 |
185 | result = -1
186 | interval = common.get_tag_content(resp_str_raw, 'interval')
187 | if interval != '':
188 | result = int(interval)
189 | else:
190 | print('[keep] %s' % resp_str_raw)
191 | except Exception as e:
192 | print('[keep] %s' % e)
193 | result = -1
194 |
195 | return result
196 |
197 | def term(self):
198 | config = self._config
199 | info = self._info
200 |
201 | self._update_time()
202 | data = payload.build_term_payload(
203 | config.get('user_agent'),
204 | info['ticket'],
205 | info['local_time'],
206 | config.get('host_name'),
207 | config.get('client_id')
208 | )
209 | cdc_checksum = common.md5_str(data)
210 | headers = self._build_headers(cdc_checksum)
211 |
212 | try:
213 | requests.post(info['term_url'], data.encode('utf8'), headers=headers, timeout=3)
214 | except Exception as e:
215 | print('[term] %s' % e)
216 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/payload.py:
--------------------------------------------------------------------------------
1 | magic_box = b'\x33\xE2\x73\x9B\x7D\x6E\x34\x52\x08\x75\x27\x97\x10\x1D\xF7\xB1\x02\xB2\xF5\xC1\x99\x3A\x43\x96\x23\xC5\x35\x32\x06\x05\x6C\xF1\x04\x53\x5B\x7E\xCB\xF8\xEF\x09\x87\xDC\xCE\x2F\x5D\x28\x3F\x77\x0F\x84\xDB\xF3\xDB\xA7\xD8\xB2\x72\x10\x1D\x93\x66\x72\x69\xFF\x9F\xE1\x62\x27\x78\x58\x33\xBD\xE8\x20\x27\x90\xD3\x31\xA7\xEF\x05\xC2\x97\x69\x9D\xA7\x0E\x53\xF6\xCC\xBC\x04\x97\x29\xFC\xF4\xF7\x7E\x90\x49\xF2\x03\xA9\x9D\x11\x04\x75\x48\xC1\xC8\xC3\x70\xF1\x00\x35\xA0\x66\xDF\x97\x73\x8E\x02\xF0\xBD\x83\x02\xEC\xF5\x2A\x64\x61\x70\xBA\x66\x29\x4A\xEF\x2B\x3B\x32\x2F\x49\x02\xE4\xD3\x7A\x65\x94\x87\xEF\x18\xF9\x4E\x4D\xE4\x18\xB4\x2A\x1C\x66\x33\x02\x1F\xB4\xBD\xAF\x09\x72\x11\xCE\x76\x01\x81\xB2\xF8\x21\x22\x9C\xE5\x29\xF6\x89\x42\xFB\x8D\xA5\x09\xA3\x58\xAA\x64\x78\x74\xB2\x12\x69\x7E\xA1\xC5\x78\x72\xB8\x22\xCE\x3D\xBB\xD4\x17\x5C\x9D\x31\x20\xF8\x94\x2B\x75\xBC\x8D\x81\xA0\x97\xC2\xCF\xEF\x82\xA8\x7C\xCE\xEB\xF7\xDE\xBD\xC0\xFB\x8B\x41\xA4\x2A\xC7\xC1\x91\x9E\x92\xD6\xBF\xEE\x94\x89\x03\xB3\x6A\xE4\x57\x13\x33\xC0\xF1\x3D\x6D\xF8\x86\x25\xE3\x70\xBD\x2C\x50\x79\x3A\xDC\xAE\x8E\x86\x81\xF8\x09\x93\x7F\xF5\xBD\x99\xE5\x5D\x83\xAA\xAA\xCE\x5E\xBB\xDC\x7C\x97\xF7\x68\x44\x8B\xB3\x8C\x0A\x7C\xBE\x9D\x83\x31\x8A\x48\x99\xC7\x53\x48\x8C\x6A\x9A\x11\x99\x78\x04\xCD\xC8\xB6\x13\xE2\xFB\xE5\xCC\x46\x62\x5D\x91\xA4\x61\xD4\x4C\xF3\xCA\x90\x7D\x96\x7B\x96\x26\xA6\x24\xF3\x0D\xBF\xC5\xBD\xEC\x09\xAE\xCE\xBB\x7E\x58\xC0\x4E\x9B\xCA\xA6\xC5\xF3\xF9\x37\x73\x7D\x6D\x2E\xA1\x0F\xC6\x64\x42\xF4\x52\x7E\x9B\xFB\x1A\x79\x45\x1D\x36\x54\x2D\xF8\x81\xB2\x57\x56\xF2\x13\x3B\xE6\xD1\x5F\x2D\x53\xBE\xAA\xE2\x8C\x34\x78\xF9\x50\x33\x95\x6B\xF5\xB0\xEE\x7B\xA0\xAD\x7C\xC5\xA9\x86\x88\x51\x09\x31\xC2\x5A\x86\x09\x84\x47\x2C\xFC\x14\x5F\x30\x3A\xCB\xC5\x53\x8E\x01\x93\xE6\x21\xC4\xFF\x55\x46\xE4\xA7\x5A\xBF\xB0\x77\xAB\x16\xCB\x7E\x5C\x6B\x2A\xCE\xB5\x77\xB2\x8D\x13\xB8\xCF\x15\x10\x08\xBC\x4B\x58\xC2\xA1\x74\x09\x54\x64\x9E\x76\xCE\xE0\x54\x11\x65\xF9\x08\xC0\x6F\x67\xFE\xE6\x77\xF7\x70\xE3\xA7\x32\x9A\x2C\xAE\xC0\x81\x7F\x04\x92\x9D\x08\xE9\x55\x0F\xE0\xDD\x9E\x69\xE6\x17\x10\x60\x2E\xB1\xC7\xF9\x0A\x3A\xC6\x93\xAF\x1D\x56\x40\x08\x59\xD4\xEF\x82\xD3\x33\x7E\x41\xA5\xC4\xD5\xFA\xDB\xEC\x14\xAB\x89\xB0\x4D\xEF\xD6\x4D\xD3\x5A\x51\x77\x72\x20\x44\x61\x2A\x77\x07\x22\xA6\x99\xFB\x94\xB7\x56\xB9\x81\x49\x78\x84\x91\xB2\x19\x69\xF5\x81\xA4\xE2\x40\x70\x3C\x6B\xCE\x8A\xBE\x46\xFB\xC3\x20\xDA\x7E\x27\x94\x79\xBB\x82\x6E\x0E\xF6\x2A\x30\xFD\x60\x35\x66\xC4\xE6\xEF\xAF\x13\x83\x4A\x13\x46\x02\xE6\x31\xFC\xB5\x5A\xDF\xD5\x65\x1F\x59\xCE\x9B\x8A\xEE\x52\x4B\xD7\x10\x7C\xB6\x82\x57\x1A\xBF\x81\x34\x7E\xE7\xC8\xD4\x76\x92\xD5\x9C\x5A\xAC\x60\x70\xAC\xA4\x20\x8D\xEE\x2F\x52\xD7\x73\x3F\x03\xB8\xC1\x99\x05\x7F\x04\x6E\x84\xEB\xD6\xD9\x55\x96\x4D\x28\xAE\x3D\xFF\xAF\x2F\x0A\x59\xFC\x1F\x63\x0C\xB0\xD4\xD1\x9E\x25\x4B\xA6\xA4\x79\x67\x45\x99\x33\x96\x64\x8B\x30\xE1\x18\xB9\x59\x41\x4C\xFA\x20\x31\x93\x4C\xFD\xED\xFD\xB1\x94\x8C\x8A\x37\xA6\x50\x42\x34\x82\x26\xFB\xE9\x24\x0E\x89\x59\x1B\xB2\x6A\x53\xF5\x44\xFF\x7E\x00\xFD\xF4\x79\xA9\xBD\xB4\x9C\x21\x0B\xB0\x21\x67\xDB\xE0\x09\x32\x6C\x6F\xC9\x0B\x69\xF3\xE9\xDF\x98\xAD\x4E\x33\x45\x02\x83\xB6\x21\x0B\x9A\xD9\x58\xB4\x88\xA8\x4C\xF7\x02\x9B\x6E\xAD\x8B\x85\xA1\x26\xEA\x19\x4F\xE9\x7C\x00\x66\x04\x44\xBE\x34\x4C\xE0\xAB\x79\xA9\xCC\x9D\xED\x57\xB7\x29\x29\xAE\x0E\x19\xF4\x2F\xE4\x60\x31\x75\x84\x0C\x4E\x34\x6E\x8F\x1F\x92\x78\x15\x23\xBB\xE8\xEC\xA0\x23\x60\x29\xC3\x2C\xFB\x8A\x74\xA1\xAD\xF3\x46\x17\x90\x20\xD7\x62\x36\x38\x92\xB5\xC9\xF2\x75\xB0\x7F\x84\x8D\x0F\x05\xC7\xC3\xD1\x2D\xE8\x00\x98\x29\xA2\x72\x86\x4E\x2E\xBA\x3C\x80\x53\xB9\x27\xED\xE5\xFE\x85\xC5\x0F\xCF\xB2\x7A\x4B\xE8\x2C\x7D\xC8\xE2\xFA\x51\x19\xDE\x74\x17\x2D\x86\x41\x4A\xD2\xF1\x7D\x32\x24\x1A\x86\xEC\xFF\x08\x2B\x87\x11\x6D\x81\x6F\xCD\xA9\xD3\x3A\xB5\x83\xA5\x16\x67\xD7\x68\xDD\xE0\xB8\x99\xA8\x7E\x41\x6D\xCC\xCB\x75\x2B\x33\xAD\x82\x54\x0B\xEC\x1A\x17\xC7\x49\x0D\xBD\x4C\x88\x6C\xBB\x4C\x27\xC2\xED\xFF\x1D\x1A\xA9\xEE\xAD\xB1\x82\x45\x51\xA5\x3F\xCB\xE7\xFA\xA8\x6D\x98\x7C\x0E\x87\xE6\x74\xF1\x31\x1E\xF3\xC3\xDD\x6C\xFD\x8E\x44\x3F\x7A\xAE\x45\x8A\x1B\x85\xB7\xB8\xCC\xCC\xD6\x04\xDD\xBF\x12\xCF\x73\x33\x49\xEB\x7B\x13\x38\x94\x21\x24\x31\x63\x2A\x31\x0F\x41\x50\xBE\x82\xA8\x14\x60\xB3\x2E\x2C\x0B\x8E\x91\xF4\x1D\x1A\x66\x37\xCE\xA5\x9D\xC3\x4F\xEB\xCF\xBC\xA9\x8B\x63\x96\xA2\x98\x37\x96\x43\x37\x78\x56\xB5\xDA\xA8\xD9\xE0\x8E\xB3\xA3\x5C\xA2\xBC\x9D\x96\x53\xDC\x00\xCD\x58\x84\x49\x0D\xB4\x6F\xE3\x1F\x4C\x78\xEB\xD8\xD7\x40\xB4\x2A\x14\x6C\x33\x08\x3C\x95\x3D\xAE\xB2\x13\x25\xA7\x14\x0B\xC3\x98\x28\xE3\xDF\x12\x27\x14\x8E\xC6\x25\xB7\x1D\x71\x2C\xDB\xDF\x89\x8E\x64\x88\x1E\x99\xF9\x2B\x7C\xDF\xBD\x9F\xD5\x85\xA2\x5C\xFF\xA4\xE4\x8F\xD5\x60\xFC\xFD\x41\x55\x13\x62\xA2\xB4\xA1\x9B\xF6\x92\x59\x80\x51\x55\xAB\xC4\xA3\x2A\xB2\xA3\x61\x54\x4B\xD7\x52\x17\x25\xC8\xBA\xC0\x7B\x01\x8F\xF9\xD0\xA8\x82\x01\x9D\x23\xC3\xB0\xD5\xEB\xF1\xE4\x5D\x2D\xEB\x6B\x8C\xBB\xEC\x12\xA2\x2D\xE0\x7A\xFF\x4C\xB4\x59\x4D\x12\x96\x8B\x15\xB5\x90\xA2\x23\x8A\x87\xCD\x7D\xCC\x43\x17\x4C\x7E\xC1\xD7\xD7\x0F\x99\x36\xE6\x1B\x59\x5B\x22\xA9\x1D\x01\xC8\x12\x6D\xEC\x39\x41\x52\x6D\xC9\xF4\x7A\xCF\x22\x6B\x8A\x50\xFB\x50\x00\xD6\x64\x04\xFC\xA6\x2E\xBB\xB4\x58\xB5\x6C\x5E\x9C\x00\x67\xD6\x1E\x57\x82\x90\xC8\x09\x41\x9A\xFB\xA6\x86\x6E\x50\x49\xEF\x7D\xEF\xF8\xF8\x55\x7F\x17\x2A\xF9\x59\x0A\xD8\xB5\xA2\x52\x6A\x1B\x58\xCD\x48\xFB\x60\x52\x93\x10\x2A\x17\xDA\x79\xC0\x87\x7E\x59\x9C\xF6\xF6\x71\x30\x3D\xF3\xE9\x68\x38\x98\x17\x4C\xD3\x66\xAC\xCF\xB8\xD8\x59\x41\xFA\xD5\x59\x48\xEB\xBA\x3D\x6C\x81\x09\x56\xED\x34\xCE\x2A\x53\x67\xA6\xC1\x03\xC3\x5E\xAC\x9D\x89\x28\x08\x25\xCD\x73\x89\xFF\xAB\xFC\xDC\xF5\xFE\xAC\x18\x18\xF0\x54\xAC\x70\x4E\x2A\x54\xBB\x9D\x5C\xE1\xDB\x24\x1A\xA9\xBA\x9A\x10\x09\xC7\x60\x90\x49\x23\x77\x4F\x23\xEB\xD3\x1D\x03\xB6\xCF\xF4\x94\x79\x5D\x88\x37\x56\x87\xD3\x98\xBD\xB9\x05\x88\xA0\x73\x23\x4E\x4E\x3F\x07\x65\x24\xE6\x66\xFC\xDD\x89\x4D\x9E\x09\xEF\xC6\x5B\x83\x97\x56\xE8\x1C\x15\xC2\x6D\x68\xAE\xBA\x81\x96\xA0\x6E\xF8\xAB\x8D\x84\x13\x0D\xBB\xFA\xA7\x3B\xAF\x10\x58\xB2\xB7\x0E\x65\x7A\x13\x09\x2B\xAA\x78\xBF\xB2\x88\xFA\xB6\x27\xC8\x85\x56\x47\x5D\x72\x59\x4F\x0F\x54\x6A\x15\x62\xBD\x23\x1F\x52\x6A\x2C\x30\xA5\xE8\x86\x8C\x90\xA6\xE3\x14\x48\x41\xD5\x35\x9B\xE4\x46\x82\x08\x11\xAA\x89\x27\x84\xE6\x56\x17\x40\xA7\x72\x33\xDF\xD6\x55\x5F\x45\x25\xE9\x04\x9B\x25\xA3\xD0\x80\xF0\xFB\xF2\x02\x96\xD9\xC2\x4E\xB5\x70\x5A\x51\x93\x40\xD2\xE9\x7C\x20\x19\x46\xEF\x02\xFF\x7F\xD2\x71\x58\x75\x83\xCD\xB3\xEA\xC1\x3E\xB3\x37\xE3\x28\x3D\xC2\xB5\x31\x20\x59\x71\xBD\x0D\x87\x92\x6D\x06\xEB\x02\x35\xCC\x0D\x11\xDE\xAE\x89\x78\x34\x74\x2D\x61\x01\xD8\x15\xEF\xA2\x29\xA6\xA4\x59\x95\xAF\xC9\xF0\x9A\x19\x91\x59\x76\xCC\xCE\x79\xF0\xC8\x5F\xE3\x9B\x3D\x4C\x1D\xFA\x2A\xF5\xE3\x07\xEC\xE0\x04\x0A\x23\x6C\xA8\xFE\x11\x86\x06\x6B\xB9\x44\x1E\x4C\x9B\x79\xC1\x8E\xEA\xB9\xDC\x87\x52\x26\x54\x6D\x3E\x70\x4F\xCC\x3B\xE2\x9B\x10\x29\x01\x0B\x00\x66\xA9\x70\x4E\x34\x34\xA1\xFC\xEA\xC3\x2C\xD3\xC3\x2E\xF9\x36\x76\x14\xEB\xDD\xFF\x26\xDB\x07\x00\xC3\x26\xC7\xCD\x92\x60\x6C\x84\xFD\xEA\x5C\x2D\xC2\x6B\x57\xE8\x73\xB0\x06\x4A\x9F\x53\x3F\xCA\xAD\xE6\x0B\xC8\xA3\xE8\x25\x12\xD2\x10\xAE\x9E\xF8\x28\xF5\x94\xF9\xF4\xEC\x13\x3D\x60\x1C\xA4\x8F\x70\xF2\xDA\x84\x67\x11\x6A\x17\x6B\xCA\xB7\x1E\xCC\xF5\xD3\x15\x3E\xC6\x3B\x42\x9A\x98\x7A\x9A\xC6\x20\xED\xE8\xA8\xAA\xF1\x07\x15\x72\x7D\x63\xE2\x86\xD2\x39\xC9\x91\xE9\x71\xDE\xD7\x1A\x87\xAA\xFA\x77\x03\x5C\x77\xCE\x40\x19\xB1\xDB\x5C\x67\x4F\xD3\xAE\xC4\xB7\x2D\x69\xF2\xD5\x12\xE8\x15\xB6\x7F\xF0\x7F\x1C\x71\xE1\x96\x8F\x2B\xBA\x13\xD3\x31\x6C\x67\x25\x08\xC9\x08\xF9\x09\x4A\xF6\x6F\x03\xF1\xCD\x71\xBC\x40\xAA\x7C\x2A\x59\x9E\x46\xBE\x9E\xFC\xF1\x44\x90\xED\x56\xDB\x02\x25\xBC\xF0\x20\xF0\xC0\xF3\x35\x32\x67\xB6\x15\xA4\x00\x16\x8C\xE2\xF0\x0D\x59\xB5\x95\x08\xE5\x23\x24\x46\x0F\xC9\xDB\xA3\xFE\xBA\xA5\x92\x53\x2B\xF7\x62\xA8\xB2\x56\x33\xB4\xBD\xAF\xBA\x6D\x2A\x6A\xCE\xEE\x47\x94\x32\xC7\xB3\xD2\x83\x5E\x8D\x3D\xC3\xE8\x2C\xFE\x4C\x69\x16\xC8\xC9\xE1\x16\xFA\xBB\x83\x76\xE0\x09\x8C\x1A\x64\xD6\xEE\xDD\x39\x90\xC0\xEE\x5A\x07\x3D\x9C\x48\x0B\x1A\x93\x10\x15\x09\xAC\x9B\x08\xAA\x3B\xFD\x44\x14\x3B\x0D\x5D\x32\xB4\xE5\xEB\x63\x55\x23\xF3\x78\xEE\xB0\x77\xAD\x63\x2F\xE1'
2 |
3 |
4 | def fuck(data: bytes):
5 | l_data = len(data)
6 | buffer = bytearray(l_data)
7 | for i in range(l_data):
8 | buffer[i] = data[i] ^ magic_box[i]
9 | return bytes(buffer)
10 |
11 |
12 | def payload_encode(data_str: str):
13 | return fuck(data_str.encode('utf8')).hex()
14 |
15 |
16 | def payload_decode(data_str: str):
17 | return fuck(bytes.fromhex(data_str)).decode('utf8')
18 |
19 |
20 | def build_ticket_payload(
21 | host_name, user_agent, client_id,
22 | ipv4_addr, ipv6_addr, mac_addr,
23 | ostag, local_time):
24 | content = '''
25 |
26 | %s
27 | %s
28 | %s
29 | %s
30 | %s
31 | %s
32 | %s
33 | %s
34 | ''' % (
35 | host_name, user_agent, client_id,
36 | ipv4_addr, ipv6_addr, mac_addr,
37 | ostag, local_time
38 | )
39 |
40 | return payload_encode(content)
41 |
42 |
43 | def build_auth_payload(
44 | user_id, passwd,
45 | ticket, client_id, host_name,
46 | user_agent, local_time):
47 | content = '''
48 |
49 | %s
50 | %s
51 | %s
52 | %s
53 | %s
54 | %s
55 | %s
56 | ''' % (
57 | passwd, user_id,
58 | ticket, client_id, host_name,
59 | user_agent, local_time
60 | )
61 |
62 | return payload_encode(content)
63 |
64 |
65 | def build_keep_payload(
66 | user_agent, local_time,
67 | ticket, host_name, client_id):
68 | content = '''
69 |
70 | %s
71 | %s
72 | %s
73 | %s
74 | %s
75 | ''' % (
76 | user_agent, local_time,
77 | ticket, host_name, client_id
78 | )
79 |
80 | return payload_encode(content)
81 |
82 |
83 | def build_term_payload(
84 | user_agent, ticket, local_time,
85 | host_name, client_id, reason=1):
86 | content = '''
87 |
88 | %s
89 | %s
90 | %s
91 | %s
92 | %s
93 | %s
94 | ''' % (
95 | user_agent, ticket, local_time,
96 | host_name, reason, client_id
97 | )
98 |
99 | return payload_encode(content)
100 |
--------------------------------------------------------------------------------