This page's shorter URL is http://tinyurl.com./ytllr.
What's the gen on the CSRSS backspace bug in Windows NT 4/NT 2000/NT XP ?
This is the Frequently Given Answer to that question.
The CSRSS Backspace Bug is a bug in the Win32 subsystem server
process (csrss.exe
) in Windows NT. It is particularly
notable for several reasons:
As far as I can determine, the first public report of the bug was on 2001-10-23, in a message posted by Masaru Tsuchiyama in the comp.os.ms-windows.programmer.win32 newsgroup on Usenet, who attributes its discovery to "a co-worker".
The bug definitely affects all versions of Windows NT from version 4 onwards (Windows NT 4, Windows NT 2000, and Windows NT XP) irrespective of service pack, except for Windows NT 2000 with service pack 3 applied and Windows NT XP with service pack 1 applied.
Because csrss.exe
has been a part of Windows NT from the
beginning, it probably affects Windows NT 3.5 and Windows NT 3.1 as well.
(I have seen a report that appears to confirm that this bug does indeed
affect Windows NT 3.5 and Windows NT 3.1. However, this report was
originally written in German, and may have been incorrectly translated.)
No version of DOS-Windows (DOS-Windows 3.x, DOS-Windows 95, DOS-Windows
98, or DOS-Windows ME) is affected by this bug. DOS-Windows does not have
a csrss.exe
process.
This bug causes an access violation in the csrss.exe
process.
Normally, with other processes, an access violation causes a message box
to be displayed containing a dump of the state of the process, and the
process to be terminated. If a debugger is installed, one is given the
option to debug the process. The Windows NT operating system carries on
unaffected, and other processes continue to run.
However, Windows NT considers csrss.exe
to be a vital system
process, just like Unix considers process 1, init
, to be a
vital system process. If process 1 dies for whatever reason on Unix, the
kernel issues a "panic" message. If csrss.exe
dies for
whatever reason, Windows NT considers the error to be unrecoverable and
halts with a "bug check" (i.e. the infamous "Blue Screen of
Death"). (Windows NT considers winlogon.exe
to be similarly
vital, and will halt with a "bug check" if that process ever dies for any
reason too.)
No application program data will be saved. Files and directories whose contents are not in the process of being altered at the time of the crash are very unlikely to be affected, however.
Aside:csrss.exe
owes its very existence to a notion, taken from microkernel operating systems, that system services run as ordinary application processes, rather than as part of the kernel. The very intention of this design is that if a system process dies, it does not take the kernel with it. Unfortunately, Windows NT committing suicide in sympathy when it notices thatcsrss.exe
has died defeats this entire idea. (Windows NT is not a microkernel operating system, of course.)
This bug is triggered by writing ordinary text characters to a console. Here is the simplest means for doing so:
notepad
does not.
However, edit
does. Simply press
[Ctrl-P] before pressing the [TAB]
and [Backspace] keys.)
A simple QBASIC program to create such a text file is:
OPEN "CSRSSBUG.TXT" FOR OUTPUT AS 1
FOR I% = 1 TO 4096
PRINT #1, I%; CHR$(9); STRING$(16, 8);
NEXT
TYPE CSRSSBUG.TXT
One can also write a short (around 10 lines) C or C++ language program to
trigger the bug. This bug involves the actual handling of backspace
characters when written to consoles using high-level console I/O.
The exact mechanism by which the text characters reach the console is
immaterial. Programs that call WriteConsole
or
WriteFile
, or any C library routines that are layered on top
of them such as fputs
or printf
, will all cause
the bug to trigger.
This is true even of non-Win32 Windows NT programs that perform
high-level console I/O, such as POSIX Windows NT programs.
Displaying the file using the POSIX cat
command supplied by
Microsoft will trigger this bug, for example.
One can also write a short script to trigger this bug in any scripting language that allows one to write characters to standard output, including VBScript, perl, and REXX. Here is a 3 line REXX script, for example:
do forever
call charout ,"090908080808080808080808080808080808"X
end
This bug will not be triggered by programs that display data using
low-level console I/O. Displaying a text file containing
backspace characters using a list
command that presents a
scrollable "full-screen" interface, for example, will not trigger this
bug.
This bug is not triggered by the cat
command supplied by
Cygwin. (Ironically, given that Cygwin is largely used to compile programs
that use the POSIX system API, Cygwin programs are actually Win32 programs,
not POSIX Windows NT programs. Cygwin interposes its own processing on top
of the Win32 high-level console I/O processing which by chance
happens to avoid this bug.)
This bug cannot be triggered by a QBASIC program. The PRINT statement in QBASIC actually performs low-level console I/O internally.
No access controls influence the triggering of this bug, and no user privileges are required in order to trigger it.
Microsoft worms: No known Microsoft worm exploits this bug.
However, given that Visual BASIC code to allocate a console and write a string of characters to it is supplied in Microsoft KnowledgeBase article Q171654 , it would not be difficult to modify an existing Microsoft worm written in VBScript or Visual BASIC to exploit this bug.
ActiveX: No known ActiveX control exploits this bug.
However, it is trivial for an ActiveX control to exploit this bug. ActiveX controls do not execute in a "sandbox", and are not subject to restrictions on what system APIs they can call. An ActiveX control can easily allocate a console and write characters to it.
ActiveX controls can, of course, perform other mischievous actions, too,
such as calling the DeleteFile()
or
ExitWindows()
system API functions. However, the difference
between those actions and exploiting this bug is that appropriate choices
of access controls and user privileges for the user accounts that use
Microsoft's web browser can prevent ActiveX controls from being able to
delete files or reboot the machine, whereas there are no access controls
or user privileges that can prevent an ActiveX control from allocating a
console and writing characters to it.
HTTP server denial of service attacks: It appears, after a superficial analysis, to be non-trivial to cause, via a web server, a machine running Windows NT to crash, using this bug, from an HTTP client. A complete analysis has not yet been performed, however.
JavaScript: No analysis has yet been performed to determine whether or not this bug can be exploited via JavaScript embedded into a web page.
VBScript: It appears, after a superficial analysis, to be possible to exploit this bug via VBScript embedded into a web page. No practical test has yet been performed, however.
Java: It appears to be impossible to exploit this bug from a web browser applet written in the Java language.
Console I/O functions specific to Win32 would have to be called in order to allocate a console to the web browser process and write to it. Java does not provide standard libraries that provide access to operating-system-specific console I/O. Such operating-system-specific features can be accessed via "native methods" in a fully-fledged standalone Java application, but the "sandbox" in which Java applets run in web browsers prevents them from using "native methods".
This bug is a combination of
The design flaw in Windows NT is that, as has already been described,
Windows NT commits suicide in response to the death of the
csrss.exe
process. The bounds-checking error in the handling of
high-level console I/O is described here.
In Windows NT, csrss.exe
handles all I/O to and from
consoles. When a character is displayed using high-level console
I/O it is csrss.exe
that performs the nitty-gritty of
actually modifying the console screen buffer (if the character is
printable) and moving the cursor position.
The code in csrss.exe
does not correctly handle the occurrence
of backspace characters at the beginning of lines. (If one invokes the
debug kernel of Windows NT XP, and writes a series of backspace characters
to the console, one sees debug messages being issued by "CONSRV" claiming
that it is ignoring attempts to backspace over the beginning of a line.
Nonetheless, the cursor does move from the beginning of a line to
the end of the previous line in response to a backspace character. It is
unknown whether the behaviour is intended and the message is erroneous, or
the behaviour is erroneous and the message is describing what the
behaviour was intended to be.)
Most importantly, the code in csrss.exe
does not correctly
handle the occurrence, in a single high-level console I/O write operation,
of a backspace character occurring immediately after a TAB character near
the beginning of the first line in the console screen buffer. When, in a
single high-level console I/O write operation, a backspace character occurs
immediately after a TAB character, the console's cursor is erroneously moved
backwards by more than one position. When this occurs at the beginning of
a line, the console's cursor is moved onto the previous line. When this
occurs on the first line, the console's cursor will be erroneously
moved to point to a position outside of the console screen buffer. If,
next, a printable character is sent to the console for display, the console
buffer modification code in csrss.exe
will write to a memory
address in the csrss.exe
process that is outside of the memory
allocated for the console screen buffer.
The exact consequences of this write depend from the exact pattern of heap
usage in the csrss.exe
process, and whether or not the memory
immediately preceding the memory used to hold the console screen buffer cell
array is committed and in use. This in turn depends from what and how many
consoles have been opened, and what other tasks csrss.exe
has
performed. This is one of the reasons that some programs to trigger this
bug do not cause it to trigger in all cases. The text file generated by the
QBASIC program given above repeats the trigger sequence 4096 times, to
increase the probability that the bug will be triggered irrespective of
starting cursor position and memory usage patterns in the
csrss.exe
process. However, in many cases it is only necessary
to write the trigger sequence to the console once and let the access
violation be caused by the next printable character being displayed (such as
when the command interpreter displays its prompt).
There is no known local fix for this bug. Given the analysis, it does not appear likely that a local fix is possible.
As yet, Microsoft has issued no hotfix for this bug.
There will not be further service packs for Windows NT 4. This is a permanent bug in Windows NT 4.
On 2002-03-23, almost five months since this bug became public knowledge and this web page was published, I received an unconfirmed report from a third party that a fixpack that includes a fix for this bug will be released, and that a knowledgebase article covering it "will" be written.
On 2002-08-01, nine and a half months since this bug became public knowledge and this web page was published, Microsoft released the third service pack for Windows NT 2000. With this service pack applied, it appears to be impossible to reproduce this bug. However, neither the change that causes this nor even the bug itself are listed anywhere in either the Windows NT 2000 service pack documentation or in Microsoft's KnowledgeBase. The problem does not officially exist, and is certainly not officially solved. The worry here is that the fact that it is no longer reproducable is coincidental, and (since Microsoft has not recognised it to actually be a problem, and therefore will not include it in any regression testing) liable to be reintroduced by subsequent service packs.
On 2002-09-09, ten and a half months since this bug became public knowledge and this web page was published, Microsoft released the first service pack for Windows NT XP. As with the Windows NT 2000 service pack, there is no official acknowledgement in the service pack documentation either that the bug exists or that it has intentionally been fixed by the service pack. I was unable myself to confirm that the bug is indeed fixed by the service pack, and no-one else had yet reported to me that it is.
On 2002-09-12, the same third party that reported the fixpack information to me reported Microsoft as saying to him that it has
a KB article that should be live soonand that this will, when it appears, be Microsoft KnowledgeBase article ID Q311486. I confirmed that no article by that ID was currently available.
On 2002-09-24, Microsoft KnowledgeBase article ID Q311486, promised six months ago, finally appeared. Its publication date is falsified to claim that it appeared on 2001-10-26. It talks about programs that "pass invalid screen size parameters" when the sample program code that it gives for replicating the bug clearly contains nothing at all relating to screen size parameters. And the explanation that it gives for the actual cause of the problem is woefully incorrect. Were it not that it has taken over eleven months for Microsoft to produce it, one might think that this article was a very badly done rush job.
On 2002-10-29, another third party, who had access to a Windows NT XP system with the first service pack applied, reported to me confirming that on that system it was now impossible to reproduce this bug.