基于Metasploit利用GHOST漏洞最终版
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于Metasploit利用GHOST 漏洞获得远程Exim邮件服务器SHELL
分析阶段
1.GHOST漏洞分析及其条件限制
2.如何利用受GHOST漏洞影响的Exim服务的原理
实际操作阶段
1.渗透环境搭建:KaliLinux与Metasploit
2.使用Nmap对目标进行端口扫描及服务查点
3.快速检查被渗透目标是否存在ghost漏洞
4.使用Metasploit加载GHOST漏洞攻击模块进行远程入侵,获得远程主
机shell
=========
分析开始
=========
GHOST漏洞分析及其条件限制
GHOST漏洞是2015年1月27号公布的Linux底层漏洞,国际编号为CVE-2015-0235,存在于GNU C库(glibc)中,受影响的Linux发现版本有:Debian 7 (wheezy),Red Hat Enterprise,Linux 6 & 7,CentOS 6 & 7,Ubuntu 12.04等。
存在漏洞的函数__nss_hostname_digits_dots()由glibc的非重入版本的文件:
nss/getXXbyYY.c,以及重入版本:nss/getXXbyYY_r.c提供。然而,这个函数的调用是由#ifdef HANDLE_DIGITS_DOTS来定义的,这个宏定义只在这几个文件有:
- inet/gethstbynm.c
- inet/gethstbynm2.c
- inet/gethstbynm_r.c
- inet/gethstbynm2_r.c
- nscd/gethstbynm3_r.c
以上这些文件实现gethostbyname*()函数族,因此也只有它们会调用__nss_hostname_digits_dots(),并且可能触发它的缓冲区溢出。该函数的作用是:“如果主机名是IPv4/IPv6地址,就跳过费时的DNS查找”。
glibc-2.17的代码如下:
35 int
36 __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
37 char **buffer, size_t *buffer_size,
38 size_t buflen, struct hostent **result,
39 enum nss_status *status, int af, int *h_errnop)
40 {
..
57 if (isdigit (name[0]) || isxdigit (name[0]) || name[0] == ':')
58 {
59 const char *cp;
60 char *hostname;
61 typedef unsigned char host_addr_t[16];
62 host_addr_t *host_addr;
63 typedef char *host_addr_list_t[2];
64 host_addr_list_t *h_addr_ptrs;
65 char **h_alias_ptr;
66 size_t size_needed;
..
85 size_needed = (sizeof (*host_addr)
86 + sizeof (*h_addr_ptrs) + strlen (name) + 1);
87
88 if (buffer_size == NULL)
89 {
90 if (buflen < size_needed)
91 {
..
95 goto done;
96 }
97 }
98 else if (buffer_size != NULL && *buffer_size < size_needed)
99 {
100 char *new_buf;
101 *buffer_size = size_needed;
102 new_buf = (char *) realloc (*buffer, *buffer_size);
103
104 if (new_buf == NULL)
105 {
...
114 goto done;
115 }
116 *buffer = new_buf;
117 }
...
121 host_addr = (host_addr_t *) *buffer;
122 h_addr_ptrs = (host_addr_list_t *)
123 ((char *) host_addr + sizeof (*host_addr));
124 h_alias_ptr = (char **) ((char *) h_addr_ptrs + sizeof (*h_addr_ptrs)); 125 hostname = (char *) h_alias_ptr + sizeof (*h_alias_ptr);
126
127 if (isdigit (name[0]))
128 {
129 for (cp = name;; ++cp)
130 {
131 if (*cp == '\0')
132 {
133 int ok;
134
135 if (*--cp == '.')
136 break;
...
142 if (af == AF_INET)
143 ok = __inet_aton (name, (struct in_addr *) host_addr); 144 else
145 {
146 assert (af == AF_INET6);
147 ok = inet_pton (af, name, host_addr) > 0;
148 }
149 if (! ok)
150 {
...
154 goto done;
155 }
156
157 resbuf->h_name = strcpy (hostname, name);
...
194 goto done;