top of page

OUR PRECONDITIONS

  • The old network infrastructure, referred to as OldNet:
    Doesn’t support 802.1x.
    Two domains on different VLAN’s with a one way trust, referred to as Enterprise and Educational.
    The two domains have their own network infrastructure, different IP Helpers, DNS, DHCP and so on.

  • The new infrastructure, referred to as NewNet:
    802.1x is required using CISCO ISE and Layer 3 switches.
    Only one fallback net with its own IP range, common for both domains, which also supports WebAuth guest access.
    The two domains still have their own IP range, DHCP, DNS etc. but will use the same PXE-server since PXE boot is taking place on the fallback network.

  • Both the old and the new network infrastructure will be used to deploy Windows 10 x64 and Windows 7 x86.

  • MAB will not be used during OSD, the network team don’t want to spread a special OSD VLAN so clients will get an IP address according to its current location and only certificate-based authentication is allowed.

  • The task sequence needs to support both the new computer and refresh scenario as well as BIOS to UEFI conversion regardless of the currently installed operating system.
    The scripts used for managing 802.1x needs to support Windows 7 and its PowerShell version.

Search
Writer's picturesomeguy100

Knowledge gained while decrypting the TSEnvironment - TSEnv3 1.0 Alpha released

Updated: Dec 22, 2021

Ok, finally I have something that you could at least call an alpha.

And I’ve rewritten my old code so now this is pure powershell, no imported c# classes whatsoever. The one thing I couldn’t do in powershell was the Zlib compression/decompression. The Dll is stored as a base64 string in the module psm1 and is loaded directly into memory, it’s never stored on disk, not even temporarily.

This took longer than what I’d hoped for… First I had performance-issues after implementing the idea of .GetVariables(). Logical flaws, since all the other methods were made just for a single variable and, on top of that, chained. Had to rewrite a lot of them from scratch.

Then there was just this one last test, WinPE… There I stumbled upon an “OutOfMemoryException”-error, but only when executing the GetVariables method for the first time.

The module do create one big *ss psobject (hashtable) array and the client I tested it on was a slow virtual machine with dynamic memory but still, another flaw hidden somewhere.

Think that I worked passed both those issues now. Let me know if I haven’t. ;)



So back to the million dollar question mentioned in the last blogpost, how is the reserved1 binary registry value related to AES256 and decrypting the TS environment?

By now I knew that just as with passwords, the password itself is seldom used, but a hash of it. Backtracking using an API monitor I found that there was an array, 20 bytes in size, which somehow lead to the AES-Key used.

After googling it I was pretty sure that the 20 bytes (160-bits) was a SHA1 hash derived from the registry value. Got ahead of myself in the last post, this is where I encountered that the key (hash) was too short to use with AES.

After a lot of late nights I was about to throw in the towel. But then I had the thought “It must be possible to use a SHA1 key hash with AES, I mean, I can’t be the first one ever to have this issue.”


using (SHA1 sha1 = SHA1.Create()) {

            // The following algorithm is taken from:
            // <link>http://msdn.microsoft.com/en-us/library/windows/desktop/aa379916%28v=vs.85%29.aspx</link>
            byte[] baseData = sha1.ComputeHash(Encoding.UTF8.GetBytes(plaintextPassword));
            byte[] buffer1 = new byte[64];
            byte[] buffer2 = new byte[64];

            for (int i = 0; i < 64; i++) {
                buffer1[i] = 0x36;
                buffer2[i] = 0x5C;
                if (i < baseData.Length) {
                    buffer1[i] ^= baseData[i];
                    buffer2[i] ^= baseData[i];
                }
            }

            byte[] buffer1Hash = sha1.ComputeHash(buffer1);
            byte[] buffer2Hash = sha1.ComputeHash(buffer2);

            return buffer1Hash.Concat(buffer2Hash).Take(_keySize / 8).ToArray();

}

I still needed to find out the IV-key and padding used but that was a simple game of trials and errors in comparison.


So here we have it: TSEnv3 (1.0_Alpha).


Alpha functions: *Can set any TS-variable to the wanted value, no matter the name of it. *Can add base64-padding to variable values. *Compress and decompress base64 variables *Decrypts the TSEnvironment at the go, no need of ComObjects, API's or Dlls. You own it. Adapt it in any way you want to.



And if you feel really adventurous or just want to take a closer look at the mess that I’ve made.

Try $TSEnv3 | gm -force

And please be kind. This is the first Powershell module I’ve ever made and the first time I’ve ever created a Powershell class.



214 views0 comments

Comments


bottom of page