One SQL Injection in rice CMS
Lines 147-163 of the \ Web \ Lib \ Action \ MemberAction. class. php file
Function modpage () {self: is_login (); $ aid = intval ($ _ REQUEST ['aid ']); if ($ _ POST) {$ _ POST ['status'] = 0; $ _ POST ['title'] = htmlspecialchars ($ _ POST ['title']); M ('Article ') -> where ('dami _ uid = '. $ _ SESSION ['dami _ uid']. 'and aid = '. $ aid)-> save ($ _ POST); $ this-> assign ('jumpurl', U ('Member/tougaolist ')); $ this-> success ('modification successful ~, Please wait for review! ');} Else {$ info = M ('Article')-> where ('dami _ uid = '. $ _ SESSION ['dami _ uid']. 'and aid = '. $ aid)-> find (); if (! $ Info) {$ this-> error ('record does not exist'); exit ();} self: pub_class ($ info ['typeid']); $ this-> assign ('info', $ info) ;}$ this-> display ();}
We can see that the aid parameter is intval.
However, during my test, I found that the aid parameter can be injected.
Let's look up.
Start
class MemberAction extends BaseAction{function _initialize() {R('Public','head');$member_menu = S('member_menu');if(!is_array($member_menu)){$member_menu = M('member_menu')->where('is_show=1')->order('drand')->select();S('member_menu',$member_menu);}$this->assign('member_menu',$member_menu);}
Let's look at the R function.
/Core/Common/functions. php
function R($module, $action, $app='@') { $class = A($module, $app); if ($class) return call_user_func(array(&$class, $action)); else return false;}
Let's take A look at.
/Core/Common/functions. php
function A($name, $app='@') { static $_action = array(); if (isset($_action[$app . $name])) return $_action[$app . $name]; $OriClassName = $name; if (strpos($name, '.')) { $array = explode('.', $name); $name = array_pop($array); $className = $name . 'Action'; import($app . '.Action.' . implode('.', $array) . '.' . $className); } else { $className = $name . 'Action'; import($app . '.Action.' . $className); } if (class_exists($className)) { $action = new $className(); $_action[$app . $OriClassName] = $action; return $action; } else { return false; }}
This means to call a remote module.
Looking back at \ Web \ Lib \ Action \ MemberAction. class. php
R ('public', 'head ');
Combined with functions A and R, that is, the head function in the PublicAction foreground public action is called.
Let's take a look at the head function.
/Web/Lib/Action/PublicAction. class. php
Public function head () {// read database and cache $ type = M ('type'); $ article = M ('Article '); $ config = F ('basic ','','. /Web/Conf/'); // encapsulate website configuration $ this-> assign ('config', $ config ); // rolling announcement $ data ['status'] = 1; $ data ['typeid'] = $ config ['noticeid']; $ roll = $ article-> where ($ data)-> field ('aid, title')-> order ('addtime desc ') -> limit ($ config ['rollnum'])-> select (); // processing title: prevent the title from being too long and messy page foreach ($ roll as $ k => $ v) {$ roll [$ k] ['title'] = msubstr ($ v ['title'], 0, 20, 'utf-8 ');} $ this-> assign ('roll', $ roll); // website navigation $ menu = $ type-> where ('ismenu = 1 ') -> order ('drank asc ')-> select (); foreach ($ menu as $ k => $ v) {$ menuson [$ k] = $ type-> where ('fid = '. $ v ['typeid']. 'AND drank <> 0')-> order ('drank asc')-> select (); $ menu [$ k] ['submenu '] = $ menuson [$ k];} $ this-> assign ('menuson', $ menuson ); $ this-> assign ('menu ', $ menu); // location navigation $ nav =' <a href = "'. $ config ['siteurl']. '"> homepage </a>'; if (isset ($ _ GET ['aid ']) {$ typeid = $ article-> where ('aid = '. $ _ GET ['aid '])-> getField ('typeid');} else {$ typeid = intval ($ _ GET ['typeid']);} $ typename = $ type-> where ('typeid = '. $ typeid)-> getField ('typename'); $ path = $ type-> where ('typeid = '. $ typeid)-> getField ('path'); $ typelist = explode ('-', $ path); // assemble the navigation bar string foreach ($ typelist as $ v) {if ($ v = 0) continue; $ s = $ type-> where ('typeid = '. $ v)-> getField ('typename'); $ nav. = "& nbsp; & gt; & nbsp; <a href = \"". U ('lists /'. $ v ). "\" >{$ s }</a> ";}$ nav. = "& nbsp; & gt; & nbsp; <a href = \"". U ('lists /'. $ typeid ). "\" >{$ typename} </a> "; $ this-> assign ('nav', $ nav); // release the memory unset ($ type, $ article); $ this-> assign ('head', TMPL_PATH.cookie ('Think _ template '). '/head.html'); $ this-> assign ('footer ', TMPL_PATH.cookie ('Think _ template '). '/footer.html ');}
Here
// Location navigation
$ Nav = '<a href = "'. $ config ['siteurl']. '"> homepage </a>'; if (isset ($ _ GET ['aid ']) {$ typeid = $ article-> where ('aid = '. $ _ GET ['aid '])-> getField ('typeid ');}
This aid is directly included in SQL without being filtered.
The getField function.
/Core/Lib/Think/Core/Model. class. php
Public function getField ($ field, $ condition = '', $ sepa ='') {if (empty ($ condition) & isset ($ this-> options ['where']) $ condition = $ this-> options ['where']; $ options ['where'] = $ condition; $ options ['field'] = $ field; $ options = $ this-> _ parseOptions ($ options ); if (strpos ($ field, ',') {// multiple fields $ resultSet = $ this-> db-> select ($ options); if (! Empty ($ resultSet) {$ field = explode (',', $ field); $ key = array_shift ($ field); $ cols = array (); foreach ($ resultSet as $ result) {$ name = $ result [$ key]; $ cols [$ name] = ''; foreach ($ field as $ val) $ cols [$ name]. = $ result [$ val]. $ sepa; $ cols [$ name] = substr ($ cols [$ name], 0,-strlen ($ sepa);} return $ cols ;}} else {// query a record $ options ['limit'] = 1; $ result = $ this-> db-> select ($ options); if (! Empty ($ result) {return reset ($ result [0]) ;}} return null ;}
Obtains a field value of a record.
So, to sum up.
After we register a user
Publish a contribution,
Then modify
This category is stored in the database. All the content mentioned above is to modify this function through the article.
Obtain the aid parameter, and then use the aid parameter to search for the type and display it.
However, the aid in this process is not filtered, resulting in injection.
SELECT * FROM 'dami _ article' WHERE dami_uid = 6 and aid = 129
In the log, the following one is that the aid in the function of modifying the article passes through Intval.
And the above
105 QuerySELECT 'typeid' FROM 'dami _ article' WHERE aid = 129 LIMIT 1
105 QuerySELECT 'typename' FROM 'dami _ type' WHERE typeid = 14 LIMIT 1
Find the typeid from the article table through the aid function passed in by get, and then find the type name (typeid) from the type table based on the typeid ).
Http: // 127.0.0.1/dami/index. php? M = member & a = modpage> aid = 129 and 1 = 2
Therefore, a complete SQL operation is like this.
108 QuerySELECT 'typeid' FROM 'dami _ article' WHERE aid = 129 and 1 = 2 LIMIT 1
108 QuerySELECT 'typename' FROM 'dami _ type' WHERE typeid = LIMIT 1
108 QuerySELECT 'path' FROM 'dami _ type' WHERE typeid = LIMIT 1
108 QuerySELECT * FROM 'dami _ article' WHERE dami_uid = 6 and aid = 129 LIMIT 1
108 QuerySELECT typeid, typename, fid, concat (path, '-', typeid) as bpath FROM 'dami _ type' WHERE islink = 0 and isuser = 1 order by bpath
108 QuerySELECT * FROM 'dami _ flash' WHERE status = 1 order by rank asc
108 QuerySELECT * FROM 'dami _ link' WHERE islogo = 1 and status = 1 order by rank asc LIMIT 8
108 Quit
Solution:
Public class (File) on the front-end)
/Web/Lib/Action/PublicAction. class. php
Set the input parameter intval.