首页 > 其他分享 >加密木马分析

加密木马分析

时间:2023-04-12 16:14:29浏览次数:41  
标签:分析 执行 加密 函数 木马 注册表 服务 main sub

前言

记一次恶意代码分析

教程:《恶意代码分析实战》第九章实验Lab9-1

恶意代码样本:https://github.com/mikesiko/PracticalMalwareAnalysis-Labs

 

实验环境(虚拟环境)

Windows XP:Ollydbg 1.1
Windows 10:IDA pro 7.7

 

定位调用main函数地址

    IDA函数窗口找到_main,进入函数实现的地方

    

   Ctrl+x列出交叉引用的地址,跳转过去

    

   00403945便是调用main函数的地址

   Ollydbg启动程序,F8单步执行到00403945,在此处下个断点,方便重新运行时快速定位到这里。

     

 

初步分析main函数

   Ollydbg F7步入main函数

     IDA中查看main函数的实现,首先判断程序执行时参数个数是否是1,如果是1个,调用sub_401000;不为1,继续执行main函数(注:程序执行时如果不带任何参数,那么argc=1)

    

   分析sub_401000,RegOpenKeyExA打开注册表项"SOFTWARE\\Microsoft \\XPS",如果打开成功,RegQueryValueExA获取"Configuration"对应的值;如果注册表打开失败,则退出sub_401000函数

    

  回到main函数,继续分析。由于执行程序时没有指定参数,注册表项也不存在,程序就会先调用sub_402410,接着跳转到loc_402d76,退出main函数

    

   分析sub_402410

     Ollydbg 先F8来到sub_402410,F7步入sub_402410

     IDA静态分析sub_402410,函数调用GetModuleFileNameA和GetShortPathNameA获取当前执行路径,然后ShellExecute执行一个cmd命令

    

 

    

 

     具体执行的命令是什么,在IDA难以分析,但是可以知道lpParameters是执行的cmd.exe的参数,在运行过程中存放在eax寄存器。Ollydbg F8执行到004024EE,查看寄存器的内容

     

    这样一来,sub_402410的作用就很清楚了,就是删除自身

  sub_402410分析结束

 

整理到此为止程序的功能:执行程序带上参数,程序继续执行;执行程序不带任何参数,程序会去查找注册表项,查找成功,继续执行;查找失败,退出程序。

换句话说,要想程序继续执行,方法一是执行程序时带上参数,方法二是添加注册表项。很明显,方法一更稳妥。

 

让main函数继续执行

  Ollydbg选项卡选择Debug->Arguments,添加任意参数

     

  Debug->Restart,重新运行。main函数成功继续执行

 

加密功能

  继续分析main函数。下面这段的含义是:取最后一个参数,调用sub_402510(var_4),如果返回值为1,继续执行main函数;否则调用sub_402410,前面已经分析过了,这个函数删除自身然后退出程序。

  

  分析sub_402510

    这个函数看上去像使用一个令人费解、硬编码的算法进行输入的完整性检查(教材原话)

    Ollydbg可以修改代码,使sub_402510只返回1

    绕过加密

    MOV EAX,1的机器码是B8 01000000
    RETN的机器码是C3
    在函数入口处右键->Binary->Edit把原来的55改成B801000000C3

        

     成功替换

      

       保存为新的可执行文件Lab09-01-Passwed-password.exe:文件右键->Copy to Executable->All modifications

          Ollydbg运行修改后的文件,带上任意的密码

           

   成功绕过!!

 

检查参数是否正确

   继续分析main函数,这一段检查输入的参数"-xxx"是否等于offset byte_40C170,不相等则跳去检查其他参数。

    

  40C170存放的数据是"-in"

    

   把参数改成"-in",Debug->restart重新运行。

    

 

获取文件路径

  main函数调用sub_4025B0

  

     sub_4025B0调用GetModuleFileNameA获取当前执行目录,__splitpath分解路径,指出完整路径path,驱动器号drive,目录路径dir,文件扩展名ext

  

 

继续执行main函数,来到这一段,执行sub_402600(ServiceName)

  

 Ollydbg执行到此处查看到ServiceName是"Lab09-01-Passwed-password"

  

 

