Привет мне интересно, как Windows выполняет проверку целостности значений реестра, прежде чем его читать.
Пока я изменяю кэшированные учетные данные домена в реестре Windows, я получил эти значения из следующих ключей HKEY_LOCAL_MACHINE \ SECURITY \ CACHE \ NL $ 1 … NL $ 10.
Я расшифровал его значениями ключей NL $ KM и выкинул хэш сохраненного пароля. И я хочу изменить хеш с моим новым сгенерированным хешем. Но Windows немного сложнее, они добавили окончательную проверку контрольной суммы для проверки, я надеюсь, но не уверен. Таким образом, существует любой способ изменить хэш и заставить систему работать в автономном режиме, когда система не связана с доменом.
Вот код для этого:
Чтобы сделать шифрование или дешифрование методов кэширования зависит от версии ОС Windows
int cryptData(LPBYTE in,LPBYTE out,DWORD dataSize,CRYPT_KEYS *keys,CRYPT_TYPE cType) {
RC4_KEY rc4_ctx;
AES_KEY aes_ctx;
BYTE aes_iv[16];
RtlMoveMemory(aes_iv,keys->aes_iv,sizeof(keys->aes_iv));
switch(cType) {
case ENCRYPT:
if(keys->version<6) {
HMAC(EVP_md5(),keys->nl$km,sizeof(keys->nl$km),keys->hmac_message,sizeof(keys->hmac_message),keys->rc4_key,NULL);
RC4_set_key(&rc4_ctx,MD5_DIGEST_LENGTH,keys->rc4_key);
RC4(&rc4_ctx,dataSize,in,out);
}
else {
AES_set_encrypt_key(keys->nl$km,128,&aes_ctx);
AES_cbc_encrypt(in,out,dataSize,&aes_ctx,aes_iv,AES_ENCRYPT);
}
break;
case DECRYPT:
if(keys->version<6) {
HMAC(EVP_md5(),keys->nl$km,sizeof(keys->nl$km),keys->hmac_message,sizeof(keys->hmac_message),keys->rc4_key,NULL);
RC4_set_key(&rc4_ctx,MD5_DIGEST_LENGTH,keys->rc4_key);
RC4(&rc4_ctx,dataSize,in,out);
}
else {
AES_set_decrypt_key(keys->nl$km,128,&aes_ctx);
AES_cbc_encrypt(in,out,dataSize,&aes_ctx,aes_iv,AES_DECRYPT);
}
break;
}
return 0;
}
Для создания нового хэша пароля: [FYI: это надежно]
HashGen hash(username,password,this->getOSVersion());
Замените хэш старого пароля новым хэшем пароля & зашифруйте их снова:
RtlMoveMemory(decipheredData,hash.getHashDigest(),NTLM_HASH_SIZE);
RtlZeroMemory(cipheredData,cachedAccount->cacheSize);
cryptData(decipheredData,cipheredData,cachedAccount->cacheSize,&keys,ENCRYPT);
RtlMoveMemory(cachedAccount->cache+96,cipheredData,cachedAccount->cacheSize-96);
Запишите их все в реестр обратно: [К сведению: работает нормально, на самом деле я делаю через системную учетную запись]
HKEY hOpenedKey;
DWORD status,nMaxLength;
if( ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,L"security\\cache",0,KEY_WRITE,&hOpenedKey) ) {
int status = RegSetValueEx(hOpenedKey,L"nl$1",0,REG_BINARY,cachedAccount->cache,cachedAccount->cacheSize );
if( status != ERROR_SUCCESS ) {
printf("cache Update failed ...");
RegCloseKey( hOpenedKey );
}
else {
RegCloseKey( hOpenedKey );
printf("cache Updated successfully ...");
}
}
Есть две контрольные суммы одна в unenc разделе и одна на хвосте.
Других решений пока нет …