学习静态代码审计_第二站:简单解读php-parser项目

Posted 南瓜__pumpkin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习静态代码审计_第二站:简单解读php-parser项目相关的知识,希望对你有一定的参考价值。


前言

  第一次接触这个项目,是2021强网杯的pop-master题目,也是这道题目给我打开了静态代码审计的大门。后来了解静态代码审计的发展历程,又接触到了昆仑镜项目。php-parse项目都下载三遍了,这次要搞定她!

  PHP Parser 是由 nikic 开发的一款 php 抽象语法树(AST)解析工具。项目地址:https://github.com/nikic/PHP-Parser。

  项目作者:nikic是PHP的主要contributor,目前在Jetbrains旗下的PhpStorm项目工作,并且开发过许多PHP的开源库。他也是LLVM项目的开发者。


项目官方说明

0x01 PHP解析器

  使用PHP编写的适合 php5.2 - php8.0 的解析器,用于简化静态代码分析和操作。

  Documentation for version 4.x (stable; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 8.0),文档地址:https://github.com/nikic/PHP-Parser/tree/master/doc.

  Documentation for version 3.x (unsupported; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.2),文档地址:https://github.com/nikic/PHP-Parser/tree/3.x/doc.

0x02 功能

  主要功能如下,其中前4项功能相比之下更具可用性。

  • 把PHP5、PHP7、PHP8的代码转换成抽象语法树AST
    • 无效代码会被解析成一个部分抽象语法树
    • 生成的AST包含准确的位置信息
  • 使用可读性高的表格转储生成的AST
  • 把AST转回PHP代码
    • 试验的:修改后的AST可以被格式化保存
  • 遍历和修改AST
  • 命名空间名称的解析
  • 常数表达式的求值
  • 简化AST结构的构造器 for 代码生成
  • 来回转换抽象语法树和Json数据

0x03 快速开始

  (1)使用PHP依赖管理工具Composer安装,由于本地Composer是全局配置,所以命令有所不同。

	composer require nikic/php-parser
	
	cd ./vendor/nikic/php-parser/

  (2)运行测试代码:nikic给出的代码示例如下,使用该软件,只需要把需要审计的代码放到$code变量中即可。

<?php
use PhpParser\\Error;
use PhpParser\\NodeDumper;
use PhpParser\\ParserFactory;

$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()}\\n";
    return;
}

$dumper = new NodeDumper;
echo $dumper->dump($ast) . "\\n";

  测试:在nikic/php-parser/lib/目录下新建MyASTest.php,复制粘贴示例代码,使用测试代码替换7-12行的代码。

<?php
var_dump(token_get_all('<?php echo "hello"; $a=1;echo $a+$a;?>'));
?>

  报错信息:使用PHPStorm打开MyASTest.php文件,使用PHP7.3.24命令解释器,发生报错。(完全使用示例代码也有相同报错)

PHP Fatal error:  Uncaught Error: Class 'PhpParser\\ParserFactory' not found in /Users/didi/Downloads/vendor/nikic/php-parser/lib/MyASTest.php:15
Stack trace:
#0 {main}
  thrown in xxx.php on line 15

  网上并没有找到明确的解决方式,但通过查阅use相关资料得知,use只是使用了命名空间,但是要想调用类,必须要加载类文件,或者自动加载。根据报错信息可以知道,use起作用了,但class类没有引用成功。

  尝试1-可行:使用自动加载。autoload.php文件在vendor目录下,通过目录遍历去包含该文件。比如本地在MyASTest.php文件第5行添加的代码如下,运行结果如图。

	require_once __DIR__ . '/../../../autoload.php';

  (3)遍历AST并执行某种操作,比如丢掉抽象语法树AST中某个函数的所有函数体。
  使用Class NodeTraverser,运行相关代码之后可以发现,只保留了Stmt_Function数组,stmts数组的内容被清空了。这意味着,我们可以对得到的AST语法树进行比较灵活的操作。(我愿称之为二次操作)

  (4)把得到的AST语法树转回PHP代码。
这个步骤很适合Webshell检测。使用PrettyPrinter文件中的Class PrettyPrinter\\Standard,但是作者给出的例子中,却没有还原函数体,具体点就是 减去了函数中var_dump()的调用。该软件还原代码的可用性有多大,还需要进一步探究。

  (5)For a more comprehensive introduction, see the documentation。

0x04 文档

  基础组件的使用这部分,其实相当重要。但持恒之初忌深远,贪多嚼不烂,后续更文再深入分析,一定记得多读文档方能熟能生巧。

  1. Introduction
  2. Usage of basic components

  下一篇学习研究PHP-Parse的使用,通过聚焦某些应用场景,比如基于该软件寻找强网杯pop-master题目的RCE pop链、探索该软件在代码审计领域的应用场景等。希望可以做到对这个PHP编写的PHP解析器项目烂熟于心,成为迈向代码安全领域坚实的一步。


参考

  《PHP Parser 简介和应用 - 为你的代码自动补全单元测试》,文章地址:https://learnku.com/articles/21846。

  《PHP中的use、命名空间、引入类文件、自动加载类的理解》,文章地址:https://blog.csdn.net/github_37767025/article/details/68064974

以上是关于学习静态代码审计_第二站:简单解读php-parser项目的主要内容,如果未能解决你的问题,请参考以下文章

学习静态代码审计_第三站:测试昆仑镜Kunlun-M项目

学习静态代码审计_第一站:编译原理和php

git命令学习第二站——高级篇

git命令学习第二站——高级篇

git命令学习第二站——高级篇

第二十二站威海_共筑“区块链共同体”物链芯全国调研行_漫克网总部威海家和中国艾草文化博物馆