程序用 -in做了什么(分析sub_402600)

    Ollydbg F7步入到sub_402600

   执行sub_4025B0(var1404),前面已经分析了该函数获取工作目录

    

  连接本地服务控制管理器
  执行OpenSCManagerA(0,0,0F003Fh),连接本地计算机的服务控制管理器,拥有所有的访问控制权限

    

  返回值为hSCManager
  如果连接成功,则返回值不为0,继续执行
  

  打开具体服务
  执行OpenServiceA(hSCManager,lpServiceName,0F01FFh),打开某个服务,其中0F01FFh表示拥有这个服务的所有访问控制权限

    

  lpServiceName表示打开的服务名,保存在eax寄存器。在OD执行到此处,查看eax的值
    

  打开的服务就是自己
  返回值保存为hService
  如果返回值为0,意味着打开服务失败,跳转到0040277D
  如果成功打开服务,则继续执行

  假设成功打开服务
    执行ChangeServiceConfigA(hService,dwService...)[以下省略9个参数]
      

  创建服务

  而我们是第一次把程序执行到此处,此前并没有创建服务,所以服务打开失败,跳转到0040277D
    执行CreateServiceA(hSCManager,lpServiceName,lpDisplayName...)[以下省略十个参数]

      

    值得注意的参数是lpBinaryPathName,对应寄存器是EAX。Ollydbg运行到此处查看寄存器:  

      

    所以程序在这里创建了一个服务,对应的可执行文件就是自己
    如果返回值不为0,表示创建成功

  创建失败:
    执行CloseServiceHandle(hSCManager),关闭服务管理器的句柄
    跳转到loc_4028F5,退出sub_402600函数

      

  创建成功:
    执行CloseServiceHandle(hService),关闭服务的句柄
    执行CloseServiceHandle(hSCManager),关闭服务管理器的句柄

    继续执行

     

  查看系统服务,确实创建了服务!!!

    

  添加扩展环境变量
  执行ExpandEnvironmentStringsA(lpSrc,lpDst,nSize)

    

  lpSrc,lpDst保存在寄存器edx,ecx。OD执行到此处,查看对应寄存器

    

  因此ExpandEnvironmentStringsA函数的作用是添加扩展环境变量,使得可以通过命令行启动程序


  执行GetModuleFileNameA(),老朋友了,获取当前执行路径
    

 

  复制文件

  CopyFileA(lpExistingFileName,lpNewFileName,bFailfExists)

    

  其中lpExistingFileName,lpNewFileName保存在寄存器EDX,ECX
  OD执行到此处,查看寄存器

    

  因此函数的作用是把自己复制到system32目录下
  到对应目录下查看,果然存在

  执行sub_4015B0(BinaryPathName)

    

  其中BinaryPathName保存在eax,OD运行到这里查看对应的值
     

  分析sub_004015B0

  步入sub_004015B0看看函数做了什么

    执行GetSystemDirectory(lpBuffer,uSize)

      

    lpBuffer存在eax,OD运行到这里查看对应的值

      

    GetSystemDirectory查询系统目录,查询结果保存缓冲区中,lpBuffer指针指向这个缓冲区。
    查看此时内存中0012CF28存放的数据。在内存窗口右键->go to->Expression输入0012CF28

      

    因此程序使用GetSystemDirectory查询到了系统目录为C:\WINDOWS\system32

 

    执行sub_4014E0(LPCSTR,lpFileName)

      

    其中LPCSTR,lpFileName存放于ecx、eax,OD运行到此处查看寄存器

      

 

      分析sub_4014E0

      步入004014E0函数

      执行CreateFileA(lpFileName...),创建kernel32.dll文件

        

      执行CreateFileA(arg_0),创建Lab09-01-Passed-password.exe文件

        

    sub_4014E0分析结束

   sub_004015B0分析结束

  执行sub_401070("ups","http://www.practicalmalwareanalysis.com","80","60")

    

  分析sub_401070  

    步入sub_401070
    创建注册表项
    执行RegCreateKeyExA(hKey,"SOFTWARE\\Microsoft \\XPS",Reserved...)[省略6个参数]

      

    其中hKey为80000002h,Ollydbg查看此处栈的数据

      

    因此RegCreateKeyExA创建了注册表项HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft \XPS

    执行RegSetValueExA(hKey,"Configuration",Reserved,dwType,lpData,cdData)

      

    其中lpData是注册表项的值,保存在edx,OD运行到此处查看
      

    由此可知RegSetValueExA在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft \XPS注册表项添加了键"Configuration"和值"ups"
  sub_401070分析结束

00402600分析结束

 

终于回到main函数!!

至此,可以知道当程序以"-in"参数运行时,把自身安装为服务,创建注册表项并设置键值,并添加环境变量。

 

按照分析“-in”参数的思路,可以分析出程序所有参数及其作用如下:

-in      把自身安装为服务,创建注册表项并设置键值,并添加环境变量。
-re      删除服务
-c       创建注册表,设置键值
-cc      读取注册表的内容

 

总结

样本分析用到的Windows系统库函数

