SQL SERVERデータベースのパスワードの脆弱性について話します。
SQLを追跡しました SERVERデータベースサーバの登録過程で、パスワード計算が非常に脆弱であることが分かりました。SQL SERVERデータベースのパスワードは脆弱であるという二つの側面を表しています。
1です。ネットワークログイン時のパスワード暗号化アルゴリズム
2です。データベースに格納されているパスワード暗号化アルゴリズム。
それぞれについて説明します。
1です。ネットワークログイン時のパスワード暗号化アルゴリズム
SQL SERVERネットワークの暗号化のパスワードはずっととてももろくて、ネット上で多く書いた対照表があって、しかしすべて具体的な計算方法の処理がなくて、実際にSQLを追跡します。
SERVERのログインプロセスは、その解読のアルゴリズムを簡単に入手できます。はい、やはりアセンブルプロセスを実証します。
登録タイプのTDSパケットは4126 a 4にジャンプして実行します。
004 DE 72 E:受信したサイズフィールドから対応するサイズのバッファを生成し、次のステップのコピーを行う。
004 DE 748受信したTDSから BUFオフセット8箇所でLOGINの情報をコピーします。
004 DE 762:コール sub_54 E 4 D 0:新規コピーのバッファを入れてパラメータチェックを行う処理
TDSパケットの中の情報を順次処理して、フィールドの気候はそれぞれのドメインの長さがあるべきで、オフセット0 X 24は長さと比較します。
以下のこのアセンブリコードは、ネットワーク暗号解読のアルゴリズムです。
.text:0065 C 880 mov cl [edi)
.text:0065 C 882 mov dl cl。
.text:0065 C 884 X or cl 5
.text:0065 C 887 X or dl 0 AFh
.text:0065 C 88 A shr dl 4
.text:0065 C 88 D shl cl 4
.text:0065 C 890 or dl cl。
.text:0065 C 892 mov [edi) dl.
.text:0065 C 894 inc edi
.text:0065 C 895 dec eax
.text:0065 C 896 jnz ショート?ト loc_65 C 880
.text:0065 C 898 jmp loc_4 DE 7 E 6
簡単にCコードに変えられます。暗号化は簡単で、明文と区別がありません。ほほほ、SNIFERにこのコードを埋め込んで、嗅ぎ嘆きのTDS登録パッケージを解読します。実は0 XA 5は特定のSQLではありません。 SERVERパスワードフィールドの境界記号は、暗号化アルゴリズムによってASCの二重バイト表現の0 x 0を自動的に0 x 5に暗号化するだけであるが、二重バイトパスワードを許可すると、これはその境界を判断する主要な原因ではない。
void sql passwd(char) * enp、char* dnp)
{
要点 i;
unsigned char a 1;
unsigned char a 2;
for(i=0;i<128;i++)
{
if(enp[i]==0)
break;
a 1 = enp[i]^5;
a 1 = a 1 << 4;
a 2 = enp[i]^0 xaf
a 2 = a 2 >> 4;
dnp[i]=a 1|a 2;
}
dnp[i]=0
dnp[i+1]=0
wprintf(L「passwd:%s」、(const) wchar_t *)dnp);
)
2です。データベースに格納されているパスワード暗号化アルゴリズム。
SQL SERVERのパスワードをデータベースに格納する暗号化方法も、不思議なものです。その過程は以下の通りです
ネットワーク暗号解読のパスワードを取得した後、
005 F 9 D 5 Aのところにコールします SQLSORT_14,大文字パスワードバッファに変換して保存することを実現します。
004 def 6 dで関数を呼び出して、データベース内の暗号化されたPASSWORDを取り出す。その形式は以下の通りである。
2バイトのヘッダ0 x 0100(固定)
4バイトのHASHと秘KEY
20バイトのHASH 1
20バイトのHASH 2
私が取り出した例のように:
fx:0 x 0100 1751857 F DFDEC 4 FB 618 D 8 E BA 5 A 27 F 615639 F 607 CD 46 BE DFDEC 4 FB 618 D 8 E BA 5 A 27 F 615639 F 607 CD 46 BE
固定 KEYを補充する HASH 1 HASH 2
パスワードは:123456です
SQLはまず4バイトのHASHと秘密KEYで二つのパスワードのバッファを補います。一つは大文字で、一つは小文字です。その後、暗号化プロセスは以下のC関数のようになります。
Crypt Acquire ContactextW(&hProv,NULL,L(Microsoft) ベース Cryptgraphic プロバイダー v 1.0"),1,0 xf 0000);
CryptCreateHash(hProv、0 x 8004、NULL、NULL、&hhash);
CryptCreateHash(hProv、0 x 8004、NULL、NULL、&hHash);
005 F 9 DFE:
Crypt HashData(hhash、passwdbuf、0 x 12、NULL);passwdbufは小文字のpasswdバッファです。そしてKEYを追加します。上記の例は正しいです。
{1,23456,0 x 17,0 x 51,0 x 85,0 x 7 Fという文字列がHASH暗号化されています。
Crypt HashData(hHash、PASSWD BUF、0 x 12、NULL);PASSWD BUFは大文字のpasswdバッファです。そしてKEYを追加します。
005 F 9 E 3 E:
Crypt GetHash Param(hhash,2,&passwdout,&outlen,0);passwdbufを取り出したのは、小文字のpasswdの暗号化値です。
Crypt GetHash Param(hHash,2,&PASSWD OUT,&OUTEN,0);passwdbufを取り出すのは大文字のpasswdの暗号化値です。
この二つの加算は本当のデータベースの中のPASSWORD暗号化フィールドです。
なぜ上記の方法は弱いですか?実際の暗号化長は20バイトしか生成されていません。
パスワードを小文字で書くHASH 1+大文字パスワードのHASH 1をつなぎ合わせた40名のHASH値の安全度は、直接20位のHASH値よりも安全です。この二つの値の因果関係をみんなが知っているからです。
復号者により多くの情報を提供します。
そのアルゴリズムのように、HASH 1=HASH 2であれば、パスワードはアルファベットではなく、数字と記号のパスワードだけを使っています。上記のように取り出された123456パスワードのHASHは、2つのHASHは完全に同じです。
アルファベットを使っています。補充されたKEY、アルゴリズム、二つの暗号化された文字列の関係を知っています。その解も大いに簡略化されたはずです。
もちろん暗号化アルゴリズムを研究したことがありませんが、このような暗号化方式は本当に安全ではないと感じています。
1です。ネットワークログイン時のパスワード暗号化アルゴリズム
2です。データベースに格納されているパスワード暗号化アルゴリズム。
それぞれについて説明します。
1です。ネットワークログイン時のパスワード暗号化アルゴリズム
SQL SERVERネットワークの暗号化のパスワードはずっととてももろくて、ネット上で多く書いた対照表があって、しかしすべて具体的な計算方法の処理がなくて、実際にSQLを追跡します。
SERVERのログインプロセスは、その解読のアルゴリズムを簡単に入手できます。はい、やはりアセンブルプロセスを実証します。
登録タイプのTDSパケットは4126 a 4にジャンプして実行します。
004 DE 72 E:受信したサイズフィールドから対応するサイズのバッファを生成し、次のステップのコピーを行う。
004 DE 748受信したTDSから BUFオフセット8箇所でLOGINの情報をコピーします。
004 DE 762:コール sub_54 E 4 D 0:新規コピーのバッファを入れてパラメータチェックを行う処理
TDSパケットの中の情報を順次処理して、フィールドの気候はそれぞれのドメインの長さがあるべきで、オフセット0 X 24は長さと比較します。
以下のこのアセンブリコードは、ネットワーク暗号解読のアルゴリズムです。
.text:0065 C 880 mov cl [edi)
.text:0065 C 882 mov dl cl。
.text:0065 C 884 X or cl 5
.text:0065 C 887 X or dl 0 AFh
.text:0065 C 88 A shr dl 4
.text:0065 C 88 D shl cl 4
.text:0065 C 890 or dl cl。
.text:0065 C 892 mov [edi) dl.
.text:0065 C 894 inc edi
.text:0065 C 895 dec eax
.text:0065 C 896 jnz ショート?ト loc_65 C 880
.text:0065 C 898 jmp loc_4 DE 7 E 6
簡単にCコードに変えられます。暗号化は簡単で、明文と区別がありません。ほほほ、SNIFERにこのコードを埋め込んで、嗅ぎ嘆きのTDS登録パッケージを解読します。実は0 XA 5は特定のSQLではありません。 SERVERパスワードフィールドの境界記号は、暗号化アルゴリズムによってASCの二重バイト表現の0 x 0を自動的に0 x 5に暗号化するだけであるが、二重バイトパスワードを許可すると、これはその境界を判断する主要な原因ではない。
void sql passwd(char) * enp、char* dnp)
{
要点 i;
unsigned char a 1;
unsigned char a 2;
for(i=0;i<128;i++)
{
if(enp[i]==0)
break;
a 1 = enp[i]^5;
a 1 = a 1 << 4;
a 2 = enp[i]^0 xaf
a 2 = a 2 >> 4;
dnp[i]=a 1|a 2;
}
dnp[i]=0
dnp[i+1]=0
wprintf(L「passwd:%s」、(const) wchar_t *)dnp);
)
2です。データベースに格納されているパスワード暗号化アルゴリズム。
SQL SERVERのパスワードをデータベースに格納する暗号化方法も、不思議なものです。その過程は以下の通りです
ネットワーク暗号解読のパスワードを取得した後、
005 F 9 D 5 Aのところにコールします SQLSORT_14,大文字パスワードバッファに変換して保存することを実現します。
004 def 6 dで関数を呼び出して、データベース内の暗号化されたPASSWORDを取り出す。その形式は以下の通りである。
2バイトのヘッダ0 x 0100(固定)
4バイトのHASHと秘KEY
20バイトのHASH 1
20バイトのHASH 2
私が取り出した例のように:
fx:0 x 0100 1751857 F DFDEC 4 FB 618 D 8 E BA 5 A 27 F 615639 F 607 CD 46 BE DFDEC 4 FB 618 D 8 E BA 5 A 27 F 615639 F 607 CD 46 BE
固定 KEYを補充する HASH 1 HASH 2
パスワードは:123456です
SQLはまず4バイトのHASHと秘密KEYで二つのパスワードのバッファを補います。一つは大文字で、一つは小文字です。その後、暗号化プロセスは以下のC関数のようになります。
Crypt Acquire ContactextW(&hProv,NULL,L(Microsoft) ベース Cryptgraphic プロバイダー v 1.0"),1,0 xf 0000);
CryptCreateHash(hProv、0 x 8004、NULL、NULL、&hhash);
CryptCreateHash(hProv、0 x 8004、NULL、NULL、&hHash);
005 F 9 DFE:
Crypt HashData(hhash、passwdbuf、0 x 12、NULL);passwdbufは小文字のpasswdバッファです。そしてKEYを追加します。上記の例は正しいです。
{1,23456,0 x 17,0 x 51,0 x 85,0 x 7 Fという文字列がHASH暗号化されています。
Crypt HashData(hHash、PASSWD BUF、0 x 12、NULL);PASSWD BUFは大文字のpasswdバッファです。そしてKEYを追加します。
005 F 9 E 3 E:
Crypt GetHash Param(hhash,2,&passwdout,&outlen,0);passwdbufを取り出したのは、小文字のpasswdの暗号化値です。
Crypt GetHash Param(hHash,2,&PASSWD OUT,&OUTEN,0);passwdbufを取り出すのは大文字のpasswdの暗号化値です。
この二つの加算は本当のデータベースの中のPASSWORD暗号化フィールドです。
なぜ上記の方法は弱いですか?実際の暗号化長は20バイトしか生成されていません。
パスワードを小文字で書くHASH 1+大文字パスワードのHASH 1をつなぎ合わせた40名のHASH値の安全度は、直接20位のHASH値よりも安全です。この二つの値の因果関係をみんなが知っているからです。
復号者により多くの情報を提供します。
そのアルゴリズムのように、HASH 1=HASH 2であれば、パスワードはアルファベットではなく、数字と記号のパスワードだけを使っています。上記のように取り出された123456パスワードのHASHは、2つのHASHは完全に同じです。
アルファベットを使っています。補充されたKEY、アルゴリズム、二つの暗号化された文字列の関係を知っています。その解も大いに簡略化されたはずです。
もちろん暗号化アルゴリズムを研究したことがありませんが、このような暗号化方式は本当に安全ではないと感じています。