记录黑客技术中优秀的内容,传播黑客文化,分享黑客技术精华

CVE-2020-8597 pppd stack buffer overflow in eap_response

2020-03-24 11:02

0x0 背景

pppd是一个通过串行接口连接的点对点协议(PPP)

github地址 :https://github.com/paulusmack/ppp

在ppp 2.4.2 - 2.4.8版本有一个栈溢出漏洞,我试着分析了整个过程

0x1复现整个过程

准备两台ubuntu的虚拟机(我用的virtualbox),设置启用串口功能。分别在两台虚拟机上git clone一份ppp,并回滚到有漏洞版本,编译安装。例如

git clone https://github.com/paulusmack/ppp.git
cd ppp
git checkout ppp-2.4.8
./configure
make
make install

开启服务端的md5认证(MD5-Challenge)

打开文件/etc/ppp/chap-secrets添加下面内容

admin   *       password        *

服务端启动pppd程序

pppd /dev/ttyS0 9600 auth local lock defaultroute debug nodetach 172.16.1.1:172.16.1.2 ms-dns 8.8.8.8 require-eap

客户端启动pppd程序

pppd noauth local lock defaultroute debug nodetach /dev/ttyS0 9600 user aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb password notpassword

下图我们发现程序没有崩溃,服务端打印出的username只有255个字节,我们输入的username255+5个字节,可惜这不是服务端对接收的内容进行的验证,这是在客户端限制了用户输入的用户名长度

0x2 漏洞分析

pppd进行MD5-Challenge的时候,通过eap_chap_response把密码hash、用户名和用户名长度一起发送到了服务端,用户名保存在一个256大小的栈变量中。

所以在我们上边的测试中,其实只发送了255长度的username到服务端。

6     typenum = id;
5 MD5_Update(&mdContext, &typenum, 1);
4 MD5_Update(&mdContext, (u_char *)secret, secret_len);
3 BZERO(secret, sizeof (secret));
2 MD5_Update(&mdContext, inp, vallen);
1 MD5_Final(hash, &mdContext);
1454 ** eap_chap_response(esp, id, hash, esp->es_client.ea_name,
1 esp->es_client.ea_namelen);
2 break;
787    eap_authwithpeer(unit, user);
20 void
19 eap_authwithpeer(unit, localname)
18 int unit;
17 char *localname;
16 {
15 eap_state *esp = &eap_states[unit];
14
13 /* Save the peer name we're given */
12 esp->es_client.ea_name = localname;
11 esp->es_client.ea_namelen = strlen(localname);
10
9 esp->es_client.ea_state = eapListen;
8
7 /*
6 * Start a timer so that if the other end just goes
5 * silent, we don't sit here waiting forever.
4 */
3 if (esp->es_client.ea_timeout > 0)
2 TIMEOUT(eap_client_timeout, (void *)esp,
1 esp->es_client.ea_timeout);
257 }
extern char user[MAXNAMELEN];/* Our name for authenticating ourselves */
extern char passwd[MAXSECRETLEN]; /* Password for PAP or CHAP */
#define MAXNAMELEN  256 /* max length of hostname or name for auth */

服务端接收的时候,vallen是已经处理的长度,len是接收的总长度,sizeof (rhostname)是username最大的长度和客户端一样256的数组,所以if判断手误了?

最后MD5-Challenge没处理好长度验证。当发送大于256长度的字符串时,发生益处。

if (vallen >= len + sizeof (rhostname)) {
dbglog("EAP: trimming really long peer name down");
BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1;
rhostname[sizeof (rhostname) - 1] = '\0';
} else {
BCOPY(inp + vallen, rhostname, len - vallen);
rhostname[len - vallen] = '\0';
}

0x3 其他

想要触发服务端崩溃,可以像参考链接中的博主一样,直接修改eap_chap_response中的username送的内容。也可以像另一位博主一样,wireshark抓包,修改数据包中username内容,在写脚本发包到服务端,

0x4一半翻译一半补充的参考链接

https://gist.github.com/nstarke/551433bcc72ff95588e168a0bb666124


知识来源: xz.aliyun.com/t/7407

阅读:52622 | 评论:0 | 标签:CVE

想收藏或者和大家分享这篇好文章→复制链接地址

“CVE-2020-8597 pppd stack buffer overflow in eap_response”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

ADS

标签云

本页关键词