Freeciv 'packets.c'缓冲区溢出漏洞

QQ空间 新浪微博 微信 QQ facebook twitter
漏洞ID 1193966 漏洞类型 缓冲区溢出
发布时间 2006-07-23 更新时间 2007-05-23
CVE编号 CVE-2006-3913 CNNVD-ID CNNVD-200607-490
漏洞平台 N/A CVSS评分 7.5
|漏洞来源
https://www.securityfocus.com/bid/19117
https://cxsecurity.com/issue/WLB-2006080005
http://www.cnnvd.org.cn/web/xxk/ldxqById.tag?CNNVD=CNNVD-200607-490
|漏洞详情
Freeciv2.1.0-beta1及之前版本和SVN15Jul2006及之前版本存在缓冲区溢出。远程攻击者可以借助common/packets.c的generic_handle_player_attribute_chunk函数中的PACKET_PLAYER_ATTRIBUTE_CHUNK数据包中的(1)负chunk_length或(2)大chunk->offset值,以及server/unithand.c的handle_unit_orders函数中的(3)大packet->length值,引起拒绝服务(崩溃)。
|漏洞EXP
#######################################################################

Luigi Auriemma

Application:  Freeciv
              http://www.freeciv.org
Versions:     <= 2.1.0-beta1 and SVN <= 15 Jul 2006
Platforms:    Windows, *nix, *BSD, MacOS and more
Bugs:         A] memcpy crash in generic_handle_player_attribute_chunk
              B] invalid memory access in handle_unit_orders
Exploitation: remote, versus server
Date:         23 Jul 2006
Author:       Luigi Auriemma
              e-mail: aluigi (at) autistici (dot) org [email concealed]
              web:    aluigi.org

#######################################################################

1) Introduction
2) Bugs
3) The Code
4) Fix

#######################################################################

===============
1) Introduction
===============

Freeciv is an open source clone of the well known Civilization game.
The game supports also online gaming through its own metaserver (which
can be seen on the web too) and GGZ (http://www.ggzgamingzone.org).

#######################################################################

=======
2) Bugs
=======

--------------------------------------------------------
A] memcpy crash in generic_handle_player_attribute_chunk
--------------------------------------------------------

handle_player_attribute_chunk (which points to
generic_handle_player_attribute_chunk) is a function used by both
client and server when a PACKET_PLAYER_ATTRIBUTE_CHUNK packet is
received.
The function acts like a reassembler of data for an allocated buffer
which can have a size of max 262144 bytes.
Exist two problems in this function:
- the length of the current chunk received (chunk_length) is not
  verified so using a negative value an attacker can bypass the initial
  check and can copy a huge amount of data ((unsigned)chunk_length) in
  the data buffer with the subsequent crash
- the check "chunk->offset + chunk->chunk_length > chunk->total_length"
  can be bypassed using a very big positive offset like 0x7fffffff
  which will allow the copying of data from our packet to the memory
  located at the malformed offset of the allocated buffer.
  Doesn't seem possible to execute malicious code with this bug since
  the destination memory is usually invalid

From common/packets.c:

void generic_handle_player_attribute_chunk(struct player *pplayer,
                       const struct
                       packet_player_attribute_chunk
                       *chunk)
{
  freelog(LOG_DEBUG, "received attribute chunk %d/%d %d", chunk->offset,
      chunk->total_length, chunk->chunk_length);

if (chunk->total_length < 0
      || chunk->total_length >= MAX_ATTRIBUTE_BLOCK
      || chunk->offset < 0
      || chunk->offset + chunk->chunk_length > chunk->total_length
      || (chunk->offset != 0
          && chunk->total_length != pplayer->attribute_block_buffer.length)) {
    /* wrong attribute data */
    if (pplayer->attribute_block_buffer.data) {
      free(pplayer->attribute_block_buffer.data);
      pplayer->attribute_block_buffer.data = NULL;
    }
    pplayer->attribute_block_buffer.length = 0;
    freelog(LOG_ERROR, "Received wrong attribute chunk");
    return;
  }
  /* first one in a row */
  if (chunk->offset == 0) {
    if (pplayer->attribute_block_buffer.data) {
      free(pplayer->attribute_block_buffer.data);
      pplayer->attribute_block_buffer.data = NULL;
    }
    pplayer->attribute_block_buffer.data = fc_malloc(chunk->total_length);
    pplayer->attribute_block_buffer.length = chunk->total_length;
  }
  memcpy((char *) (pplayer->attribute_block_buffer.data) + chunk->offset,
     chunk->data, chunk->chunk_length);
  ...

----------------------------------------------
B] invalid memory access in handle_unit_orders
----------------------------------------------

