//------------------------------------------------------------------------------ void Scan_registry_user_file(HK_F_OPEN *hks, sqlite3 *db, unsigned int session_id, char *computer_name) { DWORD userRID = 0; USERS_INFOS User_infos; #ifdef CMD_LINE_ONLY_NO_DB printf("\"RegistryUser\";\"source\";\"name\";\"RID\";\"SID\";\"grp\";\"description\";\"last_logon\";\"last_password_change\";" "\"nb_connexion\";\"type\";\"state_id\";\"session_id\";\r\n"); #endif //get ref key for hashs BYTE b_f[MAX_LINE_SIZE]; Readnk_Value(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, "SAM\\Domains\\Account", NULL,"F", b_f, MAX_LINE_SIZE); //enum all users //exist or not in the file ? HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, "SAM\\Domains\\Account\\Users"); if (nk_h == NULL)return; HBIN_CELL_NK_HEADER *nk_h_tmp; DWORD valueSize; BOOL ok_test; char SubKeyName[MAX_PATH]; char cbuffer[MAX_LINE_SIZE], buffer[MAX_LINE_SIZE]; DWORD i,nbSubKey = GetSubNK(hks->buffer, hks->taille_fic, nk_h, hks->position, 0, NULL, 0); for (i=0;i<nbSubKey;i++) { ok_test = FALSE; //for each subkey if(GetSubNK(hks->buffer, hks->taille_fic, nk_h, hks->position, i, SubKeyName, MAX_PATH)) { //get nk of key :) nk_h_tmp = GetSubNKtonk(hks->buffer, hks->taille_fic, nk_h, hks->position, i); if (nk_h_tmp == NULL)continue; //F buffer[0] = 0; cbuffer[0] = 0; valueSize = MAX_LINE_SIZE; if(ReadBinarynk_Value(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, NULL, nk_h_tmp,"F", buffer, &valueSize)) { DataToHexaChar(buffer, valueSize, cbuffer, MAX_LINE_SIZE); userRID = TestUserDataFromSAM_F(&User_infos,cbuffer); ok_test = TRUE; } //V buffer[0] = 0; cbuffer[0] = 0; valueSize = MAX_LINE_SIZE; if(ReadBinarynk_Value(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, NULL, nk_h_tmp,"V", buffer, &valueSize)) { DataToHexaChar(buffer, valueSize, cbuffer, MAX_LINE_SIZE); if(TestUserDataFromSAM_V(&User_infos,cbuffer,computer_name)) { //test if rid and sid ok userRID = HTDF(SubKeyName,8); if(User_infos.RID[0] == 0)snprintf(User_infos.RID,MAX_PATH,"%05lu",userRID); if(User_infos.SID[0] == 0)snprintf(User_infos.SID,MAX_PATH,"S-1-5-?-?-?-?-%lu",userRID); }else { if(User_infos.RID[0] == 0 && userRID)snprintf(User_infos.RID,MAX_PATH,"%05lu",userRID); if(User_infos.SID[0] == 0 && userRID)snprintf(User_infos.SID,MAX_PATH,"S-1-5-?-?-?-?-%lu",userRID); } ok_test = TRUE; }else { if(User_infos.RID[0] == 0 && userRID)snprintf(User_infos.RID,MAX_PATH,"%05lu",userRID); if(User_infos.SID[0] == 0 && userRID)snprintf(User_infos.SID,MAX_PATH,"S-1-5-?-?-?-?-%lu",userRID); } if (!ok_test)continue; //get groups if (userRID) GetUserGroupFRF(userRID, User_infos.group, MAX_PATH); //get hashs if(b_f[0] != 0 && _SYSKEY[0] != 0) { DecodeSAMHashXP(_SYSKEY,User_infos.pwdump_pwd_raw_format,userRID,User_infos.name,b_f); } //add user convertStringToSQL(User_infos.description, MAX_PATH); addRegistryUsertoDB(hks->file,User_infos.name, User_infos.RID, User_infos.SID, User_infos.group, User_infos.description, User_infos.last_logon, User_infos.last_password_change, User_infos.nb_connexion, User_infos.type, User_infos.state_id,session_id, db); //add password if (TEST_REG_PASSWORD_ENABLE) addPasswordtoDB(hks->file, User_infos.name, User_infos.pwdump_pwd_format, User_infos.pwdump_pwd_raw_format, REG_PASSWORD_STRING_LOCAL_USER, session_id, db); } } }
//------------------------------------------------------------------------------ //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; }
//------------------------------------------------------------------------------ BOOL registry_users_extract(sqlite3 *db, unsigned int session_id) { BOOL ok = FALSE; DWORD userRID; USERS_INFOS User_infos; //import syskey char sk[MAX_PATH]=""; BOOL syskeyok = registry_syskey_local(sk, MAX_PATH); //get current computer name char computer_name[COMPUTER_NAME_SIZE_MAX]=""; DWORD taille = COMPUTER_NAME_SIZE_MAX; GetComputerName(computer_name,&taille); //Set ACL in registry int ret = set_sam_tree_access(HKEY_LOCAL_MACHINE,"SECURITY\\SAM\\Domains\\Account\\Users"); if (ret == 0) { //get reference key for users hashs HKEY CleTmp; BOOL ok_test; BYTE b_f[MAX_LINE_SIZE]; if(ReadValue(HKEY_LOCAL_MACHINE, "SAM\\SAM\\Domains\\Account", "F", (char*)b_f, MAX_LINE_SIZE)<= 0x80)b_f[0] = 0; //get users if (RegOpenKey(HKEY_LOCAL_MACHINE,"SAM\\SAM\\Domains\\Account\\Users\\",&CleTmp)==ERROR_SUCCESS) { DWORD i, valueSize, SizeSubKeyName, nbSubKey = 0; if (RegQueryInfoKey (CleTmp,0,0,0,&nbSubKey,0,0,0,0,0,0,0)==ERROR_SUCCESS) { char SubKeyName[MAX_PATH], path[MAX_PATH], buffer[MAX_LINE_SIZE], cbuffer[MAX_LINE_SIZE]; for (i=0;i<nbSubKey;i++) { ok_test = FALSE; SizeSubKeyName=MAX_PATH;// on reinitialise la taille a chaque fois sinon il ne lit pas la valeur suivant SubKeyName[0] = 0; if(RegEnumKeyEx (CleTmp,i,SubKeyName,&SizeSubKeyName,0,0,0,0)!=ERROR_SUCCESS)continue; //read value snprintf(path,MAX_PATH,"SAM\\SAM\\Domains\\Account\\Users\\%s",SubKeyName); //F value cbuffer[0]= 0; buffer[0] = 0; userRID = 0; valueSize = ReadValue(HKEY_LOCAL_MACHINE, path, "F", buffer, MAX_LINE_SIZE); if (valueSize) { DataToHexaChar(buffer, valueSize, cbuffer, MAX_LINE_SIZE); userRID = TestUserDataFromSAM_F(&User_infos,cbuffer); ok_test = TRUE; } //V value cbuffer[0]= 0; buffer[0] = 0; valueSize = ReadValue(HKEY_LOCAL_MACHINE, path, "V", buffer, MAX_LINE_SIZE); if (valueSize) { //read datas DataToHexaChar(buffer, valueSize, cbuffer, MAX_LINE_SIZE); if(TestUserDataFromSAM_V(&User_infos,cbuffer,computer_name)) { //test if rid and sid ok userRID = HTDF(SubKeyName,8); if(User_infos.RID[0] == 0)snprintf(User_infos.RID,MAX_PATH,"%05lu",userRID); if(User_infos.SID[0] == 0)snprintf(User_infos.SID,MAX_PATH,"S-1-5-?-?-?-?-%lu",userRID); }else { if((User_infos.RID[0] == 0) && userRID)snprintf(User_infos.RID,MAX_PATH,"%05lu",userRID); if((User_infos.SID[0] == 0) && userRID)snprintf(User_infos.SID,MAX_PATH,"S-1-5-?-?-?-?-%lu",userRID); } ok_test = TRUE; }else { if((User_infos.RID[0] == 0) && userRID)snprintf(User_infos.RID,MAX_PATH,"%05lu",userRID); if((User_infos.SID[0] == 0) && userRID)snprintf(User_infos.SID,MAX_PATH,"S-1-5-?-?-?-?-%lu",userRID); } if (!ok_test)continue; //get groups if (userRID) GetUserGroup(userRID, User_infos.group, MAX_PATH); //get hashs if((b_f[0] != 0) && syskeyok) { DecodeSAMHashXP(sk,User_infos.pwdump_pwd_raw_format,userRID,User_infos.name,b_f); } //add user convertStringToSQL(User_infos.description, MAX_PATH); addRegistryUsertoDB("HKEY_LOCAL_MACHINE\\SAM",User_infos.name, User_infos.RID, User_infos.SID, User_infos.group, User_infos.description, User_infos.last_logon, User_infos.last_password_change, User_infos.nb_connexion, User_infos.type, User_infos.state_id,session_id, db); //add password if (TEST_REG_PASSWORD_ENABLE) addPasswordtoDB("HKEY_LOCAL_MACHINE\\SAM", User_infos.name, User_infos.pwdump_pwd_format, User_infos.pwdump_pwd_raw_format, REG_PASSWORD_STRING_LOCAL_USER, session_id, db); ok = TRUE; } } RegCloseKey(CleTmp); } } //Restore ACL in registry restore_sam_tree_access(HKEY_LOCAL_MACHINE,"SECURITY\\SAM\\Domains\\Account\\Users"); return ok; }
//------------------------------------------------------------------------------ BOOL TestUserDataFromSAM_V(USERS_INFOS *User_infos, char *buffer, char *computer) { //init User_infos->name[0] = 0; User_infos->RID[0] = 0; User_infos->SID[0] = 0; User_infos->group[0] = 0; User_infos->type[0] = 0; User_infos->description[0] = 0; User_infos->pwdump_pwd_raw_format[0] = 0; User_infos->pwdump_pwd_format[0] = 0; //get datas BOOL ret = FALSE; char tmp[MAX_PATH],tmp2[MAX_PATH],tmp3[MAX_PATH]; unsigned long int size_total = strlen(buffer); if (size_total < 350)return FALSE; //possibilité aussi de chercher : //chercher dans la chaine la chaine suivante : 000001020000000520000000200200000102000000052000000020020000 //+Nom(Wildstring) + 0000 + Description + 0100/0102/FFFF //--name //emplacement du nom (taille de la strcuturitem[10].c[0]=0;e d'entête + emplacement) //0x0C tmp[0] = buffer[30]; tmp[1] = buffer[31]; tmp[2] = buffer[28]; tmp[3] = buffer[29]; tmp[4] = buffer[26]; tmp[5] = buffer[27]; tmp[6] = buffer[24]; tmp[7] = buffer[25]; unsigned int of_name = (204+ HTDF(tmp,8))*2; //lecture de la taille du nom sur 1 int = 4octets //0x10 = taille nom user tmp[0] = buffer[38]; tmp[1] = buffer[39]; tmp[2] = buffer[36]; tmp[3] = buffer[37]; tmp[4] = buffer[34]; tmp[5] = buffer[35]; tmp[6] = buffer[32]; tmp[7] = buffer[33]; unsigned int taille_nom = HTDF(tmp,8)/2; //-- nom complet //emplacement de la description (taille de la strcuture d'entête + emplacement) //0x18 tmp[0] = buffer[54]; tmp[1] = buffer[55]; tmp[2] = buffer[52]; tmp[3] = buffer[53]; tmp[4] = buffer[50]; tmp[5] = buffer[51]; tmp[6] = buffer[48]; tmp[7] = buffer[49]; unsigned int of_full_name = (204+ HTDF(tmp,8))*2; //lecture de la taille du nom complet sur 1 int = 4octets //0x1C = taille du nom complet tmp[0] = buffer[62]; tmp[1] = buffer[63]; tmp[2] = buffer[60]; tmp[3] = buffer[61]; tmp[4] = buffer[58]; tmp[5] = buffer[59]; tmp[6] = buffer[56]; tmp[7] = buffer[57]; unsigned int taille_full_name = HTDF(tmp,8)/2; //--description //emplacement de la description (taille de la strcuture d'entête + emplacement) //0x24 tmp[0] = buffer[78]; tmp[1] = buffer[79]; tmp[2] = buffer[76]; tmp[3] = buffer[77]; tmp[4] = buffer[74]; tmp[5] = buffer[75]; tmp[6] = buffer[72]; tmp[7] = buffer[73]; unsigned int of_description = (204+ HTDF(tmp,8))*2; //lecture de la taille de la description sur 1 int = 4octets //0x28 = taille de description tmp[0] = buffer[86]; tmp[1] = buffer[87]; tmp[2] = buffer[84]; tmp[3] = buffer[85]; tmp[4] = buffer[82]; tmp[5] = buffer[83]; tmp[6] = buffer[80]; tmp[7] = buffer[81]; unsigned int taille_description = HTDF(tmp,8)/2; //password hash //-- LM PASSWORD //0x9C tmp[0] = buffer[318]; tmp[1] = buffer[319]; tmp[2] = buffer[316]; tmp[3] = buffer[317]; tmp[4] = buffer[314]; tmp[5] = buffer[315]; tmp[6] = buffer[312]; tmp[7] = buffer[313]; unsigned int of_lmpw = (204+ HTDF(tmp,8))*2; //0xA0 tmp[0] = buffer[326]; tmp[1] = buffer[327]; tmp[2] = buffer[324]; tmp[3] = buffer[325]; tmp[4] = buffer[322]; tmp[5] = buffer[323]; tmp[6] = buffer[320]; tmp[7] = buffer[321]; unsigned int taille_lmpw = HTDF(tmp,8)*2; //-- NT PASSWORD //0xA8 tmp[0] = buffer[342]; tmp[1] = buffer[343]; tmp[2] = buffer[340]; tmp[3] = buffer[341]; tmp[4] = buffer[338]; tmp[5] = buffer[339]; tmp[6] = buffer[336]; tmp[7] = buffer[337]; unsigned int of_ntpw = (204+ HTDF(tmp,8))*2; //0xAC tmp[0] = buffer[350]; tmp[1] = buffer[351]; tmp[2] = buffer[348]; tmp[3] = buffer[349]; tmp[4] = buffer[346]; tmp[5] = buffer[347]; tmp[6] = buffer[344]; tmp[7] = buffer[345]; unsigned int taille_ntpw = HTDF(tmp,8)*2; //---results--- //name if ((taille_nom>0) && (taille_nom<size_total) && (of_name>0) && (of_name<size_total)) { tmp[0] = 0; tmp2[0] = 0; strncpy(tmp,(char*)(buffer+of_name),MAX_PATH); SHexaToString(tmp,tmp2,MAX_PATH); if (taille_nom<MAX_PATH)tmp2[taille_nom]=0; else tmp2[MAX_PATH-1]=0; if (computer[0] == 0)strncpy(User_infos->name,tmp2,MAX_PATH); else snprintf(User_infos->name,MAX_PATH,"%s\\%s",computer,tmp2); ret = TRUE; } //lecture de la description (fullname) if ((taille_full_name>0) && (taille_full_name<size_total) && (of_full_name>0) && (of_full_name<size_total)) { tmp[0] = 0; tmp2[0] = 0; strncpy(tmp,(char*)(buffer+of_full_name),MAX_PATH); SHexaToString(tmp,tmp2,MAX_PATH); if (taille_full_name<MAX_PATH)tmp2[taille_full_name]=0; else tmp2[MAX_PATH-1]=0; ret = TRUE; }else tmp2[0] = 0; //lecture de la description (comment) if ((taille_description>0) && (taille_description<size_total) && (of_description>0) && (of_description<size_total)) { tmp[0] = 0; tmp3[0] = 0; strncpy(tmp,(char*)(buffer+of_description),MAX_PATH); SHexaToString(tmp,tmp3,MAX_PATH); if (taille_description<MAX_PATH)tmp3[taille_description]=0; else tmp3[MAX_PATH-1]=0; if (tmp2[0] != 0)snprintf(User_infos->description,MAX_PATH,"(%s) %s",tmp2,tmp3); else snprintf(User_infos->description,MAX_PATH,"%s",tmp3); ret = TRUE; }else if ((taille_full_name>0) && (tmp2[0] != 0)) snprintf(User_infos->description,MAX_PATH,"(%s)",tmp2); //type if (((buffer[8]=='B') || (buffer[8]=='b')) && ((buffer[9]=='C') || (buffer[9]=='c')))snprintf(User_infos->type,MAX_PATH,"2 : %s",cps[TXT_MSG_ADMIN].c); else if (((buffer[8]=='B') || (buffer[8]=='b')) && (buffer[9]=='0'))snprintf(User_infos->type,MAX_PATH,"0 : %s",cps[TXT_MSG_GUEST].c); else if (((buffer[8]=='D') || (buffer[8]=='d')) && (buffer[9]=='4'))snprintf(User_infos->type,MAX_PATH,"1 : %s",cps[TXT_MSG_USER].c); else snprintf(User_infos->type,MAX_PATH,"0x%c%c : %s",buffer[8],buffer[9],cps[TXT_MSG_UNK].c); //SID+RID //SID : après 12 octets donc 24 caractères + dernière clée : 2o donc 4caractères : 2400 4400 0200 0105 0000 0000 0005 1500 0000 //fin : 0000 //SID = col3 tmp3[0] = 0; unsigned long int type_id = 0, type_id2=0, last_id=0; unsigned long int i = Contient(buffer,"2400440002000105000000000005"); // 1500 0000 = 21 le SID de début if ((i>0) && (i<(strlen(buffer)-40))) { //création du SID : 4o-4o-4o-4o-4o sprintf(tmp,"%c%c%c%c%c%c%c%c",buffer[i+6],buffer[i+7],buffer[i+4],buffer[i+5],buffer[i+2],buffer[i+3],buffer[i],buffer[i+1]); type_id = HTD(tmp); snprintf(tmp2,MAX_PATH,"S-1-5-%lu",type_id); strcpy(tmp3,tmp2); sprintf(tmp,"%c%c%c%c%c%c%c%c",buffer[i+14],buffer[i+15],buffer[i+12],buffer[i+13],buffer[i+10],buffer[i+11],buffer[i+8],buffer[i+9]); type_id2 = HTD(tmp); snprintf(tmp2,MAX_PATH,"-%lu",type_id2); strncat(tmp3,tmp2,MAX_PATH); sprintf(tmp,"%c%c%c%c%c%c%c%c",buffer[i+22],buffer[i+23],buffer[i+20],buffer[i+21],buffer[i+18],buffer[i+19],buffer[i+16],buffer[i+17]); snprintf(tmp2,MAX_PATH,"-%lu",HTD(tmp)); strncat(tmp3,tmp2,MAX_PATH); sprintf(tmp,"%c%c%c%c%c%c%c%c",buffer[i+30],buffer[i+31],buffer[i+28],buffer[i+29],buffer[i+26],buffer[i+27],buffer[i+24],buffer[i+25]); snprintf(tmp2,MAX_PATH,"-%lu",HTD(tmp)); strncat(tmp3,tmp2,MAX_PATH); sprintf(tmp,"%c%c%c%c%c%c%c%c",buffer[i+38],buffer[i+39],buffer[i+36],buffer[i+37],buffer[i+34],buffer[i+35],buffer[i+32],buffer[i+33]); last_id = HTD(tmp); snprintf(tmp2,MAX_PATH,"-%lu",last_id); strncat(tmp3,tmp2,MAX_PATH); strncat(tmp3,"\0",MAX_PATH); strncpy(User_infos->SID,tmp3,MAX_PATH); snprintf(User_infos->RID,MAX_PATH,"%05lu",last_id); //descriptions infos + switch (type_id) { case 1: strncat(User_infos->description," Rights : Dialup\0",MAX_PATH); case 2: strncat(User_infos->description," Rights : Network\0",MAX_PATH); case 3: strncat(User_infos->description," Rights : Batch\0",MAX_PATH); case 4: strncat(User_infos->description," Rights : Interative\0",MAX_PATH); case 5: strncat(User_infos->description," Rights : Driver\0",MAX_PATH); case 6: strncat(User_infos->description," Rights : Service\0",MAX_PATH); case 7: strncat(User_infos->description," Rights : Anonymous logon\0",MAX_PATH); case 8: strncat(User_infos->description," Rights : Proxy\0",MAX_PATH); case 9: strncat(User_infos->description," Rights : Entreprise domain controllers\0",MAX_PATH); case 10: strncat(User_infos->description," Rights : Self\0",MAX_PATH); case 11: strncat(User_infos->description," Rights : Authenticated Users\0",MAX_PATH); case 12: strncat(User_infos->description," Rights : Restricted\0",MAX_PATH); case 13: strncat(User_infos->description," Rights : Terminal server user\0",MAX_PATH); case 14: strncat(User_infos->description," Rights : Remote interactive logon\0",MAX_PATH); case 15: strncat(User_infos->description," Rights : This Organization\0",MAX_PATH); case 18: strncat(User_infos->description," Rights : System\0",MAX_PATH); case 19: strncat(User_infos->description," Rights : Local service\0",MAX_PATH); case 20: strncat(User_infos->description," Rights : Network service\0",MAX_PATH); case 21: switch(last_id) { case 500 : strncat(User_infos->description," Rights : Local Administrator\0",MAX_PATH);break; case 501 : strncat(User_infos->description," Rights : Local Guest\0",MAX_PATH);break; case 502 : strncat(User_infos->description," Rights : Krbtgt\0",MAX_PATH);break; case 512 : strncat(User_infos->description," Rights : Domain Admins\0",MAX_PATH);break; case 513 : strncat(User_infos->description," Rights : Domain Users\0",MAX_PATH);break; case 514 : strncat(User_infos->description," Rights : Domain Guests\0",MAX_PATH);break; case 515 : strncat(User_infos->description," Rights : Domain Computers\0",MAX_PATH);break; case 516 : strncat(User_infos->description," Rights : Domain Controllers\0",MAX_PATH);break; case 517 : strncat(User_infos->description," Rights : Cert Publishers\0",MAX_PATH);break; case 518 : strncat(User_infos->description," Rights : Schema Admins\0",MAX_PATH);break; case 519 : strncat(User_infos->description," Rights : Enterprise Admins\0",MAX_PATH);break; case 520 : strncat(User_infos->description," Rights : Group Policy Creator Owners\0",MAX_PATH);break; case 553 : strncat(User_infos->description," Rights : RAS and IAS Servers\0",MAX_PATH);break; } break; case 32: switch(last_id) { case 544 : strncat(User_infos->description," Rights : Administrators\0",MAX_PATH);break; case 545 : strncat(User_infos->description," Rights : Users\0",MAX_PATH);break; case 546 : strncat(User_infos->description," Rights : Guests\0",MAX_PATH);break; case 547 : strncat(User_infos->description," Rights : Power Users\0",MAX_PATH);break; case 548 : strncat(User_infos->description," Rights : Account Operators\0",MAX_PATH);break; case 549 : strncat(User_infos->description," Rights : Server Operators\0",MAX_PATH);break; case 550 : strncat(User_infos->description," Rights : Print Operators\0",MAX_PATH);break; case 551 : strncat(User_infos->description," Rights : Backup Operators\0",MAX_PATH);break; case 552 : strncat(User_infos->description," Rights : Replicator \0",MAX_PATH);break; case 554 : strncat(User_infos->description," Rights : Pre-Windows 2000 Compatible Access\0",MAX_PATH);break; case 555 : strncat(User_infos->description," Rights : Remote Desktop Users\0",MAX_PATH);break; case 556 : strncat(User_infos->description," Rights : Network Configuration Operators\0",MAX_PATH);break; case 557 : strncat(User_infos->description," Rights : Incoming Forest Trust Builders\0",MAX_PATH);break; case 558 : strncat(User_infos->description," Rights : Performance Monitor Users\0",MAX_PATH);break; case 559 : strncat(User_infos->description," Rights : Performance Log Users\0",MAX_PATH);break; case 560 : strncat(User_infos->description," Rights : Windows Authorization Access Group\0",MAX_PATH);break; case 561 : strncat(User_infos->description," Rights : Terminal Server License Servers\0",MAX_PATH);break; } break; case 64: switch(last_id) { case 10 : strncat(User_infos->description," Rights : NTLM Authentication\0",MAX_PATH);break; case 14 : strncat(User_infos->description," Rights : SChannel Authentication\0",MAX_PATH);break; case 21 : strncat(User_infos->description," Rights : Digest Authentication\0",MAX_PATH);break; } break; } ret = TRUE; } //hash NT::LM if (ret) { tmp2[0]=0; tmp3[0]=0; //8 => 4 size of separator if ((taille_lmpw > 8) && (of_lmpw>0) && ((of_lmpw + 8+ taille_lmpw)<=size_total)) { strncpy(tmp2,buffer+of_lmpw+8,MAX_PATH); tmp2[32]=0; }else strcpy(tmp2,"NO PASSWORD*********************");//LM if ((taille_ntpw > 8) && (of_ntpw>0) && ((of_ntpw + taille_ntpw)<=size_total)) { strncpy(tmp3,buffer+(of_ntpw+8),MAX_PATH); tmp3[32]=0; }else strcpy(tmp3,"NO PASSWORD*********************");//NT if ((tmp2[0]!=0) && (tmp3[0]!=0)) { //pwdump format //<user>:<id>:<lanman pw>:<NT pw>:comment:homedir: //snprintf(item[10].c,MAX_PATH,"%s:%lu:%s:%s:::",item[2].c,last_id,tmp2,tmp3); snprintf(User_infos->pwdump_pwd_raw_format,MAX_PATH,":%s:%s",tmp2,tmp3); } } return ret; }
//0x28 = début du 1er SID structure + 52 //0x30 = nombre d'instances (user + paddings) void TraiterGroupDataFromSAM_C(char *buffer, unsigned int rid, char *group, unsigned int group_size_max) { char tmp[MAX_LINE_SIZE]; unsigned long int size_total = strlen(buffer); char group_name[MAX_PATH]=""; //lecture de la taille du nom sur 1 int = 4octets //0x14 = taille nom de groupe tmp[0] = buffer[46]; tmp[1] = buffer[47]; tmp[2] = buffer[44]; tmp[3] = buffer[45]; tmp[4] = buffer[42]; tmp[5] = buffer[43]; tmp[6] = buffer[40]; tmp[7] = buffer[41]; unsigned int taille_nom = HTDF(tmp,8)/2; //lecture de la taille de la description sur 1 int = 4octets //0x20 = taille de description /*tmp[0] = buffer[70]; tmp[1] = buffer[71]; tmp[2] = buffer[68]; tmp[3] = buffer[69]; tmp[4] = buffer[66]; tmp[5] = buffer[67]; tmp[6] = buffer[64]; tmp[7] = buffer[65]; unsigned int taille_description = HTDF(tmp,8)/2;*/ //0x10 = emplacement nom de groupe en unicode (taille totale) + 52 tmp[0] = buffer[38]; tmp[1] = buffer[39]; tmp[2] = buffer[36]; tmp[3] = buffer[37]; tmp[4] = buffer[34]; tmp[5] = buffer[35]; tmp[6] = buffer[32]; tmp[7] = buffer[33]; unsigned int of_name = (52+ HTDF(tmp,8))*2; //0x1C = emplacement description + 52 /*tmp[0] = buffer[62]; tmp[1] = buffer[63]; tmp[2] = buffer[60]; tmp[3] = buffer[61]; tmp[4] = buffer[58]; tmp[5] = buffer[59]; tmp[6] = buffer[56]; tmp[7] = buffer[57]; unsigned int of_description = (52+ HTDF(tmp,8))*2;*/ //0x28 = début du 1er SID structure + 52 tmp[0] = buffer[86]; tmp[1] = buffer[87]; tmp[2] = buffer[84]; tmp[3] = buffer[85]; tmp[4] = buffer[82]; tmp[5] = buffer[83]; tmp[6] = buffer[80]; tmp[7] = buffer[81]; unsigned int of_sid = (52+ HTDF(tmp,8))*2; //0x30 = nombre d'instances (user) tmp[0] = buffer[102]; tmp[1] = buffer[103]; tmp[2] = buffer[100]; tmp[3] = buffer[101]; tmp[4] = buffer[98]; tmp[5] = buffer[99]; tmp[6] = buffer[96]; tmp[7] = buffer[97]; DWORD nb_sid = HTDF(tmp,8); //2 = name if ((taille_nom>0) && (taille_nom<size_total) && (of_name>0) && (of_name<size_total)) { strncpy(tmp,(char*)(buffer+of_name),MAX_LINE_SIZE); SHexaToString(tmp,group_name,MAX_PATH); if (taille_nom<MAX_PATH)group_name[taille_nom]=0; else group_name[MAX_PATH-1]=0; } //4 = description /*if (taille_description>0 && taille_description<size_total && of_description>0 && of_description<size_total) { tmp[0]=0; strncpy(tmp,(char*)(item[12].c+of_description),MAX_LINE_SIZE); SHexaToString(tmp,item[4].c); item[4].c[taille_description]=0; }*/ //3 = sid #define DATA_USER_HEADER_SIZE 8 /*typedef struct data_user { char valid; //0x01 char nb_sid; //0x05 ou 0x01 char padding[5]; //0x0000 0000 00 char type; //0x05 char sid[1]; //par defaut découpé en section de 2octet *nb_part }DATA_USER; */ //cas de groupes vides if (of_sid+(DATA_USER_HEADER_SIZE+nb_sid*4)*2>size_total)return; DWORD i, nb_c_sid; char *d,*c = &buffer[of_sid]; for (i=0;i<nb_sid;i++) { //lecture du nombre de sid nb_c_sid = HexaToDecS(c+2); if (nb_c_sid != 1) { d = c+(DATA_USER_HEADER_SIZE*2)+(nb_c_sid-1)*8; // 48 = 6*8 tmp[0] = d[6]; tmp[1] = d[7]; tmp[2] = d[4]; tmp[3] = d[5]; tmp[4] = d[2]; tmp[5] = d[3]; tmp[6] = d[0]; tmp[7] = d[1]; if(HTDF(tmp,8) == rid) { if (group[0] != 0)strncat(group,", ",group_size_max); strncat(group,group_name,group_size_max); strncat(group,"\0",group_size_max); return; } } //next c = c+((DATA_USER_HEADER_SIZE+nb_c_sid*4)*2); } }