SQL Server Management Studioのパスワードのエクスポートツール

クリエイティブコモンズライセンス 著作権:帰属、紙ベースを作成するために他人を許可し、(同じライセンスで元のライセンス契約に基づいて用紙配布する必要がありますクリエイティブコモンズ

ここに画像を挿入説明
レジストリおよびファイル:ウィンドウでパスワードを保存すると、2つの場所以外の何ものでもありません。いくつかの条件ブレークポイントの下でwindbgを持つので、オープンクエリアナライザ(バージョンSQL Serverの管理Studio 2005のExpressの):

bp kernel32!CreateFileW ".printf \"file:%mu\\n\",poi(@esp+4);g;"
bp advapi32!RegCreateKeyExW ".printf \"reg key:%mu\\n\",poi(@esp+8);g;"
bp advapi32!RegSetValueExW ".printf \"reg value:%mu\\n\",poi(@esp+8);g;"

実行クエリアナライザは、その後終了し、パスワードを覚えておいてくださいチェック、サーバーにログインします。:windbgの出力は、多くの情報を見ることができます
ここに画像を挿入説明
mru.dat非常に疑わしいが、これらのファイルやレジストリを表示するために、見つかった:
ここに画像を挿入説明
我々が見ることができ、このファイルは、いくつかの容疑者base64では、標準的なファイル.NETバイナリシリアル、次のとおりです。
ここに画像を挿入説明
復号化されました文字化け、窓の大半を考慮して可逆暗号化DPAPIあり、その後、直接DPAPI解読:

Console.WriteLine(Encoding.Unicode.GetString(System.Security.Cryptography.ProtectedData.Unprotect(Convert.FromBase64String("AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA/GdUMC8fOkSbZeHVvNAo5AAAAAAQAAAARABlAGYAYQB1AGwAdAAAABBmAAAAAQAAIAAAABH2ACkH8BeAkWtFpoTTAJkOVsrKIKhgee/heYeTpF7nAAAAAA6AAAAAAgAAIAAAABsgv9bezhjwgM4UJmBEhO3GVZ+1+dNrvNIIsogzsX/qEAAAAM1k6Re4z8UJWAVWT6excM1AAAAAX/lp4sh4tHXD3OZQcV6Rs35q6HQ21zEfpJpGkDyFDQT6fVieZxe1m5oY02sGKne1nvD24RQAtiS8fb467EWMsA=="),null,System.Security.Cryptography.DataProtectionScope.LocalMachine)));

このファイルは、目的のファイルであれば、結果として、それは本当に覚えているパスワードは、基本的に決定することができます。SQL Serverログインサーバ、ユーザ名、パスワードが不可欠であるので、このドキュメントの必要性はさらに彼らの対応を取得することを決議したときからです。それはバイナリシリアライゼーションであるので、次のコードで逆シリアル化することができます。

static object DeserializeFile(string path)
{
  using(MemoryStream mem=new MemoryStream(File.ReadAllBytes(path)))
  {
    mem.Position=0;
    BinaryFormatter bf=new BinaryFormatter();
    return bf.Deserialize(mem);
  }
}

例外をスロー実行した後:

System.Runtime.Serialization.SerializationException: 无法找到程序集“Microsoft.SqlServer.Express.ConnectionDlg, Version=9.0.242.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91”

明らかに、これはインストールディレクトリを表示し、彼女はアセンブリを見て、そのプライベートカスタムアセンブリ、プライベートアセンブリメインプログラムのディレクトリに保存された時間の中で最もシリアライズされたオブジェクト構造です。プライベートアセンブリの多くをロードする可能性の必要性を考慮すると、自動的に不足しているアセンブリの場合の依存関係をロードし、次のコールバックを登録

static Assembly LoadDependsAssemblies(object sender, ResolveEventArgs args)
{
  try
  {
    string dllpath=@"C:\Program Files\Microsoft SQL Server\90\Tools\Binn\VSShell\Common7\IDE\"+new AssemblyName(args.Name).Name+".dll";
    Assembly asm=Assembly.LoadFile(dllpath);
    return asm;
  }catch{Console.WriteLine(args.Name);Environment.Exit(-1);}
  return null;
}

再次进行反序列化,反序列化成功,得到了一个[Microsoft.SqlServer.Express.ConnectionDlg]Microsoft.SqlServer.Management.UI.ConnectionDlg.Personalization类型的实例。
用reflector打开此程序集,可以看到其内部实例字段为两个字典:typeTable和stringTable。
ここに画像を挿入説明
用反射取出这两个字段的值,并依次对其进行遍历,在stringTable中得到了以下结果:

(省略)
[url=mailto:[email protected]][email protected][/url]\SQLEXPRESS@1@sa@Password       :Microsoft.SqlServer.Management.UI.ConnectionDlg.StringList
[url=mailto:[email protected]][email protected][/url]\SQLEXPRESS@1@sa@ET                        :Microsoft.SqlServer.Management.UI.ConnectionDlg.StringList
(省略)

很明显,stringTable的键以@为分隔符保存了数据库名称和用户的信息,最后的ET、Password等则是一个字段名称标记。
以Password结尾的键所对应的值是一个[Microsoft.SqlServer.Express.ConnectionDlg]Microsoft.SqlServer.Management.UI.ConnectionDlg.StringList的实例,这个类型实现了IEnumerable接口,于是可以获取其枚举器并进行遍历:

IEnumerable data=stringTable[k] as IEnumerable;
if(data!=null)
{
  IEnumerator ie=data.GetEnumerator();
  while(ie.MoveNext())
  {
    Console.WriteLine(ie.Current.ToString());
  }
}

最终得到了最开始获取的那段base64,解密后就是原始的密码,结合键名即可获取到完整的登录信息。

从SQL2008开始,其储存方式又有了区别,首先到%appdata%\Microsoft\Microsoft SQL Server目录下查找.net序列化的文件,发现SqlStudio.bin非常可疑:
ここに画像を挿入説明
依前法解密这一长串base64,发现与保存的密码相同,基本可确定此文件就是所需文件。
于是对其进行反序列化,得到了一个[Microsoft.SqlServer.Management.UserSettings]Microsoft.SqlServer.Management.UserSettings.SqlStudio类型的实例。这个类型本身没有实例字段,于是查看其基类[Microsoft.SqlServer.Management.UserSettings]Microsoft.SqlServer.Management.UserSettings.CommonGroupBase,可看到其内部使用了字典_valuestorage保存数据。
ここに画像を挿入説明
对字典进行遍历,发现其键名为SqlStudio类中定义的常量SSMS_PROPERTY_KEY的值SSMS,其键值类型为[Microsoft.SqlServer.Management.UserSettings]Microsoft.SqlServer.Management.UserSettings.SSMS。继续跟踪SSMS类型,发现其同样继承自CommonGroupBase,并且定义了非常多的常量键值名称,于是可断定,这个序列化文件中保存了一个巨大的目录树。
对这个目录树逐级进行跟踪:在SSMS类中ConnectionOptions键下面保存了ConnectionOptions类型的值;ConnectionOptions类中ServerTypes键下面保存了一个字典,字典的值为ServerTypeItem类型;ServerTypeItem类中Servers键下面保存了一个列表,列表的值是ServerConnectionItem类型;ServerConnectionItem中Instance键保存了一个字符串,其值为服务器名;Connections键保存了一个列表,列表的值是ServerConnectionSettings类型;ServerConnectionSettings中UserName和Password保存了两个字符串,这就是最终要获取的信息。以上结果以树状图表示大致如下:

SqlStudio
└─SSMS
    └─ConnectionOptions
        ├─ServerTypes-1
        │  ├─Servers-1
        │  │  │  Instance
        │  │  │
        │  │  ├─Connections-1
        │  │  │      Password
        │  │  │      UserName
        │  │  │
        │  │  └─Connections-2
        │  │          Password
        │  │          UserName
        │  │
        │  └─Servers-2
        │      │  Instance
        │      │
        │      └─Connections-1
        │              Password
        │              UserName
        │
        └─ServerTypes-2
            ├─Servers-1
            │  │  Instance
            │  │
            │  ├─Connections-1
            │  │      Password
            │  │      UserName
            │  │
            │  └─Connections-2
            │          Password
            │          UserName
            │
            └─Servers-2
                │  Instance
                │
                └─Connections-1
                        Password
                        UserName

知道了保存方式,接下来只要遍历就能取到结果了。需要注意的是由于其列表和字典都是其自定义类,要用其实现的接口IDictionary和IEnumerable进行操作,其伪代码大致为:

foreach ServerType in SqlStudio['SSMS']['ConnectionOptions']['ServerTypes']
{
  foreach Server in ServerType['Servers']
  {
    print Server.Instance
    foreach Connection in Server['Connections']
    {
      print Connection.UserName,Connection.Password
    }
  }
}

更高版本的序列化文件结构与SSMS2008并无任何区别,但由于其依赖版本改为了.net 4.0,所以必须要用.net4.0编译才能成功反序列化。

附件中SSMSPwd-20.exe与SSMSPwd-40.exe为编译好的程序,分别用.net 2.0和.net 4.0编译,使用方法如下:

#显示所有保存了密码的登录信息
SSMSPwd.exe
#显示所有保存信息,无论是否保存了密码
SSMSPwd.exe -a
#解密指定的文件
SSMSPwd.exe -f c:\SqlStudio.bin -p "c:\Program Files\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\"

SSMSPwd.cs为工具源码,编译命令行:

csc SSMSPwd.cs

注意版本高于2008的SSMS必须使用.net 4.0提供的csc进行编译;此工具在SSMS2005/SSMSES2005/SSMS2008/SSMS2008R2/SSMS2012/SSMS2014上测试成功。

已知错误信息:

Password: (dec err : 该项不适于在指定状态下使用。)

ユーザーが一致していない、あなたが指定したユーザーに切り替える必要があり、このプログラム(runasコマンド、またはキャッチプレーンテキストの後に黒の科学技術他)を実行します。

おすすめ

転載: blog.csdn.net/kclax/article/details/92390262