提醒:本页面将不再更新、维护或者支持,文章、评论所叙述内容存在时效性,涉及技术细节或者软件使用方面不保证能够完全有效可操作,请谨慎参考!

今天客户要求维护某信息管理系统的数据,该软件缺少相应功能,所以需要直接进入数据库系统,然后使用SQL语句进行维护。

但是该软件默认未提供连接数据库的用户名、密码和数据库名称,翻了下程序目录下的配置文件,找到了登录用户名sa以及数据库名称,但是密码却是一串奇怪的字符,看情况是被加密过了,现在要获取这个密码。

我分别尝试了好几种办法,比如使用sniffer嗅探软件,探测发送到数据库的数据包,使用编程的方式建立个假的数据库服务陷阱,但均告失败。sniffer只能探测经过网卡的数据,对于localhost本地流量一点反应都没有,至于服务陷阱,我使用Python简单写了个接收端口数据并输出的程序作为陷阱:

import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 8000)) # 端口为8000
sock.listen(5)

while True:
    conn,addr = sock.accept()
    try:
        conn.settimeout(5)
        buf = conn.recv(1024)
        print(buf)
    except socket.timeout:
        print('Time out')
    conn.close()

然后我停止了数据库服务,然后用这个程序伪造了个数据库服务(监听端口相同),然后用该信息系统软件客户端程序连接,结果用户名和数据库名都搞到了,偏偏密码没有,愁人了。

在我尝试其他办法的时候注意到该软件有个备份机制,备份时弹出一个命令提示符,提示是数据库软件目录下的 dump.exe 实用工具,也就是说这个软件要调用 dump.exe 才能备份数据库,当然这个 dump.exe 是个命令提示符工具,要调用它必须提供调用参数,我眼前一亮,对的,这个参数说不定包含了我所期待的密码!我手动尝试着调用 dump.exe 备份实用工具,果然提示需要输入密码。

为了验证我的猜想,我用C语言写了个简单的替换程序用于替换dump.exe,代码很简单,如下:

#include <stdio.h>

int main(int argc, char **argv)
{
	int i;
	for (i = 0; i< argc; i++) {
		printf("%d\t%s\n", i, argv[i]);
	}
	getchar();
	getchar();
	return 0;
}

然后要用编译器编译,我临时下了个 TCC: Tiny C Compiler 轻量编译器,再将上面的代码命名为 dump.c ,运行 tcc dump.c 命令,然后自动生成 dump.exe

好了,接下来我们可以用这个 dump.exe 替换真实的数据库备份程序了,当然我们事先备份一下 dump.exe ,然后把编写的假冒的 dump.exe 换上去,打开该信息系统软件,执行备份任务,果然用户名、密码和数据库名都有了。

最后记得把真实的备份工具 dump.exe 换上去,否则这个信息系统就无法正常备份了。