Nette框架未授权任意代码执行漏洞分析

Nette框架未授权任意代码执行漏洞分析 

漏洞介绍:

Nette Framework 是个强大,基于组件的事件驱动 PHP 框架,用来创建 web 应用。Nette Framework 是个现代化风格的 PHP 框架,主要用于国外网站开发,因此国内对该框架的研究比较少。 2020年10月,Nette框架被爆出存在未授权任意代码执行漏洞,可通过自有框架控制器MicroPresenter执行任意PHP方法。

环境复现:

通过查询发现该漏洞影响自2.0以来的几乎所有大版本,详细的范围如下

nette/application 3.0.6 (or 3.0.2.1, 3.1.0-RC2 or dev)

nette/application 2.4.16

nette/application 2.3.14

nette/application 2.2.10

nette/nette 2.1.13

nette/nette 2.0.19

通过composer安装受影响的3.0.0版本,执行composer create-project nette/web-project nette-blog 3.0.0@dev,安装完成后整体的目录结构如下:

其中app为应用程序的主目录,包含presenters控制类目录、config配置文件、router路由器类目录以及Booting.php应用启动文件。而vendor/nette目录下包含Nette的所有框架文件,www目录包含整个Web程序能够直接访问的文件,如静态资源、入口文件index.php等,同时在index.php中调用Booting中的boot方法引导启动。

 

Nette会创建Configurator类对象来对启动环境进行配置,如设置日志文件目录、临时文件目录、加载配置文件等。

 

后续会根据配置调用createContainer创建一个DI容器,并通过getByType方法实例化Nette框架主程序NetteApplicationApplication对象,最后调用了Application对象的run方法。

 

漏洞分析:

据网上披露的POC来进一步分析代码,从Application:run函数处打下断点,函数会调用createInitialRequest方法来初始化Request对象。 

跟进到createInitialRequest方法,108行通过调用路由类的match方法来处理http请求,109行则是获取需要调用的控制器类,119行则是返回处理好的Request对象。

跟进match方法,发现路由器类的调用路径如下:

NetteApplicationRoutersRouteList->NetteRoutingRouteList->NetteApplicationRoutersRoute->NetteRoutingRoute::match,该方法主要将http请求处理后转换成数组。121行将网站请求路径中的基础路径删除赋值给$path,131行将$path按照presenter/action/id形式的正则进行匹配,并将匹配的部分分别标记为p0、p4、p13,148行则将匹配出的字符型key从 $this->aliases数组中取出对应的描述字段,其中p0对应为presenter,因此取出的控制器为$params[‘presenter’]=nette.micro。

 

 

 继续跟进到173行,调用了$params[$name] = $meta[self::FILTER_IN]((string) $params[$name])处理$params,其中$meta[self::FILTER_IN]对应了path2presenter处理控制器部分,将nette.micro转成Nette:Micro。

 

 随后我们返回Application.php中的processRequest方法,这里我们主要关注控制器部分Nette:Micro如何被调用的,跟进114行到presenterFactory类的formatPresenterClass方法,调用路径为createPresenter->getPresenterClass->formatPresenterClass。

在该方法中,120行将$presenter用冒号分割,并对$mapping赋值为$this->mapping[‘Nette’]。

 

 

126行则将$mapping的第三个元素*Presenter中的*替换为Micro,并将$mapping的第一个元素和替换后的字符串相连,最终得到控制器为NetteModuleMicroPresenter。在Application.php的144-149行,程序调用了控制器NetteModuleMicroPresenter中的run函数,对应为nette/application/src/Application/MicroPresenter.php,69行获取传递进来的GET参数。

 

其中74行会检查callback参数传递进来的变量可否被当做函数调用,85行调用combineArgs方法获取回调函数中的默认参数名,并于GET请求传递过来的参数名比对,如果相同则保存在$res数组并返回到$params中。

 

返回到MicroPresenter.php的90行,这是一个典型的可变函数调用,在诸多PHP后门中比较常见,这里函数名$callback和参数$params都可控,可导致任意代码执行。以shell_exec方法为例,默认参数为cmd,构造对应的POC请求:

 

修复建议:

安装百度度御关WAF、高级威胁感知系统,以及智能安全一体化产品。

进行官方升级。

猜你喜欢

转载自blog.csdn.net/qq_48985780/article/details/121306554