分享
 
 
 

网络连接的安全问题

王朝other·作者佚名  2006-12-16
窄屏简体版  字體: |||超大  

现在越来越多的网站是架构在数据库上的,而且使用微软的SQL Server数据库的占很大比例,

而数据库的安全也是常常被管理员忽略的。下面我们要说的,并不是SQL Server存在的漏洞,而

只是一些安全缺陷,存在的一些问题,当然这些问题是SQL Server一产生的时候就存在的。

1、MS SQL Server的密码明文传输缺陷

很倒霉,我没有在微软发布SQL Server的时候做下面的分析。当我吃惊地发现SQL Server竟然

是使用明文进行密码传输的时候,我就马上去查阅是否有这些资料。可惜已经早早有人提出能够

用sniffer获取SQL Server的密码了。不过,既然微软这么大胆,我们还是去看看,分析分析这个

缺陷。

当然,SQL Server的连接过程还是先进行TCP连接的三次握手,同服务器建立连接过后,然后进行

TDS(tabular data stream)协议的数据交流,可惜的是我一直没有找到TDS协议的具体描述,只

有一些片段,所以,都只能一点点地对着数据报分析。

直接到login包吧,你会发现,你的用户名完全是明文的,而密码还不是。当你改变密码的时候,

你可以看出,相同字符的编码是一样的,密码字符之间用一个相同的字符作为分隔“a5”。呵呵。

所以,最傻的办法就是我做的这样,一个字符一个字符地改变密码,然后得到所有字符的对应编码

(我不会解密)。

我使用的是SQL Server 2000 。我这里列举得到的对应编码。大家可以根据我的笨方法很容易得到

完整的字符编码。

a —— 0xb3 A —— 0xb1

b —— 0x83 B -- 0x81

c —— 0x93 C -- 0x91

d —— 0xe3 D -- 0xe1

e —— 0xf3 E -- 0xf1

f —— 0xc3 F -- 0xc1

g —— 0xd3 G -- 0xd1

h —— 0x23 H -- 0x21

i —— 0x33 I -- 0x31

j —— 0x03 J -- 0x01

k —— 0x13 K -- 0x11

l —— 0x63 L -- 0x61

m —— 0x73 M -- 0x71

n —— 0x43 N -- 0x41

o —— 0x53 O -- 0x51

p —— 0xa2 P -- 0xa0

q —— 0xb2 Q -- 0xb0

r —— 0x82 R -- 0x80

s —— 0x92 S -- 0x90

t —— 0xe2 T -- 0xe0

u —— 0xf2 U -- 0xf0

v —— 0xc2 V -- 0xc0

w —— 0xd2 W -- 0xd0

x —— 0x22 X -- 0x20

y —— 0x32 Y -- 0x30

z —— 0x02 Z -- 0x00

