No Logon required-Wukong CRM stored XSS
The reason why audit Wukong saw a cloud burst into CRM's getshell, so he wanted to dig it out! However, if you have limited yourself, you may want to dig out unlimitedly accessible files.
Occurrence point of the story
Vulnerability file:/App/Lib/Action/LogAction. class. php
public function wxadd(){ if($_POST['subject']){ $log = M('Log'); $log->create(); $log->create_date = time(); $log->update_date = time(); $log->role_id = $_GET['id']; if($log->add()){ $this->success(L('ADD SUCCESS', array(L('LOG')))); }else{ $this->error(L('ADD_LOG_FAILED')); } }else{ $this->display(); } }
Determine whether the request is a post request. If the condition is true, add the request. (here, we will say that the website has started GPC, but it is restored when it is stored in the database)
Public function index () {$ m_log = M ('log'); $ m_comment = M ('comment'); $ where = array (); $ params = array (); $ order = "create_date desc"; if ($ _ GET ['desc _ order']) {$ order = trim ($ _ GET ['desc _ order']). 'desc';} elseif ($ _ GET ['asc _ order']) {$ order = trim ($ _ GET ['asc _ order']). 'asc ';} $ below_ids = getSubRoleId (false); $ all_ids = getSubRoleId (); $ module = isset ($ _ GET ['module'])? Trim ($ _ GET ['module']): ''; $ by = isset ($ _ GET ['by'])? Trim ($ _ GET ['by']): ''; switch ($ by) {case 'today ': $ where ['create _ date'] = array ('gt ', strtotime (date ('Y-m-d', time (); break; case 'Week': $ where ['create _ date'] = array ('gt ', (strtotime (date ('Y-m-d', time ())) -(date ('n', time ()-1) * 86400); break; case 'month ': $ where ['create _ date'] = array ('gt ', strtotime (date ('Y-m-01', time (); break; case 'add ': $ order = 'create _ date desc '; break; Case 'update': $ order = 'Update _ date desc'; break; case 'sub': $ where ['Role _ id'] = array ('in ', implode (',', $ below_ids); break; case 'me': $ where ['Role _ id'] = session ('Role _ id'); break; default: $ where ['Role _ id'] = array ('in', implode (',', $ all_ids); break ;} if ($ _ GET ['R'] & $ _ GET ['module']) {$ m_r = M ($ _ GET ['R']); $ log_ids = $ m_r-> getField ('Log _ id', true); $ where ['Log _ id'] = array ('in', impl Ode (',', $ log_ids);} if (! Isset ($ where ['Role _ id']) {$ where ['Role _ id'] = array ('in', implode (',', getSubRoleId ();} if (intval ($ _ GET ['type']) {$ where ['category _ id'] = intval ($ _ GET ['type']);} else {$ where ['category _ id'] = array ('neq', 1);} if ($ _ REQUEST ["field"]) {$ field = trim ($ _ REQUEST ['field']); $ search = empty ($ _ REQUEST ['search'])? '': Trim ($ _ REQUEST ['search']); $ condition = empty ($ _ REQUEST ['condition'])? 'Eq ': trim ($ _ REQUEST ['condition']); if ('create _ date' = $ field | 'Update _ date' = $ field) {$ search = strtotime ($ search);} elseif ('Role _ id' ==$ field) {$ condtion = "is ";} $ params = array ('field = '. $ _ REQUEST ['field'], 'condition = '. $ condition, 'search = '. trim ($ _ REQUEST ["search"]); $ field = trim ($ _ REQUEST ['field']) = 'all '? 'Subject | content': $ _ REQUEST ['field']; switch ($ _ REQUEST ['condition']) {case "is ": $ where [$ field] = array ('eq ', $ search); break; case "isnot": $ where [$ field] = array ('neq ', $ search); break; case "contains": $ where [$ field] = array ('like', '% '. $ search. '%'); break; case "not_contain": $ where [$ field] = array ('notlike', '% '. $ search. '%'); break; case "start_with": $ where [$ field] = array ('like', $ search. '% '); Break; case "end_with": $ where [$ field] = array ('like',' % '. $ search); break; case "is_empty": $ where [$ field] = array ('eq ', ''); break; case" is_not_empty ": $ where [$ field] = array ('neq', ''); break; case" gt ": $ where [$ field] = array ('gt ', $ search); break; case "egt": $ where [$ field] = array ('egt', $ search); break; case "lt ": $ where [$ field] = array ('lt ', $ search); break; case "elt": $ where [$ field] = arr Ay ('elt', $ search); break; case "eq": $ where [$ field] = array ('eq ', $ search); break; case "neq": $ where [$ field] = array ('neq', $ search); break; case "": $ where [$ field] = array ('between', array ($ search-1, $ search + 86400); break; case "nbetween ": $ where [$ field] = array ('not between', array ($ search, $ search + 86399); break; case "tgt ": $ where [$ field] = array ('gt ', $ search + 86400); break; default: $ where [$ Field] = array ('eq ', $ search) ;}$ p = isset ($ _ GET ['P'])? Intval ($ _ GET ['P']): 1; $ list = $ m_log-> where ($ where)-> page ($ p. ', 10')-> order ($ order)-> select (); $ count = $ m_log-> where ($ where)-> count (); import ("@. ORG. page "); $ Page = new Page ($ count, 10); if (! Empty ($ _ REQUEST ['by']) {$ params ['by'] = 'by = '. trim ($ _ REQUEST ['by']);} if (! Empty ($ _ REQUEST ['R']) &! Empty ($ _ REQUEST ['module']) {$ params ['R'] = 'r = '. trim ($ _ REQUEST ['R']); $ params ['module'] = 'module = '. trim ($ _ REQUEST ['module']);} if (! Empty ($ _ REQUEST ['type']) {$ params ['type'] = 'Type = '. trim ($ _ REQUEST ['type']);} $ this-> parameter = implode ('&', $ params ); if ($ _ GET ['desc_order']) {$ params [] = "desc_order = ". trim ($ _ GET ['desc _ order']);} elseif ($ _ GET ['asc _ order']) {$ params [] = "asc_order = ". trim ($ _ GET ['asc _ order']);} $ Page-> parameter = implode ('&', $ params ); $ show = $ Page-> show (); $ this-> assign ('page', $ show); foreach ($ list as $ key => $ value) {$ list [$ key] ['creator'] = getUserByRoleId ($ value ['Role _ id']); if ($ m_comment-> where ("module = 'log' and module_id = % d", $ value ['Log _ id'])-> select ()) {$ list [$ key] ['is _ comment'] = 1 ;}}$ this-> category_list = M ('logcategory ') -> order ('order _ id')-> select (); // obtain the list of lower-level and self-owned positions, and use $ d_role_view = D ('roleview') to search '); $ this-> role_list = $ d_role_view-> where ('Role. role_id in (% s) ', implode (', ', $ below_ids)-> select (); $ this-> assign ('LIST', $ list ); $ this-> alert = parseAlert (); $ this-> display ();}First, let's talk about the page that requires the login permission to access, and then query the content in our log table in a forward order. Finally, we use assign to directly output 0.0 to the current template.
Accessible pages not logged on
Enter our test XSS
Object data = "data: text/html; base64, PHNjcmlwdD5hbGVydCgiSm9zZXBoIik7PC9zY3JpcHQ + =">
/Object>
There is no interception, and the smooth feeling is great.
Log on to the background and check