mirror of
https://github.com/Cisco-Talos/clamav.git
synced 2025-10-19 10:23:17 +00:00
added SUE decryptor (enable via CONFIG_EXPERIMENTAL)
git-svn: trunk@2190
This commit is contained in:
parent
a946fc1cee
commit
3fcb62ca7b
6 changed files with 266 additions and 5 deletions
|
@ -1,3 +1,7 @@
|
|||
Fri Aug 11 19:37:24 CEST 2006 (acab)
|
||||
------------------------------------
|
||||
* libclamav: add support for SUE decryption (disabled)
|
||||
|
||||
Fri Aug 11 18:09:00 CEST 2006 (tk)
|
||||
----------------------------------
|
||||
* libclamav/others.c: apply win32 support patch from NJH
|
||||
|
|
|
@ -94,6 +94,8 @@ libclamav_la_SOURCES = \
|
|||
petite.h \
|
||||
wwunpack.c \
|
||||
wwunpack.h \
|
||||
suecrypt.c \
|
||||
suecrypt.h \
|
||||
packlibs.c \
|
||||
packlibs.h \
|
||||
fsg.c \
|
||||
|
|
|
@ -82,9 +82,9 @@ am_libclamav_la_OBJECTS = matcher-ac.lo matcher-bm.lo matcher.lo \
|
|||
filetypes.lo blob.lo mbox.lo message.lo snprintf.lo table.lo \
|
||||
text.lo ole2_extract.lo vba_extract.lo msexpand.lo pe.lo \
|
||||
cabd.lo lzxd.lo mszipd.lo qtmd.lo system.lo upx.lo htmlnorm.lo \
|
||||
chmunpack.lo rebuildpe.lo petite.lo wwunpack.lo packlibs.lo \
|
||||
fsg.lo line.lo untar.lo unzip.lo special.lo binhex.lo \
|
||||
is_tar.lo tnef.lo unrar15.lo unrarvm.lo unrar.lo \
|
||||
chmunpack.lo rebuildpe.lo petite.lo wwunpack.lo suecrypt.lo \
|
||||
packlibs.lo fsg.lo line.lo untar.lo unzip.lo special.lo \
|
||||
binhex.lo is_tar.lo tnef.lo unrar15.lo unrarvm.lo unrar.lo \
|
||||
unrarfilter.lo unrarppm.lo unrar20.lo unrarcmd.lo pdf.lo \
|
||||
spin.lo yc.lo elf.lo sis.lo uuencode.lo pst.lo
|
||||
libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS)
|
||||
|
@ -293,6 +293,8 @@ libclamav_la_SOURCES = \
|
|||
petite.h \
|
||||
wwunpack.c \
|
||||
wwunpack.h \
|
||||
suecrypt.c \
|
||||
suecrypt.h \
|
||||
packlibs.c \
|
||||
packlibs.h \
|
||||
fsg.c \
|
||||
|
@ -448,6 +450,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/special.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spin.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/suecrypt.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/system.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/table.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/text.Plo@am__quote@
|
||||
|
|
|
@ -29,7 +29,9 @@
|
|||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
|
||||
#include "cltypes.h"
|
||||
|
@ -42,6 +44,7 @@
|
|||
#include "upx.h"
|
||||
#include "yc.h"
|
||||
#include "wwunpack.h"
|
||||
#include "suecrypt.h"
|
||||
#include "scanners.h"
|
||||
#include "rebuildpe.h"
|
||||
#include "str.h"
|
||||
|
@ -812,6 +815,82 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
|||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_EXPERIMENTAL
|
||||
/* SUE */
|
||||
|
||||
if(nsections > 2 && EC32(optional_hdr32.AddressOfEntryPoint) == EC32(section_hdr[nsections - 1].VirtualAddress) && EC32(section_hdr[nsections - 1].SizeOfRawData) > 0x350 && EC32(section_hdr[nsections - 1].SizeOfRawData) < 0x292+0x350+1000) {
|
||||
|
||||
|
||||
char *sue=buff+0x74;
|
||||
uint32_t key;
|
||||
|
||||
if(lseek(desc, ep-4, SEEK_SET) == -1) {
|
||||
cli_dbgmsg("SUE: lseek() failed - EP out of file\n");
|
||||
free(section_hdr);
|
||||
return CL_EIO;
|
||||
}
|
||||
if((unsigned int) cli_readn(desc, buff, EC32(section_hdr[nsections - 1].SizeOfRawData)+4) == EC32(section_hdr[nsections - 1].SizeOfRawData)+4) {
|
||||
found=0;
|
||||
while(CLI_ISCONTAINED(buff+4, EC32(section_hdr[nsections - 1].SizeOfRawData), sue, 4*3)) {
|
||||
if((cli_readint32(sue)^cli_readint32(sue+4))==0x5c41090e && (cli_readint32(sue)^cli_readint32(sue+8))==0x021e0145) {
|
||||
found=1;
|
||||
key=(cli_readint32(sue)^0x6e72656b);
|
||||
break;
|
||||
}
|
||||
sue++;
|
||||
}
|
||||
cli_dbgmsg("SUE: key(%x) found @%x\n", key, sue-buff);
|
||||
if (found && CLI_ISCONTAINED(buff, EC32(section_hdr[nsections - 1].SizeOfRawData), sue-0x74, 0xbe) &&
|
||||
(sue=sudecrypt(desc, fsize, section_hdr, nsections-1, sue, key, cli_readint32(buff), e_lfanew))) {
|
||||
if(!(tempfile = cli_gentemp(NULL))) {
|
||||
free(sue);
|
||||
free(section_hdr);
|
||||
return CL_EMEM;
|
||||
}
|
||||
|
||||
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) {
|
||||
cli_dbgmsg("sue: Can't create file %s\n", tempfile);
|
||||
free(tempfile);
|
||||
free(sue);
|
||||
free(section_hdr);
|
||||
return CL_EIO;
|
||||
}
|
||||
|
||||
if((unsigned int) write(ndesc, sue, ep) != ep) {
|
||||
cli_dbgmsg("sue: Can't write %d bytes\n", ep);
|
||||
close(ndesc);
|
||||
free(tempfile);
|
||||
free(sue);
|
||||
free(section_hdr);
|
||||
return CL_EIO;
|
||||
}
|
||||
|
||||
free(sue);
|
||||
if (cli_leavetemps_flag)
|
||||
cli_dbgmsg("SUE: Decrypted executable saved in %s\n", tempfile);
|
||||
else
|
||||
cli_dbgmsg("SUE: Executable decrypted\n");
|
||||
fsync(ndesc);
|
||||
lseek(ndesc, 0, SEEK_SET);
|
||||
|
||||
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
|
||||
free(section_hdr);
|
||||
close(ndesc);
|
||||
if(!cli_leavetemps_flag)
|
||||
unlink(tempfile);
|
||||
free(tempfile);
|
||||
return CL_VIRUS;
|
||||
}
|
||||
close(ndesc);
|
||||
if(!cli_leavetemps_flag)
|
||||
unlink(tempfile);
|
||||
free(tempfile);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/* UPX & FSG support */
|
||||
|
||||
/* try to find the first section with physical size == 0 */
|
||||
|
@ -1961,7 +2040,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
|||
}
|
||||
|
||||
if((unsigned int) write(ndesc, dest, dsize) != dsize) {
|
||||
cli_dbgmsg("UPX/FSG: Can't write %d bytes\n", dsize);
|
||||
cli_dbgmsg("WWPack: Can't write %d bytes\n", dsize);
|
||||
close(ndesc);
|
||||
free(tempfile);
|
||||
free(dest);
|
||||
|
@ -1970,7 +2049,11 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
|||
}
|
||||
|
||||
free(dest);
|
||||
cli_dbgmsg("WWPack: Unpacked and rebuilt executable saved in %s\n", tempfile);
|
||||
if (cli_leavetemps_flag)
|
||||
cli_dbgmsg("WWPack: Unpacked and rebuilt executable saved in %s\n", tempfile);
|
||||
else
|
||||
cli_dbgmsg("WWPack: Unpacked and rebuilt executable\n");
|
||||
|
||||
fsync(ndesc);
|
||||
lseek(ndesc, 0, SEEK_SET);
|
||||
|
||||
|
|
139
clamav-devel/libclamav/suecrypt.c
Normal file
139
clamav-devel/libclamav/suecrypt.c
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright (C) 2006 aCaB <acab@clamav.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
** suecrypt.c
|
||||
**
|
||||
** 05/08/2k6 - Quick RCE, started coding.
|
||||
** 06/08/2k6 - There were large drops of black rain.
|
||||
** 07/08/2k6 - Found more versions, back to reversing.
|
||||
** 11/08/2k6 - Generic and special cases handler. Release.
|
||||
**
|
||||
*/
|
||||
|
||||
/*
|
||||
** Unpacks and rebuilds suecrypt(*)
|
||||
**
|
||||
** Not sure at all what this stuff is, couldn't find any reference to it
|
||||
** Seems to be popular in dialers, can't say more except...
|
||||
** Christoph asked for it and that's enough :)
|
||||
**
|
||||
** (*) some versions or maybe only some samples
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
** TODO:
|
||||
**
|
||||
** needs performance tests
|
||||
**
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_EXPERIMENTAL
|
||||
#if HAVE_CONFIG_H
|
||||
#include "clamav-config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cltypes.h"
|
||||
#include "others.h"
|
||||
#include "pe.h"
|
||||
|
||||
#define EC32(x) le32_to_host(x) /* Convert little endian to host */
|
||||
#define EC16(x) le16_to_host(x)
|
||||
#define VAALIGN(s) (((s)/0x1000+((s)%0x1000!=0))*0x1000)
|
||||
|
||||
char *sudecrypt(int desc, size_t fsize, struct pe_image_section_hdr *section_hdr, uint16_t sects, char *buff, uint32_t bkey, uint32_t pkey, uint32_t e_lfanew) {
|
||||
char *file, *hunk;
|
||||
uint32_t va,sz,key;
|
||||
int i, j;
|
||||
|
||||
cli_dbgmsg("in suecrypt\n");
|
||||
|
||||
if (!(file=cli_calloc(fsize, 1))) return 0;
|
||||
lseek(desc, 0, SEEK_SET);
|
||||
if((size_t) cli_readn(desc, file, fsize) != fsize) {
|
||||
cli_dbgmsg("SUE: Can't read %d bytes\n", fsize);
|
||||
free(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
va=(bkey>>16)|(bkey<<16);
|
||||
key=((sz=cli_readint32(buff+0x3e))^va);
|
||||
if (!key || key==0x208 || key==0x3bc) key=((sz=cli_readint32(buff+0x46))^va); /* FIXME: black magic */
|
||||
|
||||
if (key!=pkey) {
|
||||
cli_dbgmsg("SUE: Key seems not (entirely) encrypted\n\tpossible key: 0%08x\n\tcrypted key: 0%08x\n\tplain key: 0%08x\n", pkey, key, sz);
|
||||
va=0;
|
||||
for (i=0; i<4; i++) {
|
||||
va=(va<<8)|0xff;
|
||||
if (((key&va)|(sz&(~va)))==pkey) {
|
||||
key=pkey;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i==4) cli_dbgmsg("SUE: let's roll the dice...\n");
|
||||
}
|
||||
cli_dbgmsg("SUE: Decrypting with 0%08x\n", key);
|
||||
|
||||
i=0;
|
||||
while(1) {
|
||||
if (!CLI_ISCONTAINED(buff-0x74, 0xbe, buff-0x58+i*8, 8)) {
|
||||
free(file);
|
||||
return 0;
|
||||
}
|
||||
va=(cli_readint32(buff-0x58+i*8)^bkey);
|
||||
sz=(cli_readint32(buff-0x58+4+i*8)^bkey);
|
||||
if (!va) break;
|
||||
cli_dbgmsg("SUE: Hunk #%d RVA:%x size:%d\n", i, va, sz);
|
||||
for (j=0; j<sects; j++) {
|
||||
if(!CLI_ISCONTAINED(EC32(section_hdr[j].VirtualAddress), EC32(section_hdr[j].SizeOfRawData), va, sz)) continue;
|
||||
hunk=file+EC32(section_hdr[j].VirtualAddress)-va+EC32(section_hdr[j].PointerToRawData);
|
||||
while(sz>=4) {
|
||||
cli_writeint32(hunk, cli_readint32(hunk)^key);
|
||||
hunk+=4;
|
||||
sz-=4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (j==sects) {
|
||||
cli_dbgmsg("SUE: Hunk out of file or cross sections\n");
|
||||
free(file);
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
va=(cli_readint32(buff-0x74)^bkey);
|
||||
cli_dbgmsg("SUE: found OEP: @%x\n", va);
|
||||
|
||||
hunk=file+e_lfanew;
|
||||
hunk[6]=sects&0xff;
|
||||
hunk[7]=sects>>8;
|
||||
cli_writeint32(hunk+0x28, va);
|
||||
memset(hunk+0xf8+0x28*sects, 0, 0x28);
|
||||
|
||||
return file;
|
||||
}
|
||||
#endif
|
30
clamav-devel/libclamav/suecrypt.h
Normal file
30
clamav-devel/libclamav/suecrypt.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (C) 2006 aCaB <acab@clamav.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_EXPERIMENTAL
|
||||
#ifndef __UNSUE_H
|
||||
#define __UNSUE_H
|
||||
|
||||
#include "cltypes.h"
|
||||
#include "rebuildpe.h"
|
||||
|
||||
char *sudecrypt(int, size_t, struct pe_image_section_hdr *, uint16_t, char *, uint32_t, uint32_t, uint32_t);
|
||||
|
||||
#endif
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue