RSS Feed
更好更安全的互联网
  • GNU tar 解压路径绕过漏洞(CVE-2016-6321) 分析

    2016-11-10

    Author: LG(知道创宇404安全实验室) Date: 2016-11-09

    0x00 漏洞概述


    1.漏洞简介

    GNU tar文档管理命令是Linux系统下常用的一个打包、压缩的命令。经 CSS(FSC1V Cyber Security Services)团队的研究员 Harry Sintonen 研究发现,tar 命令在提取路径时能够被绕过,在某些情况下导致文件被覆盖。在一些特定的场景下,利用此漏洞可导致远程代码执行。

    2.漏洞影响

    受害者使用tar命令解压由攻击者构造的特殊 tar 包时,tar 包不会解压到受害者制定的目标路径,而是被解压到攻击者指定的目录位置。

    3.影响范围

    从GNU tar 1.14 to 1.29 (包含1.29) 影响包括 Red Hat,Alphine Linux,Red Star OS以及其他所有使用 GNU tar 的 Linux 系统。

    0x01 漏洞详情


    1. 漏洞检测

    方法一:

    漏洞发现者给出了示例 PoC,用户可用其自检。 (该方法会覆盖用户帐号密码,导致 root 用户密码为空,建议使用实验环境测试或者采用方法二)

    示例poc:

    example_poc

    示例poc中含有一个文件shadow,路径为etc/motd/../etc/shadow。在根目录下解压该包,由于漏洞的影响,../前面的内容给去掉了,路径文件名只剩下etc/shadow,原有etc/shadow文件就被其覆盖了。

     

    方法二:

    访问https://sintonen.fi/advisories/tar-poc.tar下载测试tar包后在提取前重命名 tar 包内的 shadow 文件名,如重命名为 test。然后运行如下命令:

    查看 etc 目录下,若生成了 test 文件,证明该漏洞存在。

    2.具体攻击场景

    以下为漏洞发现者提供的实际攻击场景

    1.攻击者可以用这种手段诱使用户替换一些重要的文件,例如 .ssh/authorized_keys.bashrc , .bash_logout , .profile, .subversion.anyconnect

    2.有一些从 web 应用或者其它类似来源自动解压文件的脚本,这些脚本一般会以 setuid root 权限执行,通常这类脚本的解压命令如下:

    在这种情况下,攻击者可以重写/var/spoon/cron/crontabs/root以获取 root 身份的代码执行能力; 也可以将可能被 root 身份执行的二进制文件替换成一个有后门的版本; 或者投放一个 setuid root 的二进制文件,等待被管理员执行,使攻击者有机会获取 root 权限。

    3.以 root 身份执行解压命令也可能被攻击 。例如上文中提到覆写/etc/shadow的例子

    tar1

    如果--exclude 规则与--anchored 选项同时使用,那么即使手动加了--exclude 规则也没有用,例如:

    tar2

    在两种情况下,攻击者都成功地把/etc/test替换成了任意内容。

    不过,在实际利用这个漏洞时,攻击者需要首先知道一些特定的前导信息,例如解压命令执行时实际在命令行下指定的路径名,毕竟在构造攻击 tar 包时 “../” 序列之前的路径前缀需要符合 tar 命令中所输入的路径,攻击才能奏效。

    3.漏洞分析

    根据漏洞发现者的分析,在lib/paxnames.c文件中,有一个safernamesuffix()函数,这个函数取代了1.13版本的检查机制。

    从代码注释可以看出,如果absolute_names变量为1,将 filename 赋值给 p 继续.反之若为 0 则将文件名中文件系统的前缀给去掉,并且也会对 filename 进行一些安全检查 。 因此,当 tar 解包时若文件名中包含“../”, safernamesuffix 函数会删除"../"及其之前的部分,将其与解压目录路径变为相对关系。这么做的目的是在兼顾文件名的安全性时保证文件的提取,而不是之前版本中改动的跳过含有恶意文件名的文件。在经过长达13年的应用后,这个漏洞终于被 Harry Sintonen 发现并公布出来。

    于是,笔者研究了这个漏洞相关的发展历史。 tar所有版本下载链接 发现:

    • tar通过 src/extarct.c 提取文件
    • extract.c Revision 1.35 前未加入安全检测,可以通过“../”字符串直接绕过解压路径问题,并将文件写到任意位置
    • extract.c Revision 1.35 加入安全检测,会警告压缩文件文件名中存在“..”字符串,并且会跳过不去处理这些文件
    • extract.c Revision 1.47引入 safernamesuffix 函数 - tar 1.16版本后,extract.c文件代码重构,在lib/paxnames.c 文件中定义 safernamesuffix 函数

    然后笔者继续深入,通过tar官网extract.c文件更新列表对比,从源代码分析 tar 的安全检测行为。

    1999/12/13 commit 前后对比

    Revision 1.35官方tag中有一条: ++(extractarchive): By default, warn about ".." in member names, and skip them.++ 即Revision 1.35加入了(extractarchive):默认情况下,在成员名称中警告“..”,并跳过它们 初版修复

    上图中,绿色代码区的功能就填补了之前安全检测的空白。它首先遍历 CURRENTFILENAME,如果存在".."就会警告"Member name contains'..'",然后跳过这些文件,不去处理它们。而左边的灰色空白区域表明之前的版本缺少安全检测,"../"字符串就能绕过解压路径将文件写到任意位置。

    2003/07/05 commit 前后对比

    在Revision 1.47官方 tag 中: ++(extractarchive): Use safername_suffix rather than rolling our own.++ 这就是漏洞初始出现的位置了。

    漏洞之处

    通过代码对比我们可以看到,更新的版本使用 safernamesuffix 函数来替代了开发者自己写的规则。

    4.补丁分析

    官方补丁地址 GNU tar修复了该漏洞,将安全检测机制重新替换回了 extract.c Revision 1.35的规则。

    补丁

    0x02 修复方案


    更新补丁

    http://git.savannah.gnu.org/cgit/tar.git/commit/?id=7340f67b9860ea0531c1450e5aa261c50f67165d

    0x03 参考


    https://www.seebug.org/vuldb/ssvid-92524

    https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=842339

    https://sintonen.fi/advisories/tar-extract-pathname-bypass.proper.txt

    https://sintonen.fi/advisories/tar-extract-pathname-bypass.patch

    https://www.gnu.org/software/tar/

    http://cvs.savannah.gnu.org/viewvc/tar/tar/src/extract.c?view=log&pathrev=release115_1#rev1.47

    作者:kk | Categories:安全研究技术分享 | Tags:
  • Joomla未授权创建特权用户漏洞(CVE-2016-8869)分析

    2016-10-28

    Author: p0wd3r (知道创宇404安全实验室) Date: 2016-10-26

    0x00 漏洞概述


    1.漏洞简介

    Joomla是一个自由开源的内容管理系统,近日研究者发现在其3.4.4到3.6.3的版本中存在两个漏洞:CVE-2016-8869CVE-2016-8870。我们在这里仅分析 CVE-2016-8869,利用该漏洞,攻击者可以在网站关闭注册的情况下注册特权用户。Joomla 官方已对此漏洞发布升级公告

    2.漏洞影响

    网站关闭注册的情况下仍可创建特权用户,默认状态下用户需要用邮件激活,但需要开启注册功能才能激活。

    3.影响版本

    3.4.4 to 3.6.3

    0x01 漏洞复现


    1. 环境搭建

    解压后放到服务器目录下,例如/var/www/html

    创建个数据库:

    2.漏洞分析

    注册

    注册部分可参考:《Joomla未授权创建用户漏洞(CVE-2016-8870)分析》

    提权

    下面我们来试着创建一个特权用户。

    在用于注册的register函数中,我们先看一下$model->register($data)这个存储注册信息的方法,在components/com_users/models/registration.php中:

    可以看到这里使用我们可控的$temp$data赋值,进而存储注册信息。正常情况下,$data在赋值之前是这样的:

    data-common

    而正常情况下我们可控的$temp中是没有groups这个数组的,所以正常注册用户的权限就是我们配置中设置的权限,对应的就是groups的值。

    那么提升权限的关键就在于更改groups中的值,因为$data由我们可控的$temp赋值,$temp的值来自于请求包,所以我们可以构造如下请求包:

    这里我们添加一组值:name="user[groups][]" value=7,让user被当作二维数组,从而groups被识别为数组,并设置数组第一个值为7,对应着Administrator的权限。

    然后发包,通过调试可以看到$temp中已经有了groups数组:

    temp

    最后创建了一个权限为Administrator的用户attacker2:

    exp

    通过存在漏洞的注册函数我们可以提权,那么在允许注册的情况下我们可不可以通过正常的注册函数来提权呢?

    通过对比这两个函数,可以发现这样一点:

    UsersControllerRegistration::register()

    UsersControllerUser::register()

    可以看到UsersControllerRegistration::register()中存储了对$requestData验证后的$data,而UsersControllerUser::register()虽然同样进行了验证,但是存储的仍是之前的$data。所以重点是validate函数是否对groups进行了过滤,我们跟进一下,在libraries/legacy/model/form.php中:

    再跟进filter函数,在libraries/joomla/form/form.php中:

    可以看到这里仅允许$fields中的值出现在$data中,而$fields中是不存在groups的,所以groups在这里被过滤掉,也就没有办法进行权限提升了。

    2016-10-27 更新

    默认情况下,新注册的用户需要通过注册邮箱激活后才能使用。并且:no-activation

    由于$data['activation']的值会被覆盖,所以我们也没有办法直接通过请求更改用户的激活状态。

    2016-11-01 更新

    感谢三好学生D的提示,可以使用邮箱激活的前提是网站开启了注册功能,否则不会成功激活。

    我们看激活时的代码,在components/com_users/controllers/registration.php中第28-99行的activate函数:

    这里可以看到仅当开启注册功能时才允许激活,否则返回403。

    3.补丁分析

    patch

    官方删除了UsersControllerUser::register()方法。

    0x02 修复方案


    升级到3.6.4

    0x03 参考


    https://www.seebug.org/vuldb/ssvid-92495

    https://developer.joomla.org/security-centre/659-20161001-core-account-creation.html

    http://www.fox.ra.it/technical-articles/how-i-found-a-joomla-vulnerability.html

    https://www.youtube.com/watch?v=Q_2M2oJp5l4

     

    作者:kk | Categories:技术分享 | Tags:
  • Joomla未授权创建用户漏洞(CVE-2016-8870) 分析

    2016-10-26

    Author: p0wd3r (知道创宇404安全实验室) Date: 2016-10-26

    0x00 漏洞概述


    1.漏洞简介

    Joomla是一个自由开源的内容管理系统,近日研究者发现在其3.4.4到3.6.3的版本中存在两个漏洞:CVE-2016-8869CVE-2016-8870。我们在这里仅分析CVE-2016-8870,利用该漏洞,攻击者可以在网站关闭注册的情况下注册用户。Joomla官方已对此漏洞发布升级公告

    2.漏洞影响

    网站关闭注册的情况下仍可创建用户,默认状态下用户需要用邮件激活,但需要开启注册功能才能激活。

    3.影响版本

    3.4.4 to 3.6.3

    0x01 漏洞复现


    1. 环境搭建

    解压后放到服务器目录下,例如/var/www/html

    创建个数据库:

    最后访问服务器路径进行安装即可。

    2.漏洞分析

    在存在漏洞的版本中我们可以看到一个有趣的现象,即存在两个用于用户注册的方法:

    • 位于components/com_users/controllers/registration.php中的UsersControllerRegistration::register()
    • 位于components/com_users/controllers/user.php中的UsersControllerUser::register()

    我们对比一下代码:

    UsersControllerRegistration::register():

    UsersControllerUser::register():

    可以看到相对于UsersControllerRegistration::register()UsersControllerUser::register()的实现中并没有这几行代码:

    这几行代码是检查是否允许注册,也就是说如果我们可以用UsersControllerUser::register()这个方法来进行注册就可以绕过这个检测。

    通过测试可知正常的注册使用的是UsersControllerRegistration::register(),请求包如下:

    虽然正常注册并没有使用UsersControllerUser::register(),但是并不代表我们不能使用。阅读代码可知,只要将请求包进行如下修改即可使用存在漏洞的函数进行注册:

    • registration.register -> user.register
    • jform[*] -> user[*]

    所以完整的复现流程如下:

    1. 首先在后台关闭注册功能,关闭后首页没有注册选项:
      no-register
    2. 然后通过访问index.php抓包获取cookie,通过看index.php源码获取token:
      get-cookie
      get-token
    3. 构造注册请求:
    4. 发包,成功注册:
      attack

    2016-10-27 更新

    默认情况下,新注册的用户需要通过注册邮箱激活后才能使用。并且:no-activation

    由于$data['activation']的值会被覆盖,所以我们也没有办法直接通过请求更改用户的激活状态。

    2016-11-01 更新

    感谢三好学生D的提示,可以使用邮箱激活的前提是网站开启了注册功能,否则不会成功激活。

    我们看激活时的代码,在components/com_users/controllers/registration.php中第28-99行的activate函数:

    这里可以看到仅当开启注册功能时才允许激活,否则返回403。

    3.补丁分析

    patch-1

    官方删除了UsersControllerUser::register()方法。

    0x02 修复方案


    升级到3.6.4

    0x03 参考


    https://www.seebug.org/vuldb/ssvid-92496

    https://developer.joomla.org/security-centre/659-20161001-core-account-creation.html

    http://www.fox.ra.it/technical-articles/how-i-found-a-joomla-vulnerability.html

    https://www.youtube.com/watch?v=Q_2M2oJp5l4

    作者:kk | Categories:安全研究技术分享 | Tags:
  • Spring Security OAuth RCE (CVE-2016-4977) 漏洞分析

    2016-10-18

    Author: p0wd3r (知道创宇404安全实验室) Date: 2016-10-17

    0x00 漏洞概述


    1.漏洞简介

    Spring Security OAuth 是为 Spring 框架提供安全认证支持的一个模块,在7月5日其维护者发布了这样一个升级公告,主要说明在用户使用Whitelabel views来处理错误时,攻击者在被授权的情况下可以通过构造恶意参数来远程执行命令。漏洞的发现者在10月13日公开了该漏洞的挖掘记录

    2.漏洞影响

    授权状态下远程命令执行

    3.影响版本

    2.0.0 to 2.0.9

    1.0.0 to 1.0.5

    0x01 漏洞复现


    1. 环境搭建


    2.漏洞分析

    首先我们查看src/resources/application.properties的内容来获取clientid和用户的密码:

    properties

    接着我们访问这个url:

    http://localhost:8080/oauth/authorize?responsetype=token&clientid=acme&redirect_uri=hellotom

    其中client_id就是我们前面获取到的,然后输入任意用户名,密码填上面的password

    点击登录后程序会返回这样一个页面:

    bug-raw

    可以看到由于hellotom对于redirect_uri来说是不合法的值,所以程序会将错误信息返回并且其中带着hellotom,那么这个不合法的值可不可以是一个表达式呢?我们再访问这个url:

    http://localhost:8080/oauth/authorize?responsetype=token&clientid=acme&redirect_uri=${2334-1}

    结果如下:

    bug-num

    可以看到表达式被执行,触发了漏洞。

    下面看代码,由于程序使用Whitelabel作为视图来返回错误页面,所以先看/spring-security-oauth/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpoint.java中第18-40行:


    这里定义了Whitelabel对错误的处理方法,可以看到程序通过oauthError.getSummary()来获取错误信息,我们再次访问这个 url 并开启动态调试:

    http://localhost:8080/oauth/authorize?response_type=token&client_id=acme&redirect_uri=${2334-1}

    error

    请求中的${2334-1}已经被带入了errorSummary中,然后errorSummary被装入model中,再用SpelView进行渲染。

    我们跟进SpelViewspring-security-oauth/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/SpelView.java中第21-54行:

    可以看到在render时通过helper${}中的值作为表达式,再用parser.parseExpression来执行,跟进一下replacePlaceholders这个函数,在/org/springframework/util/PropertyPlaceholderHelper.class第47-56行:

    这个函数是个递归,也就是说如果表达式的值中有${xxx}这样形式的字符串存在,就会再取xxx作为表达式来执行。

    我们看动态调试的结果:

    resolve-errosummary

    首先因为传入了${errorSummary},取errorSummary作为表达式来执行,继续执行程序:

    resolve-poc

    由于errorSummary中存在${2334-1},所以又取出了2334-1作为表达式来执行,从而触发了漏洞。所以从这里可以看出,漏洞的关键点在于这个对表达式的递归处理使我们可控的部分也会被当作表达式执行。

    3.补丁分析

    patch

    可以看到在第一次执行表达式之前程序将$替换成了由RandomValueStringGenerator().generate()生成的随机字符串,也就是${errorSummary} -> random{errorSummary},但是这个替换不是递归的,所以${2334-1}并没有变。

    然后创建了一个helper使程序取random{}中的内容作为表达式,这样就使得errorSummary被作为表达式执行了,而${2334-1}因为不符合random{}这个形式所以没有被当作表达式,从而也就没有办法被执行了。

    不过这个Patch有一个缺点:RandomValueStringGenerator生成的字符串虽然内容随机,但长度固定为6,所以存在暴力破解的可能性。

    0x02 修复方案

    作者:kk | Categories:技术分享 | Tags:
  • WordPress <= 4.6.1 使用语言文件任意代码执行 漏洞分析

    2016-10-13

    Author: p0wd3r (知道创宇404安全实验室) Date: 2016-10-09

    0x00 漏洞概述


    1.漏洞简介

    WordPress是一个以PHP和MySQL为平台的自由开源的博客软件和内容管理系统,近日在 github (https://gist.github.com/anonymous/908a087b95035d9fc9ca46cef4984e97)上爆出这样一个漏洞,在其 <=4.6.1 版本中,如果网站使用攻击者提前构造好的语言文件来对网站、主题、插件等等来进行翻译的话,就可以执行任意代码。

    2.漏洞影响

    任意代码执行,但有以下两个前提:

    1. 攻击者可以上传自己构造的语言文件,或者含有该语言文件的主题、插件等文件夹
    2. 网站使用攻击者构造好的语言文件来对网站、主题、插件等进行翻译

    这里举一个真实场景中的例子:攻击者更改了某个插件中的语言文件,并更改了插件代码使插件初始化时使用恶意语言文件对插件进行翻译,然后攻击者通过诱导管理员安装此插件来触发漏洞。

    3.影响版本

    <= 4.6.1

    0x01 漏洞复现


    1. 环境搭建

    2.漏洞分析

    首先我们来看这样一个场景:

    create_function_bug

    在调用create_function时,我们通过}将原函数闭合,添加我们想要执行的内容后再使用/*将后面不必要的部分注释掉,最后即使我们没有调用创建好的函数,我们添加的新内容也依然被执行了。之所以如此,是因为create_function内部使用了eval来执行代码,我们看PHP手册上的说明:

    eval

    所以由于这个特性,如果我们可以控制create_function$code参数,那就有了任意代码执行的可能。这里要说一下,create_function这个漏洞最早由80sec在08年提出,这里提供几个链接作为参考:

    接下来我们看Wordpress中一处用到create_function的地方,在wp-includes/pomo/translations.php第203-209行:

    根据注释可以看到该函数的作用是根据字体文件中的plural forms这个header来创建函数并返回,其中$expression用于组成$func_body,而$func_body作为$code参数传入了create_function,所以关键是控制$expresstion的值。

    我们看一下正常的字体文件zh_CN.mo,其中有这么一段:

    common

    Plural-Froms这个 header 就是上面的函数所需要处理的,其中nplurals的值即为$nplurals的值,而plural的值正是我们需要的$expression的值。所以我们将字体文件进行如下改动:payload

    然后我们在后台重新加载这个字体文件,同时进行动态调试,可以看到如下情景:

    debug

    我们payload中的)首先闭合了前面的(,然后结束前面的语句,接着是我们的一句话木马,然后用/*将后面不必要的部分注释掉,通过这样,我们就将payload完整的传入了create_function,在其创建函数时我们的payload就会被执行,由于访问每个文件时都要用这个对字体文件解析的结果对文件进行翻译,所以我们访问任何文件都可以触发这个payload:index

    tools

    其中访问index.php?c=phpinfo();的函数调用栈如下:

    call

    3.补丁分析

    目前官方还没有发布补丁,最新版仍存在该漏洞。

    0x02 修复方案


    在官方发布补丁前建议管理员增强安全意识,不要使用来路不明的字体文件、插件、主题等等。

    对于开发者来说,建议对$expression中的特殊符号进行过滤,例如:

    0x03 参考


    作者:kk | Categories:技术分享 | Tags:
  • 从老漏洞到新漏洞—iMessage 0day(CVE-2016-1843)挖掘实录

    2016-10-12

    Author: SuperHei (知道创宇404安全实验室) Date: 2016-04-11

    注:文章里“0day”在报告给官方后分配漏洞编号:CVE-2016-1843

    0x00 背景


    在前几天老外发布了一个在3月更新里修复的 iMessage xss 漏洞(CVE-2016-1764)细节 :

    他们公布这些细节里其实没有给出详细触发点的分析,我分析后也就是根据这些信息发现了一个新的 0day。

    0x01 CVE-2016-1764 漏洞分析


    CVE-2016-1764 里的最简单的触发payload: javascript://a/research?%0d%0aprompt(1) 可以看出这个是很明显javascript协议里的一个小技巧 %0d%0 没处理后导致的 xss ,这个 tips 在找 xss 漏洞里是比较常见的。

    这个值得提一下的是 为啥要用prompt(1) 而我们常用的是alert(1) ,我实际测试了下发现 alert 确实没办法弹出来,另外在很多的网站其实把 alert 直接和谐过滤了,所以这里给提醒大家的是在测试xss的时候,把 prompt 替换 alert 是有必要的~

    遇到这样的客户端的 xss 如果要分析,第一步应该看看 location.href 的信息。这个主要是看是哪个域下,这个漏洞是在applewebdata://协议下,这个原漏洞分析里有给出。然后要看具体的触发点,一般在浏览器下我们可以通过看 html 源代码来分析,但是在客户端下一般看不到,所以这里用到一个小技巧:

    这里是 html 里的 head 代码

    继续看下 body 的代码:

     

    那么关键的触发点:

    就是这个了。 javascript 直接进入 a 标签里的 href,导致点击执行。新版本的修复方案是直接不解析javascript://

    0x02 从老漏洞(CVE-2016-1764)到 0day


    XSS 的漏洞本质是你注入的代码最终被解析执行了,既然我们看到了document.head.innerHTML的情况,那么有没有其他注入代码的机会呢?首先我测试的肯定是还是那个点,尝试用"<>去闭合,可惜都被过滤了,这个点不行我们可以看看其他存在输入的点,于是我尝试发个附件看看解析情况,部分代码如下:

    发了个tttt.html的附件,这个附件的文件名出现在代码里,或许有控制的机会。多长测试后发现过滤也比较严格,不过最终还是发现一个潜在的点,也就是文件名的扩展名部分:

    我们提交的附件的后缀进入了 style :

    也就是可能导致 css 注入,或许我们还有机会,不过经过测试也是有过滤处理的,比如/ 直接被转为了:这个非常有意思 所谓“成也萧何,败也萧何”,如果你要注入css那么肯定给属性给值就得用: 但是:又不能出现在文件名里,然后我们要注入 css 里掉用远程css或者图片需要用/ 而/又被处理了变成了:

    不管怎么样我先注入个css测试下,于是提交了一附件名:zzzzzz.htm) 1x);color/red;aaa/((

    按推断/变为了: 如果注入成功应该是:

    当我提交测试发送这个附件的时候,我的 iMessage 崩溃了~~ 这里我想我发现了一个新的漏洞,于是我升级 OSX 到最新的系统重新测试结果:一个全新的 0day 诞生!

    0x03 后记


    当然这里还有很多地方可以测试,也有一些思路也可以去测试下,比如那个名字那里这个应该是可控制的,比如附件是保存在本地的有没有可能存在目录专挑导致写到任意目录的地方。有需求的可以继续测试下,说不定下个 0day 就是你的 :)

    最后我想说的是在分析别人发现的漏洞的时候一定要找到漏洞的关键,然后总结提炼出“模型”,然后去尝试新的攻击思路或者界面!

    0x04 参考链接


    作者:kk | Categories:技术分享 | Tags:
  • WordPress <= 4.6.1 使用主题文件触发存储型XSS 漏洞分析

    2016-10-11

    Author: p0wd3r (知道创宇404安全实验室) Date: 2016-10-08

    0x00 漏洞概述


    1.漏洞简介

    WordPress是一个以PHP和MySQL为平台的自由开源的博客软件和内容管理系统,近日研究者发现在其<=4.6.1版本中,通过上传恶意构造的主题文件可以触发一个后台存储型XSS漏洞。通过该漏洞,攻击者可以在能够上传主题文件的前提下执行获取管理员Cookie等敏感操作。

    2.漏洞影响

    在能够上传主题文件的前提下执行获取管理员Cookie等XSS可以进行的攻击,实际的攻击场景有以下两种:

    • 攻击者诱导管理员上传恶意构造的主题文件,且管理员并没有对文件进行检查
    • 攻击者拥有管理员权限可以直接上传主题文件,但既然已经有管理员权限再进行这样的攻击也就多此一举了

    3.影响版本

    <= 4.6.1

    0x01 漏洞复现


    1. 环境搭建

    2.漏洞分析

    我们先随便下载一个主题:

    然后对illdy/style.css进行如下更改:

    接着更改文件夹名字再打包:

    构造好之后我们登录后台上传该主题文件,同时开始动态调试。

    首先进入wp-admin/includes/class-theme-installer-skin.php中第55-82行:

    其中$theme_info的值如下:

    Alt text

    其中stylesheettemplate的值为我们更改的文件夹名,headers.Name为更改的style.css中的Name$theme_info中有我们可控的payload,其调用display函数后赋值给$name$name直接与html拼接,所以关键点在display函数上,动态调试跟进到wp-includes/class-wp-theme.php中第630-646行:

    由之前的调用可知,这里的$header的值为Name。首先看$this-get($header),在wp-includes/class-wp-theme.php中第594-617行:

     

    这里省略了与漏洞无关的部分,程序进入了$this->sanitize_header,在wp-includes/class-wp-theme.php第661-705行:

    这里执行了Name这个分支,可以看到程序使用wp_kses$value的值进行了过滤,仅允许$header_tags中的html符号,所以我们headers.Name的值<svg onload=alert(1234)>是不合法的,$value值被赋为空。

    然后程序回到了display函数,根据动态调试可以知道程序执行了$value = $this->markup_header( $header, $value, $translate );这个条件分支,再跟进,在wp-includes/class-wp-theme.php中第720-748行:

    这里我们看到由于$value在之前被赋为空,导致此处$value被重新赋值为了$this->get_stylesheet(),也就是值为<svg onload=alert(5678)>stylesheet变量。最后返回的$value赋给了$name$name再与html拼接返回给客户端,从而触发了漏洞:

    xss_js-1

    xss_html

    这个漏洞有趣的地方在于style.css中的payload其实起到的是一个障眼法的作用,正是因为<svg onload=alert(1234)>被过滤了才使$value被赋值成了我们真正的payload<svg onload=alert(5678)>。所以在构造主题文件的时候style.css和文件夹名这两个地方都要更改。

    3.补丁分析

    可能是由于利用条件十分苛刻,目前Wordpress官方还没有发布补丁,最新版Wordpress仍存在该漏洞。

    0x02 修复方案


    在官方发布补丁前,管理员应提高安全意识,不要轻易使用来路不明的主题。

    对于开发者来说建议对$name进行合法性检查,例如这样:

    0x03 参考


    作者:kk | Categories:安全研究技术分享 | Tags:
  • Django CSRF Bypass 漏洞分析(CVE-2016-7401)

    2016-10-08

    Author: p0wd3r (知道创宇404安全实验室) Date: 2016-09-28

    0x00 漏洞概述


    1.漏洞简介

    Django是一个由Python写成的开源Web应用框架。在两年前有研究人员在hackerone上提交了一个利用Google Analytics来绕过Django的CSRF防护机制的漏洞(CSRF protection bypass on any Django powered site via Google Analytics),通过该漏洞,当一个网站使用了Django作为Web框架并且设置了Django的CSRF防护机制,同时又使用了Google Analytics的时候,攻击者可以构造请求来对CSRF防护机制进行绕过。

    2.漏洞影响

    网站满足以下三个条件的情况下攻击者可以绕过Django的CSRF防护机制:

    • 使用Google Analytics来做数据统计
    • 使用Django作为Web框架
    • 使用基于Cookie的CSRF防护机制(Cookie中的某个值和请求中的某个值必须相等)

    3.影响版本

    Django 1.9.x < 1.9.10

    Django 1.8.x < 1.8.15

    Python2 < 2.7.9

    Python3 < 3.2.7

    0x01 漏洞复现

    1. 环境搭建

    project/app/views.py:

    project/project/urls.py:

    project/app/templates/check.html

    project/app/templates/ga.html(放置Goolge Analytics脚本的页面):

    2.漏洞分析

    我们先来看这样一个场景:

    python276-bug

    当python内置的Cookie.SimpleCookie()解析a=hello]b=world这种形式的字符串时会以]作为分隔,最后取得a=hellob=world这两个cookie,那么为什么会这样呢?

    我们看一下源码,Ubuntu下/usr/lib/python2.7/Cookie.py第622-663行:

    当传入load一个字符串时,调用__ParseString,在__ParseString中有这样一句:match = patt.search(str, i),根据之前定义的pattern来查找字符串中符合pattern的cookie,_CookiePattern在529-545行:

    在这里我们看到]并没有在_LegalCharsPatt中,由于代码中使用的是search函数,所以在匹配a=hello后碰到]会跳过这个字符然后再匹配b=world。因此正是因为使用search函数来匹配,所以当a=hello后面是任意一个不在_LegalCharsPatt中的字符(例如[\]\x09\x0b\x0c)都会达到同样的效果:

    这个漏洞也正是整个Bypass的核心所在。

    我们再来看Django(1.9.9)中对cookie的解析,在http/cookie.py 中第91-106行:

    根据动态调试发现这里的SimpleCookie也就是我们上面所说的存在漏洞的对象,从而可以确定Django中对cookie的处理也是存在漏洞的。

    我们再来看看Django的CSRF防护机制,默认CSRF防护中间件是开启的,我们访问http://127.0.0.1:8000/check/,点击Check然后抓包:

    200

    可以看到csrftokencsrfmiddlewaretoken的值是相同的,其中csrfmiddlewaretoken的值如图:csrf-form

    也就是Django对check.html中的{% csrf_token %}所赋的值。

    我们再改下包,使csrftokencsrfmiddlewaretoken不相等,这回服务器就会返回403:

    403-1

    我们再把两个值都改成另外一个值看看:

    200-2

    依然成功。

    所以Django对于CSRF的防护就是判断cookie中的csrftoken和提交的csrfmiddlewaretoken的值是否相等。

    那么如果想Bypass这个防护机制,就是要想办法设置受害者的cookie中的csrftoken值为攻击者构造的csrdmiddlewaretoken的值。

    如何设置受害者cookie呢?Google Analytics帮了我们这个忙,它为了追踪用户,会在用户浏览时添加如下cookie:

    其中[HOST][PATH]是由Referer确定的,也就是说当Referer: http://x.com/helloworld时,cookie如下:

    由于Referer是我们可以控制的,所以也就有了设置受害者cookie的可能,但是如何设置csrftoken的值呢?

    这就用到了我们上面说的Django处理cookie的漏洞,当我们设置Referer为http://x.com/hello]csrftoken=world,GA设置的cookie如下:

    当Django解析cookie时就会触发上面说的漏洞,将cookie中csrftoken的值赋为world

    实际操作一下,为了方便路由我们在另一个IP上再开一个DjangoApp作为中转,其中各文件如下:

    urls.py:

    views.py:

    route.html:

    开启中转App:

    构造一个攻击页面:

    当我们点击Click me,会先打开一个窗口,再回到原窗口,就可以看到保护机制已经绕过:

    success

    再访问一下http://127.0.0.1:8000/check/,可以看到此时cookie中的csrftoken和form中的csrfmiddlewaretoken都已被设置成boom,证明漏洞成功触发:

    cookie-boomform-boom

    攻击流程如下:

    bypass-flow

    3.补丁分析

    Python

    可以看到这个漏洞在根本上是原生Python的漏洞,首先看最早在2.7.9中的patch:

    patch279

    search改成了match函数,所以再遇到非法符号匹配会停止。

    再看该文件在2.7.10中的patch:

    patch2710

    这里将[\]设置为了合法的value中的字符,也就是

    同样Python3在3.2.7和3.3.6中也做了相应patch:

    patch336

    patch327

    不过尽管上面对[\]做了限制,但是由于pattern最后\s*的存在,所以在以下情况下仍然存在漏洞:

    这些情况在最新的Python中并没有被修复,不过在实际情况中由于浏览器和脚本的原因,这些字符不一定会保存原样发送给Python处理,所以在利用上还要根据场景来分析。

    Django

    Django在1.9.10和1.8.15中做了相同的patch:

    django1910

    它放弃了使用Python内置库来处理cookie,而是自己根据;分割再取值,使特殊符号不再起作用。

    0x02 修复方案


    升级Python

    升级Django

    0x03 参考


    作者:kk | Categories:安全研究技术分享 | Tags:
  • Drupal 8 配置文件下载漏洞分析

    2016-09-29

    Author: p0wd3r (知道创宇404安全实验室)

    Date: 2016-09-22

    0x00 漏洞概述

    1.漏洞简介

    Drupal ( https://www.drupal.org )是一个自由开源的內容管理系统,近期研究者发现在其8.x < 8.1.10的版本中发现了三个安全漏洞,其中一个漏洞攻击者可以在未授权的情况下下载管理员之前导出的配置文件压缩包config.tar.gz。Drupal官方在9月21日发布了升级公告( https://www.drupal.org/SA-CORE-2016-004 )。

    2.漏洞影响

    未授权状态下下载管理员之前导出的配置文件

    3.影响版本

    8.x < 8.1.10

    0x01 漏洞复现

    1. 环境搭建

    Dockerfile(来自Docker Hub)

     

     

    2.漏洞分析

    首先我们进入后台把配置文件导出,默认导出到了/tmp/config.tar.gz

    export
    然后看代码,我们在 core/modules/system/system.routing.yml 可以看到这样一个路由项:

    admin

    这是访问管理员页面时的路由,可以看到 requirements._permission 指定了需要管理员权限。

    然后我们再看这一项:

    router

    可以看到并没有设置 _permission ,并且 _access=TRUE ,也就是说在未授权的情况下是可以访问这个功能的。

    接下来我们跟进它的controller,在 core/modules/system/src/FileDownloadController.php 第41-68行的 download 函数:

    函数获取了我们传入的 file 参数,与 $scheme 拼接后检测文件是否存在。我们访问 http://xxx/system/temporary/?file=config.tar.gz 然后下断点动态调试,执行到该函数时各变量的值如下:

    uri

    也就是说 $scheme 的值是 temporary 。然后程序进入了 file_stream_wrapper_valid_scheme 函数检查协议有效性,动态跟进直到 core/lib/Drupal/Core/StreamWrapper/LocalStream.php 中第495-506行的 url_stat 函数:

    path

    可以看到 temporary://config.tar.gz 被映射到了 /tmp/config.tar.gz ,也就是我们刚备份到的位置,所以也就通过了 file_exists

    通过检查后回到 download 函数中,接下来执行了如下语句:

     

    跟进 invokeAll 函数,在 core/lib/Drupal/Core/Extension/ModuleHandler.php 中第397-409行:

     

     

    动态调试情况如下图:

    funcs

    implementations 的值有 config ,  file , image ,遍历这三个值并调用相应函数:

    config_file_download
    file_file_download
    image_file_download

    首先调用的是 config_file_download ,位于 core/modules/config/config.module 第64-78行:

    可以看到当且仅当文件是 config.tar.gz 时设置响应头以供下载,最后当返回到 download 函数时,执行如下语句:

    将最终的响应返回给了用户,从而触发了下载漏洞。

    download

    到这里有一个想法,我们可不可以传入 ../../etc/passwd\x00config.tar.gz 这样的参数来截断并且跳到别的目录呢?

    我们看一下在 core/lib/Drupal/Core/StreamWrapper/LocalStream.php 中第120到144行的 getLocalPath() 函数,它在上面提到的 url_stat 函数中被调用:

    可以看到路径中的 ../ realpath 过滤,跳出 /tmp 的目的也就不能达到了。

    另外还有一个方面, config_file_download 函数比较苛刻,只允许下载  config.tar.gz ,而 image_file_download 是为了下载图片,那么 file_file_download 函数能否供我们利用以下载系统的敏感文件呢?

    file_file_download 函数在 core/modules/file/file.module 中第582-633行:

     

     

    有以下三点:

    - 根据注释可以看到该函数是根据 uri 来查询数据库中的文件记录再进行下载
    - 我们请求中的 $schemetemporary ,在 file_stream_wrapper_valid_scheme($scheme) && file_exists($uri) 限制了我们只能下载 /tmp 目录下存在的文件
    - 默认 /tmp 下除了 config.tar.gz 只有 .htaccess

    综合这三点来看 file_file_download 函数是不存在下载漏洞的。

    所以总的来说该漏洞只能在管理员导出备份的情况下下载 /tmp/config.tar.gz

    3.补丁分析

    patch

    增加了权限验证,使未授权用户不能下载 cnofig.tar.gz

    0x02 修复方案

    升级Drupal到8.1.10

    0x03 参考

    作者:rungobier | Categories:技术分享 | Tags:
  • BadURLScheme in iOS

    2016-09-28

    文/ SuperHei(知道创宇404安全实验室)

    0x01 前言

    这个是今年我在KCON 2016上的演讲题目,这个漏洞我最早在今年的4月份报告给了苹果公司一直没有得到修复进度等反馈。在刚刚发布的iOS 10里已经不
    受这个漏洞影响了,所以这里直接把细节再次和大家一起分享一下。

    0x02 漏洞描述

    这个漏洞主要是在iOS对于URL Scheme及其在UIWebView等控件的自动诊断识别等处理机制下导致跨应用XSS漏洞。

    0x03 漏洞详情

    iOS下的URLScheme存在几个特点:

    1. iOS 下URL Schemes全局有效且只需安装app即可生效。

    2. iOS下的URL Schemes的链接会被UITextView或者UIWebView的Detection Links属性识别为链接。

    我们先看第2点的具体处理机制“UIWebView的Detection Links属性识别为链接”,也就是说你输入的任何URL Scheme连接都会被解析html里的a标签的调用:

     

     

    对XSS漏洞很熟悉的同学,很可能就会想到2个方向:

    1. 通过双引号闭合使用事件来执行js 经过测试在上引号出现在scheme里不会被识别,所以这个思路不通。
    2. 利用javascript:// 伪协议执行js

    在主流的浏览器内核有2种方法调用,最常见的方法:

    还有另外一种格式方法很少有人正规使用:

    注意:与://的区别,也就是这种非常见的方式导致了很多程序的漏洞,比如前面曝光的iMessage的XSS漏洞(CVE-2016-1764)

    所以这个“BadURLScheme”就是javascript了,我们回到前面提到的iOS下的URLScheme的第一个特点,当用户安装了一个注册了javascript这个URL Scheme的任意app后,如果其他的app里使用了UIWebView并且设置了Detection Links属性识别,那么在这些app里输入文本内容:

    会被Detection Links属性解析为<a>调用:

    成而导致这些app的XSS漏洞。

    0x04 实际案列

    要触发漏洞需要满足2个条件:首先用户需要下载安装一个注册了javascript这个URL Scheme的app [只要求安装就行],一般的方法主要攻击者写一注
    册了javascript这个URL Scheme的app利用短信、微信等社会工程学手段引诱用户下载安装,另外的方法就是现有app市场上有对应注册了javascript这个
    URL Scheme的app,实际上这种案列也是有的,比如:

    [Maxthon Cloud Web Browser - Best Internet Explore Experience by Maxthon Technology Limited]

    https://itunes.apple.com/cn/app/maxthon-cloud-web-browser/id541052011?l=en&mt=8

    也就是安装了Maxthon浏览器的用户很可能会受到影响。另外一个条件就是需要被攻击的app使用UIWebView并且设置了Detection Links属性,在我们实际
    中发现满足这一条件的app是非常多的,比如:微信(已修复)、QQ邮箱(已修复)、outlook、印象笔记、知乎等

    0x05 漏洞演示

    http://v.qq.com/x/page/x0328nwv6ju.html

    0x06 漏洞披露

    在这个漏洞发现只是其实存在很多疑惑的对方:“A系统上安装了B家的软件导致了C家软件被攻击,请问这个是谁家的漏洞?应该报告给谁?”经过分析后我认为是iOS的漏洞,对于Maxthon来说他也算是正规使用URL Scheme,对于那些受影响比较大的C们我还是选择了同时报告

    * 2016.4.12 报告给product-security@apple.com 4.15收到邮件确认收到报告,后续没有收到任何关于漏洞的修复计划。
    * 2016.4.11 报告给TSRC,得到了TSRC的积极反馈。并陆续修复处理了报告里提到的受BadURLScheme影响的app。
    * 2016.4.12 报告给MSRC,收到MSRC反馈改漏洞认定为iOS漏洞已经与苹果公司沟通,outlook一直没做处理
    * 2016.8.27 KCON 2016演讲《BadURLScheme in iOS》
    * 2016.9.14 苹果发布iOS 10升级,测试不受BadURLScheme漏洞影响
    * 2016.9.14 BadURLScheme in iOS细节对外全面公开

    致谢

    最后感谢 呆神、@ogc557、@windknown、@dm557、@Daniel_K4、吕耀佳(行之)、TSRC提供的各种帮助

    四、相关资源链接

    作者:rungobier | Categories:技术分享 | Tags: