24 Hour Technical Support & Seattle Computer Repair
support@seattlecomputer.repair (206) 657-6685
We accept insurance coverage!
Virus, Spyware, & Malware Removal
- Details
- Tech Support by: Emerald City IT
- Support Field: Computer Repair and Tech Support
- Support Category: Virus, Spyware, & Malware Removal
- Details
- Tech Support by: Emerald City IT
- Support Field: Computer Repair and Tech Support
- Support Category: Virus, Spyware, & Malware Removal
In early March, one of the notorious botnets, Emotet, resumed its spamming activities after a 3-month period of inactivity.
Recently, Trustwave SpiderLabs saw Emotet switch focus to using OneNote attachments, which is a tactic also adopted by other malware groups in recent months. This analysis is intended to help the cybersecurity community better understand the wider obfuscation and padding tricks Emotet is using.
For a more in-depth analysis of this technique, please refer to our series of blog posts which can be found here: Trojanized OneNote, A Noteworthy Threat, and OneNote Spear-Phishing Campaign.
At first, this spam campaign followed the typical scenario with a document file carrying malware that was attached to a convincing reply-chain email. However, Emotet used a ‘new old trick’ in an attempt to bypass security scanners by compressing a bloated document file into a ZIP file.
Figure 1. Recent Emotet spam campaign with a ZIP compressed document file
Twitter handle @Cryptolaemus1 who tracks this botnet noticed this spam activity coming from Emotet Epoch 4.
Figure 2. A tweet from Cryptolaemus
At the surface level, the ZIP file appears small in file size but when extracting the document from the ZIP, we see that the decompressed file size is a little over 500MB. Upon further investigation of the document, we found the reason for the abnormal file size is a zero-byte padding technique.
This technique is where a file's size is inflated by appending null bytes or useless data to the end of a file. Often, this is done as an evasion technique to avoid security software as many tools do not allow uploading or scanning of large files. It is extremely suspicious, so much so, that our Trustwave MailMarshal email gateway simply blocked all the samples up-front due to the massively redundant data.
Figure 3. Suspicious document before the padding is removed.
After removing most of the padding, the file comes down to just 303KB.
Figure 4. Suspicious document after the padding is removed.
Deobfuscating the Macro:
The document file is similar to previous Emotet spam campaigns and includes a highly obfuscated malicious macro. The code obfuscation may initially appear messy and difficult to read.
Figure 5. Emotet’s obfuscated VBA macro1
It contains random function and variable names, as well as thousands of lines of seemingly unused code. However, there is a recognizable macro name present in the code: AutoOpen. This macro is an event that is triggered when the document file is opened, making it the entry point function.
Figure 6. Emotet’s use of random macro names2
Within the AutoOpen macro, a specific function named ‘uYiCsM’ is called. This is repeatedly called throughout the code, appearing a total of 41 times.
Figure 7. Function uYiCsM is the decode function3
Before calling the decode function, a block of code initializes the variables that will be passed as parameters to the decode function. These parameters include the character table, a list of character indices, and string length.
Figure 8. Before calling the decode function, it initializes variables for the string length, the character table.
Deobfuscating a single string can require a block of code that is notably lengthy and may span several hundred lines of code. Nevertheless, as one delves deeper into the code, a pattern may start to emerge and become easier to discern.
Figure 9. Initializing character indices is a pattern that becomes evident throughout the code. However, assigning a single value to one index uses three lines of code, contributing to the code's overall length and complexity.
The length of obfuscated code is primarily due to the initialization of the list of character indices, which can be convoluted. Additionally, the use of individual lines of code to assign each value to an index can contribute to the overall length of the code.
The code below is the decode function that takes a character table and a list of character indices and uses them to decode a string by reading characters from the character table based on the indices and appending them to a new string.
Figure 10. Obfuscated code of the decode function.
Figure 11. Right is the deobfuscated and beautified code for easy readability.
Figure 12. We converted the decode function into a Python code to decode the strings in a controlled manner.
Once strings are decoded, we can refactor the code and beautify it for easy readability. We have shared the complete deobfuscated VBA macro code in our Gists.
Figure 13. Comparison of the obfuscated and the deobfuscated AutoOpen macro.
This summary describes the flow of the AutoOpen macro:
- Declare variables and assign values to the variables for URLs and file extensions.
- Generate a filepath with the current time and append the ‘.tmp’ file extension to it.
- Try to download a file from the first URL, and if that fails, try to download from the remaining URLs until a download is successful.
- If a download is successful, it checks whether the file is a PE or a ZIP archive.
- If the file is a ZIP archive, the malware unpacks the binary.
- Proceeds to execute the binary via regsvr32.exe.
It is worth noting that the file extracted from the downloaded archive also contains an excessive amount of null bytes, which gives the impression that it is a much larger file than it actually is.
IOCs
URLs
hxxp://xyktza.nbxyk.net/bwzysov/index/X3hFHbueMtgoEi/etaJ35/ |
hxxp://arlex.su/services/IE2h6fBsQRQOhHBI691U/ |
hxxp://api.660011.cc/wp-includes/b028GIRSxa4lY/ |
hxxp://www.garrett.kz/faq/B0faEHvS9msSo9xbVe/ |
hxxp://abrokov.com/lang/SZnqErcEtuE/ |
hxxp://rref.su/uchastniki/rNNdVArBjNc100n3p/ |
hxxp://mealux.by/pab4/wxuGxcqF85M/ |
Hashes
File Name | Hash Type | Hashes |
ACH Payment info.zip | MD5 | 68612b3d0094d51d3ca89ed6e3b16b4c |
SHA1 | b80ac7dda1b65be5297ba03b1ac17dbc2bb10339 | |
SHA256 | 7041a0d1b2d0c1199e4b7505b0ab181ad2cdc881e01a520fb66758f081e4d40d |
File Name | Hash Type | Hashes |
ACH Payment info.doc | MD5 | 141c079135312197dcb6d2adfe8b5663 |
SHA1 | 4f2e8fcbdb60e099241c0e8e203c700d9d4941b2 | |
SHA256 | 57903dc1811ef431a8480dc489764d9b2dae324fcf002c924c8f3a592b96a922 |
File Name | Hash Type | Hashes |
downloaded.zip | MD5 | 20758c45171dfad6bb02a77b773782d3 |
SHA1 | e0ea8e2d0580ffe40ec5ed3bdd2bb78c6c7b2ffb | |
SHA256 | a189c6cecce39ab05abb5386ca036887170c28a40cd1acd76dd7b4c36e0a2d9d |
File Name | Hash Type | Hashes |
sHwNyPFidh5lkT7KX86sNryPMvM4.dll | MD5 | fa914c6c9744ea25592dfca65a9d13e1 |
SHA1 | 663861e36c8d55911a036bbc9108c3d774a97b2a | |
SHA256 | cecdb3028c0879a850ccbf0535cc3918912d9b6e19b40b6dbfedb0c58265227c |
- Details
- Tech Support by: Emerald City IT
- Support Field: Computer Repair and Tech Support
- Support Category: Virus, Spyware, & Malware Removal
Trustwave SpiderLabs uncovered a new strain of malware that it dubbed Rilide, which targets Chromium-based browsers such as Google Chrome, Microsoft Edge, Brave, and Opera.
Rilide malware is disguised as a legitimate Google Drive extension and enables threat actors to carry out a broad spectrum of malicious activities, including monitoring browsing history, taking screenshots, and injecting malicious scripts to withdraw funds from various cryptocurrency exchanges.
Rilide is not the first malware SpiderLabs has observed using malicious browser extensions. Where this malware differs is it has the effective and rarely used ability to utilize forged dialogs to deceive users into revealing their two-factor authentication (2FA) and then withdraw cryptocurrencies in the background. During our investigation into Rilide’s origins, we uncovered similar browser extensions being advertised for sale. Additionally, we found that part of its source code was recently leaked on an underground forum due to a payment dispute.
Malicious Campaigns Leading to Rilide Stealer Extension
SpiderLabs uncovered two malicious campaigns leading to the installation of the Rilide extension.
Figure 1. Infection Chains Leading to the Execution of the Rilide Extension
Campaign 1: Ekipa RAT Installing Rilide Stealer
One of the Rilide samples identified by Trustwave SpiderLabs was distributed through a malicious Microsoft Publisher file. This file is part of Ekipa RAT, a Remote Access Trojan (RAT), designed for targeted attacks and often sold on underground forums.
We previously described Ekipa RAT in one of our blogs. It is important to note that Microsoft Publisher was not affected by Microsoft's decision to block macros from executing files downloaded from the Internet. As a result, when a user attempted to open a Publisher file, they would receive a warning but could still enable the execution of malicious content by clicking the ‘Enable Macros’ button. On 14 February 2023, Microsoft issued an update that resolved the Publisher security flaw. With the implementation of the ‘Mark of the Web’ feature on the .pub file, users are now left with only one option, ‘Disable Macros,’ which should have been the case all along.
Any association between the threat actors behind Ekipa RAT and those using the Rilide infostealer remains unclear. However, it is probable that Ekipa RAT was tested as a means of distribution for Rilide, before finally switching to Aurora stealer.
Figure 2. Publisher’s macro and Document_Open procedure executing remote Excel Workbook
Three tasks were configured on the C2 server:
- Download payload from hxxps://nch-software[.]info/1/2[.]exe to %temp% directory as.txt
- Change downloaded file’s extension to .exe
- Execute the payload.
File 2.exe is a Rust-based loader, responsible for installing the Rilide extension for Chromium-based browsers.
Campaign 2: Aurora Stealer Abusing Google Ads
Aurora is a Go-based stealer, which was initially spotted being advertised in April 2022 as a Malware-as-a-Service (MaaS) on Russian-speaking underground forums. The malware is designed to target data from multiple web browsers, cryptocurrency wallets, and local systems.
Recently, the threat actors behind Aurora have been observed abusing the Google Ads platform to spread the malware. According to a report published by Cyble, campaigns mimicking legitimate Team Viewer installers have been utilized to deploy Aurora. As reported by @1ZRR4H and @malwrhunterteam, Aurora was also spread via another campaign that imitated an NVIDIA Drivers installer. A downloaded sample was packed with Themida, a well-known commercial protector for executables. We used the UnpacMe service to unpack the sample.
Figure 3. Aurora campaign imitating the NVIDIA Drivers installer as shown in 1ZRR4H’s Twitter post
Restoring Function Names
The Aurora Stealer sample was stripped of debugging symbols, thus making the analysis harder. Since Go binaries are statically linked, which means that all the necessary libraries are included in the compiled binary, the number of potential functions to analyze is large. However, the original function names can be restored from the pclntab structure, as described in the CUJOAI Senior Threat Researcher Dorka Palotay’s post. Using the go_func.py script for Ghidra we were able to restore the functions names.
How an Aurora Module Downloaded Rilide Stealer
One of the eight grabbing modules, configured in the analyzed sample, contained a base64 encoded blob of data storing the URL for the Rilide Rust-based loader. The payload, hosted on Discord CDN, was saved to the %temp% directory with filename <10-alpahnumeric-characters>.exe and executed via start-process PowerShell cmdlet.
Figure 4. Part of Aurora Stealer routine downloading and executing Rilide loader
The Common Link Between Two Campaigns
The Rilide Rust-based loader samples analyzed as part of the Aurora campaign were packed with a VMProtect commercial packer. After unpacking the samples and analyzing strings contained in the binary, we found multiple references to Windows paths in the C:\Users\ilide\ directory. The same username was observed in the PDB Path of the Rilide sample obtained from the Ekipa RAT campaign.
Figure 5. The same username in a path found in Rilide Rust-based loaders samples from both campaigns.
Rilide Stealer Extension Targeting Chromium-Based Browsers
Rilide leverages a Rust loader used to install the extension if a Chromium-based browser is detected. Rilide mimics benign Google Drive Extensions and abuses several built-in chrome functionalities. The loader modifies LNK shortcut files opening targeted browsers, so that they are executed with parameter --load-extension pointing to the dropped malicious Rilide extension.
Figure 6. Rilide Stealer extension mimicking Google Drive and looking at its manifest revealing the configured permissions
Rilide’s background script attaches a listener to the tabs.onActivated and webRequest.onHeadersReceived events and removes the Content Security Policy (CSP) directive for all requests. This allows the extension to perform an XSS attack and load external resources that would otherwise be blocked by the CSP. The app script adds another listener to the DOMContentLoaded event and retrieves a list of targeted domains from the C2. If the current domain matches any of the listed targets, designated scripts are injected into the webpage.
Figure 7. Configuration list indicating targets such as email services and cryptocurrency exchanges.
Additionally, the background script carries out regular checks on the browsing history and exfiltrates URLs that are matched against the targeted domain list. Moreover, it is capable of capturing and exfiltrating screenshots of the currently active tabs on demand.
Figure 8. Rilide Stealer Execution Flow and Functionalities
Automatic Cryptocurrency Withdrawal
Rilide’s crypto exchange scripts support automatic withdrawal function. While the withdrawal request is made in the background, the user is presented with forged device authentication dialog in order to obtain 2FA. Email confirmations are also replaced on the fly if the user enters the mailbox using the same web browser. The withdrawal request email is replaced with a device authorization request tricking the user into providing the authorization code.
Figure 9. Withdrawal Requests replaced with Authorize New Device emails in Gmail mailbox
Figure 10. Content of the original and forged email. The verification code was extracted from the original message body.
We found no substantial variations in the code between the samples dropped by Ekipa RAT and used in the Aurora Stealer campaign. Both campaigns utilized a Rust dropper, and the functionalities of the browser plugins are nearly the same.
Figure 11. Code differences between Rilide Stealer plugin samples, both using the same C2 server
Rilide Stealer Origins
In the course of our research, we have encountered several stealer extensions for sale that advertised capabilities closely resembling those of the Rilide samples. However, we were unable to definitively link any of them to Rilide. One noteworthy finding was a botnet sale advertisement from an underground forum dated March 2022. Although the advertised functionalities matched those of Rilide, the botnet also included additional features such as a reverse proxy and ad clicker. Notably, the botnet's automatic withdrawal function supported the same exchanges observed in the Rilide samples.
Figure 12. Underground forum post advertising sale of botnet with Rilide-like capabilities
On February 27, 2023, a member of the same underground forum posted a link to the source code for the Rilide extension, reportedly due to an unresolved payment dispute. The leaked source closely resembles that used in the Aurora Stealer campaign but did not contain any of the injected scripts observed in the campaign sample.
Figure 13. Underground forum post, dated February 27, 2023, containing a link to part of the Rilide extension source code.
Notably there is one feature implemented that is missing in the later versions - swapping cryptocurrency wallet addresses in the clipboard. The list of addresses to be replaced is hard coded in the source code.
Figure 14. Clipboard hijacking routine in the analyzed sample from the forementioned forum post.
Pivoting on the Command-and-Control domain ashgrrwt[.]click hard coded in the sample, we identified additional Rilide loaders leading us to the GitHub user gulantin.
Figure 15. Github repository storing multiple Rilide loader and extension samples
Repositories created by this user contain loaders for the Rilide extension, but they are not Rust-based. The sample in the repository named ‘77’ is a .NET extension loader only for the Chrome browser, unlike the later Rust-based version that works for all Chromium-based browsers. Other loaders found in repositories 19 and 789 are based on Advanced Installer – a legitimate Windows Installer Packaging Tool for MSI installers.
Figure 16. Extension loading routine of the custom .NET loader from gulantin’s repository 77
The address contained in the domain variable that is supposed to store the C2 domain suggests that this version of a loader was still under development when submitted to GitHub.
Figure 17. Part of JavaScript configuration in the Rilide extension hosted on GitHub
Conclusions:
The Rilide stealer is a prime example of the increasing sophistication of malicious browser extensions and the dangers they pose. Disguised as a legitimate Google Drive extension, Rilide provides threat actors with the ability to carry out a wide range of malicious activities, including monitoring browsing history, capturing screenshots, and injecting malicious scripts to steal funds from cryptocurrency exchanges.
While the upcoming enforcement of manifest v3 may make it more challenging for threat actors to operate, it is unlikely to solve the issue entirely as most of the functionalities leveraged by Rilide will still be available.
Informational overload can dull our ability to interpret facts accurately and make us more vulnerable to phishing attempts. It is important to remain vigilant and skeptical when receiving unsolicited emails or messages, and to never assume that any content on the Internet is safe, even if it appears to be.
Ultimately, it is crucial to stay informed and educated about the latest cybersecurity threats and best practices to minimize the risk of falling victim to phishing attacks.
Indicators of Compromise:
Publisher File:
File name | Hash Type | Hash |
Tes7777.pub | SHA256 | 0e31ff6406b03982581246b7dd60f3b96edcf0bd007b31766954df001fd68f69 |
SHA1 | e049f56198c23d86e9083142bfe80042e21d4b8e | |
MD5 | 558104b26ccadec3d3eb2925113387a6 |
Aurora Stealer:
File name | Hash Type | Hash |
PackageLauncher.exe | SHA256 | e623984143e0dc6e35c79869ab1521c6714e588e8e648606496f8372ca0d8416 |
SHA1 | b1c100d5a99ae34ccb3654c7b7f8573376a44fd9 | |
MD5 | c28a180de1f80c8c98d0904e64142bef | |
- | SHA256 | ebd72806abd354f3162eec0991d127f993a5dde1a0c719b47087c9ee0edefeaf |
SHA1 | abaaa2644b1e84e8b39119988dd711572377c839 | |
MD5 | 1baaeedd1a26edf4fa79ded370e3d19a |
Rilide Loader:
File name | Hash Type | Hash |
2.exe | SHA256 | 0f11aeecbde1f355d26c9d406dad80cb0ae8536aea31fdddaf915d4afd434f3f |
SHA1 | b4b918a5898463dad1c7d823e0b3f828bac15aad | |
MD5 | 0a4f321c903a7fbc59566918c12aca09 | |
waBp.exe | SHA256 | 8342b134cddeaf34ce05bafa9e860dacf6cd01b85fd00147d90a350516c055e5 |
SHA1 | 25f3fb6d2dab206a5e9b2c0ef26ec6d6a56c5767 | |
MD5 | 561797d7e5cf956e33735180d93be5b6 |
Rilide Extension:
File name | Hash Type | Hash |
background.js | SHA256 | 4cc83be0fa496855d244050616ee2e86b044a9bc87bc5ca70b305986c1ba3bb8 |
SHA1 | 70167e7e5d71fba7d92796324b488c0fb9727712 | |
MD5 | 766d020e902b6470d0510e5c6cfcd6e8 | |
background.js | SHA256 | 55251c725e9f6f51b8db7a631b54dd85b1b59d644c3219e03ceffb0c49cd00a4 |
SHA1 | a39d252e7927ae1adf518e6a3dd08f37e7ee7c26 | |
MD5 | d9cca3dd5bdaeb0466d52821b584602b | |
background.js | SHA256 | 1b01c3e554700e1282c7fdd2dcb54314516ee1f0c5eef3560cdbabc1ba776293 |
SHA1 | ffebf78a9692293a23f9a477ea8a79f7f6ef5aa2 | |
MD5 | 9e5f43b2dc1606e27fa0cfdfb4e363d2 | |
app.js | SHA256 | a28c623d120a76dcfeef9504eaeefabac9d33f292576ccf012fa458b8d7bc6ef |
SHA1 | a46586bfe22f4d84cd9174238740af275bf50c69 | |
MD5 | 740606987f4d588c89d0a5b68648e31e | |
app.js | SHA256 | 8989f4244667626728c6c0083422ff714cb622c92c35a53f9cb1e9891f4528ff |
SHA1 | 5012e783b2ee29cb40b04a10d1a40d0bfda683d9 | |
MD5 | 1c54dd00bc7cc52b60ad4a46e2fb3a77 | |
vpn.js | SHA256 | 170a13a7a8757336babe857804fa24b6cb20aaa9593b32546d7151f23095a510 |
SHA1 | eafdc35b233600ef552b87e684faa3ab3396eae9 | |
MD5 | d54fa225b07298ec34be872cd4ebf4ae | |
manifest.json | SHA256 | bb57a504e0b821552344cecb3da9ecdd0d61817264617a4917d6f5e64a1df7e5 |
SHA1 | 0cb1d9c2a3c8b776ef1e3ec1316fbf595ced7863 | |
MD5 | baee9ba0b94ea1e2b2e566fc8a615554 | |
manifest.json | SHA256 | d70e933e10e667ae7ef6e68a625c447be8aabe9b29affdad999c969bd8769003 |
SHA1 | 84db08e3dcbe40c7cbc998a77788f7303d4a2905 | |
MD5 | 99dc4073f2fe91f48fd16bc65e7dcbc2 | |
binance.js | SHA256 | c8939f8d6237fcc17d486981a800b1e7e9974377de21d7e76677babe8ed536af |
SHA1 | f689396c73055e99a06e002c39e3a74d3d402607 | |
MD5 | 2cc204564b68c5a98b1ff68d861b66c5 | |
bitget.js | SHA256 | 2e310391d77022bcc708c354140319718777ca35efdfb76d6c80cb9de8c8091e |
SHA1 | 05536aa80f8280ddc31be5c0ac3ca995f2190a0a | |
MD5 | 646b9404a29febe9f3741797b79e300c | |
blockchain.js | SHA256 | 4bbb0584eed0c082b5c43d3f259f37cf1a0b64eabb485e85090951a6566d98d4 |
SHA1 | 28ae2440c56350f65b607e4e99b67a2632db873b | |
MD5 | 253f4319673673d2bf5285558a6903df | |
bybit.js | SHA256 | 9dca66f52f31dca921fb238bd36bfc1b1a59d3e4af7b071da9bc4c6bf294e402 |
SHA1 | 61acdad59223a9eb0b392ccd085db1e49700d65 | |
MD5 | 50e363409ba77b20fb6f0bce4eff7b1 | |
coinbase.js | SHA256 | 4df0f18a7e05518bbe93758e751f1f462fef212cdc786c7217d50ddbda14efb5 |
SHA1 | 39f546a4ec94e63e603e3c2481fecab2b5e8a475 | |
MD5 | c1f40584e4ac391d97218ce137a63fb3 | |
ftx.js | SHA256 | ef20c929f5204b223b6e53dc406ea0bcd76d9e98c9ae4942037902883d4bb22a |
SHA1 | 0ead1d32ce6b15c4a90373fce58d1554035cd40f | |
MD5 | ebce63fdc8ef245f117f06ada3ba0f6d | |
huobi.js | SHA256 | e1ad66cc0244fc075e0aabe0fd19502d4c9617829b90aa210e74be1d915275d2 |
SHA1 | 2449e4b27d778f6a4ffc00bb7b73926ac2c54e8a | |
MD5 | 4abe60d2c3506f4767e163d135f89f92 | |
kraken.js | SHA256 | a7f0fdfdfdf1ef65799fd2114bf5c1e133a8b7635b498b334553fbb64b218a05 |
SHA1 | ec6de82efa93e59da148f4d696efcfca851e051e | |
MD5 | b85c5659e946b5d7ad78410356288928 | |
okx.js | SHA256 | 68278b40b59b1b0db2f814d2d864f0b9c2b4285f5795d22cabf60715f922989c |
SHA1 | 415d790b54ca8e374f37fdbb00090110b823ba18 | |
MD5 | ff4e2df1a46d49862ab2a0af830a007e | |
gmail.js | SHA256 | 2f947644c7752ba014eae7971b247be60249a6088923c66ffe9886a7f5c5fe1c |
SHA1 | add0d61399c8c47f8ac73dc83cc83dfa31cddeca | |
MD5 | c0e120778853f0a4865e006a07cd728a |
Phishing Websites:
Malware | Domain |
Aurora | nvidia-graphics[.]top |
C2 Servers:
Malware | Domain |
Ekipa RAT | nch-software[.]info |
Aurora | 45[.]15[.]156[.]210 |
Rilide | vceilinichego[.]ru |
Rilide | ashgrrwt[.]click |
Wallet Addresses:
Cryptocurrency | Address |
BTC | bc1qkczacyp5jq29s5kaphth4asu8cv2y4u4gdgj7q |
BTC | bc1qsjg8dqx6ga30h6szjd8dv2wg50ch50qrey4t7j |
BTC | 1KqequymujeNJuyB4gH7oJSFTB3En3Hf5n |
ETH | 0xDBc1330056E2F5e2FB11FB3C96dE2c44B313eA8d |
LTC | LRYpzmnqBVozkbzJhTWndzYDPfjmNPyaLv |
XRP | rUPTadzFN6LS662Z2d2AvNyqU1xwg2japJ |
TRON | THiD8hFLiEyULVKLp3DSbBXQSbR3MQxm4X |
DOGE | D5asYfjtbTtFmFkrEwqVgbJKYv9YT7Tgjh |
- Details
- Tech Support by: Emerald City IT
- Support Field: Computer Repair and Tech Support
- Support Category: Virus, Spyware, & Malware Removal
A little bit of background for those not familiar with chfn…
“chfn (change finger) is used to change your finger information. This information is stored in the /etc/passwd file and is displayed by the finger program. The Linux finger command will display four pieces of information that can be changed by chfn; your real name, your work room and phone, and your home phone.” (from https://man7.org/linux/man-pages/man1/chfn.1.html)
Now for some history. Two years ago, I picked out chfn as a candidate to be reviewed for security bugs. Why chfn I hear you ask? (Thanks for asking.) It is one of a small number of Set owner User ID (SUID) programs loaded with Linux which means it runs with the permissions of the ‘root’ user regardless of the user who executes it, for it needs to modify the /etc/passwd file to do its job. A vulnerability in such a program would mean local privilege escalation, for any command or action we get to inject gets executed in the context of ‘root’. As a normal user, we wouldn’t be able to directly save any changes made to /etc/passwd, but via chfn we can, in a controlled and restricted way – well that’s the plan.
We can change our room number to be “41414141” by either using chfn interactively or using it from the command line with parameters and values. For example: chfn -r 41414141
After executing this command, if we then look at /etc/passwd it will show the following:
We could also change our full name (-f), home phone (-h) and work phone (-w) with other parameters which would change other details within those comma separators, which are referred to as General Electric Computer Operating System (GECOS) fields.
Keep the above in mind while we look under the hood.
I found chfn is part of two Linux packages; util-linux and shadow. In Ubuntu and other Debian-based Linux implementations it is the shadow package which is responsible for the resultant chfn binary and is vulnerable to what I’m about to discuss.
Unwrapping this package and looking at /shadow-4.5/src/chfn.c you’ll find the following treasure inside the check_fields function, namely on lines 585 to 592 with regards to setting the room number field:
We can see that the user input to “roomno” is sent to the valid_field function together with some characters. We can assume that this is likely a blacklist of characters, but let’s go down the valid_field rabbit hole just to confirm.
Digging into /shadow-4.5/lib/fields.c, at the valid_field function, on lines 52 to 81:
So, our assumptions were correct. Each character we provide to “roomno” (or any other GECOS field) is compared against a list of illegal characters and if there is a match then -1 is returned back to “err” which exits out of the chfn program with the invalid room number message.
Two things stick out to me here. First, a bunch of things are not being mentioned in that illegal list of characters (blacklists are not great, who knew?!) and secondly, the handling of non-printable characters and the “1” being returned for them along with a non-exiting warning message – importantly, chfn does not quit. If we look back at the check_fields and valid_field functions, chfn only quits out if “err” is less than 0 - we die, we do not collect $200 and we go directly to jail. But if “err” is greater than 0 we get that red rope unclipped from the silver pole at the front of the chfn club and walked straight on through to our table. Good times.
With this knowledge, I pulled ‘echo’ (with -e) out of the toolbox and started to feed control characters into the roomno (-r) parameter of chfn to see what was going down because these don’t feature in that blacklist. I had lots of fun (I’m really great at parties), but the main takeaway is that the control character CARRIAGE RETURN represented by \r or \xD (in hexadecimal) gave the biggest impact. Let me show you the bottom of /etc/passwd before any madness goes on. The ubuntu user is normal, all good - nothing to see here.
Figure 1: Contents of /etc/password before injection
However, we make the injection with the \r control character into the roomno parameter of our user (ubuntu) and then we view the /etc/passwd file again. WHAAAAAA? Where we go?! roominjection has entered the building!
Figure 2: Modified contents of /etc/password after injection
Fast forward some hours and minutes later and spoiler alert here - I was not able to circumvent the “\n” from the illegal list. The ultimate goal/dream here would have been to start a new line and add another root level user, but I was denied.
I thought, well that was cool. I was curious though, was this blacklist always there? Back to the future we go - 2006 to be exact, to shadow-4.0.13 and guess what? …the “\n” in the blacklist was missing! However, the “:” was still present which stops any new user adding fun as we need to make use of this delimiter. This also applied to full name, home and work phone number, etc. but for illustrative purposes I have just shown the roomno as an example, which is what we’ve been targeting throughout.
chfn.c (in Ubuntu) from back in the day in 2006 (shadow-4.0.13) with “\n” missing:
I went back a further two years to 2004 (shadow-4.0.3) and that “:” is still messing up our plans for adding new users:
It was at this point of digging that I came across this bad boy from 2005 in SuSE Linux; CVE-2005-3503, a local privilege escalation in chfn! (https://www.exploit-db.com/exploits/1299). The exploit happily uses both “\n” and “:” to add a new root user, exactly what I set out to do at the start of this adventure.
I left the research there, poured myself another cup of tea and got on with my life.
Two years went by and one morning while I was eating my toast, I saw a tweet from @trailofbits about exploiting a logic bug in a SUID program. Interesting, tell me more… and they do, with a blog post. (https://blog.trailofbits.com/2023/02/16/suid-logic-bug-linux-readline/)
It’s about chfn of course! This time chfn is loading (and loading badly I might add) an environment variable, resulting in an arbitrary read access bug. This blog post gave me the kick I needed to revisit my old friend chfn.
Two years older/wiser, I picked up my old research in chfn to try a few more things. Still no success in weaponising it (e.g., the holy grail of adding a new user, 2005 SuSE style) but I stand back and try to think about how it can be abused in other ways. In a way it isn’t really an issue, but in another it is a little bit concerning, concerning that I’m able to mangle the /etc/passwd file and misrepresent it to an administrator perhaps. This made me think of red teaming and how we put together pretexts in our phishing tests to convince victims to click on links or do things for us. If I can’t use this to add a new user, can I use it to fake adding a new user? Stay with me on this.
The majority of work I’ve done over the last two decades has been application security testing, the kind of testing where we need to encode all the things, double encode, find alternative representations of characters, etc. in order to circumvent input validation rules, evade WAFs and ultimately get that alert box with the number 1 popping up. This got me thinking. I can’t put in an actual colon due to that blacklist in chfn, but we got a free pass with non-printables. We can use the CARRIAGE RETURN control character “\r” to start the line again and then be a bit creative and use the Unicode character “\ua789” to get as close a match to a colon as possible, all while injecting into the roomno parameter.
And that’s exactly what I did next.
Spot the difference?
I wanted to support such a pretext where we’ve managed to compromise a local account on the machine, but that we want to pretend to the administrator that we actually have a root privileged user account, so we tell them to check the /etc/passwd file and see for themselves. Maybe this being believed would then invoke another action like them having to log into another box/invoke an IR process which we have other tools waiting for this – Responder, Mimikatz, etc. to grab hashes, tokens, etc. something like that.
Attacker making the injection:
Administrator does a ‘cat /etc/passwd’:
Here are some screenshots also so you can get a sense of believability of the colon replacement on the screen.
The /etc/passwd before:
Figure 3: /etc/passwd before injection
The injection with the subsequent “hacked” account at the bottom of /etc/passwd, with ‘root’ privileges:
Figure 4: /etc/passwd after injection of the ‘hacked’ root user
That brings us to the end of our story, well nearly.
Remember at the start where I said chfn can be found in util-linux and shadow packages? Well strangely enough, the util-linux version blocks control characters via “iscntrl” in ch-common.c. In addition, it adds the “ character into the blacklist, so perhaps there is a story and some research behind that one too?
From util-linux-2.37.2/login-utils/ch-common.c (used by chfn.c), lines 17 to 34:
Prior to this blog post being published, I got in touch with the shadow package maintainers and showed them the proof of concept. I then followed up with a pull request on GitHub with the following commit which they have now merged into the main shadow repository.
Now, if control characters are detected then -1 is returned to err (quitting out of chfn), treating them the same as the illegal characters. This little bug has been assigned CVE-2023-29383.
Thanks for reading!
Reference
TWSL2023-004: Improper input validation in shadow-utils package utility chfn
- Details
- Tech Support by: Emerald City IT
- Support Field: Computer Repair and Tech Support
- Support Category: Virus, Spyware, & Malware Removal