安全研究

安全漏洞
Firebird op_connect_request请求远程拒绝服务漏洞

发布日期:2009-07-28
更新日期:2009-07-29

受影响系统:
Firebird Firebird SQL v2.5.0 Beta 1
Firebird Firebird SQL v2.1.3 RC1
Firebird Firebird SQL v2.1.2
Firebird Firebird SQL v2.1.1
Firebird Firebird SQL v2.0.5
Firebird Firebird SQL v2.0.1
Firebird Firebird SQL v1.5.5
描述:
BUGTRAQ  ID: 35842
CVE(CAN) ID: CVE-2009-2620

Firebird是一款提供多个ANSI SQL-92功能的关系型数据库,可运行在Linux、Windows和各种Unix平台下。

在Firebird的src/remote/server.cpp文件中,process_packet2()函数负责处理从客户端发送过来的报文。这个函数有一个switch语句考虑协议中所定义的所有可能的opcode。

/-----------

src/remote/server.cpp:

...
3404    P_OP op = receive->p_operation;
3405    switch (op)
3406    {
3407    case op_connect:
    ...
3426    case op_compile:
    ...
3430    case op_attach:
    ...

- -----------/

在op_connect_request报文的情况下,执行流进入switch语句的以下case:

/-----------

src/remote/server.cpp:

...
3584    case op_connect_request:
3585        aux_request(port, &receive->p_req, sendL);
3586        break;

- -----------/

在调用aux_request()函数并执行break语句后,执行流到达:

/-----------

src/remote/server.cpp:

...
3652    if (port && port->port_state == state_broken) {
3653        if (!port->port_parent) {
3654            gds__log("SERVER/process_packet: broken port, server exiting");
3655            port->disconnect(sendL, receive);
3656            ThreadData::restoreSpecific();
3657            return false;
3658        }
3659        port->disconnect(sendL, receive);
3660        port = NULL;
3661    }

- -----------/

通过在接收到op_connect_request报文时调试fbserver.exe二进制程序可以看出满足了第一个if语句的条件,但没有满足第二个if的条件,因此执行流到达port->disconnect()调用:

/-----------

005ACE2C  |>  837E 0C 03           CMP DWORD PTR DS:[ESI+C],3
    ;port->port_state == state_broken ?
005ACE30  |.  75 1B                JNZ SHORT fbserver.005ACE4D
005ACE32  |.  837E 1C 00           CMP DWORD PTR DS:[ESI+1C],0
    ;port->port_parent == 0?
005ACE36  |.  75 0A                JNZ SHORT fbserver.005ACE42
    ;this conditional jump is taken
005ACE38  |.  68 D4D65F00          PUSH fbserver.005FD6D4
    ;  ASCII "SERVER/process_packet: broken port, server exiting"
005ACE3D  |.^ E9 44FDFFFF          JMP fbserver.005ACB86
005ACE42  |>  53                   PUSH EBX
    ; /Arg2
005ACE43  |.  57                   PUSH EDI
    ; |Arg1
005ACE44  |.  8BCE                 MOV ECX,ESI
    ; |
005ACE46  |.  E8 65D7FFFF          CALL <fbserver.rem_port::disconnect>
    ; \port->disconnect(sendL, receive)

- -----------/

根据src/remote/remote.h中的定义,port的类型为struct rem_port。这种结构类型在src/remote/server.cpp中实现了disconnect()函数:

/-----------

src/remote/server.cpp:

1464    void rem_port::disconnect(PACKET* sendL, PACKET* receiveL)

- -----------/

在这个函数中执行以下代码以释放发送和接收的报文并关闭相关的套接字:

/-----------

src/remote/server.cpp:

...
1492    REMOTE_free_packet(this, sendL);
1493    REMOTE_free_packet(this, receiveL);
1494    this->disconnect();

- -----------/

对this->disconnect()的调用最终会导致src/remote/inet.cpp中的disconnect()函数,该函数用于中断远程连接并接收rem_port结构参数。

/-----------

src/remote/inet.cpp:

1731    static void disconnect( rem_port* port)
1732    {

- -----------/

首先函数通过调用shutdown函数关闭客户端所创建的连接:

/-----------

src/remote/inet.cpp:

...
1763    if (port->port_handle && (SOCKET) port->port_handle !=
INVALID_SOCKET) {
1764        shutdown((int) port->port_handle, 2);
1765    }

- -----------/

之后如果当前正在断开的rem_port结构是其他rem_port结构的子代,就会递归的调用disconnect()断开存储在port->port_async的rem_port。port_async是rem_port结构的成员,描述异步同级端口。

/-----------

src/remote/inet.cpp:

/* If this is a sub-port, unlink it from it's parent */
...
1789    rem_port* parent = port->port_parent;
1790    if (parent != NULL) {
1791        if (port->port_async) {
1792            disconnect(port->port_async);
1793            port->port_async = NULL;
1794        }

- -----------/

在执行对disconnect()的递归调用时,作为将要断开参数传送的port->port_async对应到主服务器套接字,也就是在3050/TCP端口上监听入站连接的套接字。一旦在递归调用中调用了shutdown()和closesocket()函数,服务器就会停止监听默认的3050/TCP端口,拒绝对合法用户的服务。

<*来源:Francisco Falcon
  
  链接:http://marc.info/?l=bugtraq&m=124881637520977&w=2
        http://secunia.com/advisories/36026/
*>

测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

http://milw0rm.com/exploits/9295

建议:
厂商补丁:

Firebird
--------
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

http://tracker.firebirdsql.org/browse/CORE-2563

浏览次数:2722
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障