Skip to content

Latest commit

 

History

History

CVE-2006-4018

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

CVE-2006-4018

Experiment Environment

Ubuntu 10.04 LTS

INSTALL & Configuration

wget https://github.com/mudongliang/source-packages/raw/master/CVE-2006-4182/clamav-0.88.2.tar.gz
tar -xvf clamav-0.88.2.tar.gz
cd clamav-0.88.2
./configure
make
sudo make install

Problems in Installation & Configuration

How to trigger vulnerability

/usr/local/bin/clamscan 28348.exe

PoCs

Clam Anti-Virus ClamAV 0.88.x - UPX Compressed PE File Heap Buffer Overflow

Clam Anti-Virus ClamAV UPX Compressed PE File Heap Buffer Overflow Vulnerability

Vulnerability Details & Patch

Root Cause

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.

Stack Trace

Patch

References