Nathan Ziehnert

6 minute read

Have you ever received this frantic call before?

So, I know you gave me two hours to reboot, but I am in the middle of an important (INSERT EXCUSE HERE) and I cannot reboot at this moment.  Is there something you can do to stop it?

When it comes to SCCM reboots, the standard response is “I’m sorry, we can’t delay the reboot any further.” In my industry (Legal) ConfigMgr, there are certain users who we must accommodate immediately lest we bear the repercussions later.

So what do you do in situations like this? Well, there is a manual way to stop the reboot from taking place.

  1. Stop the SCCM Service (“sc stop ccmexec” from an elevated command prompt)
  2. Cancel the reboot (“shutdown -a” from an elevated command prompt)
  3. Instruct the user to reboot as soon as they can.

This method has a few pitfalls - namely, there is no guarantee that the user will ever reboot their machine, and then you’re stuck with a machine that is not running the SCCM client and never receives an update again. (Okay, maybe that is a little bit of hyperbole, but you get the picture).

You COULD create a new reboot manually when on the machine using “shutdown -t SECONDS -r” from an elevated command prompt, but who has time to calculate the number of seconds in an hour? (3600 x # of hours if you didn’t already know)

What if there was a way to give the user the ability to request a reboot delay even when you are unable to remote into the machine?

SCCM REBOOT DELAY REQUEST UTILITY

My goals with this project were the following:

  1. Allow the user to delay a reboot without needing to give them admin credentials.
  2. Restart the machine after the requested delay.
  3. Keep the ability to approve the delay with the Help Desk so that a user couldn’t indefinitely postpone a reboot.

I thought it best to employ some sort of challenge response system instead of a set password.  I also thought it wise to split the utility into a request generator and response generator that way I could also manage access rights to the response generator.  The only thing that caused excessive trouble was granting the user administrative rights to run the required commands to stop the reboot.

It has been accomplished, albeit in an incredibly insecure fashion.  I plan to implement better security as I am able (this is a side project at the moment), and I will update the repository as I implement these features. Review the repository README.md for more information.

HOW THE APP IS USED

The user presses the Win Key + R to bring up the run menu and then types in “DelayRequest” without quotes and presses Enter. The user will then be prompted to click yes on 3 separate UAC prompts. (If the user previously ran this utility without completing the challenge/response, they will not be prompted). This automatically cancels the reboot and then sets a new reboot for 30 minutes from now.  This way if the user has a very short period of time before they reboot, it will still give them time to complete the challenge response.  This only happens one time until the challenge/response is completed. They are then presented with the following dialog.

Reboot Delay Request

They then select a delay and give the challenge code and the requested delay to the Help Desk agent who puts it in their response window:

Delay Response Generator

The Help Desk clicks the “Generate Response” button and reads back the response code to the user.  The user then inputs it in the Request utility and clicks “Delay Reboot”.  This automatically stops the existing 30 minute reboot and then sets a new reboot based on the requested delay.

THE TECHNICAL DETAILS

Checking User Rights to Generate Response

This part was easy to accomplish.  It’s just a simple check against active directory to ensure that the user belongs to a specific group.

Challenge Response System

This was the hardest part for me to implement, and honestly I’m still not 100% satisfied with it.  It was written quickly and is very easily reversed, but I’m relatively confident that my users don’t really care to dive deep into delaying reboots.

Generating a challenge is really simplistic, it’s just a random number generator that generates four 5-digit numbers.  Since leading zeros seemed to cause an issue with the script, I opted to start the numbering at 10000.

Generating the response is pretty simple as well (and admittedly insecure):

What makes this insecure is that there has to be a shared “secret” between the two computers so that the response can be validated.  Now, I did try to create a hash using a function, but gave up when trying to get something usable and short out of those hashes.  In an attempt to obfuscate the simple multiplication, I “salted” the challenges, but since it’s not random it’s also vulnerable to reversing.

Validating the response is as simple as running the same function to generate the response and check to ensure that the values match.

Giving The User Admin Rights

WARNING!!!! This is admittedly the 2nd most insecure method of performing this function - 2nd only to storing the password cleartext.  If you choose to do this, I cannot be held responsible for anything negative that may come from it.

The method is similar to the one used in this blog post. I’ve modified it to work across all user accounts and computers.  Generating the Secure String is done from a PowerShell console using the following code:

Copy the response and save it for a later date… Now the following code will allow you to reverse the key and generate a secure credential.

Now your credentials are stored in $credentials and you can use that to run anything you need to run elevated. Stopping the reboot and setting a new one works with these credentials and the following commands.

CONCLUSIONS

Again, like I said, I would like to improve upon the security of this script, but for now it will suffice.  You can find the latest version of the PowerShell code on the GitHub repository.  I use PowerGUI to package the script into an executable, but you can use whatever method you prefer.  Eventually I plan to wrap this into a configurable installer so that us lazy folk can just run an installer.

Thanks for taking the time to read! Comment below if you have any suggestions or questions.

comments powered by Disqus

Table of Contents