0x00 背景
在攻防演练或红队评估项目中,项目成果往往依赖红队队员综合渗透技能和优良的自动化工具。信息收集贯穿整个项目生命周期,如果攻方通过获取互联网侧应用服务器权限,并以此为跳板突破目标单位互联网侧防线,进而对应用服务器数据库进行信息收集的意义非常重大。攻方可从数据库管理程序中获取数据库系统访问IP地址、用户名、口令等敏感信息,对以上信息进行分析,可大大提高渗透效率。
0x01 Navicat 数据库凭据获取
Navicat是一套快速、可靠并价格相当便宜的数据库管理工具,可以管理到MySQL、Oracle、PostgreSQL、SQLite 及 SQL Server等数据库,专为简化数据库的管理及降低系统管理成本而设。它的设计符合数据库管理员、开发人员及中小企业的需要。Navicat 是以直觉化的图形用户界面而建的,让你可以以安全并且简单的方式创建、组织、访问并共用信息。
Navicat 凭据存储位置
安装Navicat Premium(版本 11.2.7),创建一个MySQL数据库连接,用户名:root 口令:admin123!@#。同时利用RegFromApp监控navicat.exe进程对注册表的更改,结果如下图所示:
通过对RegFromApp监控结果进行分析可以观察数据库IP地址、端口、数据库用户名和数据库口令等存储信息。Navicat MySQL数据库连接凭据存储位置如下:
# 计算机\HKEY_CURRENT_USER\Software\PremiumSoft\Navicat\Servers\Info-01
进而通过Navicat 程序创建不同数据库连接,同时观察注册表变化可得出不同数据库连接用户名口令在注册表中的存储位置,如下表所示:
数据库类型 | 注册表中存储位置 |
MySQL | [HKEY_CURRENT_USER\Software\PremiumSoft\Navicat\Servers\`连接名`] |
PostgreSQL | [HKEY_CURRENT_USER\Software\PremiumSoft\NavicatPG\Servers\`连接名`] |
Oracle | [HKEY_CURRENT_USER\Software\PremiumSoft\NavicatOra\Servers\`连接名`] |
SQLite | [HKEY_CURRENT_USER\Software\PremiumSoft\NavicatSQLite\Servers\`连接名`] |
SQL Server | [HKEY_CURRENT_USER\Software\PremiumSoft\NavicatMSSQL\Servers\`连接名`] |
MariaDB | [HKEY_CURRENT_USER\Software\PremiumSoft\NavicatMARIADB\Servers\`连接名`] |
Navicat 口令加密原理
Navicat 对明文密码进行加密运算时需用到固定加密秘钥(3DC5CA39),假设明文口令是"admin123!@#",首先程序会使用SHA-1散列算法将固定加密秘密进行处理得到:
# 3DC5CA39 -> SHA-1 = 42CEB271A5E458B74AEA93947922354391873340
将其存入数组中,如下所示:
unsigned char Key[20] = { 0x42, 0xCE, 0xB2, 0x71, 0xA5, 0xE4, 0x58, 0xB7,0x4A, 0xEA, 0x93, 0x94, 0x79, 0x22, 0x35, 0x43, 0x91, 0x87, 0x33, 0x40 };
使用0xFF填充一个8字节长的数据块,然后使用Blowfish算法加密以上数据块,得到结果如下:
# 42CEB271A5E458B74AEA93947922354391873340 ->Blowfish = D9C7C3C8870D64BD
unsigned char IV[8] = { 0xD9, 0xC7, 0xC3, 0xC8, 0x87, 0x0D, 0x64, 0xBD };
随后Navicat 程序将输入的明文密码前八位取出,进行如下运算:
# "admin123!@#" -> 取出前八位 = "admin123"
# "admin123" XOR "D9C7C3C8870D64BD" -> "B8A3AEA1E93C568E"
# "B8A3AEA1E93C568E" -> Blowfish encrypt_block = "7EAA549760822DA9"
然后对剩下字符进行重复运算,过程如下:
# "D9C7C3C8870D64BD" XOR "7EAA549760822DA9" -> "A76D975FE78F4914"
# "A76D975FE78F4914" -> Blowfish encrypt_block = "9CA9FBA9AF4C12E3"
# "admin123!@#" -> 取出后三位 = "!@#"
# "!@#" XOR "9CA9FBA9AF4C12E3" -> "BDE9D8"
将得出的密文进行拼接,结果如下:
# "admin123" -> "7EAA549760822DA9"
# "!@#" -> "BDE9D8"
# "admin123!@#" -> "7EAA549760822DA9BDE9D8"
Navicat 密文解密原理
假设密文口令是"7EAA549760822DA9BDE9D8",固定密钥为3DC5CA39,首先程序会使用SHA-1散列算法将固定加密秘密进行处理得到:
# 3DC5CA39 -> SHA-1 = 42CEB271A5E458B74AEA93947922354391873340
将其存入数组中,如下所示:
unsigned char Key[20] = { 0x42, 0xCE, 0xB2, 0x71, 0xA5, 0xE4, 0x58, 0xB7,0x4A, 0xEA, 0x93, 0x94, 0x79, 0x22, 0x35, 0x43, 0x91, 0x87, 0x33, 0x40 };
使用0xFF填充一个8字节长的数据块,然后使用Blowfish算法加密以上数据块,得到结果如下:
# 42CEB271A5E458B74AEA93947922354391873340 ->Blowfish = D9C7C3C8870D64BD
unsigned char IV[8] = { 0xD9, 0xC7, 0xC3, 0xC8, 0x87, 0x0D, 0x64, 0xBD };
随后Navicat 程序将输入的密文密码前十六个字符,进行如下运算:
# "7EAA549760822DA9BDE9D8" -> 取出前十六个字符 = "7EAA549760822DA9"
# "7EAA549760822DA9" -> Blowfish decrypt_block = "B8A3AEA1E93C568E"
# "B8A3AEA1E93C568E" XOR "D9C7C3C8870D64BD" -> = "61646D696E313233"
# "7EAA549760822DA9" -> "admin123"
最后将剩余的六个字符进行运算,过程如下:
# "D9C7C3C8870D64BD" XOR "7EAA549760822DA9" -> = "A76D975FE78F4914"
# "A76D975FE78F4914" -> Blowfish encrypt_block = "9CA9FBA9AF4C12E3"
# "BDE9D8" XOR "9CA9FBA9AF4C12E3" -> = "!@#"
最终解密结果如下:
# "7EAA549760822DA9" -> "admin123"
# "BDE9D8" -> "!@#"
# "7EAA549760822DA9BDE9D8" - > "admin123!@#"
测试环境演示
渗透测试过程中在内网中获取服务器权限后会对该服务器进行信息收集,如果该服务器安装Navicat程序可利用以上方法获取注册表中保存的数据库连接信息,渗透测试工程师获取该连接信息后可对数据库进行敏感信息收集进而推进测试进度。
测试环境
服务器:Linux 、Windows Server
数据库:MySQL、Microsoft SQL Server、Oracle
测试工具:DatabaseShow.exe
# DatabaseShow在已公开的工具基础上添加测试连接可用性功能,获取到数据库连接信息后对判断其是否可用并返回相应数据库版本权限等信息。如果可用返回的Status字段包含数据库版本信息,如果不可用返回Status为False。
0x02 常见JAVA框架数据库用户名口令获取
Tomcat
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器。一般数据库配置信息位于main/webapp/META-INF/context.xml文件中,不推荐在server.xml中进行配置,而是在context.xml中进行独立的配置。因为 server.xml 是不可动态重加载的资源,服务器一旦启动了以后,要修改这个文件,就得重启服务器才能重新加载。而 context.xml 文件则不然, tomcat 服务器会定时去扫描这个文件。一旦发现文件被修改(时间戳改变了),就会自动重新加载这个文件,而不需要重启服务器 。
# MySQL
username="root"
password="password"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://192.168.3.133:3306/preg-1.5.4?autoReconnect=true"
# SQL Server
username="sa"
password="password"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://192.168.3.133:1433;DatabaseName=APP"
# Oracle
username="username"
password="password"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@192.168.3.133:1521:APP"
# PostgreSQL
username="username"
password="password"
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://192.138.3.133:5432/mydb"
0x03 常见PHP框架数据库用户名口令获取
ThinkPHP
ThinkPHP是开源,免费,快捷简单的面向对象轻量级的开发PHP框架,ThinkPHP 3.2 框架中数据库配置文件位于Application/Home/Conf/config.php,如下所示:
# 数据库配置
'DB_TYPE' => 'mysql', // 数据库类型 目前的数据库包括Mysql、SqlServer、PgSQL、Sqlite、Oracle、Ibase、Mongo,PDO
'DB_HOST' => '192.168.3.133', // 服务器地址
'DB_NAME' => 'thinkphp', // 数据库名
'DB_USER' => 'root', // 用户名
'DB_PWD' => 'password', // 密码
'DB_PORT' => 3306, // 端口
'DB_PREFIX' => 'think_', // 数据库表前缀
'DB_CHARSET'=> 'utf8', // 字符集
'DB_DEBUG' => TRUE, // 数据库调试模式 开启后可以记录SQL日志 3.2.3新增
Codeigniter
CodeIgniter有一个配置文件用来保存数据库配置(用户名、密码、数据库名等),这个配置文件位于 application/config/database.php。配置存放在一个多维数组里,原型如下:
# MySQL
$db['db']['hostname'] = '192.168.3.133';
$db['db']['port'] = '3306';
$db['db']['username'] = 'username';
$db['db']['password'] = 'password';
$db['db']['database'] = 'app';
$db['db']['dbdriver'] = 'mysqli';
# SQLite
$db['db']['hostname'] = '192.168.3.133';
$db['db']['username'] = 'username';
$db['db']['password'] = 'password';
$db['db']['database'] = './application/database/geonamesSQLite.db';
$db['db']['dbdriver'] = 'SQLite3';
# PostgreSQL
$db['postgre']['hostname'] = '192.168.3.133';
$db['postgre']['port'] = '5432';
$db['postgre']['username'] = 'postgres';
$db['postgre']['password'] = 'password!';
$db['postgre']['database'] = 'app';
$db['postgre']['dbdriver'] = 'postgre';
# Oracle
$tnsname = '(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = ORAAS005)(PORT = 1521))(ADDRESS = (PROTOCOL = TCP)(HOST = ORAAS024)(PORT = 1521))(LOAD_BALANCE= yes ))(CONNECT_DATA =(SERVICE_NAME = davoprd)(SERVER = DEDICATED)(FAILOVER_MODE = (TYPE = SELECT) (METHOD = BASIC) (RETRIES = 180) (DELAY = 5))))';
$db['oracle']['hostname'] = $tnsname;
$db['oracle']['username'] = 'username';
$db['oracle']['password'] = 'PassWord!';
$db['oracle']['database'] = '';
$db['oracle']['dbdriver'] = 'oci8';
Laravel
Laravel 能使用原生 SQL、流畅的查询构造器和Eloquent ORM在各种数据库后台与数据库进行非常简单的交互。当前 Laravel 支持四种数库:MySQL、PostgreSQL、SQLite、SQL Server。数据库的配置文件放置在config/database.php 文件中。
# SQLite 'sqlite' => [ 'driver' => 'sqlite', 'database' => env('DB_DATABASE', database_path('database.sqlite')), 'prefix' => '', ]
# MySQL
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '192.168.3.133'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'root'),
'username' => env('DB_USERNAME', 'password'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
]
# SQL Server
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST', '192.168.3.133'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'sa'),
'username' => env('DB_USERNAME', 'password'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
]
# PostgreSQL
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', '192.168.3.133'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'admin'),
'username' => env('DB_USERNAME', 'password'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
'sslmode' => 'prefer',
]
参考文章
https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password
https://www.anquanke.com/post/id/193511
http://codeigniter.org.cn/user_guide/database/configuration.html