• STATISTIQUES
  • Il y a eu un total de 2 membres et 14198 visiteurs sur le site dans les dernières 24h pour un total de 14 200 personnes!


    Membres: 2 433
    Discussions: 3 585
    Messages: 32 832
    Tutoriels: 78
    Téléchargements: 38
    Sites dans l'annuaire: 58


  • ANNUAIRE
  • [FR] Developpez.net
    Un forum communautaire qui se veut pour les développeurs en générale. Avec presque 500 000 membr...
    Programmation
    [EN] Net Force
    Javascript: 9, Java Applets: 6, Cryptography: 16, Exploits: 7, Cracking: 14, Programming: 13, Internet: 15, Steganograph...
    Challenges
    [EN] This is legal
    Basic: 10, Realistic: 5, Programming: 1, Bonus: 11, SQL: 2, Encryption: 6, Application: 4, User Contributed: 3
    Challenges
    [FR] Forum-Webmaster
    Une communauté webmaster pour apporter / recevoir de l'aide en création de site internet. Webmaster...
    Webmaster
    [EN] Gekko
    Site de challenge présenter sous la forme d'une quête. Vous êtes un agent secret qui répond sous le nom...
    Challenges
    [FR] Infomirmo
    Challenge présenté sous la forme de 6 niveaux de difficultés diverses et variées avec chacun plusieurs chall...
    Challenges
    [EN] PHPFreaks
    PHPFreaks est un site dédié à l'apprentissage et l'enseignement du PHP. Ici vous trouver...
    Programmation

  • DONATION
  • Si vous avez trouvé ce site internet utile, nous vous invitons à nous faire un don du montant de votre choix via Paypal. Ce don servira à financer notre hébergement.

    MERCI!




Note de ce sujet :
  • Moyenne : 0 (0 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5
[C++] Md5Sum Checker
04-03-2012, 19h01 (Modification du message : 19-11-2012, 19h32 par InstinctHack.)
Message : #1
Dobry Hors ligne
Tueur de lamouz
*



Messages : 206
Sujets : 25
Points: 73
Inscription : Aug 2011
[C++] Md5Sum Checker
Bonjour, voici mon dernier tool, fini qui permet de surveiller en permanence (enfin presque) un répertoire.
La première étape est de faire une sauvegarde du md5sum de tous les fichiers du répertoire (et des sous répertoires), puis vous pourrez ensuite lancer une comparaison des md5sum des fichiers avant ceux sauvegardés précédemment.
Si un fichier est supprimé, ou rajouté, alors le reste est décalé et donc la détection se fait également.
La prévention se fait par mail, mais ayant rencontré des difficulté à faire fonctionner le protocole SMTP avec celui de google, j'ai opté pour une solution autre.
L'alerte fait une simple requete HTTP vers une page PHP qui elle, envoi le mail à l'adresse désirée.
La partie sur les sockets n'était pas le but de mon exercice ici, elle est donc probablement loin d'être parfait et est fait de plusieurs bouts de codes trouvés à gauche à droite (je ne maitrise pas les socket en C/C++).
Il faut installer le paquet : libcrypto++ pour que la compilation fonctionne correctement.
Voici le code :
Code :
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#define USERAGENT "HTMLGET 1.0"
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <fstream>

#include <dirent.h>
#include <sys/socket.h>
#include <cryptopp/md5.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>

/*
*  Use ./tool d to create a md5sum of all the directory's files
*  Use ./tool s to scan all the directory's files and check with the previous
*  You can change the socket part to use a SMTP and send a mail, but I use a request
*  to a php file which send a mail (more easy).
* Compilation : sudo g++ crypt.cpp -o crypt -lcryptopp
*/
using namespace std;
using namespace CryptoPP;

string md5sum(string directory, string filename); // Return the md5sum of a file
int dumpFile(string directory, ofstream& output); // Make a new backup of all the files md5sum
int scanFile(string directory, ifstream& input); // Check the file and compare to the backup
void mail(); // Send a mail
char *get_ip(char *host); // Get ip from domaine
int create_tcp_socket(); // Create a socket
char *build_get_query(char *host, char *page); // Create the query
void usage(char *name); // Show the usage



int scan(0);

int main(int argc, char *argv[]){
    mail();
    string directory = "/home/user/Desktop";
    if(argc == 2){
      if(argv[1][0] == 'd'){ // Make a backup of the md5sum
    ofstream output("dumpMd5", ios::out | ios::trunc);
    dumpFile(directory, output);
      }else if(argv[1][0] == 's'){ // Scan the file and check them
    ifstream input("dumpMd5", ios::in);
    scanFile(directory, input);
    cout << scan << endl;
    if(scan)
      mail();
      }
    }else
    usage(argv[0]);
    return 0;
}

/* Send a mail if there are detected files */

void mail(){
struct sockaddr_in *remote;
char *host = "site.com", *page = "mail.php?id=password", *ip, *get, *htmlcontent;
char buf[BUFSIZ+1];
int sock, tmpres, sent(0), htmlstart(0);

sock = create_tcp_socket();
ip = get_ip(host);
remote = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in *));
remote->sin_family = AF_INET;
tmpres = inet_pton(AF_INET, ip, (void *)(&(remote->sin_addr.s_addr)));
remote->sin_port = htons(80);
if(connect(sock, (struct sockaddr *)remote, sizeof(struct sockaddr)) < 0){
    perror("Could not connect");
    exit(1);
  }
  get = build_get_query(host, page);
  while(sent < strlen(get))
  {
    tmpres = send(sock, get+sent, strlen(get)-sent, 0);
    if(tmpres == -1){
      perror("Can't send query");
      exit(1);
    }
    sent += tmpres;
  }
  memset(buf, 0, sizeof(buf));
  while((tmpres = recv(sock, buf, BUFSIZ, 0)) > 0){
    if(htmlstart == 0)
    {
      htmlcontent = strstr(buf, "\r\n\r\n");
      if(htmlcontent != NULL){
        htmlstart = 1;
        htmlcontent += 4;
      }
    }else{
      htmlcontent = buf;
    }
    memset(buf, 0, tmpres);
  }
  free(get);
  free(remote);
  free(ip);
  close(sock);
}


