Buffer Overflow in MySQL 43
maedls.at writes "Here is a short description of the Vulnerability:Passwords of MySQL users are stored in the "User" table, part of the "mysql" database, specifically in the "Password" field. In MySQL 4.0.x and 3.23.x, these passwords are hashed and stored as a 16 characters long hexadecimal value, specifically in the "Password" field. Unfortunately, a function involved in password checking misses correct bounds checking. By filling a "Password" field a value wider than 16 characters, a buffer overflow will occur. For details and proof of concept see: http://lists.netsys.com/pipermail/full-disclosure/ 2003-September/009819.html"
*ugh* (Score:5, Funny)
Empty set (0.00 sec)
Re:*ugh* (Score:1)
Table 'slashdot.internet_connected_mysql_servers' doesn't exist
Where can I go to get this version of MySQL?
Re:*ugh* (Score:1)
I'm afraid your server couldn't take a slashdotting
damn... (Score:1, Redundant)
Not too bad though (Score:5, Informative)
ie. access to the mysql table itself
Re:Not too bad though (Score:4, Informative)
The mysql user must have administrative privileges to exploit the bug
ie. access to the mysql table itself
If that is the case, there should be no problem unless the specific database for your application is accessed with the MySQL 'root' user (which would be very bad design) .
JP
Re:Not too bad though (Score:2)
Good to know it's fixed. And promptly too.
Re:Not too bad though (Score:5, Informative)
First, ALTER the User table of the mysql database (the table that contains the usernames and passwords of users allowed to connect to the database server) so that the Password column can have more than 16 characters.
Second, UPDATE a row in the User table to give a user a "password" consisting of your buffer overflow code.
Third, get MySQL to try to process that user's login info. This is done with "FLUSH PRIVILEDGES" which flushes the cache of users and their passwords.
You now can execute code in the context of the MySQL server.
Of course, the MySQL server should be running as an unpriviledged user anyway. And most people who can admin the MySQL server can probably admin the whole box.
Just goes to show that nobody's perfect, I guess.
Vendor Status (Score:5, Informative)
MySQL AB has been informed of this vulnerability on Wed, 6 Aug 2003.
The issue was confirmed and fixed in the developpment tree the next day.
[side note: the MySQL developpment team is not only very reactive, the guys
are also extremely nice]
Not too bad really (Score:4, Informative)
But there is no point tempting fate, and it's a good excuse to update anyway. :)
Bugs fixed: [mysql.com] * Fixed buffer overflow in SET PASSWORD which could potentially be exploited by MySQL users with root privileges to execute random code or to gain shell access (thanks to Jedi/Sector One for spotting and reporting this one).
All fixed. Get your 4.0.15 here [mysql.com].
Unfortunately, it seems that release 3.23.58 is "to be released soon". So people with older installations will have to be extra careful until an update is released.
Q.
Re:Not too bad really (Score:2)
How is still possible? (Score:3, Interesting)
Buffer overflows have been known for decades, and lots of programs exist to automatically search for them. And it's not that difficult either for someone who knows nothing about programming, to enter very large values in some fields, and see if a "Segmentation Fault" occurs.
My question here is, why are these buffer overflows still so prevalent? Is it because programmers are lazy? Too lazy to scan the source code with automated scanners to find buffer overflows? Knowing that MySQL is a very crucial program, that's just begging to be exploited, why did no one (else) care to search for buffer overflows before the source code was released? Or is there a deeper problem here?
Problem is in C libraries (Score:2, Interesting)
Re:Problem is in C libraries (Score:2, Interesting)
Re:Problem is in C libraries (Score:2, Informative)
Re:Problem is in C libraries (Score:1, Redundant)
Re:How is still possible? (Score:3, Interesting)
This issue can be seen in this exploit. The programmers knew the structure of the mysql database tables. Because of this they assumed the input to the function would always come from the mysql tables and wrote the code ac
Re:How is still possible? (Score:5, Insightful)
It isn't that programmers are lazy (which we are, but that isn't the problem). It is that programmers can't keep perfect track of everything at once, and have to make assumptions. What am I supposed to tell my boss, something like "I can't start on that bug fix until I have read and perfectly comprehend all 1,500,000 lines of code in the product"? No, I have to try to get an overall idea of how things work, and dig into the details as I think necessary. This sometimes means I will miss a detail that is indirectly connected to the work at hand, and therefore make a mistake. The most important (in my opinion) and difficult work being done in computer science is in ways to organize things so that all of the details needed for a single problem are obvious and connected. Thus comes OOP and other programming methodologies that try to keep programs organized and well-structured.
If you read the article, it showed the code at fault. It wasn't just one function, but two. One function "validated" the password. Later, another function worked with the password, assuming (correctly) that it had already been "validated". The problem was that the two functions had different ideas about what it meant to be "validated". If the error had all been within one single function, then this would be almost inexcusable. But since the problem was a coincidence of two less significant flaws, it was much harder to detect. And if some automatic overrun detection tool were to flag the code, the programmer examining the warning would very likely have determined that the tool's warning was incorrect -- "the parameter was validated already before this function call, so the buffer overrun cannot happen."
Next, you can't just enter larger values to detect everything. In this case, the database ships with a 16 char limit on the password field. So sending a large value for password wouldn't work -- the value would be truncated when it went into the database. The bug is triggered by three unrelated operations in sequence: you alter the database to allow for larger values, THEN set a large value for password, and THEN flush the table. Automatic tools can't try every possible sequence of input, just a subset.
Aside from simply "getting it right in the first place" (i.e. never making invalid assumptions, which is pretty much impossible) this kind of problem can be avoided by using one of two programming.
The first is "Defense in Depth", which means that a function isn't allowed to assume that a parameter has been validated -- every function must validate every parameter ever time it is called. This works, but it has performance penalties (a parameter can be passed around hundreds of times, so now we validate it hundreds of times instead of just once). It also is boring to program the validation code, and therefore likely to be forgotten in some crucial function. Finally, validation is hard to get exactly right, and if the concept of a valid parameter changes, you have to go change it in every place it is validated.
The second is automatic handling of the situation. Use a string class of some sort, like STL's string, or use a "safe" language like Java or C#. This is better, but again it has costs in performance, as well as ignores the problem of interoperating with existing code.
So the "deeper problem" is that we can never get everything perfect by hand, and the automatic solutions come at a price we often aren't willing to pay. Solution? None at the moment. Perhaps in the future, less code will be written in "unsafe" languages (languages with potential for overflows), so buffer overflows will only be a problem for those who write the compilers and runtimes for those safe languages. But I wouldn't hold my breath -- it will be a while. And when that day finally comes, there will still be plenty of other ways to "root" a machine -- buffer overflows aren't the only way to overcome security measures.
Re:How is still possible? (Score:2)
Re:How is still possible? (Score:1)
For one thing, I think it is reasonable to be upset about the vulnerabilities, and to hold Microsoft at least somewhat accountable -- even if it is almost impossible to catch all vulnerabilities, it still causes problems to people. It is hard to determine whether or not Microsoft has "more than their share" of vulnerabilities, since any comparison I can think of is like apples to oranges. But they do have more than anybody would like them to have (except hackers and people who want to see them fa
Re:How is still possible? (Score:1)
Re:How is still possible? (Score:2)
If that function had documented itself such that client functions know it will return correct results as long as you pass it proper data (multiple of 8, = 16), then it's completely up to the client code to e
Re:How is still possible? (Score:2)
Great post
Re:How is still possible? (Score:1)
Re:How is still possible? (Score:1)
I would like to see a specific example of OOP doing such. Most examples I have seen of such simply trade one grouping aspect for another. They bring one aspect together, but force another apart, similar t
Re:How is still possible? (Score:1)
Yes, everything is a tradeoff. That is why it takes experience to become a good programmer, so you have a feeling of which method is most appropriate.
From my experience, OOP is most important in application and systems development. OOP means that you can provide very specific and enforceable rules about how data can be manipulated and used, and a very limited set of code that can be blamed if any of the rules are broken. The private data of a class is o
Re:How is still possible? (Score:1)
Re:How is still possible? (Score:1)
else if (length % 8)
has been 'fixed' by changing it to
else if (length % 8 || length > 16)
Basically, what that says is that the valid lengths are 0, 8 and 16, and nothing else.
Why didn't they code it using the logic:
else if (length!=0 && length!=8 && length!=16)
in the first place if that's what they meant? Except that that contains mgic numbers which should be replaced. The whole "%8" nonsense is unnecessarily indirect. Why couldn't this check be pulled out as
Re:How is still possible? (Score:1)
It is not a problem of laziness with programmers. People make mistakes, that's the nature of things. If you force people to take care of bounds checking themselves, they eventually will fail to miss a case. This has been proven over and over and over and over again, since buffer overflows became known as a security problem with the first Internet worm to appear.
The only thing you can do against buffer overflows is choosing an implementation lan
Re:How is still possible? (Score:1)
> buffer overflows still so prevalent?
In a large program like MySQL, religiously checking each and every
buffer, each and every time anything is stored in it, without missing
any, is *hard*, because there are *lots* of buffers and they get
things stored in them by *lots* of different parts of the code.
The real solution is to use a langauge with builtin memory management.
Until recently this was impractical for performance reasons, but with
VHLL
Not that bad in the wild (Score:3, Interesting)
a) the MySQL instance needs to be installed as root or other priviledged user
b) the attacker needs to have an admin account
c) the attacker needs direct access to MySQL (either via a shell account on that box or over the MySQL port)
Fortunately:
a) the default install of MySQL via RPM on RedHat is as "mysql:mysql"
b) there is no default "admin" account
c) MySQL boxes are very rarely directly exposed to the internet, and the default install does not allow remote connections at all
So even though there is a pretty bad buffer overflow, the multi-layered security approach of MySQL fends off the likelihood of widespread exploitation. Note how different this is than the SQL Server vulnerabilities that have plauged the internet for the past few years.
And it speaks to the strength of OSS that the bug was found and patched at all. And to MySQL AD for applying the patch ASAP. In the closed source world, the same type of people that find exploits like this tend to not be as respectful of the software manufacturers or their customers.
Re:Not that bad in the wild (Score:2)
Regarding point a: My impression was that it does not need to be a priviledged user; by exploiting as user mysql, you still get all the access that mysql has, and may be able to use this to chain into a privilege elevation attack.
Regarding point b: If RedHat does not, by default, have any "admin" account, how are new users added?
Regarding point c: It is not unheard of, or even uncommon, for there to be flaws in web pages allowing SQL access (sometimes within certain limits).
While it's not the end of the
the proof of concept (Score:2)
> USE mysql;
> ALTER TABLE User CHANGE COLUMN Password Password LONGTEXT;
> UPDATE User SET Password =
'3.1415926535897932384626433832795028841971693 9 937 51058209123456781234567812345678123456781234567812 34567812345678123456781234567812345678123456781234 56781234567812345678123456781234567812345678123456 7812345678123456781234567812345678...' WHERE User = 'abcd';
> FLUSH PRIVILEGES;
[Connection lost]
Re:the proof of concept (Score:1)
You know this is just amazing to me that this is even considered a bad issue. That it was even posted on Slashdot I mean, if you are already admin chances are you have shutdown priv so what is the difference?? Seems to me mysql caught this way early and so that it will never cause a real problem.
Eric