zoukankan      html  css  js  c++  java
  • PHP AST学习

    前一阵和前同事交流在检测webshell方面的相关方法,其中提出了使用lex yacc做一套语法解析来解析字节码段来判断是否存在webshell。

    后来在查找相关资料中,找到了github开源的一个工具:PHP-Parser。能够把php文件解析AST(抽象语法树)

    Project: https://github.com/nikic/PHP-Parser

    安装:

    php composer.phar require nikic/php-parser

    例如:

    <?php
    use PhpParserError;
    use PhpParserNodeDumper;
    use PhpParserParserFactory;
    
    $code = <<<'CODE'
    <?php
    
    function test($foo)
    {
        var_dump($foo);
    }
    CODE;
    
    $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
    try {
        $ast = $parser->parse($code);
    } catch (Error $error) {
        echo "Parse error: {$error->getMessage()}
    ";
        return;
    }
    
    $dumper = new NodeDumper;
    echo $dumper->dump($ast) . "
    ";

    转储AST为:

    array(
        0: Stmt_Function(
            byRef: false
            name: Identifier(
                name: test
            )
            params: array(
                0: Param(
                    type: null
                    byRef: false
                    variadic: false
                    var: Expr_Variable(
                        name: foo
                    )
                    default: null
                )
            )
            returnType: null
            stmts: array(
                0: Stmt_Expression(
                    expr: Expr_FuncCall(
                        name: Name(
                            parts: array(
                                0: var_dump
                            )
                        )
                        args: array(
                            0: Arg(
                                value: Expr_Variable(
                                    name: foo
                                )
                                byRef: false
                                unpack: false
                            )
                        )
                    )
                )
            )
        )
    )

    可以看到各个节点的含义,相比较查看opcode然后再去解析容易的多,opcode比较晦涩难懂。

    如果做得好,再进行回归成原始的代码,例如webshell中存在很多字符串拼接、函数拼接等操作。回归最终原始代码,再去检测会变得容易的多。

    关于php-parser的文档也有很多:

    https://github.com/nikic/PHP-Parser/tree/master/doc

    我个人的目前思路:

    1、获取web目录

    2、对每个php文件生成AST

    3、解析AST,进行语法回归,转储原始代码 // 这个地方比较有难度

    4、使用多引擎(正则、机器学习、第三方接口)进行判断文件是否异常。

  • 相关阅读:
    redis和memcache的区别
    c语言行编辑程序
    C语言栈的实现
    双向链表
    静态链表的合并
    静态链表的创建
    链表
    将非递减有序排列(L L1)归并为一个新的线性表L2 线性表L2中的元素仍按值非递减
    C语言合并两个集合(L,L1) 将L1中不在L中的元素插入到L线性表中
    oracle--JOB任务
  • 原文地址:https://www.cnblogs.com/sevck/p/9316519.html
Copyright © 2011-2022 走看看