Windows安全通道远程代码执行漏洞(CVE-2014-6321)浅析


发布人:admin分类:网络安全浏览量:45发布时间:2017-12-12

一、背景

Windows安全通道(Secure Channel,Schannel)惊报漏洞,微软日前发布列为重大等级的MS14-066信息安全公告,揭露了在Schannel中的远程代码执行漏洞(CVE-2014-6321)。

受影响的微软产品包括:

个人端操作系统:Windows VistaSP2、Windows 7 SP1、Windows 8到Windows 8.1
服务器操作系统:Windows Server 2003 SP2、2008 SP2、2008 R2 SP1、2012到2012 R2
微软平板:Windows RT和Windows RT 8.1。

黑客可以构造特定的数据包在Schannel中远程执行恶意代码,并藉此漏洞入侵系统。因为Schannel是Windows实现SSL/TLS协议的组件之一,所以CVE-2014-6321漏洞就像是OpenSSL中的Heartbleed漏洞,危害巨大。

思科Talos团队表示,MS14-066涉及一个常见漏洞揭露CVE-2014-6321。虽然该漏洞是单一的CVE,但是实际上却包含了多个漏洞,范围广从缓冲区到凭证验证。

Rapid7资深信息安全工程经理Ross Barrett表示,目前CVE-2014-6321漏洞的影响还不大,但是如果攻击代码泄漏,该漏洞将会成为严重的问题,且影响会扩大。

目前,微软也尚未接到有关该漏洞已公开用来攻击用户的消息,而微软在官网也表示,此安全更新可以更正Schannel清理特定封包的方式,进而消除此项安全风险。

二、探究

网上关于CVE-2014-6321漏洞的详情与利用方法鲜有披露。我们通过新发布的补丁来一探究竟。

通过对打补丁前后的schannle.dll文件进行二进制比较,可查看到一些修改过的函数,其中几个是类DTLSCookieManager的方法。由此表明了至少有一个bug位于DTLSCookieManager类中。而大家最关心的bug好像是位于schannel!DecodeSigAndReverse(…)中,DecodeSigAndReverse函数的变更如下所示。

由从上图可清楚的看到DecodeSigAndReverse函数中间添加了一些新的代码块(图右侧中的灰色模块)。新添分支往往是一个好兆头!如果我们放大打补丁的版本(图右侧),情况似乎更符合预期。

上图可看到新添代码块把运行路径指向了memcpy调用(实际上是两次memecpy函数调用)。程序是如何运行到这部分代码?可查看DecodeSigAndReverse函数在未打补丁版本中的调用路径。

由上图可知,似乎需要先命中“ProcessHandshake”函数,然后再构造一个“Client Verify Message”(客户端验证消息)来命中被修改的代码。为了实现触发,我们查阅了MSDN中有关TLS/SSL的文档(如下图)。

根据调用路径中涉及的函数名称,Schannel可能是在处理一个“Certificate Verify”消息,涉及证书的认证过程(客户端发送一个证书到服务器,服务器通过证书验证客户端身份)。如果仔细查看未打补丁的函数,可从调用函数CryptDecodeObject的参数lpszStructType发现一个关键的线索。

BOOL WINAPI CryptDecodeObject(
 _In_     DWORD dwCertEncodingType,                  //使用的编码类型
 _In_     LPCSTR lpszStructType,                     //结构的类型
 _In_     constBYTE *pbEncoded,                      //指向待解码的结构
 _In_     DWORD cbEncoded,                           //待解码结构的字节长度
  _In_     DWORDdwFlags,                                         
 _Out_    void*pvStructInfo,                         //指向存储解码后的结构
 _Inout_  DWORD *pcbStructInfo                       //表示解码后的据结构的字节长度
);

通过MSDN查询,我们可获知lpszStructType参数指出证书签名的结构类型。在本例中,可以是X509_ECC_SIGNATURE(ECDSA签名)和X509_DSS_SIGNATURE(DSS签名)。若选择ECC_SIGNATURE,该结构在MSDN中有具体的定义。

//CERT_ECC_SIGNATURE结构包含了椭圆曲线数字签名算法(ECDSA)的r值和s值。
typedef struct _CERT_ECC_SIGNATURE {
 CRYPT_UINT_BLOB r;             // ECDSA签名的r值,Little-Endian字节顺序。
 CRYPT_UINT_BLOB s;              // ECDSA签名的s值,Little-Endian字节顺序。
} CERT_ECC_SIGNATURE, *PCERT_ECC_SIGNATURE;

