Smooth Operator
Contents
Smooth Operator
Malware Analysis Report
Version 1.0
29 June 2023
© Crown Copyright 2023
Smooth Operator
macOS supply chain malware that exfiltrates victim data using a
custom data encoding algorithm over HTTPS
Executive summary
•
•
•
•
•
•
Smooth Operator malware targets macOS.
Smooth Operator was distributed to victims as part of the 3CX supply chain attack.
The infected software package was signed by 3CX and notarized by Apple.
Malicious code inserted into a dynamic library (dylib) packaged with the 3CX software
downloads and runs a second-stage payload.
HTTPS is used as a C2 channel, with an additional custom encoding algorithm used to
obfuscate exfiltrated data.
Smooth Operator randomises the C2 server it communicates with. The 3CX website is
included in the list of C2 Servers it can beacon to.
Introduction
Smooth Operator malware was distributed as part of the widely reported 3CX supply chain attack,
outed in March 2023. Windows and Mac systems were both targeted as part of the attack, in which
malicious updated software packages were distributed via legitimate channels.
This report …
Malware Analysis Report
Version 1.0
29 June 2023
© Crown Copyright 2023
Smooth Operator
macOS supply chain malware that exfiltrates victim data using a
custom data encoding algorithm over HTTPS
Executive summary
•
•
•
•
•
•
Smooth Operator malware targets macOS.
Smooth Operator was distributed to victims as part of the 3CX supply chain attack.
The infected software package was signed by 3CX and notarized by Apple.
Malicious code inserted into a dynamic library (dylib) packaged with the 3CX software
downloads and runs a second-stage payload.
HTTPS is used as a C2 channel, with an additional custom encoding algorithm used to
obfuscate exfiltrated data.
Smooth Operator randomises the C2 server it communicates with. The 3CX website is
included in the list of C2 Servers it can beacon to.
Introduction
Smooth Operator malware was distributed as part of the widely reported 3CX supply chain attack,
outed in March 2023. Windows and Mac systems were both targeted as part of the attack, in which
malicious updated software packages were distributed via legitimate channels.
This report …
IoC
3dc840d32ce86cebf657b17cef62814646ba8e98
5faf36ca90f6406a78124f538a03387a
660ea9b8205fbd2da59fefd26ae5115c
6c121f2b2efa6592c2c22b29218157ec9e63f385e7a1d7425857d603ddef8c59
769383fc65d1386dd141c960c9970114547da0c2
88470888470D884712884717C6472400
9e9a5f8d86356796162cee881c843cde9eaedfb3
a64fa9f1c76457ecc58402142a8728ce34ccba378c17318b3340083eeb7acc67
d5101c3b86d973a848ab7ed79cd11e5a
e6bbc33815b9f20b0cf832d7401dd893fbc467c800728b5891336706da0dbcec
http://akamaitechcloudservices.com
http://akamaitechcloudservices.com/v2/fileapi
http://azuredeploystore.com
http://azuredeploystore.com/cloud/images
http://azureonlinestorage.com
http://azureonlinestorage.com/google/storage
http://glcloudservice.com
http://glcloudservice.com/v1/status
http://msedgepackageinfo.com
http://msedgepackageinfo.com/ms-webview
http://msstorageazure.com
http://msstorageazure.com/analysis
http://msstorageboxes.com
http://msstorageboxes.com/xbox
http://officeaddons.com
http://officeaddons.com/quality
http://officestoragebox.com
http://officestoragebox.com/api/biosync
http://pbxcloudeservices.com
http://pbxcloudeservices.com/network
http://pbxphonenetwork.com
http://pbxphonenetwork.com/phone
http://pbxsources.com
http://pbxsources.com/queue
http://sbmsa.wiki
http://sourceslabs.com
http://sourceslabs.com/status
http://visualstudiofactory.com
http://visualstudiofactory.com/groupcore
http://zacharryblogs.com
http://zacharryblogs.com/xmlquery
https://akamaitechcloudservices.com/v2/fileapi
https://azuredeploystore.com/cloud/images
https://azureonlinestorage.com/google/storage
https://developer.apple.com/documentation/security/seccodesignatureflags/1397793-adhoc
https://glcloudservice.com/v1/status
https://msedgepackageinfo.com/ms-webview
https://msstorageazure.com/analysis
https://msstorageboxes.com/xbox
https://officeaddons.com/quality
https://officestoragebox.com/api/biosync
https://pbxcloudeservices.com/network
https://pbxphonenetwork.com/phone
https://pbxsources.com/queue
https://sbmsa.wiki/blog/_insert
https://sourceslabs.com/status
https://visualstudiofactory.com/groupcore
https://zacharryblogs.com/xmlquery
rule Smooth_Operator_C2_codes {
meta:
author = "NCSC"
description = "This rule identifies sections of code which are
responsible for parsing tasking command codes in Smooth Operator."
date = "2023-06-29"
hash1 = "769383fc65d1386dd141c960c9970114547da0c2"
strings:
$ = {80340F7A48FFC14839C8} // XOR deobfuscate tasking
$ = {8B073D4938000074??3D018000008B4C24??0F[3-6]3D01900000} // C2
codes
condition:
((uint32(0) == 0xFEEDFACF) or (uint32(0) == 0xFEEDFACE) or
(uint32(0) == 0xCAFEBABE) or (uint32(0) == 0xCAFEBABF)) and all of them
}
rule Smooth_Operator_II {
meta:
author = "NCSC"
description = "This rule identifies strings observed in the
second stage of Smooth Operator."
date = "2023-06-29"
hash1 = "9e9a5f8d86356796162cee881c843cde9eaedfb3"
strings:
$ = "3cx_auth_id=%s;3cx_auth_token_content=%s;__tutma=true"
$ = "AccountName\":"
$ = "url\": \"https://"
$ = "%s/Library/Application Support/3CX Desktop
App/.main_storage"
$ = "%s/Library/Application Support/3CX Desktop App/config.json"
$ = "read_config"
$ = "enc_text"
$ = "send_post"
$ = "parse_json_config"
condition:
((uint32(0) == 0xFEEDFACF) or (uint32(0) == 0xFEEDFACE) or
(uint32(0) == 0xCAFEBABE) or (uint32(0) == 0xCAFEBABF)) and 5 of them
}
rule Smooth_Operator_Obfuscation {
meta:
author = "NCSC"
description = "This rule identifies unique strings and code
present in the C2 string obfuscation code of Smooth Operator."
date = "2023-06-29"
hash1 = "769383fc65d1386dd141c960c9970114547da0c2"
hash2 = "9e9a5f8d86356796162cee881c843cde9eaedfb3"
strings:
$ = {48 69 ?? 61 60 60 60 48 89 ?? 48 C1 EA 3F 48 C1 ?? 25 01
?? 6B ?? 55}
$ = "!#$%&()*+.0123456789:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghi"
$ = {3E00C7[5-6]26706572} // &per
$ = {3E00C7[5-6]26646F6C} // &dol
$ = {75733E00C7[5-6]26706C75} // &plus
$ = {6D693E00C7[5-6]2673656D} // &semi
condition:
((uint32(0) == 0xFEEDFACF) or (uint32(0) == 0xFEEDFACE) or
(uint32(0) == 0xCAFEBABE) or (uint32(0) == 0xCAFEBABF)) and all of them
}
rule Smooth_Operator_Obfuscation_2 {
meta:
author = "NCSC"
description = "This rule identifies unique code sections in the
C2 string obfuscation algorithm."
date = "2023-06-29"
hash1 = "769383fc65d1386dd141c960c9970114547da0c2"
hash2 = "9e9a5f8d86356796162cee881c843cde9eaedfb3"
strings:
$a_1 = {4869C8616060604889CA48C1EA3F48C1F92501D16BC95529C8[03]83F807}
$b_1 = {438D1C24F7DB41F7DC} // neg
$b_2 = {478D3C3641F7DF41F7DE} // neg
condition:
((uint32(0) == 0xFEEDFACF) or (uint32(0) == 0xFEEDFACE) or
(uint32(0) == 0xCAFEBABE) or (uint32(0) == 0xCAFEBABF)) and any of ($b*)
and $a_1
}
rule Smooth_Operator_Sleeps {
meta:
author = "NCSC"
description = "This rule identifies algorithms used by the
malware developer to generate random time values in Smooth Operator."
date = "2023-06-29"
hash1 = "769383fc65d1386dd141c960c9970114547da0c2"
strings:
$ =
{E8[4]E8[4]89C14869C93FC5254348C1E9246BC93D29C86BE83C81C5100E0000B80F0000
00} // between beacon time generation
$ = {E8[4]E8[4]89C1490FAFCE48C1E9238D0C898D0C4929C8} // C2 index
$ =
{89E8D1E841BE932449924C0FAFF049C1EE224489F0C1E0044489F129C14101EE4101CE48
8DBC24[4]4C892FE8} // initial sleep
condition:
((uint32(0) == 0xFEEDFACF) or (uint32(0) == 0xFEEDFACE) or
(uint32(0) == 0xCAFEBABE) or (uint32(0) == 0xCAFEBABF)) and any of them
}
rule Smooth_Operator_Strings {
meta:
author = "NCSC"
description = "This rule identifies broader functionality across
Smooth Operator, identifying strings observed throughout."
date = "2023-06-29"
hash1 = "769383fc65d1386dd141c960c9970114547da0c2"
strings:
$ = {80 [2] 7A 48 FF C0 48 83 F8 38} // .main_storage XOR loop
$ = "<key>ProductVersion</key>"
$ = ".session-lock"
$ = "%s/.main_storage"
$ = "%s/UpdateAgent"
$ =
{3715001316161B554F544A5A522D13141E150D095A342E5A4B4A544A415A2D13144C4E41
5A024C4E535A3B0A0A161F2D1F1831130E554F494D54494C5A5231322E3736565A1613111
F5A3D1F191115535A39120815171F554B4A42544A544F494F43544B48425A291B1C1B0813
554F494D54494C} // XOR'd UA
$ = {B02D[0-8]88470888470D884712884717C6472400} // victim ID
generation
condition:
((uint32(0) == 0xFEEDFACF) or (uint32(0) == 0xFEEDFACE) or
(uint32(0) == 0xCAFEBABE) or (uint32(0) == 0xCAFEBABF)) and 4 of them
}
5faf36ca90f6406a78124f538a03387a
660ea9b8205fbd2da59fefd26ae5115c
6c121f2b2efa6592c2c22b29218157ec9e63f385e7a1d7425857d603ddef8c59
769383fc65d1386dd141c960c9970114547da0c2
88470888470D884712884717C6472400
9e9a5f8d86356796162cee881c843cde9eaedfb3
a64fa9f1c76457ecc58402142a8728ce34ccba378c17318b3340083eeb7acc67
d5101c3b86d973a848ab7ed79cd11e5a
e6bbc33815b9f20b0cf832d7401dd893fbc467c800728b5891336706da0dbcec
http://akamaitechcloudservices.com
http://akamaitechcloudservices.com/v2/fileapi
http://azuredeploystore.com
http://azuredeploystore.com/cloud/images
http://azureonlinestorage.com
http://azureonlinestorage.com/google/storage
http://glcloudservice.com
http://glcloudservice.com/v1/status
http://msedgepackageinfo.com
http://msedgepackageinfo.com/ms-webview
http://msstorageazure.com
http://msstorageazure.com/analysis
http://msstorageboxes.com
http://msstorageboxes.com/xbox
http://officeaddons.com
http://officeaddons.com/quality
http://officestoragebox.com
http://officestoragebox.com/api/biosync
http://pbxcloudeservices.com
http://pbxcloudeservices.com/network
http://pbxphonenetwork.com
http://pbxphonenetwork.com/phone
http://pbxsources.com
http://pbxsources.com/queue
http://sbmsa.wiki
http://sourceslabs.com
http://sourceslabs.com/status
http://visualstudiofactory.com
http://visualstudiofactory.com/groupcore
http://zacharryblogs.com
http://zacharryblogs.com/xmlquery
https://akamaitechcloudservices.com/v2/fileapi
https://azuredeploystore.com/cloud/images
https://azureonlinestorage.com/google/storage
https://developer.apple.com/documentation/security/seccodesignatureflags/1397793-adhoc
https://glcloudservice.com/v1/status
https://msedgepackageinfo.com/ms-webview
https://msstorageazure.com/analysis
https://msstorageboxes.com/xbox
https://officeaddons.com/quality
https://officestoragebox.com/api/biosync
https://pbxcloudeservices.com/network
https://pbxphonenetwork.com/phone
https://pbxsources.com/queue
https://sbmsa.wiki/blog/_insert
https://sourceslabs.com/status
https://visualstudiofactory.com/groupcore
https://zacharryblogs.com/xmlquery
rule Smooth_Operator_C2_codes {
meta:
author = "NCSC"
description = "This rule identifies sections of code which are
responsible for parsing tasking command codes in Smooth Operator."
date = "2023-06-29"
hash1 = "769383fc65d1386dd141c960c9970114547da0c2"
strings:
$ = {80340F7A48FFC14839C8} // XOR deobfuscate tasking
$ = {8B073D4938000074??3D018000008B4C24??0F[3-6]3D01900000} // C2
codes
condition:
((uint32(0) == 0xFEEDFACF) or (uint32(0) == 0xFEEDFACE) or
(uint32(0) == 0xCAFEBABE) or (uint32(0) == 0xCAFEBABF)) and all of them
}
rule Smooth_Operator_II {
meta:
author = "NCSC"
description = "This rule identifies strings observed in the
second stage of Smooth Operator."
date = "2023-06-29"
hash1 = "9e9a5f8d86356796162cee881c843cde9eaedfb3"
strings:
$ = "3cx_auth_id=%s;3cx_auth_token_content=%s;__tutma=true"
$ = "AccountName\":"
$ = "url\": \"https://"
$ = "%s/Library/Application Support/3CX Desktop
App/.main_storage"
$ = "%s/Library/Application Support/3CX Desktop App/config.json"
$ = "read_config"
$ = "enc_text"
$ = "send_post"
$ = "parse_json_config"
condition:
((uint32(0) == 0xFEEDFACF) or (uint32(0) == 0xFEEDFACE) or
(uint32(0) == 0xCAFEBABE) or (uint32(0) == 0xCAFEBABF)) and 5 of them
}
rule Smooth_Operator_Obfuscation {
meta:
author = "NCSC"
description = "This rule identifies unique strings and code
present in the C2 string obfuscation code of Smooth Operator."
date = "2023-06-29"
hash1 = "769383fc65d1386dd141c960c9970114547da0c2"
hash2 = "9e9a5f8d86356796162cee881c843cde9eaedfb3"
strings:
$ = {48 69 ?? 61 60 60 60 48 89 ?? 48 C1 EA 3F 48 C1 ?? 25 01
?? 6B ?? 55}
$ = "!#$%&()*+.0123456789:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghi"
$ = {3E00C7[5-6]26706572} // &per
$ = {3E00C7[5-6]26646F6C} // &dol
$ = {75733E00C7[5-6]26706C75} // &plus
$ = {6D693E00C7[5-6]2673656D} // &semi
condition:
((uint32(0) == 0xFEEDFACF) or (uint32(0) == 0xFEEDFACE) or
(uint32(0) == 0xCAFEBABE) or (uint32(0) == 0xCAFEBABF)) and all of them
}
rule Smooth_Operator_Obfuscation_2 {
meta:
author = "NCSC"
description = "This rule identifies unique code sections in the
C2 string obfuscation algorithm."
date = "2023-06-29"
hash1 = "769383fc65d1386dd141c960c9970114547da0c2"
hash2 = "9e9a5f8d86356796162cee881c843cde9eaedfb3"
strings:
$a_1 = {4869C8616060604889CA48C1EA3F48C1F92501D16BC95529C8[03]83F807}
$b_1 = {438D1C24F7DB41F7DC} // neg
$b_2 = {478D3C3641F7DF41F7DE} // neg
condition:
((uint32(0) == 0xFEEDFACF) or (uint32(0) == 0xFEEDFACE) or
(uint32(0) == 0xCAFEBABE) or (uint32(0) == 0xCAFEBABF)) and any of ($b*)
and $a_1
}
rule Smooth_Operator_Sleeps {
meta:
author = "NCSC"
description = "This rule identifies algorithms used by the
malware developer to generate random time values in Smooth Operator."
date = "2023-06-29"
hash1 = "769383fc65d1386dd141c960c9970114547da0c2"
strings:
$ =
{E8[4]E8[4]89C14869C93FC5254348C1E9246BC93D29C86BE83C81C5100E0000B80F0000
00} // between beacon time generation
$ = {E8[4]E8[4]89C1490FAFCE48C1E9238D0C898D0C4929C8} // C2 index
$ =
{89E8D1E841BE932449924C0FAFF049C1EE224489F0C1E0044489F129C14101EE4101CE48
8DBC24[4]4C892FE8} // initial sleep
condition:
((uint32(0) == 0xFEEDFACF) or (uint32(0) == 0xFEEDFACE) or
(uint32(0) == 0xCAFEBABE) or (uint32(0) == 0xCAFEBABF)) and any of them
}
rule Smooth_Operator_Strings {
meta:
author = "NCSC"
description = "This rule identifies broader functionality across
Smooth Operator, identifying strings observed throughout."
date = "2023-06-29"
hash1 = "769383fc65d1386dd141c960c9970114547da0c2"
strings:
$ = {80 [2] 7A 48 FF C0 48 83 F8 38} // .main_storage XOR loop
$ = "<key>ProductVersion</key>"
$ = ".session-lock"
$ = "%s/.main_storage"
$ = "%s/UpdateAgent"
$ =
{3715001316161B554F544A5A522D13141E150D095A342E5A4B4A544A415A2D13144C4E41
5A024C4E535A3B0A0A161F2D1F1831130E554F494D54494C5A5231322E3736565A1613111
F5A3D1F191115535A39120815171F554B4A42544A544F494F43544B48425A291B1C1B0813
554F494D54494C} // XOR'd UA
$ = {B02D[0-8]88470888470D884712884717C6472400} // victim ID
generation
condition:
((uint32(0) == 0xFEEDFACF) or (uint32(0) == 0xFEEDFACE) or
(uint32(0) == 0xCAFEBABE) or (uint32(0) == 0xCAFEBABF)) and 4 of them
}