int create_tcp_socket(){
  int sock;
  if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
    perror("Can't create TCP socket");
    exit(1);
  }
  return sock;
}


char *get_ip(char *host){
  struct hostent *hent;
  int iplen = 15;
  char *ip = (char *)malloc(iplen+1);
  memset(ip, 0, iplen+1);
  if((hent = gethostbyname(host)) == NULL){ // Get the IP from de NDD
    herror("Can't get IP");
    exit(1);
  }
  if(inet_ntop(AF_INET, (void *)hent->h_addr_list[0], ip, iplen) == NULL){
    perror("Can't resolve host");
    exit(1);
  }
  return ip;
}

char *build_get_query(char *host, char *page){
  char *query;
  char *getpage = page;
  char *tpl = "GET /%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n"; // We send a GET request on the server
  if(getpage[0] == '/')
    getpage = getpage + 1;

  query = (char *)malloc(strlen(host)+strlen(getpage)+strlen(USERAGENT)+strlen(tpl)-5);
  sprintf(query, tpl, getpage, host, USERAGENT);
  return query;
}

string md5sum(string directory, string filename){
std::ostringstream oss;
std::ifstream file;
Weak1::MD5 hash;
byte md5[Weak1::MD5::DIGESTSIZE];
int length = 0;
char *buffer;

if(directory[directory.length()-1] != '/')
  directory.append("/");
  
directory.append(filename);
file.open(directory.c_str(), std::ios::binary);
file.seekg(0, std::ios::end);
length = file.tellg();
file.seekg(0, std::ios::beg);
buffer = new char[length];

file.read(buffer, length); // Read the file
file.close();


hash.CalculateDigest(md5, (unsigned char *)buffer, length);
for(int i=0; i<Weak1::MD5::DIGESTSIZE; i++){
     oss<< std::hex << std::setfill('0') << std::setw(2) << (unsigned short)(md5[i]); // Add the hex value to OSS
}
    

delete []  buffer;
return oss.str();
}

int dumpFile(string directory, ofstream& output){
   string path="";
   DIR *dir = NULL;
   struct dirent *file = NULL;
   if((dir = opendir(directory.c_str())) == NULL){
     return 1;
   }
   while((file = readdir(dir)) != NULL){
      if(strcmp(file->d_name, ".") && strcmp(file->d_name, "..")){
         if(file->d_type == DT_DIR || file->d_type == DT_LNK){
       path= "";
       dumpFile(path.append(directory).append("/").append(file->d_name), output);
     }else{
            output << file->d_name << endl << md5sum(directory, file->d_name) << endl; // Write the result on 2 lines (first the name, then de md5
     }
      }
   }
    
   closedir(dir);
  return 0;
}

int scanFile(string directory, ifstream& input){
   string fichier, md5, path("");

   DIR *dir = NULL;
   struct dirent *file = NULL;
  
   if((dir = opendir(directory.c_str())) == NULL){
     return 1;
   }
   while((file = readdir(dir)) != NULL){
      if(strcmp(file->d_name, ".") && strcmp(file->d_name, "..")){
         if(file->d_type == DT_DIR || file->d_type == DT_LNK){
       path = "";
       scanFile(path.append(directory).append("/").append(file->d_name), input);
     }else{
        getline(input,fichier); // Store the filename
        getline(input,md5); // Store de file's md5sum
        if(strcmp(file->d_name, fichier.c_str()) || strcmp(md5sum(directory, file->d_name).c_str(),md5.c_str())){
          scan++;
          return 0;
        }
          
     }
      }
   }
    
   closedir(dir);
    return 0;
}

void usage(char *name){
cout << "#######################" << endl;
cout << "    Md5Sum checker  " << endl << endl;
cout << "   To make a dump:  " << endl;
cout << "       "<< name << " d"<< endl;
cout << "   To lauch the scan: " << endl;
cout << "         "<< name << " s" << endl << endl;
cout << "#######################" << endl;
}
Et un code php correspondant
Code :
<?php
  if($_GET['id'] == "password")
    mail("email@email.com","Subjet","Ceci  est un message de prévention car une intrusion a été détectée sur votre site","");
?>

Quelques améliorations possibles :
Le programme de fait qu'un seul scan, ce qui n'est pas pratique, le mieux serait de l'intégré à un système de daemon, ou alors un système de boucle infini (avec un sleep par exemple) pour que la detection se fasse en continu.

Necromoine
Aestuārium Erudītiōnis

There are only two hard things in Computer Science: cache invalidation, naming things, and off-by-one errors.
+1 (0) -1 (0) Répondre


Atteindre :


Utilisateur(s) parcourant ce sujet : 1 visiteur(s)
N-PN
Accueil | Challenges | Tutoriels | Téléchargements | Forum | Retourner en haut