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 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 *dsize. 3. PoC The example of crafted upx file: http://overflow.pl/poc/clamav_upx_heap.exe [pucik@overflow 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.