//------------------------------------------------------------------------------ void reg_read_enum_MRUWvalues(HKEY hk,char *chkey,char *key,char *exclu,char* description_id,unsigned int session_id, sqlite3 *db) { HKEY CleTmp; if (RegOpenKey(hk,key,&CleTmp)!=ERROR_SUCCESS)return; DWORD nbValue,i; FILETIME last_update; if (RegQueryInfoKey (CleTmp,0,0,0,0,0,0,&nbValue,0,0,0,&last_update)!=ERROR_SUCCESS) { RegCloseKey(CleTmp); return; } //get date char parent_key_update[DATE_SIZE_MAX] = ""; filetimeToString_GMT(last_update, parent_key_update, DATE_SIZE_MAX); //read USER + RID + SID char user[MAX_PATH], RID[MAX_PATH], sid[MAX_PATH]; GetRegistryKeyOwner(CleTmp, user, RID, sid, MAX_PATH); //enum values char value[MAX_PATH], data[MAX_PATH], data_s[MAX_PATH]; DWORD valueSize,dataSize,type; for (i=0;i<nbValue && start_scan;i++) { valueSize = MAX_PATH; dataSize = MAX_PATH; value[0] = 0; data[0] = 0; type = 0; if (RegEnumValue (CleTmp,i,(LPTSTR)value,(LPDWORD)&valueSize,0,(LPDWORD)&type,(LPBYTE)data,(LPDWORD)&dataSize)==ERROR_SUCCESS) { convertStringToSQL(value, MAX_PATH); snprintf(data_s,MAX_LINE_SIZE,"%S",data); convertStringToSQL(data_s, MAX_PATH); addRegistryMRUtoDB("",chkey,key,value,data_s,description_id,user,RID,sid,parent_key_update,session_id,db); } } RegCloseKey(CleTmp); }
//------------------------------------------------------------------------------ unsigned int ReadRecord(char *buffer, DWORD size, STRING_TABLE *my_s_table, char *eventfile, sqlite3 *db, unsigned int session_id) { #define EVENTLOG_H_EVTX_SIZE 4+4+8+8+6 typedef struct _EVENTLOG_H_EVTX { unsigned char MagicString[4]; //4 ** + 0x00 + 0x00 unsigned int RecordSize; //4 unsigned long long int RecordNumber; //8 //RecordNumber unsigned long long int TimeCreated; //8 unsigned char padding_star_xml[6]; //6 : 0f01 0100 0c01 }EVENTLOG_H_EVTX; EVENTLOG_H_EVTX *h_dheader = (EVENTLOG_H_EVTX *)buffer; char indx[DEFAULT_TMP_SIZE]="", log_id[DEFAULT_TMP_SIZE]="", send_date[DATE_SIZE_MAX]="", write_date[DATE_SIZE_MAX]="", source[MAX_PATH]="", description[MAX_LINE_SIZE]="", user[DEFAULT_TMP_SIZE]="", rid[DEFAULT_TMP_SIZE]="", sid[DEFAULT_TMP_SIZE]="", state[DEFAULT_TMP_SIZE]="", critical[DEFAULT_TMP_SIZE]=""; DWORD id=0; //test de validité if (h_dheader->RecordSize <= size && h_dheader->MagicString[0] == '*' && h_dheader->MagicString[1] == '*' && h_dheader->MagicString[2] == 0 && h_dheader->MagicString[3] == 0) { //lecture des informations du header //id snprintf(indx,DEFAULT_TMP_SIZE,"%08lu",(long unsigned int)(h_dheader->RecordNumber)); //date : send_date FILETIME FileTime; FileTime.dwLowDateTime = (DWORD) h_dheader->TimeCreated; FileTime.dwHighDateTime = (DWORD)(h_dheader->TimeCreated >> 32); filetimeToString_GMT(FileTime, send_date, DATE_SIZE_MAX); //date : write_date = same strcpy(write_date,send_date); //afin de passer les enregistrelent avec header on passe tant qu'on à pas accès au header attendu ^^ //permet de traiter les cas de données corrompues //0x00 0000 0100 0400 0100 0400 char *c = buffer+EVENTLOG_H_EVTX_SIZE; DWORD pos=EVENTLOG_H_EVTX_SIZE; BOOL ok =FALSE; do { if (*c == 0x00 && *(c+1) == 0x00 && *(c+2) == 0x00 && *(c+3) == 0x01 && *(c+4) == 0x00 && *(c+5) == 0x04 && *(c+6) == 0x00 && *(c+7) == 0x01 && *(c+8) == 0x00 && *(c+9) == 0x04 &&*(c+10) == 0x00) { ok = TRUE; break; } c++; pos++; }while(pos<h_dheader->RecordSize-12); //traitement de la suite ^^ if (ok) { //recherche de l'id ^^ dans une zone de moins de 100octets ^^ //0x2100 0400 0000 XXXX = ID typedef struct _ID { unsigned short param; // 0x0021 unsigned char end; unsigned char type; // level unsigned short padding; // 0x0000 unsigned short id; }M_ID; M_ID * mid; while(pos<h_dheader->RecordSize-10) { if (*c == 0x21 && *(c+1) == 0x00) { //id identifié ^^ mid = (M_ID *)c; snprintf(log_id,DEFAULT_TMP_SIZE,"%08lu",(DWORD) mid->id); id = mid->id; //Type switch(mid->type) { case 0x00 : strcpy(state,"INFORMATION"); break; case 0x01 : strcpy(state,"WARNING"); break; case 0x02 : strcpy(state,"ERROR"); break; case 0x04 : strcpy(state,"CRITICAL"); break; case 0x08 : strcpy(state,"AUDIT_SUCCESS"); break; case 0x10 : strcpy(state,"AUDIT_FAILURE"); break; default :snprintf(state,MAX_LINE_SIZE,"UNKNOW (%d)",mid->type);break; } } c++;pos++; } c+=8; //on passe l'id + 6 octets de padding //Source char *desc = c; source[0] = 0; while(pos+4<h_dheader->RecordSize-10) {//0x05- 0x12 = S-1-5-18, revoir la phase de détection pour prendre en compte le SID !!!! if (*c != 0x00 && *(c+1) == 0x00) //unicode if (*(c+2) != 0x00 && *(c+3)==0x00) //if (*c == 0x05) { snprintf(source,MAX_LINE_SIZE,"%S",c); break; } c++; pos++; } //si aucune source n'est définie on ajoute le nom du fichier sans evtx ^^ if (source[0] == 0) { char *n = eventfile; while (*n)n++; while (*n != '\\')n--; n++; snprintf(source,MAX_PATH,"%s",n); source[strlen(source)-5]=0; //on vérifie que pas de % dans le nom sinon on met 0 à sa place ^^ n = source; while (*n) { if (*n == '%'){*n=0; break;} n++; } } //traitement de la description !! TraiterDescription (desc,h_dheader->RecordSize/*-pos*/,description,MAX_LINE_SIZE); } //add convertStringToSQL(source, MAX_PATH); convertStringToSQL(description, MAX_LINE_SIZE); addLogtoDB(eventfile, indx, log_id, send_date, write_date, source, description, user, rid, sid, state, critical, session_id, db); }
//------------------------------------------------------------------------------ int callback_sqlite_registry_local(void *datas, int argc, char **argv, char **azColName) { if (argv[0] == 0)return 0; FORMAT_CALBAK_TYPE *type = datas; unsigned int session_id = current_session_id; switch(type->type) { case SQLITE_REGISTRY_TYPE_SETTINGS: { HKEY hk = hkStringtohkey(argv[0]); switch(atoi(argv[3]))//value_type { case TYPE_VALUE_STRING: { char tmp[MAX_PATH]=""; if (ReadValue(hk,argv[1],argv[2],tmp, MAX_PATH)) { char parent_key_update[DATE_SIZE_MAX]; ReadKeyUpdate(hk,argv[1], parent_key_update, DATE_SIZE_MAX); convertStringToSQL(tmp, MAX_PATH); addRegistrySettingstoDB("", argv[0], argv[1], argv[2], tmp, argv[4], argv[5], parent_key_update, session_id, db_scan); } } break; case TYPE_VALUE_DWORD: { char tmp[MAX_PATH]=""; long int value= ReadDwordValue(hk,argv[1],argv[2]); if (value != -1) { snprintf(tmp,MAX_PATH,"0x%08X",(unsigned int)value); char parent_key_update[DATE_SIZE_MAX]; ReadKeyUpdate(hk,argv[1], parent_key_update, DATE_SIZE_MAX); addRegistrySettingstoDB("", argv[0], argv[1], argv[2], tmp, argv[4], argv[5], parent_key_update, session_id, db_scan); } } break; case TYPE_VALUE_MULTI_STRING: { char tmp[MAX_PATH]=""; long int i, tmp_size = ReadValue(hk,argv[1],argv[2],tmp, MAX_PATH); if (tmp_size>0) { char parent_key_update[DATE_SIZE_MAX]; ReadKeyUpdate(hk,argv[1], parent_key_update, DATE_SIZE_MAX); for (i=0;i<tmp_size;i++) { if (tmp[i] == 0)tmp[i]=';'; } convertStringToSQL(tmp, MAX_PATH); addRegistrySettingstoDB("", argv[0], argv[1], argv[2], tmp, argv[4], argv[5], parent_key_update, session_id, db_scan); } } break; case TYPE_VALUE_MULTI_WSTRING: { char tmp[REQUEST_MAX_SIZE]="",data_read[REQUEST_MAX_SIZE]; DWORD pos=0, data_size_read = ReadValue(hk,argv[1],argv[2],tmp, REQUEST_MAX_SIZE); if (data_size_read) { char parent_key_update[DATE_SIZE_MAX]; ReadKeyUpdate(hk,argv[1], parent_key_update, DATE_SIZE_MAX); while ((pos-1)*2<data_size_read) { snprintf(data_read+pos,REQUEST_MAX_SIZE,"%S;",tmp+(pos*2-1)); pos = strlen(data_read); } convertStringToSQL(data_read, MAX_PATH); addRegistrySettingstoDB("", argv[0], argv[1], argv[2], data_read, argv[4], argv[5], parent_key_update, session_id, db_scan); } } break; case TYPE_VALUE_FILETIME: { char tmp[MAX_PATH]=""; FILETIME ft; if (hk == 0 || argv[1][0]==0)break; ReadFILETIMEValue(hk,argv[1],argv[2],&ft); filetimeToString_GMT(ft, tmp, MAX_PATH); char parent_key_update[DATE_SIZE_MAX]; ReadKeyUpdate(hk,argv[1], parent_key_update, DATE_SIZE_MAX); addRegistrySettingstoDB("", argv[0], argv[1], argv[2], tmp, argv[4], argv[5], parent_key_update, session_id, db_scan); } break; case TYPE_VALUE_WIN_SERIAL: { char tmp[MAX_PATH]=""; if (GetWindowsCDKey_local(hk, argv[1], argv[2], tmp, MAX_PATH)) { char parent_key_update[DATE_SIZE_MAX]; ReadKeyUpdate(hk,argv[1], parent_key_update, DATE_SIZE_MAX); addRegistrySettingstoDB("", argv[0], argv[1], argv[2], tmp, argv[4], argv[5], parent_key_update, session_id, db_scan); } } break; case TYPE_ENUM_STRING_VALUE: { HKEY CleTmp=0; if (RegOpenKey(hk,argv[1],&CleTmp)!=ERROR_SUCCESS)return 0; FILETIME lastupdate; char parent_key_update[DATE_SIZE_MAX]; DWORD NameSize, DataSize; char Name[MAX_PATH], Data[MAX_PATH], tmp[MAX_PATH]; DWORD nbValue = 0, i,j, type2; if (RegQueryInfoKey (CleTmp,0,0,0,0,0,0,&nbValue,0,0,0,&lastupdate)==ERROR_SUCCESS) { filetimeToString_GMT(lastupdate, parent_key_update, DATE_SIZE_MAX); for (i=0;i<nbValue;i++) { NameSize = MAX_PATH; DataSize = MAX_PATH; Name[0] = 0; Data[0] = 0; type2 = 0; if (RegEnumValue (CleTmp,i,(LPTSTR)Name,(LPDWORD)&NameSize,0,(LPDWORD)&type2,(LPBYTE)Data,(LPDWORD)&DataSize)==ERROR_SUCCESS) { switch(type2) { case REG_EXPAND_SZ: case REG_SZ:addRegistrySettingstoDB("", argv[0], argv[1], Name, Data, argv[4], argv[5], parent_key_update, session_id, db_scan);break; case REG_LINK: snprintf(tmp,MAX_PATH,"%S",Data); convertStringToSQL(tmp, MAX_PATH); addRegistrySettingstoDB("", argv[0], argv[1], Name, tmp, argv[4], argv[5], parent_key_update, session_id, db_scan); break; case REG_MULTI_SZ: for (j=0;j<DataSize;j++) { if (Data[j] == 0)Data[j]=';'; } convertStringToSQL(Data, MAX_PATH); addRegistrySettingstoDB("", argv[0], argv[1], Name, Data, argv[4], argv[5], parent_key_update, session_id, db_scan); break; case REG_DWORD: snprintf(tmp,MAX_PATH,"0x%08X",&Data[0]); addRegistrySettingstoDB("", argv[0], argv[1], Name, tmp, argv[4], argv[5], parent_key_update, session_id, db_scan); break; default : //binary/dword strncpy(tmp,"0x",MAX_PATH); NameSize = 0; for (j=0;j<DataSize && NameSize<MAX_PATH;j++) { NameSize = strlen(tmp); snprintf(tmp+NameSize,MAX_PATH-NameSize,"%02X",Data[j]&0xFF); } addRegistrySettingstoDB("", argv[0], argv[1], Name, tmp, argv[4], argv[5], parent_key_update, session_id, db_scan); break; } } } } } break; } } break; } return 0; }
//------------------------------------------------------------------------------ int callback_sqlite_registry_file(void *datas, int argc, char **argv, char **azColName) { FORMAT_CALBAK_TYPE *type = datas; unsigned int session_id = current_session_id; char tmp[MAX_LINE_SIZE]; switch(type->type) { case SQLITE_REGISTRY_TYPE_SETTINGS: { switch(atoi(argv[3]))//value_type { case TYPE_VALUE_STRING: case TYPE_VALUE_DWORD: case TYPE_VALUE_MULTI_STRING: if (Readnk_Value(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin)+HBIN_HEADER_SIZE, local_hks.position, argv[1], NULL, argv[2], tmp, MAX_LINE_SIZE)) { //key update char parent_key_update[DATE_SIZE_MAX]; Readnk_Infos(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin), local_hks.position, argv[1], NULL, parent_key_update, DATE_SIZE_MAX, NULL, 0,NULL, 0); //save convertStringToSQL(tmp, MAX_LINE_SIZE); addRegistrySettingstoDB(local_hks.file, "", argv[1], argv[2], tmp, argv[4], argv[5], parent_key_update, session_id, db_scan); } break; case TYPE_VALUE_MULTI_WSTRING: { char data_read[MAX_LINE_SIZE]; DWORD pos=0, data_size_read = MAX_LINE_SIZE; if (ReadBinarynk_Value(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin)+HBIN_HEADER_SIZE, local_hks.position, argv[1], NULL, argv[2], tmp, &data_size_read)) { if (data_size_read) { //data_read while ((pos-1)*2<data_size_read) { snprintf(data_read+pos,MAX_LINE_SIZE,"%S;",tmp+(pos*2-1)); pos = strlen(data_read); } //key update char parent_key_update[DATE_SIZE_MAX]; Readnk_Infos(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin), local_hks.position, argv[1], NULL, parent_key_update, DATE_SIZE_MAX, NULL, 0,NULL, 0); //save convertStringToSQL(data_read, MAX_LINE_SIZE); addRegistrySettingstoDB(local_hks.file, "", argv[1], argv[2], data_read, argv[4], argv[5], parent_key_update, session_id, db_scan); } } } break; case TYPE_VALUE_FILETIME: { DWORD data_size = sizeof(FILETIME)+1; FILETIME f_date; if (ReadBinarynk_Value(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin)+HBIN_HEADER_SIZE, local_hks.position, argv[1], NULL, argv[2], (void*)&f_date, &data_size)) { //key update char parent_key_update[DATE_SIZE_MAX]; Readnk_Infos(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin), local_hks.position, argv[1], NULL, parent_key_update, DATE_SIZE_MAX, NULL, 0,NULL, 0); //convert date tmp[0] = 0; filetimeToString_GMT(f_date, tmp, DATE_SIZE_MAX); //save convertStringToSQL(tmp, MAX_LINE_SIZE); addRegistrySettingstoDB(local_hks.file, "", argv[1], argv[2], tmp, argv[4], argv[5], parent_key_update, session_id, db_scan); } } break; case TYPE_VALUE_WIN_SERIAL: { HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin)+HBIN_HEADER_SIZE, local_hks.position,argv[1]); if (nk_h!=NULL) { //key update char parent_key_update[DATE_SIZE_MAX]; Readnk_Infos(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin), local_hks.position, NULL, nk_h, parent_key_update, DATE_SIZE_MAX, NULL, 0,NULL, 0); //get value DWORD test_size = MAX_LINE_SIZE; DWORD serial_size; ReadBinarynk_Value(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin)+HBIN_HEADER_SIZE, local_hks.position, NULL, nk_h, argv[2], (void*)tmp, &test_size); if (test_size>65) { char result[MAX_PATH]=""; char key[25] = "BCDFGHJKMPQRTVWXY2346789"; BYTE enc[MAX_PATH]; char lpszSerial[MAX_PATH]; int i,c=0,nCur=0; for(i=52;i<=66;i++)enc[i-52] = tmp[i]; for(i=24;i>=0;i--) { nCur = 0; for(c=14;c>-1;c--) { nCur = nCur * 256; nCur ^= enc[c]; enc[c] = nCur / 24; nCur %= 24; } lpszSerial[i] = key[nCur]; } serial_size = 0; for(i=0;lpszSerial[i] && (i+i/5) < 30 && MAX_PATH>serial_size;i++) { if(i % 5 == 0 && i>0)snprintf(result+serial_size,MAX_PATH-serial_size,"-%c",lpszSerial[i]); else snprintf(result+serial_size,MAX_PATH-serial_size,"%c",lpszSerial[i]); serial_size = strlen(result); } //save convertStringToSQL(result, MAX_LINE_SIZE); addRegistrySettingstoDB(local_hks.file, "", argv[1], argv[2], result, argv[4], argv[5], parent_key_update, session_id, db_scan); } } } break; case TYPE_ENUM_STRING_VALUE: { HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin)+HBIN_HEADER_SIZE, local_hks.position,argv[1]); if (nk_h!=NULL) { //key update char parent_key_update[DATE_SIZE_MAX]; Readnk_Infos(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin), local_hks.position, NULL, nk_h, parent_key_update, DATE_SIZE_MAX, NULL, 0,NULL, 0); //get values char value[MAX_PATH]; DWORD i, nbSubValue = GetValueData(local_hks.buffer,local_hks.taille_fic, nk_h, (local_hks.pos_fhbin)+HBIN_HEADER_SIZE, 0, NULL, 0, NULL, 0); for (i=0;i<nbSubValue;i++) { if (GetValueData(local_hks.buffer,local_hks.taille_fic, nk_h, (local_hks.pos_fhbin)+HBIN_HEADER_SIZE, i,value,MAX_PATH,tmp,MAX_LINE_SIZE)) { //save convertStringToSQL(value, MAX_PATH); convertStringToSQL(tmp, MAX_LINE_SIZE); addRegistrySettingstoDB(local_hks.file, "", argv[1], value, tmp, argv[4], argv[5], parent_key_update, session_id, db_scan); } } } } break; } } } return 0; }
//------------------------------------------------------------------------------ void PfCheck(unsigned int session_id, sqlite3 *db, char *file) { //open file and read first datas HANDLE hfile = CreateFile(file,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,0); if (hfile != INVALID_HANDLE_VALUE) { DWORD sz_prefetch_file = GetFileSize(hfile,NULL); if ( sz_prefetch_file!= INVALID_FILE_SIZE && sz_prefetch_file > sizeof(HDR_PREFETCH)) { char CreationTime[DATE_SIZE_MAX]="",LastWriteTime[DATE_SIZE_MAX]="",LastAccessTime[DATE_SIZE_MAX]=""; DWORD count = 0, copiee; char exec_time[DATE_SIZE_MAX]=""; char *depend; char *buffer; HDR_PREFETCH *pf; char *b, *e; char application_name[PREFETCH_APPLI_NAME_MAX_SIZE+1], path_application[MAX_PATH], path_depend[MAX_PATH]; BOOL ok_path_application = FALSE; buffer = malloc(sizeof(char)*sz_prefetch_file+1); if (buffer!=NULL) { ReadFile(hfile, buffer, sz_prefetch_file,&copiee,0); pf = (HDR_PREFETCH*)buffer; if (pf->v_number > 0x11) //0x17 after winxp/2003 (+8octets) { count = pf->file_exec_counter2; filetimeToString_GMT(pf->last_file_exec2, exec_time, DATE_SIZE_MAX); }else { count = pf->file_exec_counter; filetimeToString_GMT(pf->last_file_exec, exec_time, DATE_SIZE_MAX); } //file times BY_HANDLE_FILE_INFORMATION hfi; if (GetFileInformationByHandle(hfile,&hfi)) { filetimeToString_GMT(hfi.ftCreationTime, CreationTime, DATE_SIZE_MAX); filetimeToString_GMT(hfi.ftLastWriteTime, LastWriteTime, DATE_SIZE_MAX); filetimeToString_GMT(hfi.ftLastAccessTime, LastAccessTime, DATE_SIZE_MAX); } snprintf(application_name,PREFETCH_APPLI_NAME_MAX_SIZE,"%S",pf->filename); application_name[PREFETCH_APPLI_NAME_MAX_SIZE]=0; //search in path datas if name exist ok_path_application = FALSE; b = buffer+pf->secC_off; //start of datas e = buffer+pf->secC_off+pf->secC_size; //end of datas DWORD size_depend = (e-b); if (size_depend <= sz_prefetch_file) { while (b<e) { snprintf(path_application,MAX_PATH,"%S",b); if (ContientNoCass(path_application,application_name)) { ok_path_application = TRUE; break; }else { b = b + (strlen(path_application)+1)*2; } }; if (!ok_path_application)path_application[0] = 0; //depend b = buffer+pf->secC_off; //start of datas e = buffer+pf->secC_off+pf->secC_size; //end of datas depend = (char*)malloc(size_depend+2); if (depend != NULL) { depend[0] = 0; while (b<e) { snprintf(path_depend,MAX_PATH,"%S\r\n",b); snprintf(depend+strlen(depend),size_depend-strlen(depend),"%s",path_depend); //strncat(depend,path_depend,size_depend); b = b + (strlen(path_depend)-1)*2; }; strncat(depend,"\0",size_depend); addPrefetchtoDB(file, CreationTime, LastWriteTime, LastAccessTime, count, exec_time, depend, path_application,session_id, db); free(depend); }else addPrefetchtoDB(file, CreationTime, LastWriteTime, LastAccessTime, count, exec_time, "", path_application,session_id, db); free(buffer); } } } CloseHandle(hfile); } }
//------------------------------------------------------------------------------ void read_datas_lnk(unsigned char *buffer, DWORD taille_fic, char *create_time, char *last_access_time, char *last_modification_time, unsigned char *local_path, unsigned char *to) { typedef struct { unsigned int header_size; // default : 0x0000004C (76) unsigned char lnk_class_id[16]; // default : 00021401-0000-0000-00c0-000000000046 unsigned int data_flag; unsigned int file_attribute_flag; FILETIME create_time; FILETIME last_access_time; FILETIME last_modification_time; unsigned int file_size; unsigned int icon_index; unsigned int show_window_value; unsigned short hot_key; unsigned char reserved[10]; unsigned short item_list_size; }LNK_STRUCT, *PLNK_STRUCT; unsigned char tmp[MAX_PATH]="", *b; //header PLNK_STRUCT p = (PLNK_STRUCT)buffer; //get times filetimeToString_GMT(p->create_time, create_time, DATE_SIZE_MAX); filetimeToString_GMT(p->last_access_time, last_access_time, DATE_SIZE_MAX); filetimeToString_GMT(p->last_modification_time, last_modification_time, DATE_SIZE_MAX); //unicode or not BOOL unicode = FALSE; if ((p->data_flag & 0x80) == 0x80) unicode = TRUE; //if items list we pass if ((p->data_flag & 0x01) == 0x01)//hashlinktargetid { b = buffer + 2 + p->header_size + p->item_list_size; }else b = buffer + p->header_size; if (b-buffer < taille_fic) { typedef struct { unsigned short struct_size; }LNK_WORD_STRUCT, *PLNK_WORD_STRUCT; //link info if ((p->data_flag & 0x02) == 0x02) { typedef struct { DWORD struct_size; DWORD header_size; DWORD flags; DWORD vol_ID_offset; DWORD local_base_path_offset; DWORD Network_relative_path_offset; DWORD commun_path_offset; //infos DWORD CommonNetworkRelativeLinkSize; DWORD CommonNetworkRelativeLinkFlags; DWORD NetNameOffset; DWORD DeviceNameOffset; DWORD NetWorkProviderType; }LNK_INFO_STRUCT, *PLNK_INFO_STRUCT; PLNK_INFO_STRUCT pi = (PLNK_INFO_STRUCT)b; if ((pi->flags & 0x01) == 0x01 && (pi->flags & 0x02) == 0x02) { if (pi->local_base_path_offset && pi->local_base_path_offset < pi->struct_size)snprintf(to,MAX_PATH,"%s",(char*)(b+pi->local_base_path_offset)); if (pi->NetNameOffset && pi->NetNameOffset+pi->header_size < pi->struct_size)snprintf(local_path,MAX_PATH,"%s",(char*)(b+pi->NetNameOffset+pi->header_size)); if (pi->DeviceNameOffset && pi->DeviceNameOffset+pi->header_size < pi->struct_size)snprintf(tmp,MAX_PATH,"%s\\",(char*)(b+pi->DeviceNameOffset+pi->header_size)); if (pi->commun_path_offset && pi->commun_path_offset < pi->struct_size)snprintf(to,MAX_PATH,"%s%s",tmp,(char*)(b+pi->commun_path_offset)); }else if ((pi->flags & 0x01) == 0x01) //local { if (pi->local_base_path_offset && pi->local_base_path_offset < pi->struct_size)snprintf(to,MAX_PATH,"%s",(char*)(b+pi->local_base_path_offset)); }else if ((pi->flags & 0x02) == 0x02) //network { //local path if (pi->NetNameOffset && pi->NetNameOffset+pi->header_size < pi->struct_size)snprintf(local_path,MAX_PATH,"%s",(char*)(b+pi->NetNameOffset+pi->header_size)); if (pi->DeviceNameOffset && pi->DeviceNameOffset+pi->header_size < pi->struct_size)snprintf(tmp,MAX_PATH,"%s\\",(char*)(b+pi->DeviceNameOffset+pi->header_size)); if (pi->commun_path_offset && pi->commun_path_offset < pi->struct_size)snprintf(to,MAX_PATH,"%s%s",tmp,(char*)(b+pi->commun_path_offset)); } b = b + pi->struct_size; }else if ((p->data_flag & 0x04) == 0x04 || (p->data_flag & 0x08) == 0x08/* || (p->data_flag & 0x10) == 0x10*/) { //other if (!strlen(local_path) && !strlen(to) && b-buffer < taille_fic) { DWORD tmp_size; //pass datas no used //0x04 = have name/description first ? PLNK_WORD_STRUCT t = (PLNK_WORD_STRUCT)b; if ((p->data_flag & 0x04) == 0x04) { //0x08 = relative path if ((p->data_flag & 0x08) == 0x08) { if (unicode) b = b + t->struct_size*2 + 2; else b = b + t->struct_size + 2; t = b; if(b-buffer < taille_fic) { if (unicode) snprintf(to,MAX_PATH,"%S",b+2); else snprintf(to,MAX_PATH,"%s",(char*)(b+2)); tmp_size = t->struct_size +b-buffer ; if (tmp_size < taille_fic && tmp_size < MAX_PATH) to[t->struct_size] = 0; if (unicode) b = b + t->struct_size*2 + 2; else b = b + t->struct_size + 2; t = b; //0x10 = workingdir if ((p->data_flag & 0x10) == 0x10 && b-buffer < taille_fic) { if (unicode) b = b + t->struct_size*2 + 2; else b = b + t->struct_size + 2; t = b; } //0x20 = arguments if ((p->data_flag & 0x20) == 0x20 && b-buffer < taille_fic) { if (unicode) snprintf(tmp,MAX_PATH," %S",b+2); else snprintf(tmp,MAX_PATH," %s",(char*)(b+2)); tmp_size = t->struct_size +b-buffer; if (tmp_size < taille_fic && tmp_size+1 < MAX_PATH) tmp[t->struct_size+1] = 0; strncat(to,tmp,MAX_PATH); strncat(to,"\0",MAX_PATH); } } }else { if (unicode) snprintf(to,MAX_PATH,"%S",b+2); else snprintf(to,MAX_PATH,"%s",(char*)(b+2)); tmp_size = t->struct_size +b-buffer ; if (tmp_size < taille_fic && tmp_size < MAX_PATH) to[t->struct_size] = 0; } }else { //0x08 = relative path if ((p->data_flag & 0x08) == 0x08 && b-buffer < taille_fic) { //if only we use it !!! if (unicode) snprintf(to,MAX_PATH,"%S",b+2); else snprintf(to,MAX_PATH,"%s",(char*)(b+2)); tmp_size = t->struct_size +b-buffer ; if (tmp_size < taille_fic && tmp_size < MAX_PATH) to[t->struct_size] = 0; if (unicode) b = b + t->struct_size*2 + 2; else b = b + t->struct_size + 2; t = b; //0x10 = workingdir if ((p->data_flag & 0x10) == 0x10 && b-buffer < taille_fic) { if (unicode) b = b + t->struct_size*2 + 2; else b = b + t->struct_size + 2; t = b; } //0x20 = arguments if ((p->data_flag & 0x20) == 0x20 && b-buffer < taille_fic) { if (unicode) snprintf(tmp,MAX_PATH," %S",b+2); else snprintf(tmp,MAX_PATH," %s",(char*)(b+2)); tmp_size = t->struct_size +b-buffer; if (tmp_size < taille_fic && tmp_size+1 < MAX_PATH) tmp[t->struct_size+1] = 0; strncat(to,tmp,MAX_PATH); strncat(to,"\0",MAX_PATH); } }else { //0x10 = workingdir if ((p->data_flag & 0x10) == 0x10 && b-buffer < taille_fic) { if (unicode) snprintf(to,MAX_PATH,"%S",b+2); else snprintf(to,MAX_PATH,"%s",(char*)(b+2)); tmp_size = t->struct_size +b-buffer; if (tmp_size < taille_fic && tmp_size < MAX_PATH) to[t->struct_size] = 0; if (unicode) b = b + t->struct_size*2 + 2; else b = b + t->struct_size + 2; t = b; } //0x20 = arguments if ((p->data_flag & 0x20) == 0x20 && b-buffer < taille_fic) { if (unicode) snprintf(tmp,MAX_PATH," %S",b+2); else snprintf(tmp,MAX_PATH," %s",b+2); tmp_size = t->struct_size +b-buffer; if (tmp_size < taille_fic && tmp_size+1 < MAX_PATH) tmp[t->struct_size+1] = 0; strncat(to,tmp,MAX_PATH); strncat(to,"\0",MAX_PATH); } } } } }else if ((p->data_flag & 0x200) == 0x200 || p->data_flag == 0x80) // windows 8 format : ext_string { unsigned char *pos = b; PLNK_WORD_STRUCT t = (PLNK_WORD_STRUCT)b; if ((p->data_flag & 0x10) == 0x10) //workingdir { if (unicode) pos = pos + t->struct_size*2 + 2; else pos = pos + t->struct_size + 2; } if (pos-buffer < taille_fic) { t = pos; if ((p->data_flag & 0x20) == 0x20) //arguments { if (unicode) pos = pos + t->struct_size*2 + 2; else pos = pos + t->struct_size + 2; } if (pos-buffer < taille_fic) { t = pos; if ((p->data_flag & 0x40) == 0x40) //iconlocation { if (unicode) pos = pos + t->struct_size*2 + 2; else pos = pos + t->struct_size + 2; } //pass first headers !! if (pos-buffer < taille_fic) { t = pos; if (pos-buffer+t->struct_size+8 < taille_fic) { snprintf(to,MAX_PATH,"%s",(char*)(pos+t->struct_size+8)); } } } } } if (!strlen(local_path) && !strlen(to) && b-buffer < taille_fic) { if ((p->data_flag & 0x01) == 0x01) { //first struct unsigned char *pos = buffer + p->header_size + 2; if (pos-buffer < taille_fic) { PLNK_WORD_STRUCT t = pos; pos = pos + t->struct_size; //second struct if (pos-buffer+8 < taille_fic) { if (unicode)snprintf(to,MAX_PATH,"%S",pos+8); else snprintf(to,MAX_PATH,"%s",(char*)(pos+8)); } } } } } }
//------------------------------------------------------------------------------ //extraction des données de la valeur F du profil DWORD TestUserDataFromSAM_F(USERS_INFOS *User_infos, char*buffer) { User_infos->last_logon[0] = 0; User_infos->last_password_change[0] = 0; User_infos->nb_connexion = 0; User_infos->state_id = 0; DWORD userRID = 0; if (strlen(buffer)>0x8F) { char tmp[MAX_PATH]; //Offset 0008 : date de dernière connexion FILETIME FileTime; tmp[0] = buffer[0x16]; tmp[1] = buffer[0x17]; tmp[2] = buffer[0x14]; tmp[3] = buffer[0x15]; tmp[4] = buffer[0x12]; tmp[5] = buffer[0x13]; tmp[6] = buffer[0x10]; tmp[7] = buffer[0x11]; FileTime.dwLowDateTime = HTDF(tmp,8); tmp[0] = buffer[0x1E]; tmp[1] = buffer[0x1F]; tmp[2] = buffer[0x1C]; tmp[3] = buffer[0x1D]; tmp[4] = buffer[0x1A]; tmp[5] = buffer[0x1B]; tmp[6] = buffer[0x18]; tmp[7] = buffer[0x19]; FileTime.dwHighDateTime = HTDF(tmp,8); if ((FileTime.dwHighDateTime == 0) && (FileTime.dwLowDateTime == 0))strncpy(User_infos->last_logon,cps[TXT_MSG_NEVER].c,DATE_SIZE_MAX); else { filetimeToString_GMT(FileTime, User_infos->last_logon, DATE_SIZE_MAX); if (User_infos->last_logon[0] == 0)strncpy(User_infos->last_logon,cps[TXT_MSG_NEVER].c,DATE_SIZE_MAX); } //Last password change tmp[0] = buffer[0x36]; tmp[1] = buffer[0x37]; tmp[2] = buffer[0x34]; tmp[3] = buffer[0x35]; tmp[4] = buffer[0x32]; tmp[5] = buffer[0x33]; tmp[6] = buffer[0x30]; tmp[7] = buffer[0x31]; FileTime.dwLowDateTime = HTDF(tmp,8); tmp[0] = buffer[0x3E]; tmp[1] = buffer[0x3F]; tmp[2] = buffer[0x3C]; tmp[3] = buffer[0x3D]; tmp[4] = buffer[0x3A]; tmp[5] = buffer[0x3B]; tmp[6] = buffer[0x38]; tmp[7] = buffer[0x39]; FileTime.dwHighDateTime = HTDF(tmp,8); if ((FileTime.dwHighDateTime == 0) && (FileTime.dwLowDateTime == 0))strncpy(User_infos->last_password_change,cps[TXT_MSG_NEVER].c,DATE_SIZE_MAX); else { filetimeToString_GMT(FileTime, User_infos->last_password_change, DATE_SIZE_MAX); if (User_infos->last_password_change[0] == 0)strncpy(User_infos->last_password_change,cps[TXT_MSG_NEVER].c,DATE_SIZE_MAX); } //Offste 0038, second digit = State if (buffer[0x71]=='0')User_infos->state_id=301; else User_infos->state_id=300; //Password Expire if ((buffer[0x73]=='2')||(buffer[0x73]=='3')||(buffer[0x73]=='6')||(buffer[0x73]=='7')||(buffer[0x73]=='A')||(buffer[0x73]=='B')||(buffer[0x73]=='E')||(buffer[0x73]=='F')) { strncat(User_infos->last_password_change," (",MAX_PATH); strncat(User_infos->last_password_change,cps[TXT_MSG_MDP_NEVER_EXP].c,MAX_PATH); strncat(User_infos->last_password_change,")\0",MAX_PATH); } //nombre de connexion 0x42 tmp[0] = buffer[0x86]; tmp[1] = buffer[0x87]; tmp[2] = buffer[0x84]; tmp[3] = buffer[0x85]; User_infos->nb_connexion = HTDF(tmp,4); //Offset 0030 : user RID tmp[0] = buffer[0x66]; tmp[1] = buffer[0x67]; tmp[2] = buffer[0x64]; tmp[3] = buffer[0x65]; tmp[4] = buffer[0x62]; tmp[5] = buffer[0x63]; tmp[6] = buffer[0x60]; tmp[7] = buffer[0x61]; userRID = HTDF(tmp,8); } return userRID; }
//------------------------------------------------------------------------------ //local function part !!! //------------------------------------------------------------------------------ void reg_read_enum_PathValues(HKEY hk,char *chkey,char *key,unsigned int session_id, sqlite3 *db) { HKEY CleTmp; if (RegOpenKey(hk,key,&CleTmp)!=ERROR_SUCCESS)return; DWORD nbValue,i,j; FILETIME last_update; if (RegQueryInfoKey (CleTmp,0,0,0,0,0,0,&nbValue,0,0,0,&last_update)!=ERROR_SUCCESS) { RegCloseKey(CleTmp); return; } //get date char parent_key_update[DATE_SIZE_MAX] = ""; filetimeToString_GMT(last_update, parent_key_update, DATE_SIZE_MAX); //read USER + RID + SID char user[MAX_PATH], RID[MAX_PATH], sid[MAX_PATH]; GetRegistryKeyOwner(CleTmp, user, RID, sid, MAX_PATH); //enum values char value[MAX_PATH], data[MAX_PATH]; DWORD valueSize,dataSize,type; for (i=0;i<nbValue && start_scan;i++) { valueSize = MAX_PATH; dataSize = MAX_PATH; value[0] = 0; type = 0; if (RegEnumValue (CleTmp,i,(LPTSTR)value,(LPDWORD)&valueSize,0,(LPDWORD)&type,(LPBYTE)data,(LPDWORD)&dataSize)==ERROR_SUCCESS) { switch(type) { case REG_EXPAND_SZ: case REG_SZ: convertStringToSQL(value, MAX_PATH); convertStringToSQL(data, MAX_PATH); addRegistryPathtoDB("",chkey,key,value,data,user,RID,sid,parent_key_update,session_id,db);break; /*case REG_BINARY: case REG_LINK: { tmp[0] = 0; snprintf(tmp,MAX_PATH,"%S",data); convertStringToSQL(value, MAX_PATH); convertStringToSQL(tmp, MAX_PATH); addRegistryPathtoDB("",chkey,key,value,tmp,user,RID,sid,parent_key_update,session_id,db); } break;*/ case REG_MULTI_SZ: for (j=0;j<dataSize;j++) { if (data[j] == 0)data[j]=';'; } convertStringToSQL(value, MAX_PATH); convertStringToSQL(data, MAX_PATH); addRegistryPathtoDB("",chkey,key,value,data,user,RID,sid,parent_key_update,session_id,db); break; } } } RegCloseKey(CleTmp); }
//------------------------------------------------------------------------------ void ReadDatas(unsigned int type, HKEY hk, char *chk, char *key_path, char *value, char*description_id, unsigned int session_id, sqlite3 *db) { switch(type)//value_type { //list of all string in a directory and exclude "value" case TYPE_ENUM_STRING_VALUE:reg_read_enum_MRUvalues(hk, chk,key_path,value,description_id, session_id, db);break; case TYPE_ENUM_STRING_NVALUE:reg_read_enum_MRUNvalues(hk, chk,key_path,value,description_id, session_id, db);break; case TYPE_ENUM_STRING_WVALUE:reg_read_enum_MRUWvalues(hk, chk,key_path,value,description_id, session_id, db);break; case TYPE_ENUM_SUBNK_DATE: { //read all subkey HKEY CleTmp, CleTmp2; if (RegOpenKey(hk,key_path,&CleTmp)!=ERROR_SUCCESS)return; //enum keys DWORD nbSubKey=0,i; if (RegQueryInfoKey (CleTmp,NULL,NULL,NULL,&nbSubKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS) { RegCloseKey(CleTmp); return; } char key[MAX_PATH], tmp_key[MAX_PATH], lastupdate[DATE_SIZE_MAX] =""; DWORD key_size; FILETIME LastWriteTime; char user[MAX_PATH], RID[MAX_PATH], sid[MAX_PATH]; for (i=0;i<nbSubKey && start_scan;i++) { key[0] = 0; key_size = MAX_PATH; if (RegEnumKeyEx (CleTmp,i,key,(LPDWORD)&key_size,NULL,NULL,NULL,&LastWriteTime)==ERROR_SUCCESS) { snprintf(tmp_key,MAX_PATH,"%s\\%s",key_path,key); if (RegOpenKey(hk,tmp_key,&CleTmp2)==ERROR_SUCCESS) { user[0] = 0; RID[0] = 0; sid[0] = 0; GetRegistryKeyOwner(CleTmp2, user, RID, sid, MAX_PATH); filetimeToString_GMT(LastWriteTime, lastupdate, DATE_SIZE_MAX); addRegistryMRUtoDB("",chk,tmp_key,"","",description_id,user,RID,sid,lastupdate,session_id,db); RegCloseKey(CleTmp2); } } } RegCloseKey(CleTmp); } break; case TYPE_DBL_ENUM_VALUE: { //read all subkey HKEY CleTmp, CleTmp2, CleTmp3; if (RegOpenKey(hk,key_path,&CleTmp)!=ERROR_SUCCESS)return; //enum keys DWORD nbSubKey=0, nbSubKey2,i,j; if (RegQueryInfoKey (CleTmp,NULL,NULL,NULL,&nbSubKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS) { RegCloseKey(CleTmp); return; } char key[MAX_PATH], key2[MAX_PATH], tmp_key[MAX_PATH], tmp_key2[MAX_PATH], lastupdate[DATE_SIZE_MAX] =""; DWORD key_size,key_size2; FILETIME LastWriteTime; char user[MAX_PATH], RID[MAX_PATH], sid[MAX_PATH], data[MAX_PATH]; for (i=0;i<nbSubKey && start_scan;i++) { key[0] = 0; key_size = MAX_PATH; if (RegEnumKeyEx (CleTmp,i,key,(LPDWORD)&key_size,NULL,NULL,NULL,NULL)==ERROR_SUCCESS) { snprintf(tmp_key,MAX_PATH,"%s\\%s\\AVGeneral\\cRecentFiles",key_path,key); if (RegOpenKey(hk,tmp_key,&CleTmp2)==ERROR_SUCCESS) { nbSubKey2 = 0; if (RegQueryInfoKey (CleTmp2,NULL,NULL,NULL,&nbSubKey2,NULL,NULL,NULL,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS) { RegCloseKey(CleTmp2); continue; } for (j=0;j<nbSubKey2 && start_scan;j++) { key2[0] = 0; key_size2 = MAX_PATH; if (RegEnumKeyEx (CleTmp2,j,key2,(LPDWORD)&key_size2,NULL,NULL,NULL,&LastWriteTime)==ERROR_SUCCESS) { snprintf(tmp_key2,MAX_PATH,"%s\\%s",tmp_key,key2); if (RegOpenKey(hk,tmp_key2,&CleTmp3)==ERROR_SUCCESS) { user[0] = 0; RID[0] = 0; sid[0] = 0; data[0] = 0; GetRegistryKeyOwner(CleTmp3, user, RID, sid, MAX_PATH); filetimeToString_GMT(LastWriteTime, lastupdate, DATE_SIZE_MAX); if(ReadValue(hk,tmp_key2,value,data, MAX_PATH)) { convertStringToSQL(data, MAX_PATH); addRegistryMRUtoDB("",chk,tmp_key2,value,data,description_id,user,RID,sid,lastupdate,session_id,db); } RegCloseKey(CleTmp3); } } } RegCloseKey(CleTmp2); } } } RegCloseKey(CleTmp); } break; //all string under one key case TYPE_ENUM_STRING_RVALUE: { //read all subkey HKEY CleTmp; if (RegOpenKey(hk,key_path,&CleTmp)!=ERROR_SUCCESS)return; DWORD nbSubKey=0,i; if (RegQueryInfoKey (CleTmp,NULL,NULL,NULL,&nbSubKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS) { RegCloseKey(CleTmp); return; } char key[MAX_PATH], tmp_key[MAX_PATH]; DWORD key_size; for (i=0;i<nbSubKey && start_scan;i++) { key[0] = 0; key_size = MAX_PATH; if (RegEnumKeyEx (CleTmp,i,key,(LPDWORD)&key_size,NULL,NULL,NULL,NULL)==ERROR_SUCCESS) { snprintf(tmp_key,MAX_PATH,"%s\\%s",key_path,key); reg_read_enum_MRUvalues(hk,chk,tmp_key,value,description_id, session_id, db_scan); } } RegCloseKey(CleTmp); }break; //all string under thow key + key case TYPE_ENUM_STRING_RRVALUE: { //read all subkey HKEY CleTmp,CleTmp2; if (RegOpenKey(hk,key_path,&CleTmp)!=ERROR_SUCCESS)return; DWORD nbSubKey=0,nbSubKey2,i,j; if (RegQueryInfoKey (CleTmp,NULL,NULL,NULL,&nbSubKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS) { RegCloseKey(CleTmp); return; } char key[MAX_PATH], tmp_key[MAX_PATH],key2[MAX_PATH], tmp_key2[MAX_PATH]; DWORD key_size,key_size2; for (i=0;i<nbSubKey && start_scan;i++) { key[0] = 0; key_size = MAX_PATH; if (RegEnumKeyEx (CleTmp,i,key,(LPDWORD)&key_size,NULL,NULL,NULL,NULL)==ERROR_SUCCESS) { snprintf(tmp_key,MAX_PATH,"%s\\%s",key_path,key); //second key !!! if (RegOpenKey(hk,tmp_key,&CleTmp2)!=ERROR_SUCCESS)continue; nbSubKey2 = 0; if (RegQueryInfoKey (CleTmp2,NULL,NULL,NULL,&nbSubKey2,NULL,NULL,NULL,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS) { RegCloseKey(CleTmp2); continue; } for (j=0;j<nbSubKey2 && start_scan;j++) { key2[0] = 0; key_size2 = MAX_PATH; if (RegEnumKeyEx (CleTmp2,j,key2,(LPDWORD)&key_size2,NULL,NULL,NULL,NULL)==ERROR_SUCCESS) { snprintf(tmp_key2,MAX_PATH,"%s\\%s\\%s",tmp_key,key2,value); reg_read_enum_MRUvalues(hk,chk,tmp_key2,"",description_id, session_id, db_scan); } } RegCloseKey(CleTmp2); } } RegCloseKey(CleTmp); }break; //all string under one key + key case TYPE_ENUM_STRING_R_VALUE: { //read all subkey HKEY CleTmp; if (RegOpenKey(hk,key_path,&CleTmp)!=ERROR_SUCCESS)return; DWORD nbSubKey=0,i; if (RegQueryInfoKey (CleTmp,NULL,NULL,NULL,&nbSubKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS) { RegCloseKey(CleTmp); return; } char key[MAX_PATH], tmp_key[MAX_PATH]; DWORD key_size; for (i=0;i<nbSubKey && start_scan;i++) { key[0] = 0; key_size = MAX_PATH; if (RegEnumKeyEx (CleTmp,i,key,(LPDWORD)&key_size,NULL,NULL,NULL,NULL)==ERROR_SUCCESS) { snprintf(tmp_key,MAX_PATH,"%s\\%s\\%s",key_path,key,value); reg_read_enum_MRUvalues(hk,chk,tmp_key,"",description_id, session_id, db_scan); } } RegCloseKey(CleTmp); }break; //only one value case TYPE_VALUE_STRING: { char data[MAX_PATH]; if (ReadValue(hk,key_path,value,data, MAX_PATH)) { HKEY CleTmp; if (RegOpenKey(hk,key_path,&CleTmp)==ERROR_SUCCESS) { char user[MAX_PATH]="", RID[MAX_PATH]="", SID[MAX_PATH]=""; GetRegistryKeyOwner(CleTmp, user, RID, SID, MAX_PATH); RegCloseKey(CleTmp); char parent_key_update[DATE_SIZE_MAX]=""; ReadKeyUpdate(hk,key_path, parent_key_update, DATE_SIZE_MAX); convertStringToSQL(data, MAX_PATH); addRegistryMRUtoDB("",chk,key_path,value,data,description_id,user,RID,SID,parent_key_update,session_id,db_scan); } } }break; //only one value case TYPE_VALUE_WSTRING: { char data[MAX_PATH],tmp[MAX_PATH]; if (ReadValue(hk,key_path,value,tmp, MAX_PATH)) { HKEY CleTmp; if (RegOpenKey(hk,key_path,&CleTmp)==ERROR_SUCCESS) { snprintf(data,MAX_PATH,"%S",tmp); char user[MAX_PATH]="", RID[MAX_PATH]="", SID[MAX_PATH]=""; GetRegistryKeyOwner(CleTmp, user, RID, SID, MAX_PATH); RegCloseKey(CleTmp); char parent_key_update[DATE_SIZE_MAX]=""; ReadKeyUpdate(hk,key_path, parent_key_update, DATE_SIZE_MAX); convertStringToSQL(data, MAX_PATH); addRegistryMRUtoDB("",chk,key_path,value,data,description_id,user,RID,SID,parent_key_update,session_id,db_scan); } } }break; } }
//------------------------------------------------------------------------------ DWORD WINAPI Scan_dns(LPVOID lParam) { unsigned int local_id = (unsigned int)lParam; //check if local or not :) if (!LOCAL_SCAN || WINE_OS) { h_thread_test[local_id] = 0; check_treeview(htrv_test, H_tests[local_id], TRV_STATE_UNCHECK);//db_scan return 0; } //init if(!SQLITE_FULL_SPEED)sqlite3_exec(db_scan,"BEGIN TRANSACTION;", NULL, NULL, NULL); sqlite3 *db = (sqlite3 *)db_scan; unsigned int session_id = current_session_id; //make file directory char file[MAX_PATH]=""; char ip[IPV6_SIZE_MAX],name[MAX_PATH]; snprintf(file,MAX_PATH,"%s\\WINDOWS\\system32\\drivers\\etc\\hosts",getenv("SYSTEMDRIVE")); #ifdef CMD_LINE_ONLY_NO_DB printf("\"DNS\";\"file\";\"ip\";\"name\";\"last_file_update\";\"malware_check\";\"session_id\";\r\n"); #endif // CMD_LINE_ONLY_NO_DB //open host file and read all hosts HANDLE Hfic = CreateFile(file,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,0); if (Hfic != INVALID_HANDLE_VALUE) { DWORD taille_fic = GetFileSize(Hfic,NULL); if (taille_fic != INVALID_FILE_SIZE) { char *buffer = (char *) HeapAlloc(GetProcessHeap(), 0, taille_fic+1); if (buffer != NULL) { //get last update char last_file_update[DATE_SIZE_MAX]=""; FILETIME LastWriteTime; if(GetFileTime(Hfic,NULL,NULL,&LastWriteTime))filetimeToString_GMT(LastWriteTime, last_file_update, DATE_SIZE_MAX); //read data line by line DWORD copiee; char lines[MAX_PATH]; if (ReadFile(Hfic, buffer, taille_fic,&copiee,0)) { char *r = buffer; char *s,*c; while (*r) { //read line memset(lines,0,MAX_PATH); strncpy(lines,r,MAX_PATH); s = lines; while (*s && *s != '\r')s++; *s = 0; r = r+strlen(lines)+2; //comment or not :) if (lines[0]!='#' && strlen(lines) > 8) { //get IP strncpy(ip,lines,IPV6_SIZE_MAX); c = ip; while (*c && *c != ' ' && *c!= '\t' && (*c == '.' || *c == ':' || (*c<='9' && *c>='0')))c++; if (*c) { *c = 0; //get name c = lines+strlen(ip); while (*c && (*c == ' ' || *c == '\t'))c++; memset(name,0,MAX_PATH); strncpy(name,c,MAX_PATH); addHosttoDB(file, ip, name, last_file_update,session_id,db); } } } } HeapFree(GetProcessHeap(), 0, buffer); } } CloseHandle(Hfic); } //get cache HMODULE hDLL = LoadLibrary( "DNSAPI.DLL" ); if (!hDLL) return 0; //function //typedef int(*DNS_GET_CACHE_DATA_TABLE)(PDNS_RECORD*); typedef int(WINAPI *DNS_GET_CACHE_DATA_TABLE)(PDNS_RECORD); DNS_GET_CACHE_DATA_TABLE DnsGetCacheDataTable = (DNS_GET_CACHE_DATA_TABLE)GetProcAddress(hDLL,"DnsGetCacheDataTable"); if (DnsGetCacheDataTable != NULL) { PDNS_RECORD pcache = NULL; DNS_RECORD* dnsRecords = NULL, *dnsr; IN_ADDR ipAddress; char last_file_update[DATE_SIZE_MAX]=""; if (DnsGetCacheDataTable(&pcache) == TRUE) { PDNS_RECORD cache = pcache; while (cache) { memset(name,0,MAX_PATH); snprintf(name,MAX_PATH,"%S",cache->pName); if (name[0] != 0) { //get IP + TTL if(DnsQuery(name,DNS_TYPE_A,0,NULL,&dnsRecords,NULL) == ERROR_SUCCESS) { dnsr = dnsRecords; while (dnsr != NULL) { ipAddress.S_un.S_addr = dnsr->Data.A.IpAddress; if (inet_ntoa(ipAddress) != NULL) { snprintf(ip,IP_SIZE_MAX,"%s",inet_ntoa(ipAddress)); snprintf(last_file_update,DATE_SIZE_MAX,"%lu (s)",dnsr->dwTtl); addHosttoDB("", ip, name, last_file_update,session_id,db); } dnsr = dnsr->pNext; } //free DnsRecordListFree(dnsRecords,DnsFreeRecordList); } } cache = cache->pNext; } } } FreeLibrary(hDLL); if(!SQLITE_FULL_SPEED)sqlite3_exec(db_scan,"END TRANSACTION;", NULL, NULL, NULL); check_treeview(htrv_test, H_tests[local_id], TRV_STATE_UNCHECK);//db_scan h_thread_test[local_id] = 0; return 0; }
//------------------------------------------------------------------------------ DWORD Traiter_RegBin_nk_deleted(char *fic, DWORD position, DWORD taille_fic, char *buffer, unsigned int session_id, sqlite3 *db, BOOL deleted) { if (position + HBIN_CELL_NK_SIZE > taille_fic)return 1; HBIN_CELL_NK_HEADER *nk_h = (HBIN_CELL_NK_HEADER *)(buffer+position); //valide ? if (nk_h->key_name_size >0 && nk_h->key_name_size<taille_fic && nk_h->size>0 && (position-HBIN_CELL_NK_SIZE)&& nk_h->type == 0x6B6E) { if (nk_h->nb_values > 0 && nk_h->nb_values < 0xFFFFFFFF && nk_h->val_ls_offset < 0xFFFFFFFF && nk_h->val_ls_offset > 0) { if (!deleted) return HBIN_CELL_NK_SIZE; char path[MAX_LINE_SIZE]=""; char value[MAX_LINE_SIZE]; char data[MAX_LINE_SIZE]; char type[MAX_LINE_SIZE]; char parent_key_update[DATE_SIZE_MAX]; char Owner_SID[MAX_PATH]=""; //lecture du path complet + SID ^^ ReadPath(buffer, taille_fic, position, path,MAX_LINE_SIZE,NULL,Owner_SID,MAX_PATH); //lecture des valeures ^^ DWORD i, k; S_ITEM_LS *item_ls; HBIN_CELL_VK_HEADER *vk_h; char tmp[MAX_LINE_SIZE]; char *c; //last update parent_key_update[0]=0; if (nk_h->last_write.dwHighDateTime != 0 || nk_h->last_write.dwLowDateTime != 0) { filetimeToString_GMT(nk_h->last_write, parent_key_update, DATE_SIZE_MAX); if (parent_key_update[0] != '2' && deleted) //bad date parent_key_update[0]=0; } BOOL val_ok; for (i=0;i< (nk_h->nb_values);i++) { value[0] = 0; type[0] = 0; if (nk_h->val_ls_offset+0x1000+i*HBIN_CELL_ITEM_LS+4 >= taille_fic)break; item_ls = (S_ITEM_LS *)&buffer[nk_h->val_ls_offset+0x1000+i*HBIN_CELL_ITEM_LS+4]; //lecture de l'offset de la valeure : if (item_ls->val_of>0 && (item_ls->val_of+0x1000+HBIN_CELL_VK_SIZE)<taille_fic) { //traitement des valeures !!! val_ok = TRUE; vk_h = (HBIN_CELL_VK_HEADER *)&buffer[item_ls->val_of+0x1000]; //récupération du nom de la valeur : strncpy(value,vk_h->value,MAX_LINE_SIZE); if (vk_h->name_size>=MAX_LINE_SIZE)value[MAX_LINE_SIZE-1]=0; else { value[vk_h->name_size]=0; if (strlen(value) != vk_h->name_size)val_ok = FALSE; } data[0] = 0; switch(vk_h->data_type) { //Chaines case 0x00000001 : //REG_SZ, chaine ASCII et Unicodes if (vk_h->data_size < 0xFFFFFFFF && vk_h->data_offset > 0 && vk_h->data_offset < taille_fic) { if (vk_h->data_size < 5) { snprintf(data,MAX_LINE_SIZE,"%S",vk_h->cdata_offset); data[vk_h->data_size/2]=0; }else snprintf(data,MAX_LINE_SIZE,"%S",(wchar_t *)&buffer[0x1000+vk_h->data_offset+HBIN_CELL_VK_DATA_PADDING_SIZE]); } strcpy(type,"REG_SZ\0"); break; case 0x00000002 : //REG_EXPAND_SZ, chaine ASCII et Unicodes, contient des path type %path% data[0] = 0; if (vk_h->data_size < 0xFFFFFFFF && vk_h->data_offset > 0 && vk_h->data_offset < taille_fic) { if (vk_h->data_size < 5) { strcpy(data,vk_h->cdata_offset); data[4]=0; }else snprintf(data,MAX_LINE_SIZE,"%S",(wchar_t *)&buffer[0x1000+vk_h->data_offset+HBIN_CELL_VK_DATA_PADDING_SIZE]); } strcpy(type,"REG_EXPAND_SZ\0"); break; case 0x00000006 : //REG_LINK, chaine ASCII et Unicodes, lien lien if (vk_h->data_size < 0xFFFFFFFF && vk_h->data_offset > 0 && vk_h->data_offset < taille_fic) { if (vk_h->data_size < 5) { strcpy(data,vk_h->cdata_offset); data[4]=0; }else snprintf(data,MAX_LINE_SIZE,"%S",(wchar_t *)&buffer[0x1000+vk_h->data_offset+HBIN_CELL_VK_DATA_PADDING_SIZE]); } strcpy(type,"REG_LINK\0"); break; case 0x00000007 : //REG_MULTI_SZ, multiples chaine ASCII et Unicodes, lien if (vk_h->data_size < 0xFFFFFFFF && vk_h->data_offset > 0 && vk_h->data_offset < taille_fic) { if (vk_h->data_size < 5) { strcpy(data,vk_h->cdata_offset); data[4]=0; }else { //traitement des chaines multiples : do { snprintf(tmp,MAX_LINE_SIZE,"%S",(wchar_t *)&buffer[0x1000+vk_h->data_offset+HBIN_CELL_VK_DATA_PADDING_SIZE+2*strlen(data)]); strncat (data,tmp,MAX_LINE_SIZE); strncat (data," \0",MAX_LINE_SIZE); }while (strlen(data)*2 < (vk_h->data_size)); } } strcpy(type,"REG_MULTI_SZ\0"); break; case 0x00000003 : //REG_BINARY, données binaires if (vk_h->data_size < 0xFFFFFFFF && vk_h->data_offset > 0 && vk_h->data_offset < taille_fic) { if (vk_h->data_size < 5) { for (k=0;k<vk_h->data_size && k/2<MAX_LINE_SIZE;k++) { snprintf(tmp,10,"%02X",vk_h->cdata_offset[k]&0xff); strncat(data,tmp,MAX_LINE_SIZE); } strncat(data,"\0",MAX_LINE_SIZE); }else { for (k=0;k<vk_h->data_size && k/2<MAX_LINE_SIZE;k++) { snprintf(tmp,10,"%02X",buffer[0x1000+vk_h->data_offset+HBIN_CELL_VK_DATA_PADDING_SIZE+k]&0xff); strncat(data,tmp,MAX_LINE_SIZE); } strncat(data,"\0",MAX_LINE_SIZE); } } strcpy(type,"REG_BINARY\0"); break; case 0x0000000A : //REG_RESSOURCE_REQUIREMENT_LIST, données binaires if (vk_h->data_size < 0xFFFFFFFF && vk_h->data_offset > 0 && vk_h->data_offset < taille_fic) { if (vk_h->data_size < 5) { for (k=0;k<vk_h->data_size && k/2<MAX_LINE_SIZE;k++) { snprintf(tmp,10,"%02X",vk_h->cdata_offset[k]&0xff); strncat(data,tmp,MAX_LINE_SIZE); } strncat(data,"\0",MAX_LINE_SIZE); }else { for (k=0;k<vk_h->data_size && k/2<MAX_LINE_SIZE;k++) { snprintf(tmp,10,"%02X",buffer[0x1000+vk_h->data_offset+HBIN_CELL_VK_DATA_PADDING_SIZE+k]&0xff); strncat(data,tmp,MAX_LINE_SIZE); } strncat(data,"\0",MAX_LINE_SIZE); } } strcpy(type,"REG_RESSOURCE_REQUIREMENT_LIST\0"); break; case 0x00000004 : //REG_DWORD, données numériques 32bitschar case 0x00000005 : //REG_DWORD, données numériques 32bits signées if (vk_h->data_size > 0) { snprintf(data,MAX_LINE_SIZE,"%08X",(unsigned int)(vk_h->data_offset&0xFFFFFFFF)); // en dword offset = valeur } strcpy(type,"REG_DWORD\0"); break; case 0x0000000b : //REG_QWORD, données numériques 64bits signées if (vk_h->data_offset > 0 && vk_h->data_offset < taille_fic) { c = &buffer[0x1000+vk_h->data_offset+HBIN_CELL_VK_DATA_PADDING_SIZE]; snprintf(data,MAX_LINE_SIZE,"0x%02X%02X%02X%02X%02X%02X%02X%02X",c[7]&0xff,c[6]&0xff,c[5]&0xff,c[4]&0xff,c[3]&0xff,c[2]&0xff,c[1]&0xff,c[0]&0xff); } strcpy(type,"REG_QWORD\0"); break; default : if (deleted)val_ok = FALSE; //on ajoute pas au liste view les éléments inconnus non valides if (vk_h->data_size < 0xFFFFFFFF && vk_h->data_offset > 0 && vk_h->data_offset < taille_fic) { /*for (k=0;k<vk_h->data_size && k/2<MAX_LINE_SIZE;k++) { snprintf(tmp,10,"%02X",buffer[0x1000+vk_h->data_offset+HBIN_CELL_VK_DATA_PADDING_SIZE+k]&0xff); strncat(data,tmp,MAX_LINE_SIZE); } strncat(data,"\0",MAX_LINE_SIZE);*/ if (vk_h->data_type == 0x00000000)strcpy(type,"REG_NONE\0"); else val_ok = FALSE; }else { if (vk_h->data_type == 0x00000000)strcpy(type,"REG_NONE\0"); else val_ok = FALSE; } break; } if (val_ok && strlen(value) || strlen(data)) { //ajout de l'item addDeletedKey(fic, path, value, data, type,Owner_SID, parent_key_update,session_id, db); } }else break; } //no value : only directory if ((nk_h->nb_values < 1 || nk_h->nb_values == 0xFFFFFFFF) && (nk_h->nb_subkeys < 1 || nk_h->nb_subkeys == 0xFFFFFFFF)) { addDeletedKey(fic, path, "", "", "", Owner_SID, parent_key_update,session_id, db); } } return HBIN_CELL_NK_SIZE; } return 1; }
//------------------------------------------------------------------------------ //local function part !!! //------------------------------------------------------------------------------ void Scan_registry_service_local(char *ckey, sqlite3 *db, unsigned int session_id) { HKEY CleTmp; if (RegOpenKey(HKEY_LOCAL_MACHINE,ckey,&CleTmp)==ERROR_SUCCESS) { DWORD i,nbSubKey = 0; if (RegQueryInfoKey (CleTmp,0,0,0,&nbSubKey,0,0,0,0,0,0,0)==ERROR_SUCCESS) { FILETIME LastWriteTime; char key[MAX_PATH],key_path[MAX_PATH]; DWORD key_size; DWORD state_id,type_id; char lastupdate[DATE_SIZE_MAX], name[MAX_PATH],path[MAX_PATH],description[MAX_PATH]; for (i=0;i<nbSubKey && start_scan;i++) { key_size = MAX_PATH; key[0] = 0; if (RegEnumKeyEx (CleTmp,i,key,&key_size,0,0,0,&LastWriteTime)==ERROR_SUCCESS) { //path snprintf(key_path,MAX_PATH,"%s%s",ckey,key); //read values name[0] = 0; path[0] = 0; description[0]= 0; lastupdate[0] = 0; //name if (ReadValue(HKEY_LOCAL_MACHINE,key_path,"DisplayName",name, MAX_PATH) == 0) { if (ReadValue(HKEY_LOCAL_MACHINE,key_path,"Group",name, MAX_PATH) == 0)continue; strncpy(name,key,MAX_PATH); } //state id state_id = ReadDwordValue(HKEY_LOCAL_MACHINE,key_path,"Start"); switch(state_id) { case 0: state_id=210;break;//Kernel module : 210 case 1: state_id=211;break;//Start by system : 211 case 2: state_id=212;break;//Automatic start : 212 case 3: state_id=213;break;//Manual start : 213 case 4: state_id=214;break;//Disable : 214 default:state_id=215;break;//Unknow : 215 } //path : ImagePath ReadValue(HKEY_LOCAL_MACHINE,key_path,"ImagePath",path, MAX_PATH); //description : Description if(ReadValue(HKEY_LOCAL_MACHINE,key_path,"Description",description, MAX_PATH) == 0) ReadValue(HKEY_LOCAL_MACHINE,key_path,"Group",description, MAX_PATH); //type_id type_id = ReadDwordValue(HKEY_LOCAL_MACHINE,key_path,"Type"); if (type_id == 1)type_id = 200; //SERVICE : 200 else type_id = 201; //DRIVER : 201 //last update filetimeToString_GMT(LastWriteTime, lastupdate, DATE_SIZE_MAX); convertStringToSQL(path, MAX_PATH); convertStringToSQL(description, MAX_PATH); addRegistryServicetoDB("", "HKEY_LOCAL_MACHINE", key_path, name, state_id, path, description, type_id, lastupdate, session_id, db); } } } RegCloseKey(CleTmp); } }