` —— 0xa3 ~ —— 0x42

1 —— 0xb6 ! —— 0xb7

2 —— 0x86 @ —— 0xa1

3 —— 0x96 # —— 0x97

4 —— 0xe6 $ —— 0xe7

5 —— 0xf6 % —— 0xf7

6 —— 0xc6 ^ —— 0x40

7 —— 0xd6 & —— 0xc7

8 —— 0x26 * —— 0x07

9 —— 0x36 ( —— 0x27

0 —— 0xa6 ) —— 0x37

- —— 0x77 _ —— 0x50

= —— 0x76 + —— 0x17

\ —— 0x60 | —— 0x62

[ —— 0x10 { —— 0x12

] —— 0x70 } —— 0x72

' —— 0xd7 " —— 0x87

, —— 0x67 < —— 0x66

. —— 0x47 > —— 0x46

/ —— 0x57 ? —— 0x56

: —— 0x06

对了,在SQL Server中不支持用 ; 符号作为密码,如果你在用这些字符作为密码的话,那

就糟糕了,你永远也登陆不上了,除非更改密码。

在TDS数据报的头中规定了一个字节来表示数据报类型,我探测到的是0x10,而我得到的资

料说是用0x02来表示Login的数据报,可能是MS SQL Server在协议上有一些改动,因为Sybase也是使

用的TDS协议的,那么Sybase可能也是使用的明文传输吧,我手里没有Sybase。可惜没有TDS协议的完

整描述,所以,我也偷懒没有写出专门获得SQL Server帐号和密码的sniffer程序,谁能给我TDS协议

的详细描述,请email: refdom@263.net。

不过MS对SQL Server的传输还是提供加密办法的,你可以使用SSL来加密。于是我也试了试,

可以在实例属性的网络配置里面选择强制协议加密,然后要求你重新启动SQL Server,呵呵,然后呢,

你启动起来了么?哈哈,我可是吃了亏的。因为没有SSL证书,所以,你一启动就错误,事件日志中说

明是没有提供有效的证书。重新安装吧。该死的MS也不在我选择的时候提醒一下。

嗅探得到数据库帐号意味着什么?如果能够得到SA帐号呢?哈哈,有兴趣可以看看我前些天

写的《从IIS转到SQL数据库安全》。

2、明文的数据传输缺陷

如果没有使用加密的协议的话,那么整个数据库的网络数据都是没有加密的,而且是明文传输。

无论是从客户端发送命令还是从服务器端得到结果,都是明文传输的。看来,如果你用加密的协议,微

软是不会为你做任何安全防护的。我想,目前国内使用的SQL Server数据库差不多都是没有使用SSL来加

密,看来在网络上能得到不少东西。

3、神秘的1434端口和服务器信息明文传输缺陷

对于SQL Server2000来说,打开SQL Server客户端准备连接,当拉开服务器列表的时候,整个局域网所

有的SQL Server服务器都被列出来了。于是我发现,从我自己的机器(192.168.0.1)上从1434端口广播

(192.168.0.255)了这个UDP包,然后,整个局域网中的SQL Server服务器都开始响应这个UDP数据包,这

时,我的客户端能够得到所有服务器信息。

这就是客户端进行连接的过程:当客户端连接到服务器时,应用程序请求连接远端计算机,Dbnetlib.dll

将打开到连接中所指定的计算机网络名上的 UDP 端口 1434 的连接。所有运行 SQL Server 2000 的计算

机都监听此端口。当一个客户端 Dbnetlib.dll 连接到该端口时,服务器将返回一个监听服务器上运行的

所有实例的数据包。对于每个实例,该数据包报告该实例正在监听的服务器 Net-Library 和网络地址。应

用程序计算机上的 Dbnetlib.dll 收到该数据包后,选择在应用程序计算机和 SQL Server 实例上都启用

的 Net-Library,然后连接为此数据包中的 Net-Library 列出的地址。

通过1434端口传输特定的UDP数据包,然后服务器开始回应,所有这些都是明文传输的,我们可以很容易探

测一个IP地址的1434端口,获得该IP地址上运行的SQL Server的相关信息。这些信息包括:主机名称、实

例名称、版本、管道名称以及使用的端口等。这个端口是微软自己使用,而且不象默认的1433端口那样可

以改变,1434是不能改变的,呵呵,那么我们为了安全,去改变这个1433端口能起什么作用呢?

我们可以来捕获这些数据报,可以发现,通过1434端口的数据非常简单,客户端仅仅简单地发送了02一

个字节出去。不过多次捕获,发现有时候发送的是 03。于是我就用下面程序一个一个测试,发送其他数据。

不过最后只有02、03、04有回应。看来这三种字节用来做SQL Server探测的。而且你可以发送 02 00 00,也

可以发送 02 00 00 00 00等等都能够得到SQL Server的回应,但是发送 02 03就不可以了。

下面是一个利用1434进行探测的程序,可以探测单个IP,也可以用来探测整个局域网的数据库服务器。

////////////////////////////////////////////////////////////

//

// SQLPing by refdom

//

// Author: refdom. From Chip Andrews

// Email: refdom@263.net

//

////////////////////////////////////////////////////////////

#include "stdafx.h"

#include

#include

#include

void decode_recv (char *buf, int size)

{

int index;

int counter = 0;

for (index = 3; index < size; index++)

{

if ((buf[index] == ';') && (buf[index+1] != ';'))

{

//Look for a semi-colon and check for end of record (;;)

if ((counter % 2) == 0)

{

printf(":");

counter++;

}

else

{

printf("\n");

counter++;

}

}

else

{

if (buf[index] != ';')

{

// If an end of record (;;), then double-space for next instance

printf("%c",buf[index]);

}

else

{

printf("\n");

}

}

}

printf("\n");

}

void listen (void* v)

{

static const unsigned int buffersize = 64000;

static char buffer [buffersize];

SOCKET s = (SOCKET)v;

for (;;)

{

struct sockaddr_in udpfrom;

int udpfromlen = sizeof(udpfrom);

int n = recvfrom(s, buffer, sizeof(buffer), 0, (struct sockaddr *)&udpfrom, &udpfromlen);

int e = WSAGetLastError();

if (n > 0 && e == 0)

decode_recv(buffer, n);

}

}

void useage()

{

printf("******************************************\n");

printf("SQLPing\n");

printf("\t Written by Refdom\n");

printf("\t Email: refdom@263.net\n");

printf("Useage: sqlping.exe target_ip \n");

printf("*******************************************\n");

}

int main(int argc, char* argv[])

{

WSADATA WSAData;

SOCKET sock;

SOCKADDR_IN addr_in;

char buf[5]={'\x02'};

HANDLE listener;

useage();

if (argc<2)

{

return false;

}

if (WSAStartup(MAKEWORD(2,0),&WSAData)!=0)

{

printf("WSAStartup error.Error:%d\n",WSAGetLastError());

return false;

}

if ((sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==INVALID_SOCKET)

{

printf("Socket failed.Error:%d\n",WSAGetLastError());

return false;

}

addr_in.sin_family=AF_INET;

addr_in.sin_port=htons(1434);

addr_in.sin_addr.S_un.S_addr=inet_addr(argv[1]);

const int SNDBUF = 0;

const int TCPNODELAY = true;

const int BROADCAST = true;

if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (const char*)&SNDBUF, sizeof(SNDBUF))==SOCKET_ERROR)

{

printf("Set SO_SNDBUF failed.Error:%d",WSAGetLastError());

return false;

}

if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, (const char*)&TCPNODELAY, sizeof(TCPNODELAY))==SOCKET_ERROR)

{

printf("Set TCP_NODELAY failed.Error:%d",WSAGetLastError());

return false;

}

if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&BROADCAST, sizeof(BROADCAST))==SOCKET_ERROR)

{

printf("Set SO_BROADCAST failed.Error:%d",WSAGetLastError());

return false;

}

listener = (HANDLE) _beginthread(listen, 0, (void*)sock);

// e = sendto(s, "\08", 1, 0,(sockaddr*) &hostaddr, sizeof(hostaddr));

if (sendto(sock, buf, sizeof(buf), 0,(sockaddr*) &addr_in, sizeof(addr_in))==SOCKET_ERROR)

{

printf("Send failed.Error:%d\n",WSAGetLastError());

return false;

}

printf("Listening....\n\n");

// wait a little while for listener thread

WaitForSingleObject(listener, 5000);

WSACleanup();

printf("SQLPing Complete.\n");

return 0;

}

上面的程序只有探测作用,没有破坏性。呵呵

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有