Creation Time:
Article Attribute: original
Article submitted: jamba1aya (alpha_echo3_at_yahoo.com.cn)
Ding Jie "D", easy to use
------ Discuz! Free Version Security Analysis
Author: [I .t. S] jambalaya
Forum: www.itaq.org
I remember that when I first met an analyst, he asked me what I was reading recently. I told him that I was continuing to read the reei forum.CodeHe said with a smile: "What kind of vulnerabilities do you want to read? Read discuz! For security, this is still challenging ". After reading for a few days, I thought it was really a hard bone. After that, I slowly forgot about the many things.
Not long ago, a friend of mine joked with me: "If you can find the discuz vulnerability, I will invite you to have a good goat. You cannot find it. Please eat it ." (Note: yangba is a special dish in a nearby restaurant.) A friend asks that the vulnerability must be usable when magic_qoute_gpc is on by default in PHP, and within one week. At that time, I thought about the great goat, and I was so confused that I had never thought about it ......
So the story begins ......
I. Versions involved in the Vulnerability
Discuz! Free versions earlier than 2.0 (commercial version not available ). 1.01 and lower vulnerabilities may be exploited differently, but they still exist.
Ii. Vulnerability Analysis
Because install. php's Program Writing errors may cause malicious users to construct statements that can be written to webshell to control the entire server.
In the last few nights, I read all the variables in the front-end file, as long as they are the variables in the database call. Check whether there is any lax filtering. After reading it, I think there are indeed a lot of lax filtering, but they are all protected by single quotes. In PHP, if magic_qoute_gpc = on (default), the compiler will automatically escape special characters such as single quotes, which is very difficult to change the program execution process. This greatly increases the difficulty of intrusion, and ensures its security to some extent. This is also why a friend asks that magic_qoute_gpc can still be used when it is on. If you need single quotes to exploit the vulnerability, go to discuz! The Forum is basically useless.
After reading the database connection of all files, I did not find anything valuable. At this time, my thinking started to get a little messy. I was wondering if I should try to read all the code from the programmer's thinking logic loophole, find out what programmers are not fully aware of when writing a program. These vulnerabilities are mostly caused by incorrect context logic, or they are not unique. Some of them should be noted, however, the Administrator ignores this issue.
It seems that nothing can be left to read the code. Since the target is a logical error, you must take a closer look at the context relationship. Therefore, choose to start reading from the entry point. The entry point should be logging. php, because this is the place to log on, and everyone will log on to the Forum from here. Come on!
Old Rules: Let's look at a piece of code first:
========= Codz begin ============
50 $ errorlog = "$ username/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_pw, M. status, M. styleid as styleidmem, M. lastvisit, U. groupid, U. isadmin, U. specifiedusers like '%/T $ username/T %' As specifieduser
From $ table_members m left join $ table_usergroups U on u. specifiedusers like '%/T $ username/T %' or (U. status = m. status and (U. creditshigher = '0' and U. creditslower = '0' and U. specifiedusers = '') or (M. credit> = u. creditshigher and M. credit <u. creditslower )))
Where username = '$ username' 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 ========================
Let's take a look at this code. He first records the user name and password entered. The password only takes the first two digits, then the last one, and assigns the IP address and time together. Then, store the MD5 value of the password in the database. If you think we can change the database statement execution process, it will be wrong. There is nothing we can do with single quotes (at least I can't do anything, unless it is encrypted ). If the user name and password are incorrect, the invalid user name and password will be recorded in illegallog. php. During the entire process of recording the wrong password, the variable has not been verified. That is to say, if I enter the wrong user name, it will not be checked and recorded directly. If my wrong user name is an executable code, it will be recorded. After it is recorded, we can call this file to form a shell.
Are you excited now? Sorry, your excitement is invalid. I am not excited at all, because I paid special attention to discuz when I read it for the first time! For file handle operations, it does not filter individual variables, but it is installed. during the initialization in PHP, all the operations used are provided. A sentence is added at the beginning of the data file ending with PHP: <? PHP exit ("Access Denied");?>. This is written during initialization. We should all understand the role of this sentence. You cannot call what you write, because it has ended at the beginning.
This is obviously unsuccessful. I'm a little bored. Do you think five sheep are good? Lose! I threw down the code in a bid and ran to my grandmother's house. I put my eyes on her. (It is one of my favorite tasks to play in front of my grandmother, play tricks, and make troubles) I repeatedly cursed discuz in front of my grandmother! How can I read the code carefully. Grandma doesn't know what I'm talking about, and doesn't care if I make trouble with her. She continues watching her TV. After a while, I replied, "You are a child. You are careless and not careful at all. What code do you think you have? (it is probably code) it's broken again ". I climbed back to my room with a smile. Sitting in front of the computer, I drank a cup of boiled water and calmed down.
It is necessary to be a safe person who is careful, persevering, self-taught, and good at summing up. Go back and read the logging. php file again to see if there is anything you ignore. The file is not long. I read it again and thought it was okay. Since there is no problem here, let's put it into that sentence. <? PHP exit ("Access Denied");?> How is this sentence written?
So I flipped through 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 Denied/");?> /N ");
33 @ fclose ($ FP );
34 result ();
35}
......
1389 loginit ('karmalog ');
1390 loginit ('illegallog ');
1391 loginit ('modslog ');
1392 loginit ('cplog ');
1393 dir_clear ('./forumdata/templates ');
1394 dir_clear ('./forumdata/cache ');
=========== Codz endz ============
Obviously, the loginit function is written to illegallog. php. <? PHP exit ("Access Denied");?> This sentence. In this way, even if the code is written, the execution cannot be called because of the existence of the sentence. We have completely entered a dead end. However, I seem to have some problems with this code. I have read it carefully. Why is that fopen so difficult. If you remember correctly, the syntax format of fopen should be as follows:
Resource fopen (string filename, string mode [, int use_include_path [, resource zcontext])
The first two parameters are the file handle or the file to open. The second parameter specifies the open mode, such as read or write. We would like to remind you that these two parameters are required. For example, we write jambalaya in the directory. PHP: fopen ('. /jambalya. PHP ', 'w'), which must be selected later. Otherwise, an error is returned. But we noticed that there is only one parameter in his code, so how can the program be correctly executed?
Let's do a test, create a 1.php, and write the following code:
============= Codz begin ==============
$ Fp = @ fopen ('./2. php ');
@ Fwrite ($ FP, "<? PHP exit (/"Access Denied/");?> /N ");
@ Fclose ($ FP );
Echo "success! ";
============= Codz endz ==================
Make one and discuz here! In the same environment, if this program is successfully executed, a 2.php file will be generated in the root directory, and the first line of 2. php should be <? PHP exit ("Access Denied");?>, Success is displayed on the screen. In fact, success is used to let us know where the program is executed. We submitted http: // 127.0.0.1/myhome/1.php in the URL. Success is displayed on the screen, which indicates that it has been executed to the end of the program. But when checking the directory, we found that the file named 2. php was not generated, that is, we failed to write. You may be surprised that there should be an error message when writing fails. Yes, but because @ is added before fopen, @ is used in PHP to suppress all errors generated by calling functions. In other words, even if an error occurs, no error is reported.
My lessons are correct. I am so careless!
If everything passes through my ideas, it means that during the installation and initialization, The discuz/forumdata directory will never contain any content due to the incorrect use of fopen. <? PHP exit ("Access Denied");?> The code's illegallog. php file, but because of the suppression of error information, the installation will still show that the initialization is successful, but it is not initialized, not to generate illegallog. php. If no Initialization is performed here, the generation and initialization of illegallog. php will be completed in logging. php. The initialization of logging. php does not write any protection statements or filter measures to the file to avoid user calls. Everything is clear here. To put it bluntly, it is because the install. php file is incorrectly initialized. We can write malicious code through logging. php, and then call that file to generate a shell to control the entire website.
III. Usage
you do not need to register any account. On the login page, enter the username 123456. Press enter. As you may understand, the first two digits of the password are displayed. In this way, what is stored in illegallog. php is:
* ***** 6 127.0.0.1 1022383175
you can check the PHP settings. Let's first check whether the register_globals setting is on. (Most of the websites are on.) Well, then we enter them in the login port. , We recommend that you do not use system (). Many websites disable the system () function during the test.
then we call http: // 192.168.0.13/forumdata/illegallog. php? Cmd = dir
a pile of junk information is displayed. Can you see the directory is listed below? However, writing data in this way is a little troublesome, because during the experiment, there were more than 0.1 million registered users on large websites, so the file would be surprisingly large and the opening speed would be very slow.
now we can write data like this , We changed PHP shell to JPG format and uploaded it to the host.
call in URL:
http: // 192.168.0.13/forumdata/illegallog. p... chments/jam. php
then we directly submit the URL:
http: // 192.168.0.13/Attachments/jam. PHP ?... A shell!
someone may ask me why I did not enter a shell directly in the user name. Why do I enter " " separately in the user name and password ". In fact, I also thought about this, and I directly entered the user name in the local machine test also succeeded, but when testing on other websites, but found that as long as the input It will be filtered out. I don't know if it is a version issue. (I wanted to pull the code of others and compare it. Later I was lazy and did not get it. If you are interested, you can test it on your own)
If register_globals is off, isn't it enough? The answer is no. Here is a space for everyone to think about. Think about it, hey. We don't have to write data at a time. By constructing our own statements, we can bypass the restrictions and implement other functions to write a complete shell.
here, by the way, the free version below version 1.01 may be used differently. The difference is that the file name is changed. I will not explain it here, let's test it by yourself. After all, you can learn more things only by yourself.
If we don't pay attention to any details, it will lead to the collapse of your defensive line. It's not a waste of words to say that the treasure of a thousand miles has fallen into the ant nest!
The entire article ends here. I want to add something here. At the beginning, I found this vulnerability and wanted to put it in the hidden version of itaq.org for the IT security team. I didn't want to announce it. It's not because I am stingy. I found many forums in commercial versions during the test. This vulnerability cannot be used and is initialized correctly, I thought I had a problem with the version I got, so I didn't plan to write it out. Later, some friends in the hacker circle asked me to help test several discuz! They told me their discuz when I was working on a Forum website! After the Forum is a free version downloaded from the Internet, I used this vulnerability to easily go in and get the permissions. Later, I spoke to a large number of free versions of discuz! This vulnerability can be used to test the free version of discuz! All attacks can be successful, and there are not a few users using the free online version. Once successful, it is a vulnerability that can further control the entire server. Only the free version can be attacked. So I decided to write it out for discussion.
The text is in a hurry and the technology is limited. If the article is incorrect, I hope you can give me a question at www.iraq.org.