Ethical Hacking

Learn to find vulnerabilities before the bad guys do! Gain real world hands on hacking experience in our state of the art hacking lab. Course designed and taught by expert instructors with years of penetration testing experience. 12 student maximum in every class. Certification attempt included in every package.
Computer Forensics Training at InfoSec Institute

Gain the in-demand skills of a certified computer examiner, learn to recover trace data left behind by fraud, theft, and cybercrime perpetrators. Discover the source of computer crime and abuse at your organization so that it never happens again. All of our class sizes are guaranteed to be 12 students or less to facilitate one-on-one interaction with one of our expert instructors.




Network Security Exploits-HackingTools
[Top] [All Lists]

[UNIX] chmlib Buffer Overflow (Technical Details)

Subject: [UNIX] chmlib Buffer Overflow (Technical Details)
Date: 31 Oct 2005 08:59:31 +0200
The following security advisory is sent to the securiteam mailing list, and can 
be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

The SecuriTeam alerts list - Free, Accurate, Independent.

Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html 

- - - - - - - - -



  chmlib Buffer Overflow (Technical Details)
------------------------------------------------------------------------


SUMMARY

CHMLIB is "a library for dealing with Microsoft ITSS/CHM format files. 
Right now, it is a very simple library, but sufficient for dealing with 
all of the .chm files I've come across. Due to the fairly well-designed 
indexing built into this particular file format, even a small library is 
able to gain reasonably good performance indexing into ITSS archives".

chmlib has been found to be vulnerable to a buffer overflow, allowing 
attacker to execute arbitrary code.

DETAILS

Vulnerable Systems:
 * chmlib version 0.36 and prior.

Immune Systems:
 * CHM lib version 0.37 (download  
<http://morte.jedrea.com/%7Ejedwin/projects/chmlib/chmlib-0.37.2.tgz> 
here)
 * CHM lib version 0.37.2 (download  
<http://morte.jedrea.com/%7Ejedwin/projects/chmlib/chmlib-0.37.tgz> here)

0. chm_lib.c: _chm_decompress_block(struct chmFile *h, UInt64 block,UChar 
**ubuffer)
1. see cmpLen and cbuffer declaration
2. call to _chm_get_cmpblock_bounds(h, block, &cmpStart, &cmpLen)  to set 
cmpLen
3. cmpLen is used to offset write operations in cbuffer 
(_chm_fetch_bytes(h, cbuffer, cmpStart, cmpLen))
4. if cmpLen > h->reset_table.block_len + 6144 the buffer overflows
5. as we can supply the fd data, exploitation is possible and an attacker 
can execute arbitrary code.

Vulnerable code:
/* decompress the block.  must have lzx_mutex. */
static Int64 _chm_decompress_block(struct chmFile *h,
                                   UInt64 block,
                                   UChar **ubuffer)
{
..
    UChar cbuffer[h->reset_table.block_len + 6144];     /* compressed
buffer */
    Int64 cmpLen;                                       /* compressed
len    */

..
..
..
..

    if (! _chm_get_cmpblock_bounds(h, block, &cmpStart, &cmpLen)          
||
        _chm_fetch_bytes(h, cbuffer, cmpStart, cmpLen) != cmpLen          
||
        LZXdecompress(h->lzx_state, cbuffer, lbuffer, (int)cmpLen,
                      (int)h->reset_table.block_len) != DECR_OK)
    {
..




-----------------------------


/* get the bounds of a compressed block.  return 0 on failure */
static int _chm_get_cmpblock_bounds(struct chmFile *h,
                             UInt64 block,
                             UInt64 *start,
                             Int64 *len)
{
    UChar buffer[8], *dummy;
    unsigned int remain;

    /* for all but the last block, use the reset table */
    if (block < h->reset_table.block_count-1)
    {

        ...
        ...

        /* unpack the end address */
        dummy = buffer;
        remain = 8;
        if (_chm_fetch_bytes(h, buffer,
                         (UInt64)h->data_offset
                                + (UInt64)h->rt_unit.start
                                + (UInt64)h->reset_table.table_offset
                                + (UInt64)block*8 + 8,
                         remain) != remain                                
||
            !_unmarshal_int64(&dummy, &remain, len))
            return 0;
    }

    /* for the last block, use the span in addition to the reset table */
    else
    {
       ...
    }

    /* compute the length and absolute start address */
    *len -= *start;
    *start += h->data_offset + h->cn_unit.start;

    return 1;
}


--------------
/*
 * dest(len) is read out of the fd
*/
static int _unmarshal_int64(unsigned char **pData,
                            unsigned int *pLenRemain,
                            Int64 *dest)
{
    Int64 temp;
    int i;
    if (8 > *pLenRemain)
        return 0;
    temp=0;
    for(i=8; i>0; i--)
    {
        temp <<= 8;
        temp |= (*pData)[i-1];
    }
    *dest = temp;
    *pData += 8;
    *pLenRemain -= 8;
    return 1;
}

---------------


/* utility function to handle differences between {pread,read}(64)? */
static Int64 _chm_fetch_bytes(struct chmFile *h,
                              UChar *buf,
                              UInt64 os,
                              Int64 len)
{
    Int64 readLen=0, oldOs=0;
    if (h->fd  ==  CHM_NULL_FD)
        return readLen;

    CHM_ACQUIRE_LOCK(h->mutex);
..
    readLen = pread(h->fd, buf, (long)len, (unsigned int)os);
..
    CHM_RELEASE_LOCK(h->mutex);
    return readLen;
}

Disclosure Timeline:
24.10.05 - Issue found by Sven Tantau
25.10.05 - Contacted chmlib maintainer
25.10.05 - Quick reaction with confirmation
26.10.05 - New release of chmlib and public disclosure

Vendor Status:
chmlib maintainer Jed Wing released a new version 0.37


ADDITIONAL INFORMATION

The information has been provided by  <mailto:sven@sven-tantau.de> Sven 
Tantau.
The original article can be found at:  
<http://www.sven-tantau.de/public_files/chmlib/chmlib_20051126.txt> 
http://www.sven-tantau.de/public_files/chmlib/chmlib_20051126.txt



======================================== 


This bulletin is sent to members of the SecuriTeam mailing list. 
To unsubscribe from the list, send mail with an empty subject line and body to: 
list-unsubscribe@securiteam.com 
In order to subscribe to the mailing list, simply forward this email to: 
list-subscribe@securiteam.com 


==================== 
==================== 

DISCLAIMER: 
The information in this bulletin is provided "AS IS" without warranty of any 
kind. 
In no event shall we be liable for any damages whatsoever including direct, 
indirect, incidental, consequential, loss of business profits or special 
damages. 




<Prev in Thread] Current Thread [Next in Thread>
  • [UNIX] chmlib Buffer Overflow (Technical Details), SecuriTeam <=