The WormHole vulnerability that recently has raised security concerns actually comes from a series of inappropriate developing habits. Similar problems are very common on PC, but most of them are mitigated by Microsoft’s default firewall. I wish this post with a lot of discussion on WormHole could more or less enhance the security awareness of some developers.

0x01 Background

The Lenovo ThinkVantage System Update is used to help a user download and install software, drivers and BIOS updates from its server, which significantly reduces the difficulty and workload for a user to update the system. This program is pre-installed on many Lenovo products.

The Lenovo ThinkVantage System Update can download software and updates in many ways based on different network environment and configuration. One of the ways is to download by using file sharing and the main program for this feature is UNCServer.exe. The UNCServer.exe starts with the main routine of System Update and establish a local service side waiting for the main routine connection. In early versions, UNCServer.exe would remain active even when the main routine of System Update exits.

0x02 Problem Description

In System Update 5.6.0.34, UNCServer.exe can provide multiple features by using the Remote mechanism of .NET through the TCP server.

.Net Remoting evolving from DCOM is an older .NET distributed processing technology. It serializes objects and data on the server side, then export. The client crosses the process boundaries to reference the objects on server via HTTP, TCP and IPC. However, the serialization mechanism of Remoting will implicitly export all object methods and properties. Once the client gets the object reference exported from the server side, it’s able to call every method that the server object provides. You can call a server-side object provides all the methods. So the Remoting mechanism is easy to introduce security vulnerabilities, and it’s not recommended to export the Remoting service terminal for clients that are not trusted.

The Connector object exported by UNCServer provides functions including Connect, DownloadBean, IsFileExist, IsFolderExist, GetFilesInFolder, GetSubFolder, QueryFile and LaunchIE. The client can connect and obtain its reference object to perform operations like file downloading or program installation.
Among them LaunchIE won’t verify any parameters, which can be used to start arbitrary process. The actual code is as follows:

1
2
3
4
5
6
7
8
9
case UNCAction.LaunchIE:
string fileName = (string) eventObj;
try{
Process.Start(fileName);
}
catch{
}
this.connector.Current = (object) true;
break;

Meanwhile, although System Update only adds outbound rules into the firewall policy, it is bound to 0.0.0.0:20050 due to a lack of necessary configuration on UNCServer. Therefore, when there is no firewall protection, any machine can establish a connection with it, eventually use the provided DownloadBean and LaunchIE functions to download and execute programs remotely.

UNCserver establishes channels on the server side and exports the following code:

1
2
3
4
5
6
7
8
9
10
IDictionary properties = (IDictionary) new Hashtable();
properties[(object) name] = (object) tvsuuncchannel;
properties[(object) priority] = (object) 2;
properties[(object) port] = (object) 20050;
this.channel = new TcpServerChannel(properties, (IServerChannelSinkProvider) new BinaryServerFormatterSinkProvider());
ChannelServices.RegisterChannel((IChannel) this.channel, false);
this.status = new object();
this.connector = new Connector();
RemotingServices.Marshal((MarshalByRefObject) this.connector, Connector);
this.connector.UNCEvent += new Connector.UNCEventHandler(this.connector_UNCEvent);

0x03 Mitigation

Lenovo released the System Update 5.7.0.13 on September 29th, 2015, which fixes a lot of vulnerabilities including this discussed problem. It implements the LaunchIE and LaunchHelp functions again, and verifies the parameter for the process created. It also improves the configuration on the server that is bound to 127.0.0.1:20050 in order to block remote access.

The following is a part of fixed code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
case UNCAction.LaunchIE:
try{
tring str = (string) eventObj;
Uri result;
if (Uri.TryCreate(str, UriKind.Absolute, out result) (result.Scheme == Uri.UriSchemeHttp || result.Scheme == Uri.UriSchemeHttps))
Process.Start(str);
}
catch{
}
this.connector.Current = (object) true;
break;


IDictionary properties = (IDictionary) new Hashtable();
properties[(object) name] = (object) tvsuuncchannel;
properties[(object) priority] = (object) 2;
properties[(object) port] = (object) 20050;
properties[(object) rejectRemoteRequests] = (object) true;
properties[(object) bindTo] = (object) 127.0.0.1;
this.channel = new TcpServerChannel(properties, (IServerChannelSinkProvider) new BinaryServerFormatterSinkProvider());
ChannelServices.RegisterChannel((IChannel) this.channel, false);
this.status = new object();
this.connector = new Connector();
RemotingServices.Marshal((MarshalByRefObject) this.connector, Connector);
this.connector.UNCEvent += new Connector.UNCEventHandler(this.connector_UNCEvent);

0x04 Summary

Remoting is a previous generation of .NET distributed processing technology, which was already replaced by Microsoft’s WCF technology due to its security defect in design. If there are applications still using Remoting technology for distributed processing or communication, the potential security issues should be noted and any mishandling may introduce security flaws.

Translated by WooYun Drops