在攻防对战中,暴力破解是红队外网打点过程中不可或缺的一个重要手段。其成本低,利用简单,攻击收益大,一旦成功,往往等同于获得了通向内网的钥匙。除了加强用户的安全意识,尽可能避免弱口令外,防御者往往会在前端设下层层障碍,提高攻击者暴破密码的门槛。本文讨论了前端加密发展历程以及攻击者绕过思路的发展,并借助playwright框架给出了自动化暴破的新思路和相关示例代码。
一、前端加密发展
为了应对攻击者的暴力破解,防守方通常会采用不同方式进行加密。下面,我们介绍一下攻击者是如何应对不同加密方式的。
对称加密
针对密码暴破,最简单的防御方法是通过前端使用对称加密,如AES和DES,来阻止密码进行明文传输。
![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAwoAAAEJCAYAAAA0M9CmAAAgAElEQVR4Ae2dTatsW1ambRVFUVBexY6UqSg2BEW0r2CjQFEQEVJUxA9sqGhDxS805SIpKaQItqTARtkRGxbYF/wXYkP8B9Wxl70oxs3znvvud48511oRKyJWRDwBkePrHWPO9ayIvde895yb33DiBQEIQAACEIAABCAAAQhAIAh8Q8SEEIAABCAAAQhAAAIQgAAEThwU+BBAAAIQgAAEIAABCEAAAu8IcFB4h4QEBCAAAQhAAAIQgAAEIMBBgc8ABCAAAQhAAAIQgAAEIPCOAAeFd0hIQAACEIAABCAAAQhAAAIcFPgMQAACEIAABCAAAQhAAALvCHBQeIeEBAQgAAEIQAACEIAABCDAQYHPAAQgAAEIQAACEIAABCDwjgAHhXdISEAAAhCAAAQgAAEIQAACHBT4DEAAAhCAAAQgAAEIQAAC7whwUHiHhAQEIAABCEAAAhCAAAQgwEGBzwAEIAABCEAAAhCAAAQg8I4AB4V3SEhAAAIQgAAEIAABCEAAAhwU+AxAAAIQgAAEIAABCEAAAu8IcFB4h4QEBCAAAQhAAAIQgAAEIMBBgc8ABCAAAQhAAAIQgAAEIPCOAAeFd0hIQAACEIAABCAAAQhAAAIcFPgMQAACEIAABCAAAQhAAALvCHBQeIfk+RJ/8U2ffnZRske5wm/91r8/ylYOvQ/dN9lDb5bNQQACEIAABCDwNAQOcVC41QPQrdY52qdD1y17hP3NDgmz2hH2vrSHvfev+yar9TNWHgsBCEAAAhCAAAT2IHD3g8LRH3bO3d///l93R/vZ50P7l80Pzd4PtTV/zcw1mtzrM8cjHrpvsslglE8dMQQgAAEIQAACENhK4K5Ps4/wkHPuHo9yUFj6QIweUJf6ZvWlmUv12exnrV3C5NzP6LOy5LogAAEIQAACENiHwN0OCrOHm6r52y/V8z5D+dK677HrMz/ryZrvJ/06IORbGs9XzuPOV5+sa5TT3tKqPrL1YJrv1Hpdtcwprrp8t+pzW/XuNevrasr5rMwpLpsvr2V9VFO+Zrnv8dIsr2uG29znmrjuPy8IQAACEIAABCCwJ4G7HBRmDzVZ89j9gtDFmXNYXS1zS7HPm/n1UN+9Mu+x+9XrsftZ69ZZm/OHVu/JvMcjX/1eV052Vhtpssdj96vfY/f3qmlOztbeVfe4y2V/xtm/Js7P7poeNBCAAAQgAAEIQGBEoH+aHal3zM8eaqrW1bucb+mcevYsxb7ezM8He9eqJqvaLK5avquv9tu9NXPJjh5QK59vn6Wa5+SPZlZ9Vlvq15o+w/3R/K5P2uxXXnvpbNfjuq6euaXY563x83O7pgcNBCAAAQhAAAIQmBG420GhNrX0cJP1jPPCzqlnz1Kca47ifOh3nWqyqs3irKnnUpsPrJo3ynt9pBnlq3dW89nyZb3PfZ+Zea+lr7ldvpsz03utm9flco2Mc+Yszs/sTEsNAhCAAAQgAAEIrCVw14NCbTIfcmbxrNbNSgjZ3/WkxmP3c3bG/mDvvnRrcq5xv2ZkrLlbrT+gjvyaOap5Xmt7buRL21nvybVn8Za+mXZW69bPa8j+ric1HrufszPe8pnMXmIIQAACEIAABCAwI3D3g0Jtzh92yvd3bn5U83z5/sqa17PmffKlUbzW1sP86IG+y0svm+so3/WmdktcD6bdw6nyXlOu5sv3utZVTbH0Ho/82TzNTU3Gmu16+dqL4q53VPN89mXN61nT/txK47mZ75/jmY4aBCAAAQhAAAIQOIfAIQ4K52x8r557PWx1D/tdbq/rvPccf2he2ssW7dKso9Sf8ZqOwpZ9QAACEIAABCBwHQIvfVDQvym41WFh9m8EZrXr3PpjTdU/TX/GB+pnvrZjfYrYDQQgAAEIQAACexJ46YPCniCZBQEIQAACEIAABCAAgWciwEHhme4m1wIBCEAAAhCAAAQgAIGdCHBQ2AkkYyAAAQhAAAIQgAAEIPBMBDgoPNPd5FpO3/ANn3+k3T8XTc3YY86569MHAQhAAAIQgAAE7kXg86eqe+3ghuse6aHvER4+xUt26Vat1c3mXMKl6+1ys/Wzdml/ziOGAAQgAAEIQAACj0LgZQ4K/sDn/rVu1C3WuNbea27uP+PR2mt1o/5Rfs3cTtPlRmt0+Uv7u5nkIAABCEAAAhCAwCMQeMmDwi1uzKM/YJ67/3P7lu7J0txZfVa7dN2lfuoQgAAEIAABCEDgUQk8/UGhHhLzrZulfBd7zX1pyyov2+Wq5i9pMy9NV1fO50u/xqrf11RuNtP1Wsf7ul7VZbNP+bL+WpOXxvvk5zzly85qruv8S3q7eeQgAAEIQAACEIDAoxB4+7T2KLs+Y5+jB77Me1x+xlra85VbitUnm/qlGaX3Hvc1s7Op87j8jHNGatbs02d085WTHenX5KXpZq2pSdPZ2cxOTw4CEIAABCAAAQg8EwEOCs0/2dYNzgdFj92X3u059ezx2P1aJ2Nf2/3Ueez+0kzXup99a2rSyM72q1qnVS334PmlWmozXlo39cQQgAAEIAABCEDgWQhwUOCg8PGzPHso9pr71eyx+6OaNLIfNxCz1uSl6WatqUkzsrO5ox7yEIAABCAAAQhA4BkIcFCwg0I9FPqDoft1sz12P2sZpzbrFdcrdR6732m/PuH9/8769qjVDJ/jfu5TtbS+a9U8N5oz06g2mqf6kr20f2k+dQhAAAIQgAAEIHBUAi9xUKiHPX/nzVCt8vLdZl79qVFeVnXFZZVzO6orn9qMpRvZTp+5WVy1fElf+c73XKfpcuqRna2ZNc3LfM265HVp/yVr0wsBCEAAAhCAAATuSeCyp6h77py1IdAQ8Ad79xvpqlTN2GPOqsUQQQACEIAABCAAgQMR4KBwoJvBViAAAQhAAAIQgAAEIHAUAhwUjnIn2AcEIAABCEAAAhCAAAQORICDwoFuBluBAAQgAAEIQAACEIDAUQhwUDjKnWAfEIAABCAAAQhAAAIQOBABDgoHuhlsBQIQeF0C+ZfmFcu+LpnrX7kYy2rFjJXH7kPA+bq/z3SmQAACexDgoLAHxTvOqB+u+b7jdnZZWtezy7AVQ2693ootPZRE/NLqIjyv3NGs71H+2j1K77brVX1Uy3zp6yWb9VvE2rPbW6x7zTV0Lb6GGMt2Nc9dy9feun1ca81L5l6yz663y12yP3ohAIHLCXBQuJzh3SfkD9eM777BMzZw62u49XpnIGlbbr3v0XqZz7g23+Xai7pycrSPzGe8tK01+pEm84plc+1RPnUZn9OXPRnnGo8Q+zXIl839j/Kp2zO+5Zq3XMsZdet2Oe/BhwAEbk+Ag8Ltme++Yv5wzXj3BW8w8NbXcOv19kJ4632P1hvl/TrXaFx/LX+0j8xnvLSfNfpO0+X2WKubscda58zo9nLP3NZr2Kq/9Npuud4t1xKX2ZqzmvqxEIDA7QhwUNiZdf2Qyx90mVM800mzZnvdHO/TrNSVxmtZ72rKqVfWe6XxXOqkqbxeyskqP7LSpR3pMz/r89qaPuml9Vi+W+lku5pypXHfY+XLbnl5X/Z6TTM9J1+1sj7D/ZEm8zlTsVvv0Zqqq+ax+6nPmuqa47G0ZZVXrtN7LvWa4Zou53X3ta5b1TOnuOry3apvyVaPv7pYc11XvvKyXldO1vXyZUujl/SeS5006vF6V3Nd5+danUa5bn7mFI/mZl76NWtkr3rSaqZb1yhfOfc9rry/pHPrdfnZp3zZc2s+Ax8CENiPwNtv+X5zX3pS/qDz2P2C1MWZW4JZen+7Pmd57H7uZU1NGtmcMYpdr71mLmPp9rI532P38xouralfNudnXLq12rVstsxzbe7N19M+Zb0mP2d181wjP+2aPvUsabU36apP76zNYvW7psv5vqTtcqqN7KjH8+5rTpdTbWSrx9+uy3keu189Hrs/qkkjm7pR7PrS1CtzGX+QDc2leu93v9vb2pzPcX/UP7q47HVd1Zbqrve11Sfrui6n+qwmDRYCELgdAQ4KV2CdP+gyriUrp7dvodN6vfPX9Git1Co/mpv60imX1muaJ80oHuWzTzq3penerhn5Od9j96vfY/dzdtY8lp9W8yvvb82Wfm0s3cz6TPerx/cg32elXjXPu6+6ZnusnNaRlUZz0q7tyzmjeJTXulnPfNYVl01txp3G+0d+N0faqo3qo7x6O7umR2umVvnR3NSXTrm0XtM8aUbxKJ990o3spfquv3J657ojvetcozluXTvzfU7qZrXSdnXl0vps1Twnf1aTBgsBCNyOAAeFK7HWDztZX8Zz7pcmY+8b+Us9Xnff543y3Z6kTTvTai31KJbNfMbS7WVzvsfu13oeu597yZrH8tPm/C0zl3pzlse1D+0l8x6n3/WUZpT3/k7T5dSjWtql9aTPOaN4lB/Nyfyov/KpzbjTaN7MdnOkr9qoPsqrt7NLPV5332eN8qXJmuK0M63WUo9i2cxnLN3IbtXXHPXI+mzPuS/Nmpxr3NeMtXbWO6vV/K6uXFrfj2qekz+rSYOFAARuR4CDwpVY64edrJbZGqtvZnOma7PmsfvV47H7WfN4rU57Sv0oP9JJf6nN+R67X+t47P6sVjrXyk+bMzKWvvL1msVeK9/jD+3tjFktZ3g88rt9rs11M5WT7Watrb3p/fu/O/2fb/5vp9Mf/fbp9FdfOX36P/7rZ7b8Lh7ltuhzjVmvap31OWt8zRhpVe+s92Q9ax67X30eu581j9fqtK/Uj/J/W/f9L//8dPra1+ojMX35Z8uFlR/VSqearHqXYu9VT+Zqhs9xf0nrMzut13Ou17JXNfWkVV1WdcVlu5zX8SEAgdsT4KBwReajH3qVz3dto8stbc97RlrXyF9aTzrZnF15zehqXZ9ysrO+kSZ7Lom1hlvN63JbaqX1GeUrJ6ucx7Ocz/ts2If/UX4p19V9PdU1r6uVRvVOr5r3ek6+en1e16O6bKeZ5bSea07/+Z+n//c/v/F0+gLv12Twyef3/tu/6XT6p3/0j+M7/81nx6r6bFnqnbvUqxnSeSzfh3rO/dIoLusv5T2XfqdRTtZ7lHNbdcXyZSufr7U57+t6vI4PAQjsT+D9t3f/NZgIAQgciED+ss34QFvdfyv1T5B/4Ls/f1DksACL+gz84z+0n7WX+m60BK6bdL7uj1Zdoxn1kocABM4jwEHhPG50QeChCdQvXL0f+kK2bL4OCd/3HYMHY/unzBweBoye5d/AdPf6k9Pp3/51y6cJLQQgAIGXIMBB4SVuMxcJAQic/uav3z8Af++3n04/8SOn01c+ffP3E/Rn27Ff//saT8XhS793Ov3wD55O3/HNbz8Pv/aLfEkgAAEIQCAIcFAIIIQQgMCTEviNX3n7YPj937XqL7M+KQ0u64s//vbzUDEvCEAAAhB4Q4CDwhscBBCAwNMS+P3fevtg+NM/9rSXyoWtIPDpH55OX7A/hlQHSV4QgAAEIPCGAAeFNzgIIACBpyXw1S/bg+Enp9NXv/zZ39PQ9b7c39nQhb+Abe9t/Wdw/e+jVMwLAhCAAATeEOCg8AbH4wXtL8ADX4b2K3vErWpvbn2fni//aC/fX+0t4zX7VU9qlS/7cK94MPzsv7kfF7H1usQjxmwKZzNG+1HPqF4byJr3yN+00Yk415JU64zq0p1jNTt7Z/k32vg8fPb3MN4ICCAAAQhA4AF/23PTksA1fgnnGnvEuc+M91gjZ1yyRtebuYxz/XvFua+l2Pfp2pFfeq95/2H9eDDMg8K513NuXzLMORVnLnu6WPyzN2PpLrWX7vOS9fOaPB75H9eLzwMHhY9kcCAAAQh8JMBB4SOKx3X8F+JRr+Jee7xk3a63yx2Ree5zKfZrSK1qmc9YusPaKz0YXsJhqberZy7j4l+5zGe8533qZmcu4z3Wz5kZT9eIz0MeHKe9FCEAAQi8CAEOCjvf6PpFlb+sMqd4ppNmzfY0Rz2K1dvlM5exetO6zv3UZVza2UuzStP56ldtZLVGV1dN1jXKua169xrlO63nuvWUK537o761a6dOsdZwq7U8J1817W8We02+5rhVTXZUU7507nd9VfeX9G/y8WC49Z8gtzNtb6r7PspXXrbLVa17jfKuTY1iWWkr9vco732ul68+t97jefel8Tldrnqkkc05ymd/5r3vnR+fh9lBQeu8m0ECAhCAwJMT6H87PflFX/vy8peKx+7XPro4c0v7db37o/mat6SVbg+ba3UzS9PpMuex+zVzKda6a3SpUa/WmdVdK73nvLf8jKX1fDdHurRLfVn3/qVa1Wcan1V+aj12f6RNzUindVP/MY4Hwy0HhY8zPizisfu5t1kttdq/2+z32qhfPbLqmcWqpfU1utpotvKy6s1Yedmqu5/xrJZarTW08XmYHRSGMyhAAAIQeHICHBSucIOXfpnVkqXR27eQvV4b+eqRdZ3WcJv1irte18n3Oe6rPrJr5s80qslqna3x2r7S5Wz1ul2j0azS+ltzcobH7ku/xmbfUuwzU6ta5jOWLm3qMi595fT2/k6reqfPWW808WC45aCQa/q+3Nf60itOjeqj/Jp61+s59zXPrdflpy195hSPZnne+z2vGWmlqbxqynWzUpOx977z4/PAQeEdIRIQgAAEThwUrvQh0C8sWV/Gc+6XJmPvG/nVo3dqluapLpv9e8Vr5s80qslqX1vjtX2ly9nqdbtGszQrZ3jsvq+75GffUuzzUqta5jOWLm3qZvGslnMVr+6JB8OtBwVfZ+TXnrymPY7yI636RvVZvmr+Hs3yGfLT+r672mj22vxspq89mqf+UV351sbngYNCS4kkBCDw4gQ4KFzpA6BfYLJaZmusvpn1me5Xz1LcaWZrXVJb2kvWc62unrlZ7DX3RwxS0+lcU77Hvv/Me+x+rrFUy7rWzPwsntU0L/eVcc3IOerNvMfu58wuvmjmBQ+Gs32eW5td3+g6u55cf9SbOo/lp/X1utpoLe8baUbzlO/6ZrVuTc1obXweth4c25kkIQABCDwZAQ4KV7yh+UtNS1U+31XrcuoZWe/xGa5PjdfUk7lrxaO9eL787tXl1/Yt9e6xnvbSzaqc6r6XzGU86vP8lvVcq7W6XFfzNavur5E+e7Kvq0ujmbLdel0tZ37siwfDrf8EWWu5zbWq5i/Xbqnl3NnMnLu2VzO1R/XJKq/5buWnVjMzr1lZly7z0vs60nhNvuYo7vrU/9HG52F2UFg17+NgHAhAAALPQ+Dtb7XnuS6uZAOBR/kl2O2zy2249HdSn+f+OyGJ1QQOw7F5MDzM3lbTRLgbgebzMJrN52REhjwEIPDsBDgoPPsdHlxf/eLTeyA5RFp77H5Rz2rnbv4aM8/dyzP0HYrnhgfDZ2DPNSwQ4POwAIgyBCAAgRN/mZkPAQQg8CIEeDB8kRu98jL5PKwEhQwCEHhlAvwbhVe++1w7BF6JAA+Gr3S3l6+Vz8MyIxQQgMDLE+Cg8PIfAQBA4EUI8GD4Ijd65WXyeVgJChkEIPDKBDgovPLd59oh8AIEPv79Fh4Mn/pu6+/DdBf58TPgRT4PTgMfAhCAQEuAg0KL5TGT7S/DO1yKfmHL3mELi0tqb269yfPlH+3l+6u9Zbxmv+pJrfJlH/315hrOfDAUj0tYzGa82aMtop5RvaRZ8x75NvIiN9fSMK0zqkt3jtXs7J3lU6v43f7O/DxoHhYCEIDAKxB4/CeBV7hLD3SN+cs442tcyiVrdL2Zy/ga13DOzNzXUuxruHbkl95r3v8o/pv9X/Bg+GbOxov3XvfFN3PK+zKdZovOZ53j1/rdHjKX8TlrZU/O9Hjk54yKXftZ/YLPQzefHAQgAIFnJMBB4Rnv6p2u6d0v4hvt45J1u94ud6NL2bRM7nMp9uGpVS3zGUv3CPbd3i94MHw3awOApd6unrmMa/nKZT7jDdtclHazM5fx4tAVgpyZ8YoRHyVvei/4PHwciAMBCEDgyQlwUNj5Btcvoje/jJpf6NLMdNKs2Z60s3maI63izkqTttN6Ltf3WvmaN/LVL93Iam5XV03WNcq5rXr3GuU7ree69ZQrnfujvrVrp06x1nCrtTwnXzXtbxZ7Tb7muFVNdlRTvnTud31V95f0mZfmXX7Fg+FopuffzbW9S1d7kO9We3PbzfO6ZnlOPbKq+Vpey/zamuZ2e/CafM3Vet7nOeWVU5/PyZrH8qVfa9+sE5+Hrf9P3WvXRAcBCEDgkQm8/c37yFdyoL2/+WX04YFB25vVSnPuL0D1ah3ZpfWk28PmWt3M0fVlr8fu18ylWOuu0aVGvVpnVnet9J7z3vIzltbz3Rzp0i71Zd37l2pVn2l8Vvmp9dj9kTY1I53WTX3GXf8pHgw/izXwgmvItZdiW/IzN/Vr6uqRVc8sVi1t9WZOsea6xnPuZ4/itN0saZZqXd33sOT7Okufh6VZ1CEAAQi8AgEOCle4y29+GdkvYV+qNHpn3uMtfq5bvZnLuJuvfaXttJ5bO9t73Fe/rGpb47V9pcvZ6nW7RqNZpfW35uQMj92Xfo3NvqXYZ6ZWtcxnLF3a1GVc+srp7f2dVvVOn7NmGs35zH7l09PpC9/4+fvLf/KmrEDzfF/ul66LM+fz5Hd21Netk7lZ70irHlnXKSdbNb263KwmfVrvUU25splbir13yX8z66tfPp2+8MmHz8Mnp9OXfm+pnToEIACBlyPAQeFKt1y/kGR9Gc+5X5qMvW/JH/UqL7s059z6mvkzjWqy2sfWeG1f6XK2et2u0SzNyhkeu+/rLvnZtxT7vNSqlvmMpUubulk8q+VcxXv0nH7n1z8/JNSB4Ud/SOM/Wl9n5JfYax+bB/mRVn2j+ixfNX+PZvkM+Wn9erraaPba/Gymrz2ap/5RXfk19s2sX/qZt5+HX/jpNSPQQAACEHgpAhwUrnS79QtJVstsjdW3xuZs9Sgvq/w1bK6xFOceUl/1zM1ir7nfzVmb8znle+z7z7zH7ue6S7Wsa83Mz+JZTfNyXxnXjJyj3sx77H7O7OI9ZrYzfvc33z4Yfue3nE71cFj/puGvvnL67M+o1x9P+vD22P3Uzmqp1Wy32d/1dJo1Ou+Tn9bndDXtVTXF3qdcahTLLum2zNSstfbjHurfJPzqz51O3/Ntbz8PP/uT+thgIQABCEDgAwEOClf8KOQDkpaqfL6r1uXUM7PZV3G+ulxq9op9Pz7T86P9dPm1fUu9vhf5Sz1Z117Un1Z178tcxjWjy3k+11E86su64rLeU36+vO415T0nXzVZ5WWVd1s1j8v316yWvd7n/puZ//Hv9kdN7I8gffzjJ57Df/PHtPyPbD2p/wv//b/4RwcfAhCAAATq9zQUIHAkAm8e7D5srMtdsmef5/4lM1+998gc3+ztz/747T9FftKH3ld7yL/4en/+pz47tL7695jrhwAEIJAEOCgkEeKbE6gHOb1zceXfPOylaGN8jZkbt/BU8ofj+ad/wGGBA9Lnn4Ff/uLp9LWvPdV3kouBAAQgsBcBDgp7kWQOBCDwOAT+5Z9Ppy/++Nff9efV7e8m4H/+9zSeksXv/9bn9/5v/+ZxPrPsFAIQgMAdCHBQuAN0loQABCAAAQhAAAIQgMDRCXBQOPodYn8QgAAEIAABCEAAAhC4AwEOCneAzpIQgAAEHpXAnn9f6FEZsO/jEnilz+crXetxP3HPvzMOCs9/j5/qCvUXZ5/qouxibnV9WkfWtnAYV3tz65vzfPlbXqnPWYp9pnKyXnsVv649X+Ihm/UjxNqbW9+X58s/2sv3V3vLeM1+1ZNa5cs++suvwa9L/jNcn19jXU/Gl1zjs3C6hAG97wk8/k+G99dE5sAE9vihtseMAyPa9Qd/d53JL+Ou59LcJWt0vZnLeGm/nT5zHrtfszNeWu8R6muuKTVL8TWuO9fcskbXm7mMt8y/pjb3tRT7Xlw78kvvNe9/FD/3vxQ/ynX5Pq99TTnf18Z/TQIcFF7zvt/tqvf4IbTHjLsBWLHwNa/vmrNnl3bJul1vl5ut7zX1yqqWsfJlZzXXPbK/dI1Zz/hW137Jul1vl7vVtWxZJ/e5FPvs1KqW+YylewTb7T1zGT/CdeUeu2voctm3Nt5z1to10R2bAAeFne9Pfcnyi5Y5xTOdNGu3J73PVK5muO8zlZdVzePOr5zPlSZtzvO6arJra6Wrl+vla5as8upRvutfqmmWemV9tjSeS500S+t5PX3NSJu6jHNfXV0azS6N/Kx53n3N9Zx81WSVL9u9tua7GZ7TPFnVPHa/qyu3xtYsvaX32H3Vyyovq5rHnV+5rl9a2ZynvPpVl818xtLJal7Fna9+1UY257lONdlZTfuQ1m31nfPq1lOu5rnv85WX9drIL62/FGuGW+k8J1+1spXzV8Zek685blWTHdWUL537XV/V/SV95qXp8pnr4splvmYqL6t1RjXXaZ7nsq+b55qunvOk0XqKL7GapbUUa2aXz1zG6sU+JoG338THvIbD7br7YmmTs1pp9AWTfo2dzcx5rnVfa/t62avarG9W69a4dOZsvWvWNFu2uzavqZ455cWhi712qd+tnzNL0+ky57H73TVkXWtmPuNulnpV63pck770sqpX7G/l3aruuZnfrSF9znKt+6Xv4syNdL6e/CWt6+TnehlL57Y0nS5zHrtfs5ZirbdGlxr1ap1Z3bXSe857y89YWs93c6RLu9SXde9fqlV9pvFZ5afWY/dH2tSMdFo39Rl3/cqVVm/NU20U53yP3c85qqVN3ShW32hfXd8o5zO2+L4H97t1vO5+p92yB7THIsBB4Qr3Y80XpjR6+xay12sjX3PcSpvzPHZferezumqy6tsae1/1+ttr8sv6Gu5nTT3dTGmzP3sUy0qfVvOkWxNLq1mjWHm31dO9XdP5udZWjfpl1b81XttXupytXrdrNNKXVm/lyvoM910jf6nuOuP3TI0AACAASURBVK0l6zX5ZX2m+66RP6urJjvqWaqrT3arvvqyR7O8lpqtsWYu9fma6ulszuk0mlVaf0ubMzx2X/o1NvuWYp+ZWtUyn7F0aVOXcekrp7f3d1rVO33Ommk0R3a2lmu6mV0uexTLar20VVcutaN4lM853Wz1nmM1X9ZnVC7fWa+463Ud/mMR4KBwpfulL4qsL+M590uTsfeN/FlP1jx2v5s9q6smq/6t8ahP+bKzmbNa9qZWa4zy2e+xemS9NprrWmnW9Ln2Un+0B58706gmq76t8dq+0uVs9bpdo+lmeZ/7Prvz12pnuqx57P7W9dUrq/6tsfpkl/qlc5s9XS01W2PNXOorXWrU63aNZmlWzvDYfV93yc++pdjnpVa1zGcsXdrUzeJZLecq3qOnZuUczZf1uvuqL83IHsVpuznSaK2MR/lO1+XUv9XWLL2zd2kd1WWzn/gxCXBQuNJ90xdFVstsjdU3s7OZ59ZqvezNPXT1zM1ir7mfax+p5nub7ct14pb6UX6kk/5Sm/OX4lwv9VXP3Cz2mvvdnLU5n1O+x77/zHvsfq67VMu61sy8x+5vWS+1Wsttzu56UuOx+7O5qVuKfVa3py43m+k197s5a3M+p3yPa4ZemffY/dJ77H5Xy/qa9bo56svaLO9rl+/xlr612rW63EfGmpP5jKUrmzWP3U/trObatTrtKfWjfOoy9r5RTZrOeo/7pV2KO41y2dutTe6YBDgoXPG+jL4Ylc93baPLrd2e96oncxnnmurLfPV1ry7va3R1n50zvXdWk85nec57lXe71Ofa8vOlnKzXvXeUX+rTDO/f29cauRfPZ0176PJr+5Z6tYbbpZ6say8+o3zlpfd45GtG1pX3uZ5z33uVz1zGPrdq/nJt1qTr8mv7ut61c6Uru3Y979nS1+3T18y5mp1578mZqmWPYtW9L3MZax/Ka5bnPee+esp2L9W9ppys18pXvqy/lPecfNVklZdV3m3VPC7fX7Na9nqf+z7T57nGfdfIr7p82VmP19Tr1uuaV9Zfns+aZo00nV6zZzVp3Poavu5M4zX1ZG6W77TkjkXg7af1WHtjNwcn0P0Q6nLXvIxbr3fNa3mU2R3zLnfJ9fg89y+Z+Uq9HbMudw6TvebU2t2sLnfOPtXj89xXHbudwJE5Hnlv20nPO2bXOqvNp15W7dbtcpetQvctCXBQuCXtJ1irvvB65+Uof6sfCrdeL6/3leIZ61ntXEbXmHnuXh6lb8ZsVrv19c32Mqudu89rzDx3L8/QB89nuIv7XgOfiX15Hm0aB4Wj3RH2AwEIQAACEIAABCAAgQMQ4KBwgJvAFiAAAQhAAAIQgAAEIHA0AhwUjnZH2A8EIAABCEAAAhCAAAQOQICDwgFuwp5b0J8V3HMmsyAAAQhAAAIQgAAEXo8AB4Unu+d1UOAFAQhAAAIQgAAEIACBSwnwVHkpwYP1c1A42A1hOxCAAAQgAAEIQOBBCXBQeNAbN9o2B4URGfIQgAAEIAABCEAAAlsIcFDYQusBtBwUHuAmsUUIQAACEIAABCDwAAQ4KDzATVq7RQ4Ja0mhgwAEIAABCEAAAhBYIsBBYYnQg9U5LDzYDWO7EIAABCAAAQhA4KAEOCgc9Macuy0OCueSow8CEIAABCAAAQhAwAlwUHAaT+BzUHiCm8glQAACEIAABCAAgQMQ4KBwgJuw5xY4KOxJk1kQgAAEIAABCEDgdQlwUHiye18HBQ4LT3ZTuRwIQAACEIAABCBwBwIcFO4AnSUhAAEIQAACEIAABCBwdAIcFI5+h9gfBCAAAQhAAAIQgAAE7kCAg8IdoLMkBCAAAQhAAAIQgAAEjk6Ag8LR7xD7gwAEIAABCEAAAhCAwB0IcFC4A3SWhMC5BPiL6ueSow8CEIAABCAAga0EOChsJfbi+mv+V5U0WzZRH+khebQX7b2rz2p5rV3czex0yl26nuZgIQABCEAAAhB4TQIcFF7zvl901VsfWNcsljMzXjPjVho9gOd6uWeP3a++jHNWF2/pSW3G3XxyEIAABCAAAQhAwAlwUHAa+KsIXOOh8xozV13MmaJuv5nz2P1aMuOlbVyq39q/tB/qEIAABCAAAQg8PwEOCs9/j3e/Qj10ltXbF1FOuqplLmNpfI78TtvVpFOtrHJl89XlUjOK1/S6xv2amfFoHeUv1W/t17pYCEAAAhCAAARel8D7p6fXZcGVryTgD53uV/ssntW0dGlS5zX5sq51v+pLsWacY3N2zujqldM79bO4mzXTq6a1zu3XHCwEIAABCEAAAq9JgIPCa973i65aD56yPswfTuVnveKut9Mt5VTv5ml9t9Jfarv1NLOrZS5j9XZ2i1b92ZOxdFgIQAACEIAABCAwIsBBYUSG/JBAPXTqnaKlB1LVZbNfcVfvcufq1XeuHe1lbX6k6/azRav+7MlYOiwEIAABCEAAAhAYEeCgMCJDfkjAHzrdr4aluNN0uZzTaSpXL9eO/NR9vfP8//V1NCVzHru/ZS/Zp7WWbPZ5XL7HS7OoQwACEIAABCDwmgQ4KLzmfT/7qvWQqQdNxT5QOWm8Vn6X956sZ83rs5rWkmbNPlLTxZrn+8i1pPF+5bLPNelv0Xa9WrOrZY4YAhCAAAQgAAEIOAEOCk4D/yYELnn4vckGD7LItThda+5BsLENCEAAAhCAAAR2IsBBYSeQjJkT0D/Z5iF1zokqBCAAAQhAAAIQOAoBDgpHuRPsAwIQgAAEIAABCEAAAgciwEHhQDeDrUAAAhCAAAQgAAEIQOAoBDgoHOVOsA8IQAACEIAABCAAAQgciAAHhQPdDLYCAQhAAAIQgAAEIACBoxDgoHCUO/GA+7j1X0y+9XoPeEvYMgQgAAEIQAACENiNAAeF3VAyCAIQgAAEIAABCEAAAs9DgIPC89xLrgQCEIAABCAAAQhAAAK7EeCgsBvK1xk0+v9EUN5JZO6cPz6kGdmr/Gw9r+FDAAIQgAAEIAABCKwnwEFhPSuUQSAf3KucuYxjxKawm5W5jDctgBgCEIAABCAAAQhA4CMBDgofUeBsJdA9lGcu461ruL6blbmMvR8fAhCAAAQgAAEIQGA9AQ4K61mhDAKjh3LlZaPt7HA0T3nZsxegEQIQgAAEIAABCEDgIwEOCh9R4GwlMHowV15269yRfjRPeVn1V5w51bAQgAAEIAABCEAAAnMCHBTmfKg2BPQA7jZlowf0UT77PfZ15Hu9/NHcUT77iSEAAQhAAAIQgAAE3hLgoPCWB9ETEeCQ8EQ3k0uBAAQgAAEIQODmBDgo3Bz5wRf8+787nX7n10+nP/rt0+mvvsIbBnwGzv0M/P5vnU5/+een09e+dvAvPduDAAQgAAEI9AQ4KPRcXi/7n/95On3/d55OX/hG3jDgM3DxZ+CTzxl++zedTv/0j6/3M4UrhgAEIACBhyfAQeHhb+EOF1D/xPMHvvvzB5uLH5I4bHDg4jPw7jPwj/+ww5eVERCAAAQgAIHbEeCgcDvWx1ypDgnf9x2DQ4L9U1EODwNGPBC/eyDms3I6faH77nxyOv3bvx7z5wC7ggAEIAABCDQEOCg0UF4q9Td//f4B+Hu//XT6iR85nb7yKX8+/dw/n07fa392vvR7p9MP/+Dp9B3f/Pb79Wu/+FI/XrhYCEAAAhB4bAIcFB77/l2++9/4lbcPMt//XTf5y5ej/8zp5Rf0doLWkX1bPUakvbn1nXm+/Fu9tO4e62mWbM2U7zbX8lr5D/f64o+//X5VzAsCEIAABCDwIAQe8Dfvg5B9lG3Wf5nF/6jIT//YzXZ+7Qe/nJ/xNS70kjW63sxlfI1r8Jl7rJczPHa/1vXY/az5Hg/tf/qHb/8YUh3MeUEAAhCAAAQehAAHhQe5UVfb5le/bA8yn5xOFd/olQ+Cey57zdmzfV6ybtfb5Wbr7127dP2l/qwrlt37em4+r/4Imh/EK+YFAQhAAAIQeBACHBQe5EZdbZsbH2TqAS7fuTevz2r5MLjUl7Nmcc5OrdaqfOerX7WR1dyurpqsa5RzW/XuNcp32sr5OvJTq3w322tZ91rO7OLsT03WFcum/uHijd+vh7s+NgwBCEAAAk9NoH8yeepL5uLeEDjjQUYPcWlrrnJaw2P3UzuradYWm/O63tJ0usx57H5eQxdr3aW+Wa9qOUOzOyttWs3yHmkuqfk893225+VX3d+el//Q9ozv10NfL5uHAAQgAIGnIsBB4alu5xkXc8aDjB7+0tbqymknHruf2qrlWzPOsblWN2OmUU1W/VvjtX2ly9nqdbtG47Okl/Wa5m6pldbfmjGyPrvTZF2xbNfzULkzvl8PdX1sFgIQgAAEnpoAB4Wnvr0rLu6MBxk9xKWt1ZTTyh67n9qsqf9cu2beTKOarPaxNV7bV7qcrV63azQ+S3pZr2nuuTX1z6zP7nRZVyzb9TxU7ozv10NdH5uFAAQgAIGnJsBB4alv74qLO+NBRg9xaWs15bSyx+6ndlbTrK12aWbWc35Xz9ws9pr7ee1aNzWdzjXle6w53qe6rNek36vmczT7Huv52nf3z/h+3X3PbAACEIAABCDwgQAHhVf/KGx8kKmHQT0QupVfOKXxnDB7TX5XU062m6XazGqN7Pd81jSvy6/tW+rVGm6XerKuvfiM8j2vHs+5RnWfIa1b1bucz5MubdfnOflr+qSpnsO/Nn6/Dn89bBACEIAABF6KwAP8pn2p+3H7i+VBZsi8exDtcsMBKwo+z/0VrS8teRhWfL9e+nPKxUMAAhB4dAIcFB79Dl66fx5k3hCsB1C93xTsn9Tv+ZCqtfacmfsmviMBvl93hM/SEIAABCBwKQEOCpcSfPR+HmQe/Q6y/yMT4Pt15LvD3iAAAQhAYIEAB4UFQE9f5kHm6W8xF3hHAny/7gifpSEAAQhA4FICHBQuJfjo/TzIPPodZP9HJsD368h3h71BAAIQgMACAQ4KC4CevsyDzNPfYi7wjgT4ft0RPktDAAIQgMClBDgoXErw0fvv9CCjv8Tb4RvVjvIXfrU/2e4a7p3T3tz6njxf/q1eWndpPencqkc5xXtZzXV78ew7fb8u3jcDIAABCEAAAvUfcoHCixO444NMPZCNXrPaqOcW+dxXxtfYwyVrdL2Zy/ga1+Az166XOo/d99mX+Dkz47Nm3/H7ddZ+aYIABCAAAQgYgfGTmolwn5jAHR9kZg9is9q97sa99nTJul1vl7sl07Xrp85j96+x993m3/H7dQ0uzIQABCAAgdciwEHhte73+6vd+CBTD1D5zqFen9XyYcz7vOZ5n6d85dzvNF29clteS3pfo/PVr9rIak9dXTVZ1yjnturda5TvtJXzdeSnVvlutte6es7Smp73Pvk+N7Xn1DRD8xWfbTd+v85eh0YIQAACEIDAFQj0TxFXWIiRByVwxoNMPkR57H5dscfub6mJXPZrhufX+Jq31frsUW9pOl3mPHZf1+Tzs65a5jPuZqlXta7HNe6n1mP3NVu9s5o0na0+f7vGZ7pfmlk8q43me36zf8b3a/MaNEAAAhCAAASuRICDwpXAPszYMx5k1jxslUZvsZj1zWqj/srP+rzmvuZttWtmzDSqyWr9rfHavtLlbPW6XaPpZnV9ldNba6QuY+nSznSqyXpvl8v6TDOr+ZxV/hnfr1VzEUEAAhCAAARuQICDwg0gH3qJMx5k8kFqFnvN/WLisftZE7/UdLrUVJw5zdtq18yZaVST1fpb47V9pcvZ6nW7RtPNyj6PR343x/fivs/wvGZUvdN0uezXjC35TruYO+P7tTgTAQQgAAEIQOBGBDgo3Aj0YZc540EmH8Q8dr+u2WP3t9TELvtzRsadXrPOtTlzKc51Up97Xoq93/2ub23O55Tvcc3QK/Meu196j93valkfrad8N2NU26pNvc89yz/j+3XWOjRBAAIQgAAErkCAg8IVoD7UyDMeZOrBzt95vV6TL41it0s118qvHvllu3iU+0wcD7PKrbG5rno8rz2pJtvl1/Yt9WoNt0s9WddefIZ81WSVl1Xe7VJNWulklS+br6wpdp1y2e/5rKl/lFd9kz3j+7VpPmIIQAACEIDAFQm8/y18xcUYfUACZzzI7PogdUUkuc+Mr7j0cHS3hy43HLCi4PPcX9E6lew5a7rQMxXP+H490+VzLRCAAAQg8NgEOCg89v27fPcbH2TqYVHvyxe//gTt9Z4PubM9zGrn0nmUmede30P1bfx+PdS1sVkIQAACEHh6AhwUnv4WL1wgDzILgChD4AICfL8ugEcrBCAAAQjcmwAHhXvfgXuvz4PMve8A6z8zAb5fz3x3uTYIQAACT0+Ag8LT3+KFC+RBZgEQZQhcQIDv1wXwaIUABCAAgXsT4KBw7zuww/r6M+ndqKpNXzzITPFQhMBFBPh+XYSPZghAAAIQuC+BhafI+26O1dcTmB0IZrUTDzLrIaOEwFYCfL+2EkMPAQhAAAIHIsBB4UA345KtzA4Ds9rpK5+eTl/4xs/fX/6TS7ZBLwQg4AS++uXT6QuffPh+fXI6fen3vIoPAQhAAAIQODQBDgqHvj3rNzc9DMz+z8V+59c/PyTUgeFHf2j9oighAIE5gV/6mbffr1/46bmeKgQgAAEIQOBABDgoHOhmXLKVsw8Kv/ubbx9kvvNbTqd6mKl/01B/bII3DPgMbP8M1L9J+NWfO52+59vefr9+9icv+ZrTCwEIQAACELgpAQ4KN8V93cVmh4Vh7T/+3f5ohP0RpI9/XMJz+G/+mJb/kS38tw/E8Oh5/N9/uO4PAaZDAAIQgAAEdiTAQWFHmPccNTwIfNjUtP5nf9w/1PCwBxc+A/t9Bn7+p+75I4K1IQABCEAAApsJcFDYjOyYDdODwOzvKOhy/vQP9nsg4uESlnwG3n4GfvmLp9PXvqZvGxYCEIAABCDwEAQ4KDzEbVre5OygMKu9mfwv/3w6ffHHv/6uP1/Nn02HAZ+B8z4Dv/9bn3+X/vZv3nzNCCAAAQhAAAKPQoCDwqPcqYV9zg4Ds1qNXaovLE0ZAhCAAAQgAAEIQOAJCXBQeIKbWg/6o4f9Ud4ve43G9fgQgAAEIAABCEAAAs9PgIPC899jrhACEIAABCAAAQhAAAKbCXBQ2IyMBghAAAIQgAAEIAABCDw/AQ4Kz3+PuUIIQAACEIAABCAAAQhsJsBBYTMyGiAAAQhAAAIQgAAEIPD8BDgoPP895goh8O4vu+svsMuC6HoExFhWK2WsPBYCEIAABCBwFAIcFK58J+phgAeC8yGLX1pN9LxyR7O+R/lr9yi9265X9VEt86Wvl2zWbxFrz25vse4119C1+BpiLNvVPHctX3vr9nGtNZk7J6B7Mlc9bvXZr+9x7ww7h8B6AhwU1rM6W/mov5hvve/RepnPuG5Mlzv7hl3QONpH5jNeWnKNfqTJvGLZXHuUT13G5/RlT8a5xiPEfg3yZXP/o3zq9ozvseae+z/SrD1Y7jHjSExyL89+fXm9xBB4NgIcFG5wRx/1B+Wt9z1ab5T3W7dG4/pr+aN9ZD7jpf2s0XeaLrfHWt2MPdY6Z0a3l3vmtl7DVv2l13br9S7d75H792C5x4xnZ3Tk62NvEHh2AhwUrnSH64e/v32ZUb40Xivfc5ohjdeUU4+0qVFeeq9nTZpuprSd9b7s9Zp6PSdftbI+w/2RJvM5U7Fb79Gaqqvmsfupz5rqmuOxtGWVV67Tey71muGaLud197WuW9Uzp7jq8t2qb8lWj7+6WHNdV77ysl5XTtb18mVLo5f0nkudNOrxeldzXefnWp1GuW5+5hSP5mZe+jVrZK960mpm2tSNYu+TRrmK3Vfd81n3uPMr1/VLK6u1FLtVTXZtrXT1cr18zZJVXj3Kd/1LNc1Sr6zPlsZzqZNmab2se4wPAQgcl8DnvyGPu8eH21n3Q1UXcc2aZsvWmu5nXDWvu59a7X/J+gz3u3lLda1VOn8r7zZnLa0nfdo1fepZ0ub+qk/vrM3ibp0u5/vSvC6n2siOejzvvuZ0OdVGtnr87bqc57H71eOx+6OaNLKpG8WuL029MpfxB9nQXKr3fve7va3N+Rz3R/3DizujMFuval4f+d0+s1db8xnZN6ulVvO6vM9xP7X3qmld2dzXKHZ9aeqVuYw/yDAQgMCDEOCgcIUblT8YPXa/lvbY/dxW1jyWn1bzK+9vzZZ+bSzdzPpM96vH9yDfZ6VeNc+7r7pme6yc1pGVRnPSru3LOaN4lNe6Wc981hWXTW3Gncb7R343R9qqjeqjvHo7u6ZHa6ZW+dHc1JdOubRe0zxpRvEon33Sjeyl+q6/cnrnuiO961yjOW5d2/mudb/TZs718qWp2F8eu+8a+bO6arKjnqW695XW316TX9Znup819XQzpc3+7FEsK31azZNuTSytZo1i5bEQgMBjEHj7U/cx9nz4Xc5+UG6p+YWu6ZNGtvrd93ldLbUZZ/8orr6ut8v5jFF9lF/qnfWplrZmKufz5WdtKd7al/NG/ZVPbcadRvNmtpsjfdVG9VFevZ1d6vG6+z5rlC9N1hSnnWm1lnoUy2Y+Y+lGdqu+5qhH1md7zn1p1uRc475mXNPO1suax+53+5vVVZNV/9Z41Kd82dnMWS17U6s1Rvns91g9sl4bzXWtNGv6XIsPAQgcnwAHhSvco/wB6rH7tbTH7s9qpXOt/LQ5I2PpK1+vWey18j3+0N7OmNVyhscjv9vn2lw3UznZbtbaWvZu6cveiv3ls5TPXMYjnfIj63PW+Joz0qreWe/JetY8dr/6PHY/ax6v1WlfqR/lRzrp3Y60lR/Vql81Wc1cir1XPZmrGT7H/dT6jL382Xrn1tbsO2d3PanxeOTnHNfdu+brz/bluvLrlfoP6Xf5kU56LAQgcGwCHBSudH/qh2O+tZTnlZNdUyut68pXTlY5j2c5n/fZsA//o/xSrqv7eqprXlcrjeqdXjXv9Zx89fq8rkd12U4zy2k91yzNUk/p8pVzqi69W+/zvHyva0bmluKc5bH8svlSLfNdLG03R3rXyK+afFnpl2qqux31jvK1Zr60D7ep6eJuVuk0p+tRbqlXM6TzWL5m5ZpZV1z2Fq9uvcxl7NeQ+3Rt1nQ9XX5t31Kv1pDNuerPvPSyWV/Tlz2aJeszlJP1XuXKel79s3pqMvZefAhA4FgEbvNT/1jXzG6uSCB/AWR8xaUffvQ1WV1z9sODv9MFcE/uBH6wbHc/utygfZf0rdfbZdNnDHmV6zwDDS0QOBwBDgqHuyWPv6H6JaD341/Nda9AnJ71F6dfn/vXpcp0CKwjMPtMzmrrpm9T3Xq9bbtDDQEIvCoBDgqveue5bghAAAIQgAAEIAABCEwIcFCYwKEEAQhAAAIQgAAEIACBVyXAQeFV7zzXDQEIQAACEIAABCAAgQmBlzgo6M9+TjhQggAEIAABCEAAAhCAAASMwEscFOp667DACwIQgAAEIAABCEAAAhBYR+Blnp45KKz7QKCCAAQgAAEIQAACEIBAEeCgwOcAAhCAAAQgAAEIQAACEHhHgIPCOyQkIAABCEAAAhCAAAQgAIGXOSjUreaPH/GBhwAEIAABCEAAAhCAwDoCL3NQ4JCw7gOBCgIQgAAEIAABCEAAAkWAgwKfAwhAAAIQgAAEIAABCEDgHQEOCu+QkIAABCAAAQhAAAIQgAAEOCjwGYAABCAAAQhAAAIQgAAE3hF4iYNC/f0E/o7Cu3tPAgIQgAAEIAABCEAAAkMCL3FQGF49BQhAAAIQgAAEIAABCECgJcBBocVCEgIQgAAEIAABCEAAAq9NgIPCa99/rh4CEIAABCAAAQhAAAItAQ4KLRaSEIAABCAAAQhAAAIQeG0Chz8o/MU3ffrad4irhwAEIAABCEAAAhCAwB0IHOKgMDoMjPLX4LTnWnvOusa1MhMCEIAABCAAAQhAAAJLBO5+UJg9VM9qSxd2i/psf7PaLfbGGhCAAAQgAAEIQAACELiEwF0PCrOH6Vntkgves3dpj0v1PffCLAhAAAIQgAAEIAABCOxJ4G4HhaWH6FG98v52GJ73fuVL677Hrs/8rCdrvh/NyRwxBCAAAQhAAAIQgAAEjk7gLgeFfChPSKN65j12v+Z1ceZ83a6WuaXY57mffV7DhwAEIAABCEAAAhCAwBEJ3OWgUCBmD89Lta7e5Rz4OfXsWYp9PfnZozwWAhCAAAQgAAEIQAACRyZwt4NCQRk9RI/yDjI1Gbt2tpZ0XX/mlmLNkk298lgIQAACEIAABCAAAQgcncBdDwoFJx+mM3aAWfPY/a1zO32Xm60xq/k14EMAAhCAAAQgAAEIQOARCNz9oFCQ/CHb/QRYNX/P6l7znpyfNa9nzWfKl0ZxWZ/heXwIQAACEIAABCAAAQg8CoFDHBQE62gP2EfbjzhhIQABCEAAAhCAAAQgcG0ChzooXPtit8zXvyngsLCFGloIQAACEIAABCAAgWchwEHhWe4k1wEBCEAAAhCAAAQgAIEdCXBQ2BEmoyAAAQhAAAIQgAAEIPAsBDgoPMud5DogAAEIQAACEIAABCCwIwEOCjvCZBQEIAABCEAAAhCAAASehQAHhWe5k1wHBCAAAQhAAAIQgAAEdiTAQWFHmIyCAAQgAAEIQAACEIDAsxDgoPAsd5LrgAAEIAABCEAAAhCAwI4EOCjsCJNREIAABCAAAQhAAAIQeBYCHBSe5U5yHRCAAAQgAAEIQAACENiRAAeFHWEyCgIQgAAEIAABCEAAAs9CgIPCs9xJrgMCEIAABCAAAQhAAAI7EuCgsCNMRkEAAhCAAAQgAAEIQOBZCHBQeJY7yXVAAAIQgAAEIAABCEBgRwIcFHaEySgIQAACEIAABCAAAQg8CwEOCs9yJ7kOCEAAAhCAAAQgAAEI7EiAg8KOMBkFAQhAAAIQgAAEIACBZyHAQeFZ7iTXlR4BiQAAAKpJREFUAQEIQAACEIAABCAAgR0JcFDYESajIAABCEAAAhCAAAQg8CwEOCg8y53kOiAAAQhAAAIQgAAEILAjAQ4KO8JkFAQgAAEIQAACEIAABJ6FAAeFZ7mTXAcEIAABCEAAAhCAAAR2JMBBYUeYjIIABCAAAQhAAAIQgMCzEOCg8Cx3kuuAAAQgAAEIQAACEIDAjgQ4KOwIk1EQgAAEIAABCEAAAhB4FgL/HxT9Z1/RDxu0AAAAAElFTkSuQmCC)
但这种方式的弊端也显而易见,攻击者可以通过翻看前端js代码,获取加密模式、填充方式、偏移量、数据块大小、密码等解密数据,调试后可以通过编写python脚本对密码字典进行加密。
![](https://download.qingteng.cn/frontendcdn//medias/image/3a082c919c140249af65df35a1cc8eb7.png)
非对称加密和自定义加密算法
随着密码学的发展,RSA2作为新一代非对称加密算法逐渐被运用到前端加密中,由于公私钥分离,这在一定程度上提高了攻击者调试的门槛。
![](https://download.qingteng.cn/frontendcdn//medias/image/ce5c0e49064609cf18f69786d54ccc6a.png)
此外,有些开发者会自定义加密函数对密码字段进行加密。作为应对措施,攻击者可提取网页中对密码进行加密的那段JS代码,通过BurpCrypto插件为intruder模块添加processor,把暴破的payload加密。
![](https://download.qingteng.cn/frontendcdn//medias/image/de54181dc8c9124d9fdb8d39195c5174.png)
webpack打包
随着前后端分离的热潮,webpack工具逐渐应用于vue等框架中。webpack除了缩小项目体积,提高加载速度外,还对代码进行了一定程度的混淆,极大降低了前端JS代码的可读性。
![](https://download.qingteng.cn/frontendcdn//medias/image/da9b305b08395d3ef747552e1982e33b.png)
攻击者若要对webpack打包的网站进行暴力破解,需要掌握JS断点调试等逆向技术,或挖掘到该网站的sourcemap泄露漏洞,利用.js.map文件来进行逆向还原,这给暴破带来不小的难度。
二、使用自动化测试工具绕过前端加密
那么,有没有一种方式可以忽略一切前端加密措施,模拟用户在浏览器手动输入账号密码呢?实际上,在Web自动化测试领域,往往使用Python等脚本语言将以前的人为测试转化为机器测试,极大提高测试效率。我们可以借助pyppeteer、selenium、playwright等Web 浏览器自动化工具来暴破账号密码。
将playwright武装成爆破工具
Playwright 是微软在 2020 年初开源的新一代自动化测试工具,它的功能类似于 Selenium、Pyppeteer 等,都可以驱动浏览器进行各种自动化操作。
使用playwright模拟用户登录操作
Playwright 目前提供了 Python 和 Node.js 的 API,这里我们使用python。
![](https://download.qingteng.cn/frontendcdn//medias/image/0675f9d57508c9a26cc3ef9577ea5cc6.png)
首先,我们导入Playwright库中的sync_playwright模块,用于同步执行Playwright库中的函数。然后,代码定义了一个主函数,用来执行浏览器操作。
在主函数中,首先定义了要访问的URL,以及登录的用户名和密码。然后,使用sync_playwright()函数创建了一个新的浏览器对象,并使用p.chromium.launch(headless=False)函数打开了一个新的浏览器窗口。为了方便观看效果,我们取消了默认的无头浏览器模式。
然后,使用browser.new_context()函数创建了一个新的浏览器上下文,并设置了本地语言为中文和忽略HTTPS错误。随后,使用context.new_page()函数创建了一个新的浏览器页面,并使用page.goto()函数访问了给定的URL。然后,使用page.once()函数注册了一个回调函数,用来处理页面中弹出的对话框。
接下来,代码使用了两个page.locator()函数来填写登录表单中的用户名和密码。最后,使用page.get_by_role()函数找到了页面中的登录按钮,并使用click()方法点击了它,以完成登录操作。通过sleep语句,我们可以更直观地看到效果。
![](https://download.qingteng.cn/frontendcdn//medias/image/771971dfdffa7fa53c4a514cbd4e5006.gif)
通过响应包特征判断登录是否成功
通过抓包我们可以发现,如果密码不正确,响应包会出现Please enter valid LoginName and Password,我们可以以此为依据判断暴破是否成功。
![](https://download.qingteng.cn/frontendcdn//medias/image/126de7af481546065a2aa0b4fd84af40.png)
我们可以定义一个新的函数on_response(),用来处理页面的响应事件。这个函数接收一个参数response,表示页面的响应对象。在函数中,首先使用response.finished()方法确保响应已完成,然后检查响应的URL和请求方法是否与预期的值相等。如果相等,则检查响应的文本内容是否包含特定的关键字,如果不包含,则表示登录成功,打印出相应的消息。之后,我们可以使用page.on()函数注册上面定义的on_response()函数,用来处理页面的响应事件。相关代码如下:
![](https://download.qingteng.cn/frontendcdn//medias/image/8bd18f05ee8217b9e2fa479d6c472577.png)
![](https://download.qingteng.cn/frontendcdn//medias/image/1c478baa5535e164e621ccd6afb3c7d0.gif)
通过前端页面特征判断登录是否成功
对于部分防护严密的网站,往往后端响应包经过加密,此时难以定位响应包特征,因此我们可以通过提取前端页面特征判断是否登录成功,如最常见的标题。如果登录后标题还是带登录页、Login Page等特征,则说明账号或密码错误,跳转回了登录页。
![](https://download.qingteng.cn/frontendcdn//medias/image/b6a6af3e7a675be3ad93eca030f06bc6.png)
通过OCR技术绕过图形验证码
如果登录界面存在验证码,我们可以使用OCR库或者第三方API帮我们识别验证码结果。这里我们使用国内开发者开发的ddddocr库。
![](https://download.qingteng.cn/frontendcdn//medias/image/9af5de4d33807250e493e0d3a6eb2b82.png)
我们首先使用ddddocr.DdddOcr()函数创建了一个新的验证码识别器对象,然后定义了要访问的URL,以及登录的用户名和密码的列表。接下来,我们使用page.locator()函数获取页面上的验证码图片,并使用page.screenshot()函数截取图片并保存到本地。然后,我们使用open()函数打开保存的图片文件,并使用ocr.classification()函数将图片中的验证码识别出来,再使用page.fill()函数将识别出的验证码填入输入框。
![](https://download.qingteng.cn/frontendcdn//medias/image/4cca2b06b47a54be51bcd8969f8ced43.gif)
通过模拟鼠标操作绕过简易滑块验证码
在实战中,我们经常也会遇到带滑块的验证码,这时就需要我们运用playwright的api模拟鼠标操作,代码如下。
![](https://download.qingteng.cn/frontendcdn//medias/image/b475bf574ad4eba350e2e0aaa007c899.png)
![](https://download.qingteng.cn/frontendcdn//medias/image/88fe2e9cb5dd8a1c75df383bba329cf0.png)
在这段代码中,bounding_box 方法用来获取一个元素(通过 locator 方法查找到的元素)在页面中的位置和大小。我们通过对page.mouse对象进行操作,首先模拟鼠标移动到滑块中心位置,通过down方法按住滑块,然后通过move方法让滑块滑动到最右边,之后再用up方法将鼠标松开,这样我们就模拟了一个正常用户的操作。
![](https://download.qingteng.cn/frontendcdn//medias/image/1a1530495ef9dcd842031b29642af9b0.gif)
三、结语
随着开发人员安全意识的加强,暴力破解的难度也在逐步提高,可以预见到的是将密码明文传输的网站会越来越少。通过利用web的自动化测试工具,我们可以尽可能模拟真实用户的登录操作来突破前端防御策略。
关于作者:
Lion:青藤红队一队成员,主要研究方向为红蓝对抗和红队武器库开发。