//------------------------------------------------------------------------------ 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); } } }
//------------------------------------------------------------------------------ void Scan_registry_user_local(sqlite3 *db, unsigned int session_id) { if (registry_users_extract(db,session_id))return; //load all users informations HMODULE hDLL; typedef DWORD (WINAPI *NETAPIBUFFERFREE)(LPVOID Buffer); NETAPIBUFFERFREE NetApiBufferFree; typedef DWORD (WINAPI *NETUSERENUM)(LPCWSTR servername, DWORD level, DWORD filter, LPBYTE* bufptr, DWORD prefmaxlen, LPDWORD entriesread, LPDWORD totalentries, LPDWORD resume_handle); NETUSERENUM NetUserEnum; typedef DWORD (WINAPI *NETUSERGETINFO)( LPCWSTR servername, LPCWSTR username, DWORD level, LPBYTE* bufptr); NETUSERGETINFO NetUserGetInfo; typedef DWORD (WINAPI *NETUSERGETLOCALGROUPS)( LPCWSTR servername, LPCWSTR username, DWORD level, DWORD flags, LPBYTE* bufptr, DWORD prefmaxlen, LPDWORD entriesread, LPDWORD totalentries); NETUSERGETLOCALGROUPS NetUserGetLocalGroups; typedef struct _USER_INFO_0 { LPWSTR usri0_name; }*LPUSER_INFO_0; typedef struct _USER_INFO_2 { LPWSTR usri2_name; LPWSTR usri2_password; DWORD usri2_password_age; DWORD usri2_priv; LPWSTR usri2_home_dir; LPWSTR usri2_comment; DWORD usri2_flags; LPWSTR usri2_script_path; DWORD usri2_auth_flags; LPWSTR usri2_full_name; LPWSTR usri2_usr_comment; LPWSTR usri2_parms; LPWSTR usri2_workstations; DWORD usri2_last_logon; DWORD usri2_last_logoff; DWORD usri2_acct_expires; DWORD usri2_max_storage; DWORD usri2_units_per_week; PBYTE usri2_logon_hours; DWORD usri2_bad_pw_count; DWORD usri2_num_logons; LPWSTR usri2_logon_server; DWORD usri2_country_code; DWORD usri2_code_page; } USER_INFO_2, *PUSER_INFO_2, *LPUSER_INFO_2; typedef struct _GROUP_USERS_INFO_0 { LPWSTR grui0_name; } GROUP_USERS_INFO_0, *PGROUP_USERS_INFO_0, *LPGROUP_USERS_INFO_0; //load function if ((hDLL = LoadLibrary( "NETAPI32.dll"))!=NULL) { NetApiBufferFree = (NETAPIBUFFERFREE) GetProcAddress(hDLL,"NetApiBufferFree"); NetUserEnum = (NETUSERENUM) GetProcAddress(hDLL,"NetUserEnum"); NetUserGetInfo = (NETUSERGETINFO) GetProcAddress(hDLL,"NetUserGetInfo"); NetUserGetLocalGroups = (NETUSERGETLOCALGROUPS) GetProcAddress(hDLL,"NetUserGetLocalGroups"); if (NetApiBufferFree && NetUserEnum && NetUserGetInfo && NetUserGetLocalGroups) { //enumerate all accounts DWORD nStatus, i, nb, total; LPUSER_INFO_0 pBuf, Buffer; USER_INFO_2 * pBuf_info; char name[MAX_PATH],RID[MAX_PATH],SID[MAX_PATH],group[MAX_PATH],type[MAX_PATH], description[MAX_PATH],last_logon[DATE_SIZE_MAX],last_password_change[DATE_SIZE_MAX]; DWORD nb_connexion,state_id; LPGROUP_USERS_INFO_0 LBuffer,pTmpBuf; DWORD dwEntriesRead, dwTotalEntries, j, s; do { nStatus = NetUserEnum(0,0,2,(LPBYTE*)&pBuf,-1,&nb,&total,0); if (((nStatus == 0) || (nStatus == 234)) && (Buffer = pBuf) != 0) { for (i = 0; i < nb; i++) { if (Buffer->usri0_name!=0) { //init name[0] = 0; RID[0] = 0; SID[0] = 0; group[0] = 0; description[0] = 0; last_logon[0] = 0; last_password_change[0] = 0; nb_connexion = 0; state_id = 0; type[0] = 0; if (NetUserGetInfo(0,Buffer->usri0_name,2,(LPBYTE *)&pBuf_info) == 0) { //name snprintf(name,MAX_PATH,"%S",Buffer->usri0_name); //get account infos ^^ SID + RID GetSIDFromUser(name, RID, SID, MAX_PATH); //group if (NetUserGetLocalGroups(0,Buffer->usri0_name,0,1,(LPBYTE*)&LBuffer,-1,&dwEntriesRead,&dwTotalEntries) == 0) { if ((pTmpBuf = LBuffer) != 0) { for (j = 0; j < dwEntriesRead; j++) { if(pTmpBuf != 0) { s = strlen(group); if (s>=MAX_PATH)break; snprintf(group+s,MAX_PATH-s,"%S,",pTmpBuf->grui0_name); } pTmpBuf++; } } } //description snprintf(description,MAX_PATH,"(%S) %S %S",pBuf_info->usri2_full_name,pBuf_info->usri2_usr_comment,pBuf_info->usri2_comment); //state if (pBuf_info->usri2_flags&0x2)state_id = 300;//Disable else state_id = 301;//Enable if (pBuf_info->usri2_flags&0x10)state_id+=2;//Lock //last_logon if (pBuf_info->usri2_last_logon != 0) { timeToString(pBuf_info->usri2_last_logon, last_logon, DATE_SIZE_MAX); } //last_password_change if (pBuf_info->usri2_password_age != 0) { snprintf(last_password_change,DATE_SIZE_MAX,"%lu %02lu:%02lu:%02lu", pBuf_info->usri2_password_age/86400, pBuf_info->usri2_password_age%86400/3600, pBuf_info->usri2_password_age%86400%3600/60, pBuf_info->usri2_password_age%86400%3600%60); } //nb_connexion nb_connexion = pBuf_info->usri2_num_logons; //type switch(pBuf_info->usri2_priv) { case 0:snprintf(type,MAX_PATH,"%lu : %s",pBuf_info->usri2_priv,cps[TXT_MSG_GUEST].c);break; case 1:snprintf(type,MAX_PATH,"%lu : %s",pBuf_info->usri2_priv,cps[TXT_MSG_USER].c);break; case 2:snprintf(type,MAX_PATH,"%lu : %s",pBuf_info->usri2_priv,cps[TXT_MSG_ADMIN].c);break; default:snprintf(type,MAX_PATH,"0x%02X : %s",(unsigned int)(pBuf_info->usri2_priv & 0xff),cps[TXT_MSG_UNK].c);break; } addRegistryUsertoDB("NETAPI32",name, RID, SID, group, description, last_logon, last_password_change, nb_connexion, type, state_id, session_id, db); } Buffer++; }else break; } } }while (nStatus == ERROR_MORE_DATA && start_scan); } FreeLibrary(hDLL); } }
//------------------------------------------------------------------------------ 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; }