thinkphp 5.0.23 rce分析和复现 · 风之栖息地


8种机械键盘轴体对比
本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

分析

入口是在app::run(),这里有创建http的请求实例,

随后在后面会有路由检查,从这里跟进函数routeCheck

在路由检查中会到路由类的check方法处,继续跟进。

在check中会有获取当前方法的method

下面在method中会获取var_method这个伪变量,其实这个就是我们通过post传进的_method,这里进入判断之后会将我们post的值当做Request类的方法调用,这里我们的poc是传入的__construct,这样就会调用它的构造方法,并且参数是post数据。

继续跟进构造方法,这里的foreach会遍历所有变量,将存在的参数全部覆盖掉,在我们传入的参数中的filter,就把之前的覆盖了,并且在这里传入method为get的原因也是因为之前注册路由是get方法,所以这里要把请求的method覆盖成get,避免报错。

在这调用完成之后routeCheck将返回method赋值给dispatch。之后会继续在run函数里面执行exec函数。由于type为method执行相应的分支。

而这里的param方法能获取参数,并且和URL中的参数合并。这里得到的参数就是post数据中的get[]=dir

它的返回调用了input方法,跟进input

input最后将参数和filter一起传入array_walk_recursive中。其中参数中有我们传的dir,而filter通过getFilter有我们传的system

在这之后调用的array_walk_recursive会用filterValue,来处理数据,在这之中用call_user_func

这里systemdir分别是filter和value中的值,凑在一起就触发命令执行。

这里是第一个poc的分析,而第二个poc比较类似,同样是利用input函数,这里利用的点是在param的$this->method(true)中。

因为是true所以进入了server('REQUEST_METHOD'),最后同样到input中,并且data是server数组,filter同样是system。

造成的效果都是命令执行。

复现

后记

在调试的过程中也算是学到了很多东西,比如vscode+xdebug的动态调试方案,特别的轻巧,功能点也很完善。关于在验证poc的时候其实出了一些小问题,那就是我的burp发送的post数据和header之前多了一个空行,也就是这个多的空行导致我的poc老是失败……这也是注意小的细节问题,只有在真正调试的时候才会被发现。

以后还是要多动手实践。接下来几天我会研究一点新的东西,拭目以待吧。

Reference

https://paper.seebug.org/787/

https://blog.csdn.net/qq_29647709/article/details/86307859

https://xz.aliyun.com/t/3845