COMMAND
quota
SYSTEMS AFFECTED
Win2000
PROBLEM
Dave Tarbatt found following. He has been looking into disk
quotas under Windows 2000 and have uncovered a few anomalies. On
top of a few peculiarities there appears to be a bug which allows
a user to exceed their disk quota by as much as they wish. This
was tested with Windows 2000 Professional build 2195 (release
version). Existing files can be extended even if a user is over
quota. If exploited by a malicious user then at best it is a
nuisance at worst it may act as a DoS if the disk if filled.
After playing around with the newly introduced disk quotas in
Windows 2000 he soon uncovered a bug which would allow an
ordinary, unprivileged user to exceed their allocated disk quota
and fill a disk/partition. Under normal circumstances when a user
is under quota he discovered by experiment that new files can be
created upto a size of (Quota - UsedSpace + 2KB - 1byte), i.e.
they can go overquota by up to 2047 bytes. Not too much of a
problem. Extending existing files can be up to (Quota - UsedSpace
+1KB -1byte) i.e. up to 1023 bytes overquota - nothing much to be
worried about.
However, if you are overquota new file creation is only possible
upto 728 bytes if (UsedSpace < Quota+1KB), i.e. you havn't gone
more than 1KB overquota. Exisiting files can be extended by up to
736 bytes up until (UsedSpace >= Quota+1KB). Using this point
alone, Dave created a lot of files with "echo.>file0000" at 2
bytes each to use up the user allocated diskquota and extended
them up to the 736 byte limit per file - he was now way over
quota. The limit of how far over quota he could go depended on
his initial quota and how many tiny files he could create up until
he hit the quota then extending them all. What if we create 0
byte files?.
Oh dear! If you are under quota you can create as many 0 byte
files as you wish. They count towards nothing. Then extend these
files by 736 bytes and your disk starts filling up and up and up...
How to recreate? Create an ordinary unprivileged user and give
them a diskquota of, say, 1MB. Open a command prompt and using
whatever means you wish, create a lot of 0 byte files (e.g.
SHIFT>FILE0000). Then append/extend those files by up to 736
bytes (e.g. ECHO 736-characters-here>>FILE0000). If you try and
extend beyond 736 bytes the file and it's contents get chopped off
at 674 bytes so for speed disk filling with fewer files don't try
and go beyond 736 bytes. See below for a batch file to create
10,000 of 0 byte files then extend them all to 736 bytes.
OverQuota.BAT:
@echo off
echo Windows 2000 disk (over)quota exploit
echo Dave Tarbatt 26/02/2000 http://redirect.to/null/
rem
rem Create 10,000 zero byte files ('REM>filename' used to work but not any more)
echo Creating 10,000 zero byte files...
for %%i in (0 1 2 3 4 5 6 7 8 9) do for %%j in (0 1 2 3 4 5 6 7 8 9) do for %%k in (0 1 2 3 4 5 6 7 8 9) do for %%l in (0 1 2 3 4 5 6 7 8 9) do shift>FILE%%i%%j%%k%%l
rem
rem Create a 736 byte file (the largest extent that works)
echo Creating 736 byte file...
shift>736.txt
for %%i in (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22) do for %%j in (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15) do echo.>>736.txt
rem
rem Appending the 736 byte file to all the empty ones (extend them)
echo Appending 736 bytes to all 10,000 files...
for %%i in (0 1 2 3 4 5 6 7 8 9) do for %%j in (0 1 2 3 4 5 6 7 8 9) do for %%k in (0 1 2 3 4 5 6 7 8 9) do for %%l in (0 1 2 3 4 5 6 7 8 9) do type 736.txt>>FILE%%i%%j%%k%%l
rem
echo.
echo Done. Massively over quota!
After some experiments Frank Heyne thinks he found the reason
for this behaviour; there is a large flaw in the implementation
of disk quotas in W2K.
When you create a file, at least one cluster on disk is used for
this file. Even when you create a file with a content of 0
bytes, a directory entry, a file header and a security descriptor
are created for this file, using some disk space.
The only reason we can imagine is to stop users from occupy too
much disk space. Disk space used by the current user is not
available for other users.
How should it be done? Obviously, the only way to do this, is
decreasing the space available for the user every time he
occupies a new chunk on disk by the size of this chunk. When this
is done correctly, the sum of the bytes used by the current user
and the free bytes available for all users should always result
in the same number (as long as only this one user is using the
machine).
How is it done? The current implementation works as follows.
When the user creates a new file, only the size of the data
stream of this file is subtracted from the number of bytes
available for the user! File header, security descriptor, unused
space of the disk sector behind the data - all these bytes are
lost for other users, but are not taken into account for the
current user!
So we have the result Dave Tarbatt reported here - despite disk
quotas every user can fill up the disk with files of 0 bytes
content. There is the bug, not in the possibility to fill up
these files with some hundred bytes after they are created! What
is filled up here is the space in the sectors reserved for these
files - it is lost for other users anyway, even when not filled by
the curent user!
Testing? There is an API function GetDiskFreeSpaceEx which
reports:
- the total space available for the current user
- the free space available for the current user
- the free space available for all users
Frank made the tests on a 2 GB partition with clusters of 2048
bytes. There were already files deleted by that user. What he
did repeatedly was creating a file with 100 bytes data and running
GetDiskFreeSpaceEx afterwards. The results:
1. Normally the free space available for the current user did not
decrease at all after creating a new file. But sometimes it
decreased by 2048 bytes.
2. The free space available for all users sometimes did not
decrease, but sometimes it decreased by 4096, 8192 or 16348
bytes when a single file with 100 bytes data was created.
3. The free space available for the current user was decreasing
significantly slower than the free space available for all
users, though no other user was logged on at the test machine.
Frank did not test how disk quota products of third parties work,
but the way Microsoft's quota manager works is just broken.
SOLUTION
None known. However, to prevent DoS on servers you should not
permit people to write to the same partiton that the operating
system resides on.
A NTFS file system isn't limited by the number of clusters on a
disk. The various components of a file are called streams, and
the $data stream is just one of them. If a file has a small data
segment, then the entire file can be stored in the MFT, along
with the security descriptor, attributes, name, etc. So the
minimum amount of disk space that a file can take up is the size
of one MFT entry, which may or may not involve an additional
cluster. If the file grows, then the data stream within the MFT
is replaced by a pointer to the cluster where the data is stored.
Hence, the concept of inodes isn't germane to NTFS.