OpenSCManagerA:建立与服务控制管理器的连接,并打开指定的服务控制管理器数据库
OpenServiceA: 打开一个已存在的服务
ChangeServiceConfigA:更改服务的配置参数
CloseServiceHandle:关闭指向服务控制管理对象的句柄,也可能是指向服务对象的句柄
CreateServiceA:创建服务对象并将其添加到指定的服务控制管理器数据库
RegDeleteValueA:删除注册表中的键值
RegCreateKeyExA:创建指定的注册表项。如果键已经存在,函数将打开它
RegSetValueExA:设置注册表键值的数据和类型
RegOpenKeyExA:打开指定的注册表项
RegQueryValueExA:检索与开放注册表键关联的指定值名称的类型和数据。与RegOpenKeyExA功能类似
DeleteService:从服务控制管理器数据库中删除的指定服务

Windows API文档:https://learn.microsoft.com/en-us/windows/win32/api/_shell/

 

程序自定义函数需要步入进去了解其功能
系统函数不需要步入,找到参数对应的值即可分析清楚

 

IDA静态代码分析:分析函数基本结构

Ollydbg动态代码分析:查看运行过程中寄存器/栈/内存 

    

标签:分析,执行,加密,函数,木马,注册表,服务,main,sub
From: https://www.cnblogs.com/jimmy-hwang/p/17308674.html

相关文章

  • 假设检验之 :单因素方差分析
    秩和检验:用于比较两组独立样本的中位数是否有明显差异。它不需要对数据的分布进行任何假设,适用于任何两组样本大小相等或不等、符合连续性变量的情况。在进行Mann-WhitneyU检验时,需要根据研究问题确定备择假设类型来选择使用双侧检验还是单侧检验。如果没有明确的预测或假......
  • 【JAVA】四则运算计算题生成及完成情况分析程序
    第七周结对编程任务为给出一个300道四则运算计算题并能够完成和检查答案是否正确,我(2152113)邀请到了我计科专业的舍友(2152123)与我一同组队,编程语言选择了我们都较为熟悉的JAVA。代码初现先由我来进行了计算题生产器的代码编写代码如下importjava.util.Random;publicclass......
  • Youpk 脱壳机脱壳原理分析
    Youpk是一个针对整体加固和Dex抽取加固壳的脱壳机主要是基于虚拟机的,也就是基于VA的脱壳机,相对FART出来的更晚一些,厂商针对少一些,脱壳位置相对更底层一些,还提供了Dex修复的工具,简直棒棒1.先分析整体脱壳的原理在ActivityThread的handleBindApplication中增加了代......
  • 手机号码归属地 API 实现个性化推荐的思路分析
    前言随着移动互联网和智能手机的普及,越来越多的人使用手机上网和购物,移动营销已成为企业获取用户和提升品牌知名度的重要手段。手机号码归属地API作为移动营销的关键工具,具有广阔的应用前景。本文将探讨如何利用手机号码归属地API进行个性化推荐和精准广告投放,希望对大家有......
  • UVa 113 / POJ 2109 Power of Cryptography (使用double处理大整数&泰勒公式与误差分
    113-PowerofCryptographyTimelimit:3.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=99&page=show_problem&problem=49http://poj.org/problem?id=2109题意:给出n和p,求出 ,但是p可以很大()如何存储p?不用大数可不可以?先看看double......
  • 选币模型:评估加密货币投资价值
    以下选币模型我是基于ChatGPT进行训练微调得出的。评估加密货币投资价值的关键因素主要包括:技术背景:加密货币所采用的技术是否先进,能否满足当前市场的需求,以及是否有未来的潜力。实际应用:加密货币是否有实际应用场景,是否能够解决当前市场上的问题。团队实力:加密货币的开发团队是......
  • 利用hibernate分析数据库中的表,属性以及对应的类的类名,字段
    2010-08-1109:27hibernate获得数据库的表名列名及其数据@TestpublicvoidtestHIbernateConfig1(){SessionFactoryfactory=newAnnotationConfiguration().configure().buildSessionFactory();AbstractEntityPersisterclassMetadata=......
  • 条码分析
    条码类别分析在线扫码:https://demo.dynamsoft.com/barcode-reader/​ https://online-barcode-reader.inliteresearch.com/汉信码解码:https://tuzim.net/hxdecode/QRazyBox:https://merricx.github.io/qrazybox/?tdsourcetag=s_pctim_aiomsg汉信码、QR码等常用二维码数......
  • 复杂网络社区发现算法聚类分析全国电梯故障数据和可视化:诊断电梯“安全之殇”|附代码
    参考原文:http://tecdat.cn/?p=2186最近我们被客户要求撰写关于复杂网络社区发现算法的研究报告,包括一些图形和统计输出。物业工程肩负着维持项目各类设施设备的正常运作,保障全体业主的正常生活,令物业保值升值,是项目的心脏部门。拓端数据(tecdat)研究人员根据全国电梯故障上报汇总......
  • .sct文件分析
    点击查看代码;*************************************************************;***Scatter-LoadingDescriptionFilegeneratedbyuVision***;*************************************************************LR_IROM10x000000000x00080000{;loadregions......