记一次有趣的挖矿病毒
0 前言
本病毒使用了去符号表、敏感信息混淆、int 0x80执行系调函数、sh -c 执行bash脚本获取相关信息等技术来做免杀处理,但是不足的点也很明显:
1)top命令可以直接查看病毒进程占用cpu比率。
2)crontab -l可以发现病毒的定时任务。
3)没有去掉特征字符,核心代码修改自github某著名挖矿源码。
注:由于网络安全法的规定,本文未将病毒链接放出。
1 背景
某一天,一个朋友突然微信过来一个病毒(绝对不是无中生友~)。截图是朋友给的检查结果以及时间。看图的样子,这个病毒静态检测起来比较复杂??
2 病毒分析
拿到病毒第一件事,查壳。还好,这个病毒只是一个标准的压缩壳,没有做什么大的变化。
(x86版本x64版本代码一样,习惯用x86分析)
脱壳:upx –d filename 一切顺利。如果病毒作者自己修改upx的壳的话,标准的upx –d是脱不掉的,需要单步跟随一步步dump吧。病毒分析是一个耐心的活,考验的是细心。还有一点,此病毒全程没有符号表,这给逆向的人员带来很多麻烦,很多函数都需要一点点跟进才行。对于linux病毒,如果单纯使用gdb调试的话,很容易陷入局部,不能整体把控。此时,IDA的动态调试功能就凸显出来了。使用IDA的动态调试既简单又有效,可以节省大量时间。
方法:
1)将ida dbgsrv目录下的linux_server放在linux虚拟机中,以root形式运行linux_server,如下图。
2)在实体机中使用IDA载入病毒后,点击F9或start process按钮(绿色三角)。IDA会弹出Debugger warning提示框,点击“ok”。这里注意一点的是,Hostname要输入linux虚拟机的ip地址,并且确保linux_server是运行状态。至于Application、Input File、Directory这三个忽略不计也可以。之后一路“ok”就可以调试了。
病毒内含有大量的看似无用代码,其实包含了大量需要解码的内容。流程较为简单直接,一直F8即可。大致如下图所示:
首先经过解密,其配置如下:用户名FUCKERS,密码Rxl,矿池xmr.winscp.top:80。至此,此病毒的关键信息已被提取。而且有意思的一点—donate-level默认级别是5,病毒作者改成了20,捐赠的心还是很大方的~经查看,此病毒核心部分为github上一知名挖矿病毒~
部分解密采用了xor解密,红框中为解密后的,乱码为未解密的内容。如下图所示:
解密后的脚本如下:
当可执行bash脚本被解密后,系统通过sys_execve(bin/sh)的方式呼唤起shell,然后通过sh -c执行bash的脚本。
这里有一点需要注意的是病毒执行sys_execve的方式并不是直接调用函数sys_execve,而是采用了int 0x80的方式。Linux系统提供了200多个系统调用,通过汇编指令 int 0x80 实现,用系统调用号来区分入口函数。为了对避免毒软件对敏感函数的纠察,病毒正好利用了此特性,通过两个步骤来实现所要执行的函数过程。比如需要执行sys_execve。
1)首先查看资料得知sys_execve的序号是11。接着病毒将此序号传入代码中等待。
2)通过汇编语句调用 int 80,启动软中断,以软中断方式进入调用sys_execve的执行。
如下图所示:
又是一段bash解密
将bash执行后,退出程序,接着依靠crontab内的计划再次启动,进入挖矿模式。
3 清除病毒
1)通过top命令查看cpu占用,此病毒占用还是很高的。
2)通过crontab -l 发现其启动规律
删除crontab中病毒启动命令后,kill -9 virusPID即可。接着删除病毒所在文件目录。
4 附录
解密完毕后,内存中会释放出许多挖矿脚本,这里使用idapython将其dump出来。脚本如下:
from idaapi import *
from idc import *
addr_start=0xxxxxxxx
addr_end=0xaaaaaa
len=addr_start-addr_end
buf=dbg_read_memory(addr,len);
fp = open("d:\dmp.txt", "wb");
fp.write(buf);
fp.close();
- 深入理解JVM原理之编译openjdk7
- 初识ActiveMQ
- Kafka集群安装
- 知其所以然之永不遗忘的算法
- ZOOKEEPER集群搭建及测试
- 【Python环境】Scikit-Learn:开源的机器学习Python模块
- 【Python环境】可爱的 Python: 自然语言工具包入门
- 电脑静音工作,又听不到12306的来票音乐,纠结啊 !但春节前工作多任务重,不能安心工作,就动手做个“无声购票弹窗”工具吧!
- .net访问PostgreSQL数据库发生“找不到函数名”的问题追踪
- “领域驱动开发”实例之旅(1)--不一样的开发模式 一、分析业务需求。 二、设计领域对象模型 三、测试领域对象模型 四、设计业务处理类 五、设计Entity和Vi
- Java基础——左移和右移
- 【Python环境】利用 Python、SciKit 和文本分类来实现行为分析
- LJMM平台( Linux +Jexus+MySQL+mono) 上使用MySQL的简单总结
- 判断两个单链表是否相交(有环、无环两种)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Python处理HTTP请求之requests指北
- 习题 3: 数字和数学计算
- Python桌面图形程序美化的方法论
- Windows 入侵痕迹清理技巧
- Linux 入侵痕迹清理技巧
- 面经手册 · 第10篇《扫盲java.util.Collections工具包,学习排序、二分、洗牌、旋转算法》
- 一次代码评审,差点过不了试用期!
- 利用ELK分析Nginx日志生产实战(高清多图)
- 习题 4:变量和命名
- 习题 5: 更多的变量和打印
- 习题 6 字符串(string)和文本
- Milvus 迁移升级攻略
- 习题 7: 更多打印
- 习题 8: 打印,打印
- Kafka Producer 异步发送消息居然也会阻塞?