1

我得到了一个相当古老的桌面应用程序,它可能是用 Delphi C++ Builder 编写的,带有一个嵌入式 AbsoluteDB。

我需要使用 Swing 或 Flex/Air 创建一个新版本,但在此之前我需要检查数据库的确切架构。

不幸的是,数据库受密码保护。编写这个应用程序的程序员很久以前就离开了公司。

有没有办法恢复这个密码?

4

1 回答 1

4

天真的蛮力攻击

使用股票TABSDatabase尝试蛮力攻击是没有意义的,因为:

  • 内部哈希方法和加密方法使用唯一的缓冲区作为输入和输出(作为参考传递)。每次迭代都需要处理相同的输入内容(为了节省 CPU 时间,无需缓存以供重用)。
  • 每个虚假密码都会引发异常,SEH 会增加另一个惩罚层(时间复杂度)。
  • 我怀疑其他设计特性(针对暴力攻击的对策)。

摆脱所有多余的负担

在我的尝试中,我想出了这个工作的裸 Delphi 类:

type
  TABSDBHack = class
  private
    FFilename: TFileName;

    // 2 relevant contiguous headers of an Absolute Database file
    FDBHeader: array [0..SIZEOFDBHEADER-1];
    FCryptoHeader: array [0..SIZEOFCRYPTOHEADER-1];

    // Mirror of the ControlBlock record from CryptoHeader
    FControlBlock: array [0..SIZEOFCONTROLBLOCK-1] of Byte; 
    //
    function GetEncrypted: Boolean;
    function GetFileName: TFileName;
    function GetPageSize: Word;
    function GetPageCountInExtent: Word;
    function GetCryptoAlgorithm: Byte;
  protected
    // Retrieving Data from stream into FDBHeader and FCryptoHeader
    procedure ReadStream(F: TStream);

    // Mainly FillChar(..., ...,#0) of the corresponding record
    procedure ClearDBHeader;
    procedure ClearCryptoHeader;
    procedure ClearControlBlock;

    // Probe the existence of 'ABS0LUTEDATABASE' as file signature
    function CheckABSSignature: Boolean;

    // Compute the CRC of FControlBlock record
    function CRC32: Cardinal;

    // Decrypt the persisted Control Block into FControlBlock
    function InternalDecryptBuffer(const APassword: string):Boolean;
  public
    procedure Clear;

    // Wrapping a ReadStream using a local TFileStream
    procedure LoadFromFile(Filename: TFileName);

    // Return True if the decrypted Control Block correspond to original plain one.
    // Otherwise stated: The persisted CRC (in the Crypto Header) is equal to 
    // the value returned by the function CRC32
    function CheckPassword(const APassword: string): Boolean;

    property FileName: TFileName read GetFileName;

    // Sample of plain Data peristed that can be retrieved
    property PageSize: Word read GetPageSize;
    property PageCountInExtent: Word read GetPageCountInExtent;
    property Encrypted: Boolean read GetEncrypted;
    property CryptoAlgorithm: Byte read GetCryptoAlgorithm;
  end;

我直接从文件中检索相关数据并探测给定的密码。

免责声明

我使用了绝对数据库版本 6.0.7 的个人版来开发它。

类定义已清除对分布式 DCU 中任何类型定义的任何引用,我无权基于它分发二进制文件。

据了解,它在很大程度上取决于 DCU 的分布,主要用于散列和解密方法。随着时间和对 Absolute Database 内部的更多了解,编写其加密引擎的洁净室实现应该是可行的:它似乎基于Hagen Reddmann 的免费软件Delphi Encryption Compendium 。


其他探索方向

  • 强制恢复普通控制块可以认为是 SIZEOFCONTROLBLOCK 仅等于 256。
  • 给定一对普通/加密的控制块,可以使用暴力恢复密钥的内部表示,但请注意:例如 AES/Rijndael 的 128/192/256!
  • RipeMD(128 和 256),一个众所周知的单向函数,在内部用于初始化 Key:恐怕在给定哈希值的情况下恢复字符串是不合理的!
  • 大多数加密算法(至少是最近的)在被采用为标准之前在公众监督下经过了彻底的测试:简单地说,它们很强大,我的意思是非常强大。

结论

是的!在某些规定下可以恢复密码。

在玩 TABSDBHack 时,成功的关键是找到一种减少搜索空间的方法(密码是字符串类型):这很容易,特别是对于密码。我强调,它有效。

来自 Component Ace 的人很聪明,他们的工作做得很好(设计密码系统等):您可以依赖 Absolute Database,我强烈推荐它。

于 2012-04-05T14:17:23.473 回答