在上一篇文章中做代码审计的时候,提到过 phpjm 混淆的解密还原,后面有一些小伙伴私信问具体过程,本篇就展开说说。
0x00 前言
在上一篇文章:https://forum.butian.net/share/1206 中做代码审计的时候,提到过 phpjm 混淆的解密还原,后面有一些小伙伴私信问具体过程,本篇就展开说说。
下面是上次文章所举例过的系统的其中一个经过混淆的文件
<?php
$O00OO0=urldecode("n1zb/ma5\vt0i28-pxuqy*6lrkdg9_ehcswo4+f37j");$O00O0O=$O00OO0{3}.$O00OO0{6}.$O00OO0{33}.$O00OO0{30};$O0OO00=$O00OO0{33}.$O00OO0{10}.$O00OO0{24}.$O00OO0{10}.$O00OO0{24};$OO0O00=$O0OO00{0}.$O00OO0{18}.$O00OO0{3}.$O0OO00{0}.$O0OO00{1}.$O00OO0{24};$OO0000=$O00OO0{7}.$O00OO0{13};$O00O0O.=$O00OO0{22}.$O00OO0{36}.$O00OO0{29}.$O00OO0{26}.$O00OO0{30}.$O00OO0{32}.$O00OO0{35}.$O00OO0{26}.$O00OO0{30};eval($O00O0O("JE8wTzAwMD0iZ0pqUU5IUkx5RGJoU0luTXF0R29LbHB3eG16QlhUdk9rc2VpYWZQWmRyY0FWVUNFRnVZV2VtWmtpbkVhVXh5c0FkcVdMSXZ1T0hnVEpOekdvYmZjU2p3aHB0ckJSRE1QUVZYWUtGQ2xyeDlUcG5QaVhONXN5bFF6TXZLWkJBR1p5M21Ib3ZKZ0NaamVDMkpzTTNXZUV2ZGV3VUdUTU5IMkNvRUhkWEV6Qm9tMkJvZDdkbkdVcG9Cc1J2VmVtbkdVQmJqZU1ubWdSTkswQkFHelJ2SzBwbFdlbXZIRk0zRXN5TmlIY1VHVFJsbWpwbFdlTTNFc1J2SFpkdkIxeU5pMHBsOUZkdlJIUllIRk0zRXN5TmlIT1hIN2R2SE5PdlFJTW5FNU9uaUh5dkM2Y2hFZ3lxaTBDbDVaQkFTZ3dVR3pCbEpOY1p1U3BsNXpSdktGQzJWOXlOUTNkbmlIeXZDdU9iamV0QUdVQm9FMU1ONGVNMlFqQlp1Nm12SEZNM0VzeU5pSGNVRzlkbkdVcG9Cc1J2VmVCcVFGQzNFZ3kyNGVvMTlaeXY5RkJBZWd3MzBlTW5tZ1JOSzBCQUdOUmw1WlJ2SGZ5aEd0bzJpZnlxaTBNcVFaUlhlZ2RuamVSbm01ZG5qZW1uRXVwb1dlYWI0ZU0yUVVSTlFVZHgwZXlOUTNkS0prRVk4dW0yMTVNM0tqY05zZk0zazltVVBGZFlpZnlOQmdCenU2QjJRME9YUlNDaDV1eTNpMG1VU2VhaFBxYzNHZk1xazltVVBGZFlpZnlOQmdCenU2QjJRME9YUlNDaDVUeTNtMG1VU2VhaFBxYzJFaHlOS0lCYjBxZFg0ZWsyOUZCTkhxY1pncUJva3VtMkVoYU41c3lsVnFPQVRlazI5RkJOSHFjWmdxQm9rdW0yRWhhcVF6Qm9kcU9BVGVrMjlGQk5IcWNaZ3FCb2t1bTJFaGFxRzNtVVNnY1VQU1J2c2dNVVBJcmhHekJvbTJCb2RlYWI0ZU0yUTBrb0UwTU5IaFJvRUhPS0prRVk4NmNTS1ZRS210RVFtQWJWOVlFQVRlb0tHWWJ6dTZFUW1BYlY5WUVROUtsWWlLVktFbWIwNGdjVVBTUnZzZ01VUElyaEd6Qm9tMkJvZGVhYjRlQm9zSENVZWhNMlEwZHY1c3lsUXpkblEwQlplaE9iamVtbkV1cG9XZWFiNGVNbm1IZHgwZWsyOUZCTkhxY1pncUJva3VtMkVoYXFFc0NOSkhNbm1IbVVTN2RuMGVDMkswQzJldW9LR1liMFE0QzJRVFJ2SGZ5aFBTQkFTZXdVR0h3dkgwT1hFSGRYMCtkdlJIUlkxSE0zaXNCMlZ1T0FTN2RuMGV0QUdUUmxtanBsV2VCcVFGQzNFZ3kyNGVNM0tqT1hFSlJsUVV3QVNld1VHME1xU2V3VVBTYmw5U0JsVGVyQVBTUnZzZ01VUElyaEd6Qm9tMkJvZGVhYjRlTW5tSE12S1VCQWVTTW9RSE1xU2djVVBTYmw5U0JsVGVhYjRlQm9zSEMzUTBCQWVnY1VQU3lROVNDb0VzZHgwZW1ZMWZCdlFqZFgwK2R2QkhSdml1a2xKak9LSmtFWTg2Y1NCS1FZaWRvMEtiVjA5eE9iamVNTlEwUm9tRmRYRUlvMkVzUnZZN2RuMGVDMkswQzJldW9LR1liMFE0QzJRVFJ2SGZ5aFBTQkFTZXdVR0h3dkgwT1hFSGRYMCtkdlJIUlkxSE0zaXNCMlZ1T0FTN2RuMGV0QUdUUmxtanBsV2VCcVFGQzNFZ3kyNGVwbDV6Qm9tME9YRTBDbG1qQkFUZW12S1VNTks1YVhFZ00xOWpDb2kwQWw1ekJvbTBBbGs5RVNLV1YwVmdkbmplUm5tNWRuamVtdkhGUnY4ZXJBUGhkWmplbW5Cc3lYUDlkdktVTU5LNU9YUzdkWEVneXFpSE1xRXR5cVFJZHgwZVd4amVtdmlVQmxLMEJROUlCb0V1eTJrZXJBUHFtemplQk45VUJsS1pwWFB1bXZLVU1OSzVkdkt6ZFhFREJvU2VyYjRlbW5Cc3luUUhPQUc3ZFhFZ3lxRWZkWDQ5ZFhtN212SUh3bzBqZFpqZW1uQnN5S0lSZHgwZW1uQnN5blFIY1VQU3BsNXpCb20wbzI1MXlBakRjVUc5ZHZCZk1oUHVtdlNlckFQVGNVUFNwQVA4ZFhFZ3lxaUhNcUV0eXFRSWNVUFNwQWpET0FHN2RYRVpNTlFzUnZRdHlsUTBwdjlTZFg0OWRYTS9hWE03ZG4wZW12aVVCbEswQlE5SUJvRXV5MmtlckFHVVJubWd5QWVTQzNtSENvRUhvMjFIUnZzZkJYVGVkaFRoT2JqZW12SEZSdjhlckFHVVJubWd5QWVTcGw1MHlVVGVkaFRoT2JqZW1ZMWZCdlFqZHgwZW1uRXVwb1dlYWI0ZU0yUVVSTlFVZFgwK2RuR1VCb0dzTU5WdWROSEZNMlFVUlhHZ3lxRWZkbmpTUnZzZ01VUElyaEdUTU5ROXdVRTBDbG1qQm8wZU9ualNwbDUweTMwZ2RuQnN5blFITVVQdXdVRVpNTlFzUnZRdHlsUTBwdjlTdEFTaE9iamVtdlE0QkFQOWRYRWl5MkVIeVhQSXJoR0h3dlFaUm9FSE9YRTJDbFRnY1VHZ0JoUHVkQUVnTTE5akNvaTBBbDV6Qm9tMEFsa2dkbmplTU5RMFJvbUZkWEVId3ZWN2RuMGVCbEp6QkFHN2RYRUlCb0V1eTJFdHBsa2VyQVBTUnZzZ01VUElyaEd6Qm9tMkJvZGVhYjRleXZLelJZSEZNMlFVUllIU09YUzdkbm1IUm5RVXloUFN5bFEwcHY5U28ySFNjVUc5ZG4wZUMySzBDMmVlT0tKa0VZOUt3dmlITW5FZ3kyNGVtdlZnZG5qZUJvc2dSWGVTQkFQSXJoR3FCb0VpQm9pekNsUkhPWFNnY1VHOWRuMGVNblFoeXZIWmR2QjF5TmkwcGw5RmRuaUh5dlFaUlhlU1J2S2h5dlZqbW5SdUJvbUhkeDBlbVVNamRYRUx5MkhGZHgwZW1VTWpkWEVTQm9pWmR4MGVtVU1qZFhFanBsMWdSWFA5ZFhNcWFYRU5wbFFqQlhQOWRYTXFPb2plUm5tNWRuamVtdkhOUjJzSE1OVmVyQVBxbXpqZW12OVVCdlFVZHgwZW1VTTdkWEVTQm9pWm8ySmd5bEgwZHgwZW1VTTdkdkhOZFhlc2R2UUlNbkU1T1hFM3B2UVVCQVNnZG5qZW12SE5SMnNITU5WZXJBUGhSMnNITU5WZXdVRTNwdlFVQm8waGNVRzlkdkhOZFhlc2R2UUlNbkU1T1hFU0JvaVpPQVNld1VQU3kzbVNCb2RlckFQaHkzbVNCb2RlQ3FTZXdVRVNCb2ladEFHU0JvaVpkWmpldEFHZ0JoUHVkQUdIeW9HMHdBZVN5dkhJcG9rZ09BRzdkWEVTQm9pWm8ySmd5bEgwZHgwZWROSmd5bEgwZG5qU3l2SElwb0U5ZFpqZXRBR0h5b0cwd0FlU0JOSEh5dmtnZHg4ZW12QmdCbEpTZHgwZWRodWhkeHVlRVNLV1YwVjdkWEV6TWxUZXJBUGhWMFFXRVZpVmRualNCTkhIeXZFOWRZQkFiMDBld1VFMHB2SHpkWDArZG5HVUJvMTdtbkVzQ05KSHRBRzdtdmdmcGw1OWRualNwbEIzcHZRVUJvMGV3VUVmTU5FSE1xMGV3VUVTQm9pWm8ySmd5bEgwdEFkN2RYRXpNbFRlckFHelJubXRNTlFUeXZLWkJBZXFNbm1Ib1VNam1uRXVwb1dlYWI0ZU1ubUhhWFBTTTNLak9iamVtWTFmQnZRamR4MGVtbkV1cG9XSXJxaUhNcUJITWgwK01ubUhNdktVQkFlU00zS2pPYmplbVkxZkJ2UWphYjVId3ZRWlJvRUhPWFM3ZFhFSW8yRXNSdlllckFQU2JsOVNCbFRJck5CSFJ2aXVrbEpqT0tKa0VZODZjU0JLUVlpZG8wS2JWMDl4T2JqZU1OUTBSb21GZFhFSW8yRXNSdlk3ZG4wZUMySzBDMmVlT0tKa0VZOUt3dmlITW5FZ3kyNGVtdlZnZG5qZUJvc2dSWGVTQkFQSXJoR3FCb0VpQm9pekNsUkhPWFNnY1VHOWRuMGVNblFoeXZIWmR2QjF5TmkwcGw5RmRuUVRCdkswQkFlU1J2S2h5dlZqbXZLVU1OSzVhWFBTUjJzSE1OVmVyQVBxbVVIN2RuRVV3QUc3ZFhFU0NvRXNkeDBlZGhkN2RYRTFNdkVzUnZRdEJ2SzBDQVA5ZHZLVU1OSzVPWFM3ZFhFZ0JxUnVCb21IZHgwZW1VTTdkdkJmTU5Rc0MyZWVPWEVzTXFtc3dBR3NNVVBTcDJRNWR4MCtkWEUyQ2xKMUJBU2V3VVBTQnZLMENBUEZyQVBod1VFREJvSDlyYjhqZFpqZW1uUVRCdkswQlE5U0NvRXNsMTBlckFQU1JOS2pSbFY3ZG4wZW12RXNSdlllckFHVVJubWd5QWVTQnZLMENBVGVkaFRoT2JqZXBsQ2VPWFllQmwxVFJuU3VtblJ1Qm9tSE9BU2V3VVBTcGxCM3B2UVVCQVA5ZFhtM3B2UVVCQUc3bW5SdUJvbUh0QWQ3ZG4wZW1ZMWZCdlFqZHgwZW1uRXVwb1dJcnFpSE1xQkhNaDArTW5tSE12S1VCQWVoUm9HU0NvRUhkbmpTUnZzZ01VUElyaEdUTU5ROXdVRTBDbG1qQm8wZU0yUTBkbmpTQnZLMENvMGV3VUVnQnFSdUJvbUh0QWRnY1VQU0Jvc0hkeDBlbVkxZkJ2UWphYjVId3ZRWlJvRUhPWEUxTXZFc1J2UXRCdkswQ0FTN2RubUhSblFVeWhQU0Jvc0hjVUc5ZHZpc1J2aXVkWHNNVllFckVvc1pCb0cwcGw5RmRYRUhPQUc3ZHZRNHBva3VtdlZlYWI0ZUIyUTBibFF6TTJLcUJBZWdPYmpldEFHOWRuRzFDTkpnQ1VHTlJsNVpSdkhmeWhHU0JsSkhSdlZ1bW5Fc0NOSkhhWEUzcHZRVUJBUDlkWE1xT29qZVJubTVkbmplcGxDZU9YWWVCbDFUUm5TdW1uUnVCb21IT0FTZXdVUFNwbEIzcHZRVUJBUDlkWG0zcHZRVUJBRzdtblJ1Qm9tSHRBZDdkbjBlbVkxZkJ2UWpkeDBlbW5FdXBvV0lycWlITXFCSE1oMCtNbm1ITXZLVUJBZWhFWVFXRVFFS2RZQkFiMDBld1VFMHB2SHpkWDArZG5HVUJvMTdtbkVzQ05KSHRBRzdtdkhOUjJzSE1OUTlkaFM3ZFhFU0JsVGVyQVBTYmw5U0JsVElyTlE0QmxpMVJ2VnVPYmplTU5RMFJvbUZkWEVTQmxUN2RuMGVDMkswQzJlZU9LSmtFWTlLd3ZpSE1uRWd5MjRlbXZWZ2RuamVCb3NnUlhlU0JBUElyaEdxQm9FaUJvaXpDbFJIT1hTZ2NVRzlkbjBlTW5RaHl2SFpkdkIxeU5pMHBsOUZkdjlUQmw1Vk1OS0ZNMktaUnZIZnloZWd3VVBTUnZzZ01VMCtNMlFVUk5RVWFiNWhCbFJneUhFVUNsNXpDbGkwcGw5Rk9YUzdkbjBlTW5RaHl2SFpkdkIxeU5pMHBsOUZkdmlmeWwxZ1JYZWd3VVBTUnZzZ01VMCtNMlFVUk5RVWFiNVp5MjFJcG9rdU9iamV0QUdUUmxtanBsV2VCcVFGQzNFZ3kyNGVNTjlqeVltc0MyanVPb2plbW5FdXBvV0lycWlITXFCSE1oMCtNTjlqeVltc0MyanVPYmpldEFHVFJsbWpwbFdlQnFRRkMzRWd5MjRlbzE5U0JvaTBNcVFaUlhlZ2RuamVtbkV1cG9XZWFiNGVNMlFVUk5RVWR4MGV5cVFqeXhqZXRBRzlkeDgrIjtldmFsKCc/PicuJE8wME8wTygkTzBPTzAwKCRPTzBPMDAoJE8wTzAwMCwkT08wMDAwKjIpLCRPTzBPMDAoJE8wTzAwMCwkT08wMDAwLCRPTzAwMDApLCRPTzBPMDAoJE8wTzAwMCwwLCRPTzAwMDApKSkpOw=="));
?>
我们就从手动解混淆、debug解混淆、写脚本解混淆三个方向去说
0x01 手动解混淆
首先将代码中的eval
替换成echo
,并且执行 php 文件
然后把执行输出的代码复制替换掉前面整个echo
语句,即如下
接着重复工作,继续把下面的eval
函数替换成echo
输出
接着继续执行,重复如此,最终成功还原成原来的代码
0x02 debug解混淆
这里我使用的是 vscode + Xdebug + PHP Debug(vscode插件)
首先格式化一下代码,并且打上断点,选择单文件调试,即Launch currently open script
然后 F5 启动调试,接着 F11 走单步调试
可以看到变量不断的被赋值,接着一直按 F11 单步调试,最后跟完得到还原后的代码
0x03 编写脚本
这里我们看一道 bugku平台 上的题:《getshell》
代码如下
<?php
define('pfkzYUelxEGmVcdDNLTjXCSIgMBKOuHAFyRtaboqwJiQWvsZrPhn', __FILE__);
$cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ = urldecode("n1zb/ma5\vt0i28-pxuqy*6lrkdg9_ehcswo4+f37j");
$BwltqOYbHaQkRPNoxcfnFmzsIjhdMDAWUeKGgviVrJZpLuXETSyC = $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{3} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{6} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{33} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{30};
$hYXlTgBqWApObxJvejPRSdHGQnauDisfENIFyocrkULwmKMCtVzZ = $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{33} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{10} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{24} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{10} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{24};
$vNwTOsKPEAlLciJDBhWtRSHXempIrjyQUuGoaknYCdFzqZMxfbgV = $hYXlTgBqWApObxJvejPRSdHGQnauDisfENIFyocrkULwmKMCtVzZ{0} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{18} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{3} . $hYXlTgBqWApObxJvejPRSdHGQnauDisfENIFyocrkULwmKMCtVzZ{0} . $hYXlTgBqWApObxJvejPRSdHGQnauDisfENIFyocrkULwmKMCtVzZ{1} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{24};
$ciMfTXpPoJHzZBxLOvngjQCbdIGkYlVNSumFrAUeWasKyEtwhDqR = $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{7} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{13};
$BwltqOYbHaQkRPNoxcfnFmzsIjhdMDAWUeKGgviVrJZpLuXETSyC.= $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{22} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{36} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{29} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{26} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{30} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{32} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{35} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{26} . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ{30};
eval($BwltqOYbHaQkRPNoxcfnFmzsIjhdMDAWUeKGgviVrJZpLuXETSyC("JE52aXV5d0NlUFdFR2xhY0FtZmpyZ0JNVFlYekhacEl4RHFRbnNVS2tob3RGU09SZFZKTGI9IldBckllVEJFWFBaTlN0b3ppZ2hmcENPUlV2S0x5eFFubXdsR2NqYVZiRGtGdUpZZHNNSHF1d1dBZW1NVWhRb0NMYURma0Z4VEtsenRCWHJkT2liSEpqeU52WVNQcGNzSVpFR1JnblZxUWM5alNWd0ZvTlBKU3U1eXJsUjZTMkNzcHV5TlBJb3JMSUk1dnU5RFJVYU9wSHhmbVZSSmIwdGpQQnlvU3lFSXVzRUNQMmlidVU5MlJCNUhCMkV4b0JJVkVPaWpvSmE2dVBQeXBWeEl0MjF1RzJ0VW1zaUJTeXhjQjB5SG1CRWRtM1BBYkJvNUJIdHhHSjlpUjBLS0JQUjJ2MUtPQk54WnJtZ3NieW96R3NDWVNKOWlHdTUxdnlJeVNVeUh0QjlhbVVSU21QUDZlUHQ0QlZDMFMzUk1SSm9qQjBhTHVOaXJTdXRodFVvb0xjMTF2Smlzb3VDWG9OQkRBa0IydG1VeUMwVXlDWUF5bnNHeUNzYnlDWVUxRW1QY0VtdjJFbXYwbmxCMnptQTRFbUVVRW12akVtdjRFbXYxRW12aUVtdjVFbUVNQ2tCMmJPQjNua0IyYmtCMkNsQjJDZnN5Q0JHeUNZQnlDWUZ5Q1lueUNmbnlDZnZ5Q3NHMEVtRWxFbUcybmZ2eUNzVWtybWdzR2h5enZ1NXlwM0VVTFZ4TmJ5QzNHMGFEbU5LckJWdFFTQkNKdUJJSHVIb2twSXhQQnl0aFBKMWp0QjF0dDJhNkx1dGZSbTBzYnlvekdzQ1lTSjlpR3U1MXZ5SXlTVXlIdEI5YW1VUlNtUFA2ZVB0NEJWQzBTM1JNUkpvakIwYUx1TmlyU3V0aHRVb29MVmdmVEw0c2J5b3pHc0NZU0o5aUd1NTF2eUl5U1V5SHRCOWFtVVJTbVBQNmVQdDRCVkMwUzNSTVJKb2pCMGFMdU5pclN1dGh0VW9vTFZnMlRMNHNieW96R3NDWVNKOWlHdTUxdnlJeVNVeUh0QjlhbVVSU21QUDZlUHQ0QlZDMFMzUk1SSm9qQjBhTHVOaXJTdXRodFVvb0xWZ2ZuMzBaRVVFdW1KRWNHMktYdnVJWlJoRXRvdXhFbzBQUXBCaVZ1czFQZUh5QmVJTWZSTmEzYmhvSnZJQ2RCeXhnTEp5c1AwdE51Qng3bmZNOXpPdG90MUtBUkp5amIzUDZtMW9pdnlSQkJCb2dvSHlsTGh0YnYyeGtHM3h5THMxZEdCUEdwMjEzQkpSWlB1YW1vVUlubXN0cVFMdGxQczVrYjJDcXAzSXhwSFBPQnVQREx1UkltMjFudDFLQ1BoSzVQVnhidjN0V1IwSTJvSE1tTDFFR3BVS0tvSVJVdHl5QWVmbmZUTDRzYnlvekdzQ1lTSjlpR3U1MXZ5SXlTVXlIdEI5YW1VUlNtUFA2ZVB0NEJWQzBTM1JNUkpvakIwYUx1TmlyU3V0aHRVb29MVmdpblYwWkVVRXVtSkVjRzJLWHZ1SVpSaEV0b3V4RW8wUFFwQmlWdXMxUGVIeUJlSU1mUk5hM2Job0p2SUNkQnl4Z0xKeXNQMHROdUJ4N25ZdDlka3RsUHM1a2IyQ3FwM0l4cEhQT0J1UERMdVJJbTIxbnQxS0NQaEs1UFZ4YnYzdFdSMEkyb0hNbUwxRUdwVUtLb0lSVXR5eUFlZlVqVEw0c2J5b3pHc0NZU0o5aUd1NTF2eUl5U1V5SHRCOWFtVVJTbVBQNmVQdDRCVkMwUzNSTVJKb2pCMGFMdU5pclN1dGh0VW9vTFZnT0NWMDdFSXRzdlUxclMyeEd0aElTbUpDYkdoeGtlQmFodDNLdVJOUEhCdTVPdUJpUXRKeTFTc3RjcEJ4THBWUk1iSjlQTGhvbXYyRzlFSXlWdXN4MlNoTWNSaEtRUEhJT1AxdHR0SmlKZUJFRVJJTWZTTkVZZU5Qcm1CYXh0UHhYcGhSTG8yNVBTMUNzYkJpenROSzduVjBaRVVFdW1KRWNHMktYdnVJWlJoRXRvdXhFbzBQUXBCaVZ1czFQZUh5QmVJTWZSTmEzYmhvSnZJQ2RCeXhnTEp5c1AwdE51Qng3bm14OWRrdGxQczVrYjJDcXAzSXhwSFBPQnVQREx1UkltMjFudDFLQ1BoSzVQVnhidjN0V1IwSTJvSE1tTDFFR3BVS0tvSVJVdHl5QWVmQzlka3RvdDFLQVJKeWpiM1A2bTFvaXZ5UkJCQm9nb0h5bExodGJ2MnhrRzN4eUxzMWRHQlBHcDIxM0JKUlpQdWFtb1VJbm1zdHFlZk05ZGt0b3QxS0FSSnlqYjNQNm0xb2l2eVJCQkJvZ29IeWxMaHRidjJ4a0czeHlMczFkR0JQR3AyMTNCSlJaUHVhbW9VSW5tc3RxZWZJOWRrdGxQczVrYjJDcXAzSXhwSFBPQnVQREx1UkltMjFudDFLQ1BoSzVQVnhidjN0V1IwSTJvSE1tTDFFR3BVS0tvSVJVdHl5QWVmQTBUbWdzdjNLeUcyMW9SdUlPcFZ4TlBCeWhldTlrUk5vWm1VNXJCUHRjdFZvYlMxb210MHhIdFBLS3VOeFFtQmEzdlVFc2J1S2lCWTBzYnlvekdzQ1lTSjlpR3U1MXZ5SXlTVXlIdEI5YW1VUlNtUFA2ZVB0NEJWQzBTM1JNUkpvakIwYUx1TmlyU3V0aHRVb29MVmczVEw0c2J5b3pHc0NZU0o5aUd1NTF2eUl5U1V5SHRCOWFtVVJTbVBQNmVQdDRCVkMwUzNSTVJKb2pCMGFMdU5pclN1dGh0VW9vTFZnaW4zMDdFTkk1bUhJWm91OU90VXg0dHNFbVIyQ2RTVWlxTHlNMG0yeWNveXlNbzFLMkdKaUdQUEVCUDFvYXZVUENCQlJXZXN5c3YzQlpRTHRsUHM1a2IyQ3FwM0l4cEhQT0J1UERMdVJJbTIxbnQxS0NQaEs1UFZ4YnYzdFdSMEkyb0hNbUwxRUdwVUtLb0lSVXR5eUFlZkFPVEw0c2J5b3pHc0NZU0o5aUd1NTF2eUl5U1V5SHRCOWFtVVJTbVBQNmVQdDRCVkMwUzNSTVJKb2pCMGFMdU5pclN1dGh0VW9vTFZnZkNIMFpFVUV1bUpFY0cyS1h2dUlaUmhFdG91eEVvMFBRcEJpVnVzMVBlSHlCZUlNZlJOYTNiaG9KdklDZEJ5eGdMSnlzUDB0TnVCeDduWXk5ZGt0bFBzNWtiMkNxcDNJeHBIUE9CdVBETHVSSW0yMW50MUtDUGhLNVBWeGJ2M3RXUjBJMm9ITW1MMUVHcFVLS29JUlV0eXlBZWZBMlRMNHNieW96R3NDWVNKOWlHdTUxdnlJeVNVeUh0QjlhbVVSU21QUDZlUHQ0QlZDMFMzUk1SSm9qQjBhTHVOaXJTdXRodFVvb0xWZ2ZuVjBaRVVFdW1KRWNHMktYdnVJWlJoRXRvdXhFbzBQUXBCaVZ1czFQZUh5QmVJTWZSTmEzYmhvSnZJQ2RCeXhnTEp5c1AwdE51Qng3bmZFOWRrdGxQczVrYjJDcXAzSXhwSFBPQnVQREx1UkltMjFudDFLQ1BoSzVQVnhidjN0V1IwSTJvSE1tTDFFR3BVS0tvSVJVdHl5QWVmbjFUTDRzYnlvekdzQ1lTSjlpR3U1MXZ5SXlTVXlIdEI5YW1VUlNtUFA2ZVB0NEJWQzBTM1JNUkpvakIwYUx1TmlyU3V0aHRVb29MVmdPQ0gwWkVVRXVtSkVjRzJLWHZ1SVpSaEV0b3V4RW8wUFFwQmlWdXMxUGVIeUJlSU1mUk5hM2Job0p2SUNkQnl4Z0xKeXNQMHROdUJ4N25mTTl6MlAyR3VqREVOSTVtSElab3U5T3RVeDR0c0VtUjJDZFNVaXFMeU0wbTJ5Y295eU1vMUsyR0ppR1BQRUJQMW9hdlVQQ0JCUldlc3lzdjNCREFzS0l1czl4TElLeEJZTWpweW9ndHlva3VWTTVHMFI0dlBLR3RIRUJudWl6UG1NZ1NQb0FCSG9ZblZ0Q0J1NURCMUdPdHN5eFBCNXFCeVBMblBLTlNVRXNuQkExdUowMHpCeWd2VlB5cHlLNUJzUnVleUNocFU1a1BCb2RQQlB6bklvWmJ5eXNuQjVMQllFTnYxb1BlTjl1bll5V29QUnp0MUV1Qll0U251aml1dWlyYjFDSVJJTXhuY1BpdUo1TmV5eXVMc2F5UEppNFBjTTBTeW9HTEh0dW5VR09Hc1JycHlLV25QSUxTMngyb2NDTHAySWd1SmF4UHlFckcwb0RiMUVoQ1BFaHBITUJQVXh1TE5Vam1zUFNQbUIwQlBvV0NQdGh6bUlrUGZQbFB1S3R6QnlxUk5pc3BCb2ZMMENZZDFNS0czUHJ0MEcxUE41TlJQS2h6aHlMdHVGMEJKYXJQTmJPbXNpeHRoeGlCMmlsbkliT3BVdFNwTmlsdVlJam55eWFlSXl1UHNLUFBZSVNSTkNJUHM1UFB1dE9vdWFnUzJuZlB1OXJ0SmlBUDJhRG5KSUdic3RzdVZNYlBKNU5lUEdpQnlFTHBoeGFvUFByTEp0TmJIS3h0MEtxb0JSdUwxdFBSTnhMUEp4Mkd5eHNCMURPQ1BveG5CNVdCUFA0bTFFVnAyOXJ0eUVXRzBCaUwyVU9TSXlMdVVveFBOMXpCUHlHU055eVBodEdCWUNqUDJ0VlBKNVBQZlA1UDFQNEJJRWFwY0l4UzFFVUd5UERCMkVBb1VFdHBteXVCMXhTUE5uT3V1OXJ0UEtRR0J4U0dQQWp2TjV1cFVvdUd5eGpldUNWZVZJU3VVb09QY0lnbXlCanBOeXVMSUUyR2ZNMG1QSVpTSUN1bnNvRUdQUHpTeUVQQllJU3RKeGxvY0lsQ1BLYUNWQ3JMVTQydXlSelJJUkdQSnhZcGhGMEJKaXVMeUdmcFZvb3B5RWFHSmE0bTFDZ3R5UHRuSUFPUEJSMFAxQmpvVXlTbklveEdQb0RwMWJqbkJpc24wRWN1c1BOdnVDdUxoSUNTdWFmTHNvTFMyQ0luQmF4bkp4b0J5eE5HUHRhbXlJb3VOeEtvUFAwdUlBZnZJUnN0MW9aUFB2MWVQUlBlSU1McHVqaUd1YUx0TkVQU0lDa0xOdGxCdTA1UHlDR3V5dFlueXlYTHNQU20ySUF1SklMblZNWlBKaU5QSkVHdlZ5WXQzeGl1eXhOdnliaXBVNVBuTmlLUHN4TFJKbmpSVTF0cEp4bVBZRU5MdUlQbUpLTFBQQWl1c29EYkpiaWJZUFNwbXRmTHN4ekN5S2htSHRodUlvREcyMTRDSUVnUHNLdW4yaTJ1dTVMcHVFV2VVOW1wVW9QQm1NTG55UFZSSVJQbk50RXVZTXVHdUl1U045Qm5jSW5vY0NsYjFLSXRISVlQc3lmTHN4ekN5S2htSHRodUlvREcyMTRDSUVnUHNLdW4yaTJ1dTVMcHVFV2VVOW1wVW9QQm1NTG55UFZSSVJQbk50RXVZTXVHdUl1U045Qm5jSW5vY0NsYjFLSXRISVlQc3lqbVVDTFBQS0FiczVtcGh0WFAwUHVlSVJXQ3VLUHQwRzB1dTVnbUlHam9jb3VweUVndVlJTlJ1Q2dwVTFCbklLam9JUmp0UFVPbkJ5UHBoRmZCUFByUnlvUHBjRVBuMDVhTDBDTHQxdGFTY0VoUzJ0ZHVZSVNCeW9obm1vWXBzRWZHdTF1ZU5VanpQS0JQczVydXVpTG5OQWZtc2lCdEJEMFB1aXNTSUNWcFV0b25Jb0lvSVJMdVBJR29JSXlQMUsxbVV0TXYwS0FtWW9TUDA1MFAxeHVTTkNhZWN0THBJb3JQWUNnUnl5WkJKMWtTM3hRQjJpTlBQVWpCWUVQdDN0aFBtTXNMUERqUEpJeFBKeFhQY3dpbU5iZmJzQ1N0Qm9pRzFvRXZVYW1TM01RUmYwOUFrc0t6ZjgrUWM5alNWd0ZvTlBKU3U1eXJsUlpTeW81djBFU1JIeE9tTmFOdXV0enAyb1lvMFIxR2hSVUxKRWd2VTltQkJQQUJ5UGFMMnlNU1ZLRWIyUDBCVTFpdUlSQkVPaWpvSmE2dVBQeXBWeEl0MjF1RzJ0VW1zaUJTeXhjQjB5SG1CRWRtM1BBYkJvNUJIdHhHSjlpUjBLS0JQUjJ2MUtPQk54WnJtZ3NtMmladE5hNm1KUGlSSktkcFB5RG1CRUVCM3hyYjNQU295SUxSMGloTFVSTnYzdFBHMElYdUlvNXZKRUt0UHRiR3V0SHZjMTF2Smlzb3VDWG9OQkRBa0IydG1VeUMwVXlDWUF5bnNHeUNzYnlDWVUxRW1QY0VtdjJFbXYwbmxCMnptQTRFbUVVRW12akVtdjRFbXYxRW12aUVtdjVFbUVNQ2tCMmJPQjNua0IyYmtCMkNsQjJDZnN5Q0JHeUNZQnlDWUZ5Q1lueUNmbnlDZnZ5Q3NHMEVtRWxFbUcybmZ2eUNzVWtybWdzTE5FR29WdFZQdWF5dEJ0Z0JKUmpSM0N4dkpvWlB5eVhQSUNkTHVDYlJKeGNQMktsU2hLdG1JSzR0czExZXUxTW1ISXJtZjBzbTJpWnROYTZtSlBpUkpLZHBQeURtQkVFQjN4cmIzUFNveUlMUjBpaExVUk52M3RQRzBJWHVJbzV2SkVLdFB0Ykd1dEh2VmdmVEw0c20yaVp0TmE2bUpQaVJKS2RwUHlEbUJFRUIzeHJiM1BTb3lJTFIwaWhMVVJOdjN0UEcwSVh1SW81dkpFS3RQdGJHdXRIdlZnMlRMNHNtMmladE5hNm1KUGlSSktkcFB5RG1CRUVCM3hyYjNQU295SUxSMGloTFVSTnYzdFBHMElYdUlvNXZKRUt0UHRiR3V0SHZWZ2ZuMzBaRVU5Z3BzdFdlczV5dmhvcUwyMW9TVTFsTFBDNExzQzF1Sm90QkhSblAweFZ0SEMwUHVDTXAxeHVlaEVrU0JQQkJOSXNvM003bmZNOXpPdEVwMkN5YjI1aVBzYVF0SmFPcElFcVBQTUlvVTVEYmhQbW1CS2xlSjFWUnl0bmVodEt2MlJqdXl5a0JQeEFvc3QzUDN4eFFMdFFwTjVVUzNLem9oSTJTc2FhdXV4Q2JzeW1lVUtjUlBLSkJQRTNtSVJBdDBvZlJJUFlidTlHUEh5T0dKeUlQSU14b05SamVmbmZUTDRzbTJpWnROYTZtSlBpUkpLZHBQeURtQkVFQjN4cmIzUFNveUlMUjBpaExVUk52M3RQRzBJWHVJbzV2SkVLdFB0Ykd1dEh2VmdpblYwWkVVOWdwc3RXZXM1eXZob3FMMjFvU1UxbExQQzRMc0MxdUpvdEJIUm5QMHhWdEhDMFB1Q01wMXh1ZWhFa1NCUEJCTklzbzNNN25ZdDlka3RRcE41VVMzS3pvaEkyU3NhYXV1eENic3ltZVVLY1JQS0pCUEUzbUlSQXQwb2ZSSVBZYnU5R1BIeU9HSnlJUElNeG9OUmplZlVqVEw0c20yaVp0TmE2bUpQaVJKS2RwUHlEbUJFRUIzeHJiM1BTb3lJTFIwaWhMVVJOdjN0UEcwSVh1SW81dkpFS3RQdGJHdXRIdlZnT0NWMDdFVXRZR0h5Ym1ITW9CMGExdEJDMm91YUVQeUtnbTFJTlBVMTNvMXhLcHNJSkd1OUFvVktpU1VSaEJIRW52MjFyYkpLUFJWRjlFVXlYRzJQY3BISXVMMDlOUzNFZ0JKS1BCVVBzbUp4TVJQQ0NMc0U2cEJSMlBVaTVSTnlmbzNNU3V1RXR1VXhKdFZSaGVOSTduVjBaRVU5Z3BzdFdlczV5dmhvcUwyMW9TVTFsTFBDNExzQzF1Sm90QkhSblAweFZ0SEMwUHVDTXAxeHVlaEVrU0JQQkJOSXNvM003bm14OWRrdFFwTjVVUzNLem9oSTJTc2FhdXV4Q2JzeW1lVUtjUlBLSkJQRTNtSVJBdDBvZlJJUFlidTlHUEh5T0dKeUlQSU14b05SamVmQzlka3RFcDJDeWIyNWlQc2FRdEphT3BJRXFQUE1Jb1U1RGJoUG1tQktsZUoxVlJ5dG5laHRLdjJSanV5eWtCUHhBb3N0M1AzeHhlZk05ZGt0RXAyQ3liMjVpUHNhUXRKYU9wSUVxUFBNSW9VNURiaFBtbUJLbGVKMVZSeXRuZWh0S3YyUmp1eXlrQlB4QW9zdDNQM3h4ZWZJOWRrdFFwTjVVUzNLem9oSTJTc2FhdXV4Q2JzeW1lVUtjUlBLSkJQRTNtSVJBdDBvZlJJUFlidTlHUEh5T0dKeUlQSU14b05SamVmQTBUbWdzUzJDM0wyRW1vMnhoU2hLb3RoUE10MHRRUFVveExJeHRCSHRabVZ5bHBVS2piMHlhb3VLZnZzNTJ1SEliUFBvNG9zMXNwZjBzbTJpWnROYTZtSlBpUkpLZHBQeURtQkVFQjN4cmIzUFNveUlMUjBpaExVUk52M3RQRzBJWHVJbzV2SkVLdFB0Ykd1dEh2VmczVEw0c20yaVp0TmE2bUpQaVJKS2RwUHlEbUJFRUIzeHJiM1BTb3lJTFIwaWhMVVJOdjN0UEcwSVh1SW81dkpFS3RQdGJHdXRIdlZnaW4zMDdFVXhrdU50MHQxUFdvQlBVcElFSHZWUmZHaEVKcHlvb3AxdG1MMHlZQlZvRGIxUnFiSnk2QkJpU2VVb0NSaHlhYkI1aUxzOFpRTHRRcE41VVMzS3pvaEkyU3NhYXV1eENic3ltZVVLY1JQS0pCUEUzbUlSQXQwb2ZSSVBZYnU5R1BIeU9HSnlJUElNeG9OUmplZkFPVEw0c20yaVp0TmE2bUpQaVJKS2RwUHlEbUJFRUIzeHJiM1BTb3lJTFIwaWhMVVJOdjN0UEcwSVh1SW81dkpFS3RQdGJHdXRIdlZnZkNIMFpFVTlncHN0V2VzNXl2aG9xTDIxb1NVMWxMUEM0THNDMXVKb3RCSFJuUDB4VnRIQzBQdUNNcDF4dWVoRWtTQlBCQk5Jc28zTTduWXk5ZGt0UXBONVVTM0t6b2hJMlNzYWF1dXhDYnN5bWVVS2NSUEtKQlBFM21JUkF0MG9mUklQWWJ1OUdQSHlPR0p5SVBJTXhvTlJqZWZBMlRMNHNtMmladE5hNm1KUGlSSktkcFB5RG1CRUVCM3hyYjNQU295SUxSMGloTFVSTnYzdFBHMElYdUlvNXZKRUt0UHRiR3V0SHZWZ2ZuVjBaRVU5Z3BzdFdlczV5dmhvcUwyMW9TVTFsTFBDNExzQzF1Sm90QkhSblAweFZ0SEMwUHVDTXAxeHVlaEVrU0JQQkJOSXNvM003bmZFOWRrdFFwTjVVUzNLem9oSTJTc2FhdXV4Q2JzeW1lVUtjUlBLSkJQRTNtSVJBdDBvZlJJUFlidTlHUEh5T0dKeUlQSU14b05SamVmbjFUTDRzbTJpWnROYTZtSlBpUkpLZHBQeURtQkVFQjN4cmIzUFNveUlMUjBpaExVUk52M3RQRzBJWHVJbzV2SkVLdFB0Ykd1dEh2VmdPQ0gwWkVVOWdwc3RXZXM1eXZob3FMMjFvU1UxbExQQzRMc0MxdUpvdEJIUm5QMHhWdEhDMFB1Q01wMXh1ZWhFa1NCUEJCTklzbzNNN25mTTl6MlAyR3VqREVVeGt1TnQwdDFQV29CUFVwSUVIdlZSZkdoRUpweW9vcDF0bUwweVlCVm9EYjFScWJKeTZCQmlTZVVvQ1JoeWFiQjVpTHM4REFzS0lTTjFzUHM1WlBJUHJCTlBWU1Zvc3BzRGpHSjBpdUpQYVJJb0xuSUtOUDI1enZJRU5TY1BtUzJpZnV1YTB0SUdPdlZSdVMzeHRQc3hzU0pDaFBKeEJTMG9tdXNvSXpCeWdvY010bjJ4NkcxUHVuUHRJQ1BQUG5OdG1HbUlTcFBSV1JVeXhwSW9TUEJQZ1J5RE9DQkN4UFBLWEcyMXJDUGJpU054b25Vb2dHc3ZpbjJDSXZOYXlweUtMQnNCaXQxeWdMeUtrUzN4Z1BZQ3VMSW9JUlZLQnBWd09QY0NsU3lEalBIeXN0Snhjb0JQekJKRVZ2SVJTUzFBZlBtQWlDdUNQU1ZNeG5CRXpvdTFMTDF5UHBWb3RQMnh1UDBSSEN1UFp0SjV4UHV0bVBJUlNTMkNVTEoxa3Bzb1Z1UHhEU0lvcXBVNVlQUEtTUEJSemVzNVBlY0VQUHNFckJQb2xTMDFhUk41bXBJbzRtQnhsUjJDVlBtSWtuMEV6QllJTm0wMGZ1SjFvUFVFUXVtQ0xteVJHdklQQ1B1dFFQTjVycFBuZnVzUkN1SW80RzJpU0NOVWl2SUl4TFVBMVBOYU5QdVB1dVlNc1Nzb2x1c3ZpQ3MxVm1zRVluMXk1b1VQU0NKUEl2SVJRUEJvUG1QUHNlUEVxbXlJb3BKdDZQQlBnZU5QUG9OYW10VUt0R1lDWWVQeWF0Skt1dGZiNUx1SzBwTnRhdEhDZGIyblhCTnlZUkJLSVNOeWh0MUFqQllJdXZ5S1BQc1BrdHNLWkcweHNleXlHTEoxa3BJS1NHWUlMUEluanBOS1BMSUtYQm1Jc3ZQSWFwY29QUGh4eG9CUFNtSnRHcFZ0dFBtUDRCMmc0cDBLSXBWb29ueW9VR0o1TlAxbmp6QlJ4bjBLZlB1MWpQeVBJUEphQnB1eGxvSW96bXlDV0xZb2tQdWJPUHNQNEN1dFZwVktTbjBFeFAxUnJCeVJJU04xTExOdEdvQlJJcDBLSUJKS29wSml0UE41bHV5QmpSY0lMUEI0T3V5UjBMeW9ndlZDQm5Cb1ZQc0JpbjFEaVNWTWtTMG9hdVB2NUxQS0F2Vnh4dHV0R1B1NXJtdW5PbkJhdHBoTXVvVXhIcDBLSVNOMXNQczVaUElQckJOUFZTVm9zcHNEakdKMGl1SlBhUklvTG5JS05QMjV6dklFTlNjUG1TMmlmdXVhMHRJR092VlJ1UzN4dFBzeHNTSkNoUEp4QlMwb211c29JdjBLVlJOS3NuVnRLUG1Fc3AxR09wY29oUFBHaUJQUHN0UGJpQnNSb1B1eG9QUG9ybk5FV2VjUHRwaHhkRzBQekxKRWhQSElZbjBLUW9OaWplSVBOUHlSeXQxS3p1c3Y0dkIxS1MzQ3J0UEVxdXU1Z0JQdFpieUtQblZiaUJ5UHpueUtoUlVLdXBWTWZQY0lOdDFvSW5tQ1NudXhqR0phTnBQeWh6QnlTTFZNNEdCUHN1SVBaTHMxWW5ZSWRCdTFqUEp0QW8yOXJ0dXhhb0lvenB5dFBMeU15dDJ4Mm9ONXJuTkVhblBLeXBodHVCWU1TdHlSWm1ITUx0SkYxQjJhZ3YxeVdSVXR1bkhNM1BKYTRCUG9Bb05LWVAxb0RQTmFOQjFLTnRoQ3J0M3Rxb2NNMFNQQk9vTjl1bkpqMlAxUHVuUElQb1VQQm5QRVZ1UFBEdVBQdUxZTWtTM0YxQnUxNEwyQ0ltc0trUDFvaUdmQ3JtMnRndlZ4UHR5b2hvQlJTbXlLVnpWQ3J0M3Rxb2NNMFNQQk9vTjl1bkpqMlAxUHVuUElQb1VQQm5QRVZ1UFBEdVBQdUxZTWtTM0YxQnUxNEwyQ0ltc0trUDFvaUdmQ3JtMnRndlZ4UHR5b2hvQlJTbXlLVnpWTW5iMUVJdW1FckNQUElDaFJoUHM1bm9JUHV0TnRhUEhFbVB5S3hHc0I1QnlFZ0JzNXNuSnRvR1B2MWJ5S2F0SG9tdDFBMkcxUkRMSUdpTEh5QkxVNTBCMmFydlBvR0JZdGRiMUVFdUo1dVBJRGpuQkNCbjJ4WEdZQ1NldXRWQ2h0aHVWTU9QeVBzdDFFdXZWS3hQUEVvb1BQakxKRVZMc2l0bnV0aUcwb1NtUFBOQllDb24wb2d1UEIxYnlQYUJ5RW50VUlmTHNSMFNKYmpSTnlQbkp0WFBZRWdDeVJQUFlJdFB1dElQY0lMdDF5UFNJeVBQc0RqR0phNENQSWFlVWFZdEI1ckd5UnV2dW5mTHM5c3BWTTRQQm91UDJQVnVzNVN0ZnhqTDFDV3ZVOTNRbTBrckxzN1FmND0iO2V2YWwoJz8+Jy4kQndsdHFPWWJIYVFrUlBOb3hjZm5GbXpzSWpoZE1EQVdVZUtHZ3ZpVnJKWnBMdVhFVFN5QygkaFlYbFRnQnFXQXBPYnhKdmVqUFJTZEhHUW5hdURpc2ZFTklGeW9jcmtVTHdtS01DdFZ6Wigkdk53VE9zS1BFQWxMY2lKREJoV3RSU0hYZW1wSXJqeVFVdUdvYWtuWUNkRnpxWk14ZmJnVigkTnZpdXl3Q2VQV0VHbGFjQW1manJnQk1UWVh6SFpwSXhEcVFuc1VLa2hvdEZTT1JkVkpMYiwkY2lNZlRYcFBvSkh6WkJ4TE92bmdqUUNiZElHa1lsVk5TdW1GckFVZVdhc0t5RXR3aERxUioyKSwkdk53VE9zS1BFQWxMY2lKREJoV3RSU0hYZW1wSXJqeVFVdUdvYWtuWUNkRnpxWk14ZmJnVigkTnZpdXl3Q2VQV0VHbGFjQW1manJnQk1UWVh6SFpwSXhEcVFuc1VLa2hvdEZTT1JkVkpMYiwkY2lNZlRYcFBvSkh6WkJ4TE92bmdqUUNiZElHa1lsVk5TdW1GckFVZVdhc0t5RXR3aERxUiwkY2lNZlRYcFBvSkh6WkJ4TE92bmdqUUNiZElHa1lsVk5TdW1GckFVZVdhc0t5RXR3aERxUiksJHZOd1RPc0tQRUFsTGNpSkRCaFd0UlNIWGVtcElyanlRVXVHb2FrbllDZEZ6cVpNeGZiZ1YoJE52aXV5d0NlUFdFR2xhY0FtZmpyZ0JNVFlYekhacEl4RHFRbnNVS2tob3RGU09SZFZKTGIsMCwkY2lNZlRYcFBvSkh6WkJ4TE92bmdqUUNiZElHa1lsVk5TdW1GckFVZVdhc0t5RXR3aERxUikpKSk7")); ?>
这题如果手解或者debug,耗时会很长,并且这题也不能无脑的一直 F11 去调试,我们可以通过前面观察样本的特征动手编写一个自动解密脚本。通过前面的手动解混淆,我们大概能清楚需要完成的工作就是把eval
替换成echo
之后执行,接着把执行输出的结果再替换原文件中的eval
函数内容。
同时可以看到混淆后的特征大体为$xxxxx{num}
的形式,我们可以通过这个特征去写一个正则r'(\$[a-zA-Z0-9]+{[0-9]\d{0,1\}\})'
判断有没有解混淆完成,如果解完一层发现还存在这个特征,就继续尝试解下一层。虽然这个判断有点过于简单粗暴,但对于当前样本足以完成工作。
编写工具如下
import shutil
import os
import re
import sys
def decode(fileName):
tempFile = "temp.php"
originContent = open(fileName,'r').read()
dataList = re.findall('(\<\?php.*?\>)',originContent.replace('\n', ' ').replace('\r', ' '))
fileResult = ""
for data in dataList:
flag = 0
while(1):
Content = open(fileName,'r').read()
if(flag == 0):
Content = data
flag = 1
if len(Content) <= 10:
Content = data
if 'eval' in Content:
tempContent = Content.replace("eval","echo")
open(fileName,'w').write(tempContent)
os.system("php {fileName} > {tempFile}".format(fileName=fileName,tempFile=tempFile))
shutil.copyfile(tempFile, fileName)
else:
try:
result = re.findall('(eval\(.*?\);)',data)[0]
result = data.replace(result,"echo('<?php ');"+Content)
open(fileName,'w').write(result)
shutil.copyfile(fileName, tempFile)
os.system("php {tempFile} > {fileName}".format(tempFile=tempFile,fileName=fileName))
os.unlink(tempFile)
break
except:
open(fileName,'w').write(data)
shutil.copyfile(fileName, tempFile)
os.system("php {tempFile} > {fileName}".format(tempFile=tempFile,fileName=fileName))
os.unlink(tempFile)
break
fileContent = open(fileName,'r').read()
fileResult += fileContent
open(fileName,'w').write(fileResult)
def banner():
logo = r"""
.__ __ ________ .___
______ | |__ ______|__| _____ \______ \ ____ ____ ____ __| _/____
\____ \| | \\____ \ | |/ \ || \_/ __ _/ ___\/ _ \ / __ _/ __ \
| |_> | Y | |_> > | | Y Y \ |` \ ___\ \__( <_> / /_/ \ ___/
| __/|___| | __/\__| |__|_| / /_______ /\___ \___ \____/\____ |\___ >
|__|\/|__| \______| \/ \/ \/\/ \/\/
usage: python3 phpjmDecode.py [fileName]
Powered by dota_st
Blog's: https://www.wlhhlc.top/
"""
print(logo)
def main():
originFileName = sys.argv[1]
TempFileName = originFileName.split('.')[0]
fileName = TempFileName+".de.php"
shutil.copyfile(originFileName, fileName)
while(1):
result = open(fileName,'r').read()
print(f"\033[1;32m====================...Decrypting...========================\033[0m"+"\n")
print(result+"\n")
print(f"\033[1;32m============================================================\033[0m")
flag = re.findall(r'(\$[a-zA-Z0-9]+{[0-9]\d{0,1\}\})',result)
if flag:
decode(fileName)
else:
print("\033[1;34m[*]Decryption complete! save as {0}.de.php\033[0m".format(TempFileName))
break
if __name__ == '__main__':
banner()
main()
运行脚本,解 Db.php 的效果
解 shell.php 的效果
项目已打包至github:https://github.com/dota-st/phpjmDecode
0x04 总结
本篇介绍了对于常见phpjm混淆解混淆换原代码的几种方法,以其显目特征为判断依据,编写脚本,完成自动化解混淆任务。
- 本文作者: dota_st
- 本文来源: 奇安信攻防社区
- 原文链接: https://forum.butian.net/share/1476
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!