起因:

在做题过程中,遇到该题:

23.计算机中存在数据库管理工具,该工具连接使用的数据库密码是?

过程

  1. 通过仿真和取证大师并未发现系统含有数据库密码的明文线索,但是通过打开Navicat,发现该工具保存了数据库的连接信息。
  2. 由于镜像不包含服务器端,所以无法通过破解工具破解密码。
  3. 尝试使用搜索关键词,发现有很多文章介绍如何破解Navicat保存的密码。
  4. 实施尝试

步骤

  1. 打开Navicat,选择文件->导出连接,选择需要破解的数据库连接(记得勾选导出密码)。
    导出连接
  2. 导出连接信息,并保存到本地。
  3. 打开C:\Users\Administrator\Desktop\connections.ncx文件。复制password字段中的内容。
  4. 运行php脚本,将倒数第二行字段替换为你自己的值,即可将密码转换为明文。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    <?php

    namespace FatSmallTools;

    class NavicatPassword
    {
    protected $version = 0;
    protected $aesKey = 'libcckeylibcckey';
    protected $aesIv = 'libcciv libcciv ';
    protected $blowString = '3DC5CA39';
    protected $blowKey = null;
    protected $blowIv = null;

    public function __construct($version = 12)
    {
    $this->version = $version;
    $this->blowKey = sha1('3DC5CA39', true);
    $this->blowIv = hex2bin('d9c7c3c8870d64bd');
    }

    public function encrypt($string)
    {
    $result = FALSE;
    switch ($this->version) {
    case 11:
    $result = $this->encryptEleven($string);
    break;
    case 12:
    $result = $this->encryptTwelve($string);
    break;
    default:
    break;
    }

    return $result;
    }

    protected function encryptEleven($string)
    {
    $round = intval(floor(strlen($string) / 8));
    $leftLength = strlen($string) % 8;
    $result = '';
    $currentVector = $this->blowIv;

    for ($i = 0; $i < $round; $i++) {
    $temp = $this->encryptBlock($this->xorBytes(substr($string, 8 * $i, 8), $currentVector));
    $currentVector = $this->xorBytes($currentVector, $temp);
    $result .= $temp;
    }

    if ($leftLength) {
    $currentVector = $this->encryptBlock($currentVector);
    $result .= $this->xorBytes(substr($string, 8 * $i, $leftLength), $currentVector);
    }

    return strtoupper(bin2hex($result));
    }

    protected function encryptBlock($block)
    {
    return openssl_encrypt($block, 'BF-ECB', $this->blowKey, OPENSSL_RAW_DATA|OPENSSL_NO_PADDING);
    }

    protected function decryptBlock($block)
    {
    return openssl_decrypt($block, 'BF-ECB', $this->blowKey, OPENSSL_RAW_DATA|OPENSSL_NO_PADDING);
    }

    protected function xorBytes($str1, $str2)
    {
    $result = '';
    for ($i = 0; $i < strlen($str1); $i++) {
    $result .= chr(ord($str1[$i]) ^ ord($str2[$i]));
    }

    return $result;
    }

    protected function encryptTwelve($string)
    {
    $result = openssl_encrypt($string, 'AES-128-CBC', $this->aesKey, OPENSSL_RAW_DATA, $this->aesIv);
    return strtoupper(bin2hex($result));
    }

    public function decrypt($string)
    {
    $result = FALSE;
    switch ($this->version) {
    case 11:
    $result = $this->decryptEleven($string);
    break;
    case 12:
    $result = $this->decryptTwelve($string);
    break;
    default:
    break;
    }

    return $result;
    }

    protected function decryptEleven($upperString)
    {
    $string = hex2bin(strtolower($upperString));

    $round = intval(floor(strlen($string) / 8));
    $leftLength = strlen($string) % 8;
    $result = '';
    $currentVector = $this->blowIv;

    for ($i = 0; $i < $round; $i++) {
    $encryptedBlock = substr($string, 8 * $i, 8);
    $temp = $this->xorBytes($this->decryptBlock($encryptedBlock), $currentVector);
    $currentVector = $this->xorBytes($currentVector, $encryptedBlock);
    $result .= $temp;
    }

    if ($leftLength) {
    $currentVector = $this->encryptBlock($currentVector);
    $result .= $this->xorBytes(substr($string, 8 * $i, $leftLength), $currentVector);
    }

    return $result;
    }

    protected function decryptTwelve($upperString)
    {
    $string = hex2bin(strtolower($upperString));
    return openssl_decrypt($string, 'AES-128-CBC', $this->aesKey, OPENSSL_RAW_DATA, $this->aesIv);
    }
    }


    use FatSmallTools\NavicatPassword;

    //需要指定版本,11或12
    $navicatPassword = new NavicatPassword(12);
    //$navicatPassword = new NavicatPassword(11);

    //解密
    //$decode = $navicatPassword->decrypt('15057D7BA390');
    $decode = $navicatPassword->decrypt('你的密码');
    echo $decode."\n";

参考:

  1. 在线运行php工具:https://tool.lu/coderunner/
  2. 项目地址:https://github.com/tianhe1986/FatSmallTools
  3. JAVA版本:https://github.com/Zhuoyuan1/navicat_password_decrypt