熊猫烧香详解

1. 样本概况

该熊猫烧香加有fsg壳,利用局域网传播,感染主机可执行文件。

1.1 样本信息

病毒名称:xiongmao.vir

所属家族:Fujack

MD5值:512301c535c88255c9a252fdf70b7a03

SHA1值:ca3a1070cff311c0ba40ab60a8fe3266cfefe870

CRC32:E334747C

病毒行为:设置注册表实现自启动,向系统服务发送控制码,创建文件扩展名为exe的html文件,创建一个微改过的拷贝,修改资源管理器(explorer)的文件夹的隐藏属性,将文件属性设置为隐藏,检测系统内存大小,可能通过内存大小来判断是否运行在虚拟机中,在文件系统上创建可执行文件。

1.2 测试环境及工具

Win7 32位虚拟机,IDA,010editor,OllyDebug,exeinfo,LoadPE.

1.3 分析目标

2.具体行为分析

2.1 主要行为

火绒检测:

感染后文件:

比较被感染的可执行文件:

流程图

2.2 恶意代码分析

熊猫烧香是Delphi程序,需要注意:

  • IDA导入bds symbol。
  • Delphi默认的调用约定是,从右往左传参,前三个参数分别用寄存器 eax,edx,ecx ,超过三个的放在堆栈中,被调用者平衡堆栈。
  • Delphi也是可以内联汇编的。(asm...end...)
  • 字符串类型分为P(Pascal字符串),A(Ansi字符串),L

其他经验

  • 主要函数的分析时,可以暂时忽略返回值eax没有被保存或使用的调用。
  • mov 的目的地址是内存地址时需要重点关注。

2.3 恶意程序的代码分析片段

(1)sub_405250 解密

参数是两个字符串eax,edx,一个缓冲区ecx。

功能是把eax通过edx解密后放入ecx。

if ( pStrKey ) /*pStrKEy is valid*/
  {
    int lenthofStrKey = GetpascalStrLenth(pStrKey); /*key length*/ 
    if ( lenthofStrKey > 0 )
    {
      int i = 1;
      int XorValue = 0;
      do
      {
        lenthofStrXboy = GetpascalStrLenth(pStrXboy);
        XorValue =(strXboy[i % 4d] % 10d) ^ (strKey[i-1])
        stosbEax2Edx(
          10,           /* always 10 */
          XorValue,     /* the XorValue */
          &BufftoSaveXorValue/* buff to save XorValue */);
        LStrCat((char **)&decryptedStrBuff, BufftoSaveXorValue);
        ++i;
        --lenthofStrKey;
      }
      while ( lenthofStrKey );
    }
    /*save the _Out_ parameter*/
    System::__linkproc__ LStrAsg(OutputDecryptedStr, decryptedStrBuff);  
  }

需要查一下 stosbEax2Edx


三个主函数都没有参数

(2)sub_40819C 释放备份

Delphi 函数特点 eax是传入参数,用 mov 取值,edx 是传出参数,用 lea 取地址。

复制文件到新的目录:

运行新文件,并退出当前进程:

第一次运行

会在 系统目录 C:/Windows/System32/drivers 下 创建 病毒文件的拷贝 spo0lsv.exe 并运行,然后退出。

