lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20060809171805.4p4m7b6d7ztw0k4k@www.overflow.pl>
Date: Wed, 09 Aug 2006 17:18:05 +0200
From: pucik@...rflow.pl
To: full-disclosure@...ts.grok.org.uk, bugtraq@...urityfocus.com
Subject: [Overflow.pl] Clam AntiVirus Win32-UPX Heap Overflow

Overflow.pl Security Advisory #6

Clam AntiVirus Win32-UPX Heap Overflow

Vendor: Clam AntiVirus
Affected version: Prior to 0.88.4
Vendor status: Fixed version released (0.88.4)

Author: Damian Put <pucik@...rflow.pl>
URL: http://www.overflow.pl/adv/clamav_upx_heap.txt
Date: 09.08.2006

1. Background

"Clam AntiVirus is a GPL anti-virus toolkit for UNIX. The main purpose of this
software is the integration with mail servers (attachment scanning).  
The package
provides a flexible and scalable multi-threaded daemon, a command line  
scanner,
and a tool for automatic updating via Internet. The programs are based on a
shared library distributed with the Clam AntiVirus package, which you can use
with your own software. Most importantly, the virus database is kept  
up to date"

http://www.clamav.net


2. Description

Remote exploitation of a heap overflow vulnerability could allow execution of
arbitrary code or cause denial of service.

Vulnerability exists in pefromupx() function, that is used to buil  
Win32 PE file
from UPX packed file.

The vulnerable code is:

libclamav/upx.c:
------------
int pefromupx (char *src, char *dst, uint32_t *dsize, uint32_t ep, uint32_t
upx0, uint32_t upx1, uint32_t magic)
{
   char *imports, *sections, *pehdr, *newbuf;
   int sectcnt, upd=1;
   uint32_t realstuffsz;
   uint32_t foffset=0xd0+0xf8;

   imports = dst + cli_readint32(src + ep - upx1 + magic);
   realstuffsz = imports-dst;

   if (realstuffsz >= *dsize ) {
     cli_dbgmsg("UPX: wrong realstuff size - giving up rebuild\n");
     return 0;
   }
....

OK first we check that realstuffsz is not larger than dsize.

....
   foffset+=0x28*sectcnt;

   if (!CLI_ISCONTAINED(dst, *dsize, sections, 0x28*sectcnt)) {
     cli_dbgmsg("UPX: Not enough space for all sects - giving up rebuild\n");
     return 0;
   }
....

Now we check that we have enough space for section headers.

....

   for (upd = 0; upd <sectcnt ; upd++) {
     uint32_t vsize=cli_readint32(sections+8)-1;
     uint32_t rsize=cli_readint32(sections+16);
     uint32_t urva=cli_readint32(sections+12);

     .....

     cli_writeint32(sections+8, vsize);
     cli_writeint32(sections+20, foffset);
     foffset+=rsize;
     sections+=0x28;
   }

....

Now, we add to foffset rsize value of all sections and we DON`T check
that we have enough space in *dst.

....

   /* CBA restoring the imports they'll look different from the originals
anyway... */
   /* ...and yeap i miss the icon too :P */

   memcpy(dst, newbuf, foffset);
   *dsize = foffset;
   free(newbuf);

   cli_dbgmsg("UPX: PE structure rebuilt from compressed file\n");
   return 1;
}

....

And there is our heap overflow. We copy from newbuf to dst pointer foffset
bytes, but we don`t check that foffset > *dsize.


3. PoC

The example of crafted upx file: http://overflow.pl/poc/clamav_upx_heap.exe


[pucik@...rflow UPX]$ clamscan clamav_upx_heap.exe
*** glibc detected *** double free or corruption (out): 0x08bcbbc0 ***
Przerwane (core dumped)

You can control value of foffset changing "SizeOfRawData" of section 1.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