Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Fri, 4 May 2012 10:32:41 +0300
From: Henri Salo <henri@...v.fi>
To: oss-security@...ts.openwall.com
Subject: Re: CVE-request: OpenKM 5.1.7 Privilege Escalation
 / OS Command Execution (XSRF based)

On Fri, Mar 23, 2012 at 09:09:30AM -0600, Kurt Seifried wrote:
> On 03/23/2012 04:00 AM, Henri Salo wrote:
> > Can I get CVE-identifiers for these two security vulnerabilities?
> > 
> > http://osvdb.org/show/osvdb/78105 COMPASS-2012-001
> > http://osvdb.org/show/osvdb/78106 COMPASS-2012-002
> > 
> > - Henri Salo
> 
> I'm going to need some original vendor information (name, site, etc.).
> 
> -- 
> Kurt Seifried Red Hat Security Response Team (SRT)

Hello Kurt and list,

I received following information from Paco Avila from OpenKM. I hope this clarifies things.

"OpenKM Permission Weakness Admin Privilege Escalation"
COMPASS-2012-001 / OSVDB:78105 / SA47424:
Diff: AuthServlet.diff
Issue tracker: http://issues.openkm.com/view.php?id=1973

"OpenKM Arbitrary Admin User Creation CSRF"
COMPASS-2012-002 / OSVDB:78106 / SA47420:
Diff: scripting.diff
Issue tracker: http://issues.openkm.com/view.php?id=1750

- Henri Salo

Index: AuthServlet.java
===================================================================
--- AuthServlet.java	(revisión: 9702)
+++ AuthServlet.java	(revisión: 9732)
@@ -74,51 +74,59 @@
 		Session session = null;
 		updateSessionManager(request);
 		
-		try {
-			session = JCRUtils.getSession();
-			
-			if (action.equals("userCreate")) {
-				userCreate(session, request, response);
-			} else if (action.equals("roleCreate")) {
-				roleCreate(session, request, response);
-			} else if (action.equals("userEdit")) {
-				userEdit(session, request, response);
-			} else if (action.equals("roleEdit")) {
-				roleEdit(session, request, response);
-			} else if (action.equals("userDelete")) {
-				userDelete(session, request, response);
-			} else if (action.equals("roleDelete")) {
-				roleDelete(session, request, response);
-			} else if (action.equals("userActive")) {
-				userActive(session, request, response);
-			} else if (action.equals("roleActive")) {
-				roleActive(session, request, response);
+		if (isMultipleInstancesAdmin(request) || request.isUserInRole(Config.DEFAULT_ADMIN_ROLE)) {
+			try {
+				session = JCRUtils.getSession();
+				
+				if (action.equals("userCreate")) {
+					userCreate(session, request, response);
+				} else if (action.equals("roleCreate")) {
+					roleCreate(session, request, response);
+				} else if (action.equals("userEdit")) {
+					userEdit(session, request, response);
+				} else if (action.equals("roleEdit")) {
+					roleEdit(session, request, response);
+				} else if (action.equals("userDelete")) {
+					userDelete(session, request, response);
+				} else if (action.equals("roleDelete")) {
+					roleDelete(session, request, response);
+				} else if (action.equals("userActive")) {
+					userActive(session, request, response);
+				} else if (action.equals("roleActive")) {
+					roleActive(session, request, response);
+				}
+				
+				if (action.equals("") || action.equals("userActive") ||
+						(action.startsWith("user") && WebUtils.getBoolean(request, "persist"))) {
+					userList(session, request, response);
+				} else if (action.equals("roleList") || action.equals("roleActive") ||
+						(action.startsWith("role") && WebUtils.getBoolean(request, "persist"))) {
+					roleList(session, request, response);
+				}
+			} catch (LoginException e) {
+				log.error(e.getMessage(), e);
+				sendErrorRedirect(request,response, e);
+			} catch (RepositoryException e) {
+				log.error(e.getMessage(), e);
+				sendErrorRedirect(request,response, e);
+			} catch (DatabaseException e) {
+				log.error(e.getMessage(), e);
+				sendErrorRedirect(request,response, e);
+			} catch (NoSuchAlgorithmException e) {
+				log.error(e.getMessage(), e);
+				sendErrorRedirect(request,response, e);
+			} catch (PrincipalAdapterException e) {
+				log.error(e.getMessage(), e);
+				sendErrorRedirect(request,response, e);
+			} finally {
+				JCRUtils.logout(session);
 			}
+		} else {
+			// Activity log
+			UserActivity.log(request.getRemoteUser(), "ADMIN_ACCESS_DENIED", request.getRequestURI(), request.getQueryString());
 			
-			if (action.equals("") || action.equals("userActive") ||
-					(action.startsWith("user") && WebUtils.getBoolean(request, "persist"))) {
-				userList(session, request, response);
-			} else if (action.equals("roleList") || action.equals("roleActive") ||
-					(action.startsWith("role") && WebUtils.getBoolean(request, "persist"))) {
-				roleList(session, request, response);
-			}
-		} catch (LoginException e) {
-			log.error(e.getMessage(), e);
-			sendErrorRedirect(request,response, e);
-		} catch (RepositoryException e) {
-			log.error(e.getMessage(), e);
-			sendErrorRedirect(request,response, e);
-		} catch (DatabaseException e) {
-			log.error(e.getMessage(), e);
-			sendErrorRedirect(request,response, e);
-		} catch (NoSuchAlgorithmException e) {
-			log.error(e.getMessage(), e);
-			sendErrorRedirect(request,response, e);
-		} catch (PrincipalAdapterException e) {
-			log.error(e.getMessage(), e);
-			sendErrorRedirect(request,response, e);
-		} finally {
-			JCRUtils.logout(session);
+			AccessDeniedException ade = new AccessDeniedException("You should not access this resource");
+			sendErrorRedirect(request, response, ade);
 		}
 	}
 	
@@ -166,8 +174,8 @@
 		log.debug("userEdit({}, {}, {})", new Object[] { session, request, response });
 		String usrId = WebUtils.getString(request, "usr_id");
 		
-		if (isMultipleInstancesAdmin(request) || !usrId.equals(Config.ADMIN_USER)) {
-			if (WebUtils.getBoolean(request, "persist")) {
+		if (WebUtils.getBoolean(request, "persist")) {
+			if (isMultipleInstancesAdmin(request) || !usrId.equals(Config.ADMIN_USER)) {
 				String password = WebUtils.getString(request, "usr_password");
 				User usr = new User();
 				usr.setId(usrId);
@@ -188,22 +196,16 @@
 				
 				// Activity log
 				UserActivity.log(session.getUserID(), "ADMIN_USER_EDIT", usr.getId(), usr.toString());
-			} else {
-				ServletContext sc = getServletContext();
-				sc.setAttribute("action", WebUtils.getString(request, "action"));
-				sc.setAttribute("persist", true);
-				sc.setAttribute("roles", AuthDAO.findAllRoles());
-				sc.setAttribute("usr", AuthDAO.findUserByPk(usrId));
-				sc.getRequestDispatcher("/admin/user_edit.jsp").forward(request, response);
-			}	
+			}
 		} else {
-			// Activity log
-			UserActivity.log(request.getRemoteUser(), "ADMIN_ACCESS_DENIED", request.getRequestURI(), request.getQueryString());
+			ServletContext sc = getServletContext();
+			sc.setAttribute("action", WebUtils.getString(request, "action"));
+			sc.setAttribute("persist", true);
+			sc.setAttribute("roles", AuthDAO.findAllRoles());
+			sc.setAttribute("usr", AuthDAO.findUserByPk(usrId));
+			sc.getRequestDispatcher("/admin/user_edit.jsp").forward(request, response);
+		}	
 			
-			AccessDeniedException ade = new AccessDeniedException("You should not access this resource");
-			sendErrorRedirect(request, response, ade);
-		}
-			
 		log.debug("userEdit: void");
 	}
 	
