Deploy PowerShell as Clickable Icons (Part 2)

by Oct 29, 2020

In the previous tip we illustrated how you can embed up to 4096 characters of PowerShell code inside a Windows Explorer shortcut file and produce clickable PowerShell code.

The embedded PowerShell code can easily be viewed though simply by right-clicking the link file and opening the properties dialog.

With a very simple adjustment, you can hide your payload though. Run the code below to produce a sample clickable PowerShell icon on your desktop:

$code = {
   # place your code here (must be less than 4096 characters)
   # (this example generates a battery report on notebooks
   #  and opens it in your default browser)
   $r = "$env:temp\report.html"
   powercfg /batteryreport /duration 14 /output $r
   Invoke-Item -Path $r
   Start-Sleep -Seconds 2
   Remove-Item -Path $r
}

# turn code into a one-liner, remove comments, escape double quotes
# NOTE: this is a very simplistic conversion. Does not support block comments
#  or quoted double quotes or any edgy stuff
#  USE with simple staight-forward code only
$oneliner = $code.ToString().Trim().Replace('"','\"').Replace([Char[]]10,'').
             Split([Char[]]13).Trim().Where{!$_.StartsWith('#')} -join ''

# create path to a link file. It is always placed on your desktop
# and named "clickme.lnk"
$desktop = [Environment]::GetFolderPath('Desktop')
$linkpath = Join-Path -Path $desktop -ChildPath 'ClickMe.lnk'

# create a blank string of 260 chars
$blanker = " " * 260

# create a shortcut file
$com = New-Object -ComObject WScript.Shell
$shortcut = $com.CreateShortcut($linkpath)
# minimize window so PowerShell won't pop up
$shortcut.WindowStyle = 7
# use a different icon. Adjust icon index if you want
$shortcut.IconLocation = 'shell32.dll,8'
# run PowerShell
$shortcut.TargetPath = "powershell.exe"
# submit code as an argument and prepend with a blank string
# so payload is hidden in the properties dialog
$shortcut.Arguments = "$blanker-noprofile $oneliner"

# save and create the shortcut file
$shortcut.Save()

When you double-click the icon “clickme” on your desktop, the embedded payload code runs and creates a battery report, then displays it in your default browser.

When you right-click the icon and choose “Properties”, the embedded PowerShell code won’t show. The dialog just shows the path to powershell.exe but no arguments.

This was achieved by prepending the arguments with 260 blank characters. While shortcut files support command lines of up to 4096 characters, Windows Explorer and its dialog boxes show only the first 260 characters. To view the embedded payload, users would have to use the PowerShell code above to programmatically read the shortcut file and dump the arguments property.


Twitter This Tip! ReTweet this Tip!