Exploit-DB #18622
Description: LANDesk Lenovo ThinkManagement Suite 9.0.3 - Core Server Remote Code Execution
Type: remote
Platform: windows
Date: 2012-03-19
Author: rgod

Exploit:
LANDesk Lenovo ThinkManagement Suite 9.0.3 Core Server AMTConfig.Business.dll 
RunAMTCommand Remote Code Execution Vulnerability

Tested against: Microsoft Windows Server 2003 r2 sp2

Software home page: http://www.landesk.com/lenovo/thinkmanagement-console.aspx

Download url: http://www.landesk.com/downloads/lenovo/50.aspx

Files tested: 
ThinkManagement9.0.2.exe
LD90-SP2-MCP_CONS-2011-0428.exe
LD90-SP2-MCP_SD-2011-0428.exe
ThinkManagementConsole9.0.3_b28.zip

Instrunctions were to install 9.0.2, then apply two patches, finally to install 9.0.3

Background:
The mentioned product creates various virtual directories on IIS.
Among them the 'core.anonymous' one inside the 'landesk' tree.
Without prior authentication / authorization is possible to 
invoke the 'ServerSetup.asmx' web service which exposes various
functions inside the underlying dlls.

Vulnerability:
By specifying the 'RunAMTCommand' operation is possible to 
create arbitrary files inside public virtual directories.
This operation supports five arguments: when the 'Command'
argument is set ex. to '-PutUpdateFileCore', 
'Data2' and 'Data3' are used for file creation.
The first one suffers of a directory traversal vulnerability.
You are in control of the path, extension and content
of the newly created file.
Then you can execute arbitrary code by invoking this file.

Vulnerable code:

C:\Program Files\LANDesk\ManagementSuite\LANDesk\ManagementSuite\Core\core.anonymous\ServerSetup.asmx

...
<%@ WebService Language="c#" Codebehind="ServerSetup.asmx.cs" Class="ServerSetup.ServerSetup" %>
...

Now look RunAMTCommand() inside ServerSetup.dll :

...
[WebMethod]
public int RunAMTCommand(string Command, string Data1, string Data2, string Data3, ref string ReturnString)
{
    return Convert.ToInt32(Business.RunAMTCommand(Command, Data1, Data2, Data3, ref ReturnString));
}
...
 
Again, look RunAMTCommand() inside ServerSetup.Business.dll :

...
public static int RunAMTCommand(string Command, string Data1, string Data2, string Data3, ref string ReturnString)
{
    SSLog.Log("RunAMTCommand()", new object[0]);
    SSResult sSFailure = SSResult.SSFailure;
    try
    {
        int num = new DBAccessBusiness().AvProBusinessInterface(Command, Data1, Data2, Data3, ref ReturnString); //<-------------
        if (num == 0)
        {
            sSFailure = SSResult.SSOK;
        }
        else
        {
            SSLog.Log("ConfigureAMT - RunAMTCommand returned " + num.ToString(), new object[0]);
            sSFailure = SSResult.SSAMTConfigFailure;
        }
    }
    catch (Exception exception)
    {
        SSLog.Log("ConfigureAMT exception: " + exception.Message, new object[0]);
        sSFailure = SSResult.SSException;
    }
    SSLog.Log("ConfigureAMT returned " + Convert.ToInt32(sSFailure).ToString(), new object[0]);
    return Convert.ToInt32(sSFailure);
}
...
 

Finally AvProBusinessInterface() inside AMTConfig.Business.dll :


public int AvProBusinessInterface(string Command, string Location, string Module, string Data, ref string ReturnString)
{
    int exitCode = -1;
    try
    {
        RollingTempLog.Log("AMTConfig.Business.AvProBusinessInterface() Command: " + Command, new object[0]);
        if (Command.Equals("-RunExe"))
        {
            RollingTempLog.Log("AMTConfig.Business.AvProBusinessInterface() - Did run: " + Module, new object[0]);
        }
        if (Command.Equals("-RunClientNotify"))
        {
            Process process = new Process();
            if (process != null)
            {
                process.StartInfo.FileName = Path.Combine(LDMainPath, "ClientNotify.exe");
                process.StartInfo.Arguments = Data;
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.CreateNoWindow = true;
                if (process.Start())
                {
                    RollingTempLog.Log("AMTConfig.Business.AvProBusinessInterface() - Sucessfully run: " + process.StartInfo.FileName, new object[0]);
                    RollingTempLog.Log("AMTConfig.Business.AvProBusinessInterface() - Arguments: " + process.StartInfo.Arguments, new object[0]);
                    exitCode = 0;
                    Thread.Sleep(0);
                    process.Close();
                }
                else
                {
                    RollingTempLog.Log("AMTConfig.Business.AvProBusinessInterface() - Sucessfully run: " + process.StartInfo.FileName, new object[0]);
                }
            }
        }
        if (Command.Equals("-RunGetAMTIDs"))
        {
            Process process2 = new Process();
            if (process2 != null)
            {
                process2.StartInfo.FileName = Path.Combine(LDMainPath, "getamtid.exe");
                process2.StartInfo.Arguments = Data;
                process2.StartInfo.UseShellExecute = false;
                process2.StartInfo.RedirectStandardOutput = true;
                process2.StartInfo.CreateNoWindow = true;
                process2.StartInfo.WorkingDirectory = LDMainPath;
                if (process2.Start())
                {
                    ReturnString = process2.StandardOutput.ReadToEnd();
                    process2.WaitForExit();
                    process2.Close();
                    RollingTempLog.Log("AMTConfig.Business.AvProBusinessInterface() - Sucessfully run: " + process2.StartInfo.FileName, new object[0]);
                    RollingTempLog.Log("AMTConfig.Business.AvProBusinessInterface() - Arguments: " + process2.StartInfo.Arguments, new object[0]);
                    exitCode = 0;
                    Thread.Sleep(0);
                }
                else
                {
                    RollingTempLog.Log("AMTConfig.Business.AvProBusinessInterface() - Unsucessfully run: " + process2.Star