其中一个memcpys函数调用的size参数好像存在问题,可能与证书的编码过程有关。

void *memcpy(
void *dest,             //目的的缓冲区。
const void *src,        //源的缓冲区
size_t size             //字节长度。
);

据我们所知,最快速的处理方法就是在运行状态下观察这个函数(PS当然要用调试器,不然看不到哟)。因此,利用OpenSSL创建一个ECDSA签名的证书,并将IIS设置成证书认证的方式。然后,把远程调试器附加到运行IIS服务的服务器中的LSASS进程,并在比较ECC_SIGNATURE(ECDSA签名)的地方设置断点(cmp ebx, 2F)。

令人吃惊的是,当利用OpenSSL client第一次尝试链接IIS服务进行认证时,断点就被触发。既然能够命中存在问题的代码,下一步就是触发漏洞。为了加快分析过程,我们决定修改OpenSSl来模糊测试这个调用路径。

在OpenSSL中,源文件s3_clnt.c实现了“client verify messages”的ECDSA签名。客户端的已编码的ECDSA签名由客户端上OpenSSL中ECDSA_sign(…)函数生成,最终命中IIS服务器上schannel!DecodeSigAndReverse()中的函数CryptDecodeObject(…)。如果追踪函数ssl3_send_client_verify(…),发现它最终会调用ECDSA_sign(…),下图就是对“client verify messages”进行ECDSA签名的代码块。

#ifndef OPENSSL_NO_ECDSA
                            if(pkey->type == EVP_PKEY_EC)
                            {
                            if(!ECDSA_sign(pkey->save_type,
                                     &(data[MD5_DIGEST_LENGTH]),
                                     SHA_DIGEST_LENGTH,&(p[2]),
                                     (unsignedint *)&j,pkey->pkey.ec))
                                     {
                                     SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
                                         ERR_R_ECDSA_LIB);
                                     gotoerr;
                                     }
                            s2n(j,p);
                            n=j+2;
                            }
                   else
#endif

为弄清楚这个调用过程,其中ECDSA_sign函数的原型如下:

int  ECDSA_sign(
int type,                      //可忽略
const unsigned char *dgst,     //指向待签名的散列值
int dgstlen,                   //散列值的长度
unsigned char *sig,            //指向存储DER编码的签名的存储空间
unsigned int *siglen,          //签名的长度
EC_KEY *eckey                  //EC_KEY对象,包含了EC私钥
);

通过查阅该函数的帮助文档,可知“DER编码后的签名存储在sig中,而sig的长度存储在sig_len中”。如果打算使用OpenSSl s_client向IIS发起身份认证,然后Schannel一路运行到schannel!DecodeSigAndRevers(…)函数,我们可以看到变量“p”经ECDSA_sign(…)运算的结果会提交到schannel!CryptDecodeObject(…)函数,经过解码后并传递到存在问题代码中的memcpy调用。

因此,仅需将变量“p”中的一个字节设置为一个随机值,然后不停向IIS发送“Certificate Verify”消息,直到一些奇怪的事情发生。如果等待足够的时间,可以观察由memcyp引起的进程崩溃。

进一步的分析和漏洞利用留给读者来练手。(太给读者们面子了)

[参考信息来源beyondtrust,内容有所删减,尽量保留了原文本意。译自Rabbit_Run,喜欢文章请点赞鼓励。]


被黑站点统计 - 文章版权1、本主题所有言论和图片纯属会员个人意见,与本文章立场无关
2、本站所有主题由该文章作者发表,该文章作者与被黑站点统计享有文章相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该文章作者和被黑站点统计的同意
4、文章作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、被黑站点统计管理员有权不事先通知发贴者而删除本文

免责声明

本站主要通过网络搜集国内被黑网站信息,统计分析数据,为部署安全型网络提供强有力的依据.本站所有工作人员均不参与黑站,挂马或赢利性行为,所有数据均为网民提供,提交者不一定是黑站人,所有提交采取不记名,先提交先审核的方式,如有任何疑问请及时与我们联系.

admin  的文章


微信公众号

微信公众号


Copyright © 2012-2022被黑网站统计系统All Rights Reserved
页面总访问量:21292763(PV) 页面执行时间:271.662(MS)
  • xml
  • 网站地图