U.R.C. project

Angelo Rosiello <[email protected]> 10 Apr 2003 14:29:40 -0000
Newsgroups gmane.comp.security.papers
Message-ID <[email protected]>

=0D
#########################################################################=
=0D
#									#=0D
#			    U. R. C. project		                #=0D
#							 		#=0D
#	               UDP     Remote    Controls			#=0D
#    	           Copyright (c) dtors.net  (2003)	         	#=0D
#			  by Angelo Rosiello				#=0D
#		         All Rights Reserved				#=0D
#		       		                                        #=0D
#									#=0D
#########################################################################=
=0D
=0D
=0D
=0D
--[ Contents	=0D
	1 - Introduction=0D
	2 - UDP Basics=0D
	3 - How to spoof datagrams=0D
	    3.1 - Pieces of code=0D
	    3.2 - Explaining the code=0D
	4 - Direct contact with my implementation=0D
	    4.1 - Analysis of the program=0D
	    4.2 - Fast how to=0D
	5 - Source of the project=0D
	    5.1 - Server sources=0D
	    5.2 - Client sources=0D
	    5.3 - Crypto sources	=0D
=0D
=0D
=0D
=0D
=0D
--[ 1 - Introduction=0D
=0D
I want to illustrate, with this article, the possibility to control =0D
servers with the UDP protocol.=0D
In  order to exemplify all the question,I realized the program too. =0D
You can  find the  complete  package here:=0D
http://packetstormsecurity.org/UNIX/penetration/udp-remote-final.tar.gz=0D
=0D
The sources of the project, are below, point number 5.=0D
=0D
=0D
=0D
--[ 2 - UDP Basics=0D
=0D
Before  describing  the  program  functions and services, I thought that =
=0D
it  was useful to  explain some  important topics  about the  UDP =0D
protocol,  that is the basic element of the whole project. =0D
=0D
=0D
User Datagram Protocol (rfc 768), together with TCP, is the the transport=
=0D
layer protocol of the ISO/OSI model:=0D
=0D
=0D
			7. APPLICATION LAYER=0D
=0D
			6. PRESENTATION LAYER=0D
=0D
			5. SESSION LAYER=0D
=0D
			4. TRANSPORT LAYER (TCP-UDP) <-- We are here!=0D
=0D
			3. NETWORK LAYER	(IP)=0D
=0D
			2. DATA LINK LAYER=0D
=0D
			1. PHYSICAL LAYER         =0D
=0D
=0D
The generic format of the UDP datagram is the following:=0D
=0D
Format ------=0D
                 0      7 8     15 16    23 24    31  =0D
                 +--------+--------+--------+--------+ =0D
                 |     Source      |   Destination   | =0D
                 |      Port       |      Port       | =0D
                 +--------+--------+--------+--------+ =0D
                 |                 |                 | =0D
                 |     Length      |    Checksum     | =0D
                 +--------+--------+--------+--------+ =0D
                 |                                     =0D
                 |          data octets ...            =0D
                 +---------------- ...                 =0D
=0D
=0D
                      User Datagram Header Format=0D
=0D
=0D
1. Source Port 		   :  The source port is  an optional field,  =0D
    (16 bit)		   it  indicates the port from which the  packet =0D
			   was sent  and eventuallytoward which  the =0D
answer =0D
			   is expected. If no value is set, the default =0D
			   value is forced to 0.=0D
=0D
2. Destination Port	   : It indicates the destination port of the  =0D
final=0D
      (16 bit)		   peer process.=0D
=0D
3. Length 		   : It  specifies  in   bytes  the  datagram   =0D
  (32 bit)		   length  in  its entireness(header+payload).=0D
=0D
4. Checksum		   : It develops tipical functions as error-control=0D
  (16 bit)	           on the  TCP IU,  added a  header containing   =0D
the =0D
  			   source  IP  address,  the destination  IP =0D
address,=0D
  			   the number of TCP protocol and the number (in =0D
bytes)=0D
  			   of the UDP fragment.=0D
=0D
The error-control  procedure realized  by the  checksum field is optional=
,=0D
in order to relieve the protocol as much as possible.=0D
=0D
=0D
=0D
--[ 3 - How to spoof datagrams=0D
=0D
In the OSI model, the UDP protocol exploits the IP services. =0D
The UDP service  is connectionless, it doesn't  get any logical =0D
connection  =0D
between the  two communicating hosts, it doesn't guarantee  the sequence =
=0D
of =0D
the Informative Unit transfer on the net, finally there's  no certainty =0D
about  the correct datagrams transfer. One of  the "vulnerabilities" of t=
he=0D
UDP is the possibility to send "spoofed" packets (with a faked source IP)=
. =0D
=0D
This is the direct consequence of the connectionsless service,realized by=
 =0D
UDP.=0D
=0D
=0D
=0D
--[ 3.1 - Pieces of code=0D
=0D
In order to make this explanation clear,  here is a piece of code =0D
that  let  you spoof the source IP of the datagram.=0D
=0D
............. =0D
#include  .... main()  =0D
{=0D
int  ....; =0D
char  ....; =0D
int  sd; =0D
int  port =3D 34567;      =0D
struct sockaddr_in source_addr, destination_addr;=0D
udp_initialize(&source_addr, 0,  inet_addr(argv[1])); 		//   (1)=0D
udp_initialize(&destination_addr, port,  inet_addr(argv[2]));	//   (2)=0D
sd =3D socket(AF_INET, SOCK_DGRAM, 0); =0D
bind(sd, (struct sockaddr *)  &source_addr,=0D
	sizeof(source_addr); =0D
sendto(sd, argv[3], strlen(argv[3]), 0, (struct sockaddr *) =0D
	&destination_addr, sizeof(destination_addr)); =0D
=0D
void  udp_initialize(struct  sockaddr_in  *address, int  port, long  =0D
IPaddr)=0D
{=0D
address->sin_family   =3D  AF_INET;=0D
address->sin_port  =3D   htons((u_short)port);=0D
address->sin_addr.s_addr =3D IPaddr; =0D
}=0D
=0D
=0D
=0D
--[ 3.2 - Explaining  the  code =0D
 =0D
(1)  This   piece  of   code  calls  the  udp_initialize procedure  that =
 =0D
let  you   fill the  socket structure  fields.	  =0D
In this particular case   we put the socket's port to 0 and the IP  =0D
address =0D
as  argv[1].=0D
W.N:The Ip and the port are chosen arbitrarily, because no reply is =0D
expected=0D
=0D
In the case (2), the destination's socket value are set correctly.=0D
=0D
The step (1) let us create a spoofed datagram. =0D
=0D
Now that  we have  an idea  of UDP's  functions, we can understand my  to=
ol=0D
better.  =0D
This  program can  be  used in different ways, but in the complex  it's=0D
surely interesting.=0D
=0D
=0D
=0D
--[ 4 - Direct contact with my implementation=0D
=0D
The  program was  idealized in 2002 as a tool to execute remotely =0D
commands, =0D
withouot  opening  any  direct logical connection with the wished server.=
 =0D
I discarded immediately the TCP protocol,because it is connection-=0D
oriented.  =0D
Another  aspect   that   I wouldn't exclude was the  possibility to avoid=
  =0D
to open TCP ports, that could be easily scanned and maybe flooded =0D
(or  similar). The first version of the program included a not very =0D
good    =0D
dynamic algorithm, because it didn't  supply  any procedure  of commands =
 =0D
reading from an external file, but directly from  the source  file.  =0D
For these reasons I coded another procedure that let you read commands =0D
to be executed from the configuration file.=0D
=0D
=0D
=0D
--[ 4.1 - Analysis of the Program=0D
=0D
(This  is my  own program  but you  can realize another one, this  is onl=
y=0D
a concept question!)=0D
=0D
$cat server.c=0D
=0D
#define PORT 32980	 // Listening port.=0D
=0D
#define ETC  "udp.conf"  //  Configuration file.  It indicates  the name =
=0D
			     of the file, from which the reading of the =0D
			     commands to execute will start.=0D
=0D
You can modify the above values, as you wish.=0D
=0D
The file "udp.conf" (not crypted), must be edited, for a correct use =0D
as follows:=0D
=0D
$cat udp.conf =0D
KEY WORD:/PATH/TO/PROGRAM=0D
=0D
example: =0D
angelo:/home/angelo/hello=0D
=0D
When the server  will receive the  key-word "angelo", it  will execute=0D
the  file "/home/angelo/hello"=0D
=0D
The tool even implements a logging procedure of all the received =0D
commands,  =0D
with date and source IP.=0D
=0D
fd =3D open("server.log", O_CREAT | O_RDWR | O_APPEND, 0644);	=0D
=0D
The log file will be placed in the same directory of the program and  =0D
it's name will be "server.log".=0D
=0D
During the implementation of the project, I have decided to crypt the=0D
configuration file and the log file too. The crypto() algorithm is really=
  =0D
easy, but not so stupid; it executes a XOR cryptation of any file's byte =
=0D
with the key.=0D
The default key is:=0D
=0D
int key =3D 0xff17261;		// This is the cryptation Key; Change IT!!!=0D
=0D
You can modify it and insert another one like 0xff71678 and so on...=0D
=0D
The "UDP.CONF"  file, after  being edited  correctly, must  be crypted  =0D
with =0D
the crypto program,that you will find in the main directory,of the =0D
package. =0D
It's really IMPORTANT that the keys of server.c and crypto.c must be =0D
the same,  or the server  program  won't  work at all,  as  it couldn't =0D
read  =0D
the  "udp.conf" file correctly.=0D
=0D
=0D
=0D
--[ 4.2 - Fast how to=0D
=0D
Edit the  "udp.conf" file  following the  above indications.  =0D
Change the keys of server.c and crypto.c (they must be IDENTICAL!).=0D
=0D
Compile the program.=0D
=0D
$./server  (the program will go in background)=0D
=0D
Now  just send key commands using the client.=0D
=0D
$./client SOURCE-IP DEST-IP PORT command=0D
=0D
=0D
=0D
--[ 5 - Source of the project=0D
=0D
Project Sources for Linux.=0D
=0D
--[ 5.1 - Server sources=0D
=0D
#######################	SERVER.C ############################=0D
/*=0D
***=0D
***=0D
***	               	  UDP REMOTE CONTROLS=0D
*** =0D
***=0D
***                Copyright (c) The last of Calamities =0D
***                       All Rights Reserved       =0D
***      	 	AUTHOR: Angelo Rosiello (Guilecool)=0D
***=0D
*** 		DATE: 30/01/2003 (maybe It was the 20th hand..)=0D
***=0D
***=0D
*/=0D
=0D
#include <stdio.h>=0D
#include <sys/types.h>=0D
#include <sys/socket.h>=0D
#include <netinet/in.h>=0D
#include <string.h>=0D
#include <signal.h>=0D
#include <fcntl.h>=0D
#include <assert.h>=0D
#include <netdb.h>=0D
#include <time.h>=0D
#include <stddef.h>=0D
=0D
#define PORT 32980=0D
#define ETC "udp.conf"=0D
=0D
void bg();		=0D
void udp_initialize();=0D
char crypto(char ch);=0D
void logging();=0D
=0D
=0D
=0D
main() /* well, I like to put main() right here ;P */=0D
  {=0D
=0D
	 int sd, client_len, status, binding, fd, result, i,comando, eof;=0D
         char ch[1024], temp, crypted, memorizza[100];=0D
	 struct sockaddr_in server_addr, client_addr;=0D
	 udp_initialize(&server_addr, PORT, INADDR_ANY);=0D
	 sd =3D socket(AF_INET, SOCK_DGRAM, 0);=0D
	 if(sd < 0) perror("Socket");=0D
	 assert(sd >=3D 0);=0D
	 binding =3D bind(sd, (struct sockaddr *) &server_addr, =0D
	 		sizeof(server_addr));=0D
	 if(binding !=3D 0) perror("Bind");=0D
	 assert(binding =3D=3D 0);=0D
	 fd =3D open(ETC, O_RDONLY); =0D
	 if(fd <=3D 0) perror("UDP.CONF");=0D
	 assert(fd > 0);	 =0D
	 bg();=0D
=0D
	 while(1)=0D
	 {=0D
	 	for(i =3D 0; i< 1024; i++) ch[i] =3D '\0';=0D
		for(i =3D 0; i< 100; i++) memorizza[i] =3D '\0';=0D
         	recvfrom(sd, ch, 1023, 0, (struct sockaddr *) &client_addr,=0D
         		 &client_len);=0D
		result =3D 1;=0D
		i =3D 0;=0D
		lseek(fd, 0, 0);=0D
=0D
		logging(ch);=0D
=0D
=0D
		while(result)	=0D
		{=0D
	     		eof =3D read(fd, &temp, 1);=0D
			if(eof =3D=3D 0) break;=0D
			crypted =3D crypto(temp);=0D
			if(crypted !=3D ':' && crypted !=3D '\n')=0D
			{=0D
				memorizza[i] =3D crypted;		=0D
				i++;				=0D
			}=0D
			else if(crypted =3D=3D '\n')		=0D
			{=0D
				for(i=3D0; i< 100; i++) memorizza[i] =3D '\0';=0D
				i =3D 0;=0D
			}=0D
			else if(crypted =3D=3D ':')=0D
			{=0D
		  		if(!strcmp(memorizza, ch))=0D
		    		{=0D
					for(i=3D0; i< 100; i++) =0D
							memorizza[i] =0D
=3D '\0';		=0D
					i =3D 0;=0D
					comando =3D 1;=0D
					while(comando)=0D
					{=0D
						read(fd, &temp, 1);=0D
						crypted =3D crypto(temp);	=0D
					=0D
						if(crypted !=3D '\n')=0D
						{=0D
						memorizza[i] =3D crypted;=0D
						i++;=0D
						}=0D
						else if(crypted =3D=3D '\n')=0D
						{=0D
                                  =0D
							system(memorizza);=0D
							comando =3D 0;=0D
						}=0D
					}=0D
				}=0D
				else =0D
				{=0D
					for(i=3D0; i<100; i++) memorizza[i]=0D
=3D '\0';=0D
					i =3D 0;=0D
				}=0D
	    		}=0D
		}=0D
	 	=0D
	 } 								=0D
		=0D
		    		=0D
} 									=0D
		=0D
=0D
=0D
/*=0D
** Implementing the procedures=0D
**   =0D
** 1) Background=0D
**   =0D
** 2) Setting up addresses=0D
**   =0D
** 3) Logging=0D
**=0D
** 4) Decrypting the config file and reading it=0D
** =0D
*/=0D
=0D
=0D
=0D
/**********************************************=0D
* Background procedure			      *=0D
* Nothing to explain even...                  *=0D
**********************************************/	 =0D
=0D
void bg()=0D
{=0D
	signal(SIGHUP, SIG_IGN);=0D
	if (fork ()!=3D 0)=0D
	{=0D
		exit(0);=0D
	}=0D
}=0D
=0D
=0D
=0D
=0D
/**********************************************=0D
* Address initialize procedure                *=0D
**********************************************/=0D
=0D
void udp_initialize(struct sockaddr_in *address, int port, long IPaddr)=0D
{=0D
	address->sin_family =3D AF_INET;=0D
	address->sin_port =3D htons((u_short)port);=0D
	address->sin_addr.s_addr =3D IPaddr;=0D
}=0D
=0D
=0D
=0D
=0D
/**********************************************=0D
* Crypting procedure                          *=0D
* The configuration file will be decripted    *=0D
* The Log file will be cripted...             *=0D
**********************************************/=0D
=0D
char crypto(char ch)=0D
{=0D
        char crypted;=0D
        int key =3D 0xff17261;=0D
        crypted =3D ch ^ key;=0D
        return(crypted);=0D
}=0D
=0D
=0D
=0D
=0D
/**********************************************=0D
* Logging procedure                           *=0D
* The Logs' file will be "server.log"	      *=0D
**********************************************/=0D
=0D
void logging(char ch[1024])=0D
{=0D
	struct hostent *entity;=0D
	struct sockaddr_in client_addr;=0D
	struct tm *ptr;=0D
	int fd, i;=0D
	unsigned long ip;=0D
	char orario[30], temp[1024], crypted, carattere, indirizzo[32];=0D
	char source[] =3D "Connection from \n";=0D
	char stringa[] =3D " ---> Received: \n";=0D
        time_t lt;=0D
        lt =3D time(NULL);=0D
        ptr =3D localtime(&lt);=0D
        fd =3D open("server.log", O_CREAT | O_RDWR | O_APPEND, 0644);=0D
	if(fd < 0) perror("Opening logs' file");=0D
	assert(fd >=3D 0);=0D
        entity =3D gethostbyaddr((char *) &client_addr.sin_addr, =0D
        	 sizeof(struct in_addr), AF_INET); =0D
        assert(entity >=3D 0);=0D
        ip =3D inet_ntoa((struct in_addr) client_addr.sin_addr);=0D
	i =3D 0;=0D
	=0D
	sprintf(orario, "%s", (asctime(ptr)));=0D
	while(1)=0D
	{=0D
		if(orario[i] =3D=3D '\n')=0D
		{=0D
			i =3D 0;=0D
			break;=0D
		}=0D
		carattere =3D orario[i];=0D
        	crypted =3D crypto(carattere);=0D
		write(fd, &crypted, 1);=0D
		i++;=0D
	}=0D
	crypted =3D crypto('\n');=0D
	write(fd, &crypted, 1);=0D
=0D
	while(1)=0D
	{=0D
		if(source[i] =3D=3D '\n')=0D
		{=0D
			i =3D 0;=0D
			break;=0D
		}=0D
	        carattere =3D source[i];=0D
        	crypted =3D crypto(carattere);=0D
		write(fd, &crypted, 1);=0D
		i++;=0D
	}=0D
	=0D
        sprintf(indirizzo, "%s\n", ip);=0D
	while(1)=0D
	{=0D
		if(indirizzo[i] =3D=3D '\n')=0D
		{=0D
			i =3D 0;=0D
			break;=0D
		}=0D
		carattere =3D indirizzo[i];=0D
		crypted =3D crypto(carattere);=0D
		write(fd, &crypted, 1);=0D
		i++;=0D
	}=0D
=0D
	while(1)=0D
	{=0D
		if(stringa[i] =3D=3D '\n')=0D
		{=0D
			i =3D 0;=0D
			break;=0D
		}=0D
		carattere =3D stringa[i];=0D
		crypted =3D crypto(carattere);=0D
		write(fd, &crypted, 1);=0D
		i++;=0D
	}	=0D
=0D
	while(1)=0D
	{=0D
		if(ch[i] =3D=3D '\0')=0D
		{=0D
			i =3D 0;=0D
			break;=0D
		}=0D
		carattere =3D ch[i];=0D
		crypted =3D crypto(carattere);=0D
		write(fd, &crypted, 1);=0D
		i++;=0D
	}=0D
	crypted =3D crypto('\n');=0D
	write(fd, &crypted, 1);			=0D
	write(fd, &crypted, 1);	=0D
}=0D
=0D
/* =0D
**=0D
** 				EOF=0D
**=0D
**=0D
*/=0D
	 =0D
--[ 5.2 - Client Sources.=0D
=0D
############################ CLIENT.C ##################################=0D
/*=0D
**=0D
**=0D
**				Unix Udp Client=0D
**=0D
**	This is the Unix client UDP , to send spoofed/unspoofed commands.=0D
**=0D
** ex:=0D
** $./udp source-ip destination-ip dest-port message=0D
**=0D
**=0D
** AUTHOR: Angelo Rosiello (Guilecool)=0D
**=0D
*/=0D
=0D
#include <stdio.h>=0D
#include <sys/types.h>=0D
#include <sys/socket.h>=0D
#include <netinet/in.h>=0D
#include <string.h>=0D
#include <assert.h>=0D
=0D
#define mia_porta 0=0D
 =0D
void udp_initialize();=0D
=0D
int main(int argc, char *argv[]) =0D
{=0D
	int sd, PORT, binding;=0D
	struct sockaddr_in server_addr, mio_addr;=0D
	if(argc !=3D 5)=0D
	{=0D
	fprintf(stdout, "Unix UDP client by Angelo Rosiello =0D
			(Guilecool)\n");=0D
	fprintf(stdout, "USAGE: %s SOURCE-IP DEST-IP PORT MESSAGE\n", =0D
		argv[0]);=0D
	exit(0);=0D
	}=0D
=0D
	PORT =3D atoi(argv[3]);=0D
=0D
	udp_initialize(&mio_addr, mia_porta, (long) inet_addr(argv[1]));=0D
	udp_initialize(&server_addr, PORT, (long) inet_addr(argv[2]));=0D
	sd =3D socket(AF_INET, SOCK_DGRAM, 0);=0D
	binding =3D bind(sd, (struct sockaddr *) =0D
			&mio_addr, sizeof(mio_addr));=0D
	if(binding !=3D 0) perror("Bind");=0D
	assert(binding =3D=3D 0);=0D
=0D
	sendto(sd, argv[4], strlen(argv[4]), 0, (struct sockaddr *) =0D
		&server_addr, sizeof(server_addr));=0D
}=0D
=0D
void udp_initialize(struct sockaddr_in *address, int port, long IPaddr)=0D
{=0D
	address->sin_family =3D AF_INET;=0D
	address->sin_port =3D htons((u_short)port);=0D
	address->sin_addr.s_addr =3D IPaddr;=0D
}=0D
=0D
/*=0D
***=0D
*** 	EOF=0D
***=0D
*/=0D
=0D
--[ 5.3 - Crypto sources.=0D
=0D
########################## CRYPTO.C #####################################=
=0D
/*=0D
***			     Crypto Program=0D
***=0D
***                Copyright (c) The Last of Calamities=0D
***                       All Rights Reserved=0D
***                AUTHOR: Angelo Rosiello (Guilecool)=0D
***=0D
*/=0D
=0D
=0D
#include <stdio.h>=0D
#include <string.h>=0D
#include <fcntl.h>=0D
#include <assert.h>=0D
#include <unistd.h>=0D
#include <sys/types.h>=0D
=0D
char crypto(char ch);=0D
=0D
main(int argc, char *argv[])=0D
{=0D
	char ch, crypted;=0D
	int fd, new_fd, lettura;=0D
	if(argc !=3D 3)=0D
	{=0D
		printf("Copyright (c) 2002/03 Angelo Rosiello =0D
			(Guilecool)\n");=0D
		printf("All Rights Reserved\n");=0D
		printf("USAGE: %s SOURCE-FILE DEST-FILE\n");=0D
		exit(0);=0D
	}=0D
	fd =3D open(argv[1], O_RDONLY);=0D
	assert(fd > 0);=0D
	if(fd <=3D 0) perror("file");=0D
        new_fd =3D open(argv[2], O_CREAT | O_RDWR | O_TRUNC, 0644);=0D
        assert(new_fd > 0);=0D
        if(new_fd <=3D 0) perror("file");=0D
	while(1)=0D
	{=0D
		lettura =3D read(fd, &ch, 1);=0D
		if(lettura =3D=3D 0) break;=0D
		crypted =3D crypto(ch);=0D
		write(new_fd, &crypted, 1);=0D
	}=0D
		=0D
}=0D
=0D
char crypto(char ch)=0D
{=0D
	char crypted;=0D
	int key =3D 0xff17261;=0D
	crypted =3D ch ^ key;=0D
	return(crypted);=0D
}=0D
=0D
/*=0D
***=0D
*** EOF=0D
***=0D
*/=0D
=0D
#################### END OF PROJECT ###########################=0D
=0D
=0D
=0D
Reguards...=0D
=0D
Angelo Rosiello=0D
=0D
contact: [email protected], [email protected], [email protected]=
=0D
=0D
=0D
|=3D[ EOF ]=3D-----------------------------------------------------------=
----=3D|=0D
=0D
=0D
=0D
=0D
=0D
=0D