一.背景介绍
MikroTik是一家拉脱维亚公司,成立于1996年,目的是开发路由器和无线ISP系统。MikroTik现在为全球大多数国家的互联网连接提供硬件和软件。RouterOS是MikroTik基于Linux v3.3.5内核的独立操作系统。
二.漏洞信息
在处理NetBIOS会话请求消息时,MikroTik RouterOS SMB服务中发现缓冲区溢出。有权访问该服务的远程攻击者可利用此漏洞并在系统上获得代码执行权。溢出发生在身份验证发生之前,因此未经身份验证的远程攻击者可能利用此漏洞。
CVE编号:CVE-2018-7445
三、漏洞影响
版本号低于 6.41.3/6.42rc27的RouterOS
四、漏洞分析
本次分析使用的系统版本6.40.5,下载并解压iso文件
使用WinHEX查看npk文件,npk文件经过一定的处理
前0×1000是无效的,之后是Squashfs文件系统的头部标识
使用binwalk解包,设置偏移offset=0×1000
解包后,系统文件目录如下
对smb文件分析
在void *__cdecl sub_8060430(int a1, int fd)函数中,使用recvmsg函数接收数据包,在接收过程中,有对数据包大小进行校验,若msg.msg_conntrollen不等于指定大小则返回失败,若接收到的message符合一定格式时,如msg_conntrol>49,且conntrollen等于指定值时进行下一步解析
并从接收到的消息处先行拷贝出50字节进行相关处理,但在处理过程中已接收到并被拷贝出的数据的第12字节处为指针参数调用sub_8054607(parse_names)函数,
根据代码解析,接收到的数据的第12到16字节应该是name长度,将name完整拷贝置大小为34字节大小的栈空间内,但由于未验证12-16字节处大小,导致栈溢出
伪代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
char* buf; char mid_buf[50]; char dst[32] struct msghdr message; void* result; result = (void *)recvmsg(fd, &message, 0); if (result==-1) { printf("NBServ: recvmsg error"); return; } else if(result>49) { if(message.msg_control>12) result=message.msg_control; while(result) { if(!message.msg_conntrollen&&message.msg_flags==8) ... if(message.msg_conntrollen==limit_len) { memcpy(buf,message.msg_iov,50); parse_names(dst,buf[12]) ... } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
int parse_names(char *dst, char *src) { int len; int i; int offset; // take the length of the first string len = *src; offset = 0; while (len) { // copy the bytes of the string into the destination buffer for (i = offset; (i - offset) < len; ++i) { dst[i] = src[i+1]; } // take the length of the next string len = src[i+1]; // if it exists, then add a separator if (len) { dst[i] = "."; } // start over with the next string offset = i + 1; } // nul-terminate the string dst[offset] = 0; return offset; } |
- 升级到最新版
- 如果不能更新系统的,可以禁用smb服务