int main(){
  ParamStr(this, (char *)&v75);    /* 
								   ** ParamStr(int index,_Out_ char* retValue);
                                   ** return the index number of param in commandLine;
                                   ** eax = 0 ,edx = &var_238 = pathofVirusFile;
								   */
  /* GetAppPath is to get the ./ of the Path _In_ */
  GetAppPath(pathofVirusFile_0, &dirofVirusFile);
  LStrCat((char **)&dirofVirusFile, "Desktop_.ini");
  if (FileExists(dirofVirusFile_afterStrcat) )/*if Desktop_.ini is exist? 0 is not exist.*/ 
  {
    System::ParamStr(pathofVirusFile_1, (char *)&v73);
    GetAppPath(v4, &v74);
    LStrCat((char **)&v74, "Desktop_.ini");
    v5 = (const CHAR *)LStrToPChar();
    j_SetFileAttributesA(v5, 0x80u);
    j_Sleep(1u);
    System::ParamStr(v6, (char *)&v71);
    GetAppPath(v7, &v72);
    System::__linkproc__ LStrCat((char **)&v72, "Desktop_.ini");
    v8 = (const CHAR *)System::__linkproc__ LStrToPChar();
    j_DeleteFileA(v8);
  }
  ParamStr(pathofVirusFile_1, (char *)&v70);
  /* 
  ** ReadVirusFileToAnsiStr(_In_ AnsiString filePath,_Out_ char* pFileStr)
  ** var_1 = pFileStr
  ** maybe get more information.but out to param is only pFileStr
  */
  ReadVirusFileToAnsiStr(pathofVirusFile_2, &pFileStr);/*Also read Import dir to memory */ 
  LStrClr();
  for ( i = GetpascalStrLenth(pFileStr); i > 0 && *(_BYTE *)(pFileStr + i - 1); --i )// skip
  {
    v12 = pFileStr;
    LOBYTE(v12) = *(_BYTE *)(pFileStr + i - 1);
    stosbEax2Edx(pathofVirusFile_3, v12, (char **)&v69);
    LStrCat3(Always0, v69);
  }
  if ( !Always0 ) /*in*/ 
  {
    ParamStr(pathofVirusFile_3, (char *)&v67);
    AnsiUpperCase(pathofVirusFile_3Upper);
    GetDir_System32(v68, v52);
    LStrCatN(dirSystem32, (char *)3, "spo0lsv.exe", "drivers\\", v65);
    AnsiUpperCase(v15);
    LStrCmp((int)IsFalse, v66);  /* to confirm which exe is running*/
    if ( !v16 ) 			     /*if mot spo0lsv.exe*/ 
    {
      sub_405FC4(); /*use Tlhelp enume process;search spo0lsv.exe*/ 
      sub_405FC4();
      GetDir_System32(128, v52);
      System::__linkproc__ LStrCatN(dirSystem32_1, (char *)3, "spo0lsv.exe", "drivers\\", v64);
      v18 = (const CHAR *)System::__linkproc__ LStrToPChar();
      j_SetFileAttributesA(v18, (DWORD)IsFalse);
      j_Sleep(1);
      GetDir_System32(0, v52);
      LStrCatN(dirSystem32_2, (char *)3, "spo0lsv.exe", "drivers\\", v63);
      NewFileName = (const CHAR *)System::__linkproc__ LStrToPChar();
      ParamStr(pathofVirusFile_4, (char *)&v62);
      ExistingFileName = (const CHAR *)System::__linkproc__ LStrToPChar();
      j_CopyFileA(ExistingFileName, NewFileName, (BOOL)IsFalse);
      GetDir_System32(1, v52);
      LStrCatN(dirSystem32_3, (char *)3, "spo0lsv.exe", "drivers\\", v61);
      v23 = (const CHAR *)System::__linkproc__ LStrToPChar();
      j_WinExec(v23, (UINT)IsFalse);
      j_ExitProcess_0(0);
    }
  }
}

FileExist(char* Name) return a boolean, TRUE is exist, FALSE is not existing.

第二次执行 即 spolsv.exe 执行

int __thiscall sub_40819C(void *this)
{
  System::ParamStr(this);
  unknown_libname_89(v1, &v79);
  System::__linkproc__ LStrCat(v2, "Desktop_.ini");
  System::ParamStr(v4);
  sub_407650(v12, &v85);
  System::__linkproc__ LStrClr();
  if ( !v84 )
  {
    System::ParamStr(v13);
    Sysutils::AnsiUpperCase(v16);
    sub_4053AC(v75);
    System::__linkproc__ LStrCatN(v17, 3, "spo0lsv.exe", "drivers\\", v73);
    Sysutils::AnsiUpperCase(v18);
    System::__linkproc__ LStrCmp(v19, v74); //exist 
    if ( !v20 ) //pass it
    {/*...*/}
  }
  v30 = unknown_libname_75(v84);
  LStrDelete(v30, i);      // delete virusfile memory image, but haven't delete it
  v49 = unknown_libname_77(v48, v84);
  if ( v49 > 0 )
  {/*...*/}
  v51 = v63;
  v63 = (int *)&loc_408788;
  LStrArrayClr(v51, 29);
  return LStrArrayClr(v52, 5);
}

(3.1)sub_40D18C 主体1 感染文件

Fun2 是一个递归函数,要遍历所有文件

对 Desktop_.ini 的修改

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值