The server's function handle_unit_orders doesn't check the maximum
size of the packet->length value which should not be bigger than 2000
(MAX_LEN_ROUTE) while is possible for an attacker to use any positive
number.
The crash could require different tries (usually 3) before happening.

From server/unithand.c:

void handle_unit_orders(struct player *pplayer,
			struct packet_unit_orders *packet)
{
  struct unit *punit = player_find_unit_by_id(pplayer, packet->unit_id);
  struct tile *src_tile = map_pos_to_tile(packet->src_x, packet->src_y);
  int i;

if (!punit || packet->length < 0 || punit->activity != ACTIVITY_IDLE) {
    return;
  }

if (src_tile != punit->tile) {
    /* Failed sanity check.  Usually this happens if the orders were sent
     * in the previous turn, and the client thought the unit was in a
     * different position than it's actually in.  The easy solution is to
     * discard the packet.  We don't send an error message to the client
     * here (though maybe we should?). */
    return;
  }

for (i = 0; i < packet->length; i++) {
  ...

#######################################################################

===========
3) The Code
===========

No proof-of-concept available, you must modify the source code of the
client for forcing the sending of the malformed data.

#######################################################################

======
4) Fix
======

The bugs have been fixed in the SVN of the 16 Jul 2006

#######################################################################

--- 
Luigi Auriemma
http://aluigi.org
http://mirror.aluigi.org
|受影响的产品
Pardus Linux 2007.1 Mandriva Linux Mandrake 2006.0 x86_64 Mandriva Linux Mandrake 2006.0 Freeciv Freeciv 2.1 beta1 Freeciv Freeciv 2.0.8 Freeciv Freeciv 2.0.7
|参考资料

来源:BUGTRAQ
名称:20060723TwocrashvulnerabilitiesinFreeciv2.1.0-beta1(SVN15Jul2006)
链接:http://www.securityfocus.com/archive/1/archive/1/441042/100/0/threaded
来源:SECUNIA
名称:21254
链接:http://secunia.com/advisories/21254
来源:MANDRIVA
名称:MDKSA-2006:135
链接:http://frontal2.mandriva.com/security/advisories?name=MDKSA-2006:135
来源:BID
名称:19117
链接:http://www.securityfocus.com/bid/19117
来源:VUPEN
名称:ADV-2006-2942
链接:http://www.frsirt.com/english/advisories/2006/2942
来源:SECUNIA
名称:21171
链接:http://secunia.com/advisories/21171
来源:MISC
链接:http://aluigi.altervista.org/adv/freecivx-adv.txt
来源:XF
名称:freeciv-unithand-dos(27956)
链接:http://xforce.iss.net/xforce/xfdb/27956
来源:XF
名称:freeciv-packetsc-dos(27955)
链接:http://xforce.iss.net/xforce/xfdb/27955
来源:MANDRIVA
名称:MDKSA-2006:135
链接:http://www.mandriva.com/security/advisories?name=MDKSA-2006:135
来源:DEBIAN
名称:DSA-1142
链接:http://www.debian.org/security/2006/dsa-1142
来源:SREASON
名称:1296
链接:http://securityreason.com/securityalert/1296
来源:SECUNIA
名称:21352
链接:http://se