@@ -215,26 +217,20 @@
 		log.debug("userDelete({}, {}, {})", new Object[] { session, request, response });
 		String usrId = WebUtils.getString(request, "usr_id");
 		
-		if (isMultipleInstancesAdmin(request) || !usrId.equals(Config.ADMIN_USER)) {
-			if (WebUtils.getBoolean(request, "persist")) {
+		if (WebUtils.getBoolean(request, "persist")) {
+			if (isMultipleInstancesAdmin(request) || !usrId.equals(Config.ADMIN_USER)) {
 				AuthDAO.deleteUser(usrId);
 				
 				// Activity log
 				UserActivity.log(session.getUserID(), "ADMIN_USER_DELETE", usrId, null);
-			} else {
-				ServletContext sc = getServletContext();
-				sc.setAttribute("action", WebUtils.getString(request, "action"));
-				sc.setAttribute("persist", true);
-				sc.setAttribute("roles", AuthDAO.findAllRoles());
-				sc.setAttribute("usr", AuthDAO.findUserByPk(usrId));
-				sc.getRequestDispatcher("/admin/user_edit.jsp").forward(request, response);
 			}
 		} else {
-			// Activity log
-			UserActivity.log(request.getRemoteUser(), "ADMIN_ACCESS_DENIED", request.getRequestURI(), request.getQueryString());
-			
-			AccessDeniedException ade = new AccessDeniedException("You should not access this resource");
-			sendErrorRedirect(request, response, ade);
+			ServletContext sc = getServletContext();
+			sc.setAttribute("action", WebUtils.getString(request, "action"));
+			sc.setAttribute("persist", true);
+			sc.setAttribute("roles", AuthDAO.findAllRoles());
+			sc.setAttribute("usr", AuthDAO.findUserByPk(usrId));
+			sc.getRequestDispatcher("/admin/user_edit.jsp").forward(request, response);
 		}
 		
 		log.debug("userDelete: void");
@@ -246,20 +242,14 @@
 	private void userActive(Session session, HttpServletRequest request, HttpServletResponse response) 
 			throws ServletException, IOException, DatabaseException, NoSuchAlgorithmException {
 		log.debug("userActive({}, {}, {})", new Object[] { session, request, response });
+		boolean active = WebUtils.getBoolean(request, "usr_active");
 		String usrId = WebUtils.getString(request, "usr_id");
 		
 		if (isMultipleInstancesAdmin(request) || !usrId.equals(Config.ADMIN_USER)) {
-			boolean active = WebUtils.getBoolean(request, "usr_active");
 			AuthDAO.activeUser(usrId, active);
-			
+		
 			// Activity log
 			UserActivity.log(session.getUserID(), "ADMIN_USER_ACTIVE", usrId, Boolean.toString(active));
-		} else {
-			// Activity log
-			UserActivity.log(request.getRemoteUser(), "ADMIN_ACCESS_DENIED", request.getRequestURI(), request.getQueryString());
-			
-			AccessDeniedException ade = new AccessDeniedException("You should not access this resource");
-			sendErrorRedirect(request, response, ade);
 		}
 		
 		log.debug("userActive: void");

Index: scripting.jsp
===================================================================
--- scripting.jsp	(revisión: 7735)
+++ scripting.jsp	(revisión: 8207)
@@ -1,7 +1,11 @@
 <%@ page import="com.openkm.servlet.admin.BaseServlet" %>
+<%@ page import="com.openkm.util.UserActivity"%>
+<%@ page import="com.openkm.util.SecureStore"%>
+<%@ page import="com.openkm.util.WebUtils"%>
 <%@ page import="bsh.Interpreter"%>
 <%@ page import="java.io.ByteArrayOutputStream"%>
 <%@ page import="java.io.PrintStream"%>
+<%@ page import="java.util.UUID"%>
 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
@@ -41,33 +45,45 @@
 <%
 	if (BaseServlet.isMultipleInstancesAdmin(request)) {
 		request.setCharacterEncoding("UTF-8");
-		String script = request.getParameter("script");
+		String script = WebUtils.getString(request, "script");
+		String reqCsrft = (String) session.getAttribute("csrft");
 		StringBuffer scriptOutput = new StringBuffer();
 		Object scriptResult = null;
 		Exception scriptError = null;
 		
-		if (script != null) {
-			script = new String(script.getBytes("ISO-8859-1"), "UTF-8");
-			ByteArrayOutputStream baos = new ByteArrayOutputStream();
-			PrintStream pout = new PrintStream(baos);
-			Interpreter bsh = new Interpreter(null, pout, pout, false);
-			
-			// set up interpreter
-			bsh.set("bsh.httpServletRequest", request);
-			bsh.set("bsh.httpServletResponse", response);
-			
-			try {
-				scriptResult = bsh.eval(script);
-			} catch (Exception e) {
-				scriptError = e;
+		if (!script.equals("")) {
+			if (WebUtils.getString(request, "csrft").equals(reqCsrft)) {
+				ByteArrayOutputStream baos = new ByteArrayOutputStream();
+				PrintStream pout = new PrintStream(baos);
+				Interpreter bsh = new Interpreter(null, pout, pout, false);
+				
+				// set up interpreter
+				bsh.set("bsh.httpServletRequest", request);
+				bsh.set("bsh.httpServletResponse", response);
+				
+				try {
+					scriptResult = bsh.eval(script);
+				} catch (Exception e) {
+					scriptError = e;
+				}
+				
+				pout.flush();
+				scriptOutput.append(baos.toString());
+				
+				// Activity log
+				UserActivity.log(request.getRemoteUser(), "SCRIPTING", null, request.getRemoteHost() + ", " + script);
+			} else {
+				out.println("<div class=\"error\"><h3>Security risk detected</h3></div>");
+				
+				// Activity log
+				UserActivity.log(request.getRemoteUser(), "SECURITY_RISK", null, request.getRemoteHost() + ", " + script);
 			}
-			
-			pout.flush();
-			scriptOutput.append(baos.toString());
 		} else {
 			script = "print(\"Hola, mundo!\");";		
 		}
 		
+		String genCsrft = SecureStore.md5Encode(UUID.randomUUID().toString().getBytes());
+		session.setAttribute("csrft", genCsrft);
 		out.println("<h1>Scripting</h1>");
 		out.println("<h2>Results</h2>");
 		out.println("<table class=\"results\" width=\"95%\">");
@@ -77,6 +93,7 @@
 		out.println("</table>");
 		out.println("<hr>");
 		out.println("<form action=\"scripting.jsp\" method=\"post\">");
+		out.println("<input type=\"hidden\" name=\"csrft\" value=\"" + genCsrft + "\">");
 		out.println("<table class=\"form\" align=\"center\">");
 		out.println("<tr><td><textarea cols=\"80\" rows=\"25\" name=\"script\" id=\"script\">"+script+"</textarea></td></tr>");
 		out.println("<tr><td align=\"right\"><input type=\"submit\" value=\"Evaluate\"></td></tr>");

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Powered by Openwall GNU/*/Linux - Powered by OpenVZ