Tuesday, May 22, 2018

Code Execution with JDK Scripting Tools & Nashorn Javascript Engine

The Java Development Kit (JDK) provides command-line scripting tools that allow for in-memory execution of code that is interpreted by the Nashorn Javascript Engine, which can be utilized on Windows, macOS and Linux when the JDK is installed. This blog post will cover the usage of these JDK command-line scripting tools and the Nashorn Javascript Engine to perform several actions, such as downloading files, executing scripts locally and remotely, and gaining an interactive shell to a computer system. Detective and preventative controls will also be covered for the usage of these JDK scripting tools.

Why is this useful for Offense?

There are several advantages from an offensive perspective in using these JDK scripting tools. Obviously, this completely relies on the JDK being installed in order to take advantage of these tools.
  • No native logging for usage of JDK scripting tools or Nashorn Javascript Engine
  • Can assist in evasion of host-based security controls that rely on or factor in parent process id relationships for detections
  • No need to drop anything to disk
  • JDK Scripting Tools are signed binaries by Oracle
  • Supported on multiple platforms (Windows, Linux, macOS)


First, let's cover a couple basics when it comes to the Java Development Kit and the Java Runtime Environment (JRE).

Java Runtime Environment

he JRE is the Java Virtual Machine (JVM) where Java programs run on, along with browser plugins for applet execution

Java Development Kit

he JDK is a full feature software development kit for Java, which includes the JRE. The JDK is comparable to what the .NET Framework SDK is for developing .NET applications.

Usage of JDK vs. JRE

Below are the differences between the JDK and JRE in relation to their usage.
  • JDK is used if you need to do Java programming or if applications running on host depend on it in order to function. An example of an application running on a host that could depend on the JDK being installed could be a Java Web Application.
  • JRE is used if you only need to be able to run Java programs in browser or on computer. This is all that is needed for typical users.

JDK Version History

The below table shows the version history between JDK versions.
JDK Version Historyhttps://en.wikipedia.org/wiki/Java_version_history

JDK Scripting Tools

JDK Scripting Tools are command-line tools that can run scripts which interact with the JRE. These tools are located in the below file locations for Windows, Linux and macOS.

  • Windows (default install)
    • C:\Program Files\Java\jdk<version>\bin
    • C:\Program Files (x86)\Java\jdk<version>\bin
    • C:\Program Files\Java\jre<version>\bin
    • C:\Program Files (x86)\Java\jre<version>\bin
  • Linux & macOS (default install)
    • /usr/bin


JRunscript is a command-line scripting shell installed with the JDK on operating systems such as Windows, Linux and macOS that can be used to execute code interpreted by supported Javascript Engines. This tool is installed starting with Java SE 6.

Showing JRunscript Signed by Oracle

JRunscript has the ability to perform several actions with built-in global functions that can be passed to the "-e" switch.
JRunscript Evaluate Switch (-e)

The below functions can be called by "jrunscript -e functionName(arguments)". These definitions were found at http://apprize.info/javascript/scripting/10.html.
  • cat(path, pattern) -  Shows the content of a file, URL, or InputStream specified by path. Optionally, you can specify pattern to show only the matching contents. 
  • cp(from, to)Copies a file, URL, or stream to another file or stream.
  • exec(cmd)Starts a child process, executes the specified command, waits for completion, and returns the exit code.
  • load(path) - Loads and evaluates JavaScript code from a stream, file, or URL.


JJS (Java Javascript) is another command-line scripting shell installed with the JDK on operating systems such as Windows, Linux and macOS that can be used to execute code interpreted by the Nashorn Javascript Engine. This tool is installed starting with Java SE 8.

Showing JJS Signed by Oracle

Nashorn Javascript Engine

The Nashorn Javascript Engine is a code engine that can interpret and execute ECMA-compliant Javascript. This engine can also interpret and execute Java code starting with Java SE 8. The previous engine utilized was the Mozilla Rhino Javascript engine.

Scripting Syntax

It utilizes a traditional Javascript-like syntax. A great resource can be found at https://www.n-k.de/riding-the-nashorn/.

Extending the Java Programming Language

You can extend the Java programming language as seen in the example below by getting direct access to a Java object. The below example uses the "Runtime" Java object to execute an operating system command with the "getRuntime().exec()" method, which in this case is just "calc.exe". More great examples can be found at https://github.com/shekhargulati/java8-the-missing-tutorial/blob/master/10-nashorn.md.


Below you will see several practical uses of the JDK Scripting tools to download files, execute system commands, run local and remote scripts, and get a reverse shell on a computer system.

Downloading Files

The below commands show how to download files with JRunscript either from a web server or file share using the "cat" and "cp" global functions.

Execute System Commands

The below commands show how to execute system commands with JRunscript using the "exec" global function.

Loading & Running Local Scripts

The below commands show how to execute local scripts with JRunscript and JJS.

Loading & Running Remote Scripts

The below commands show how to execute remote scripts with JRunscript using the "load" global function. This will load and execute a script without dropping it to disk.

One-Liner Reverse Shell

The below commands show how to execute a one-liner to give a reverse shell with JRunscript. For the Windows command, it will send the "cmd.exe" process to the IP address and port that you specify. In the Linux & macOS command, it will send "/bin/bash -i" to the IP address and port that you specify. Credit for the original finding of the one-liner reverse CMD shell goes to Chris Frohoff.

Base64 Encoded One-Liner Reverse Shell

The below commands show how to execute a base64 encoded one-liner to give a reverse shell with JRunscript. An example script that can be base64 encoded for a reverse CMD shell can be found here. Credit for the original finding of this base64 encoded one-liner and example reverse CMD shell goes to Chris Frohoff.

Defensive Considerations

There are multiple detective and preventative controls that can be implemented in regards to the usage of the JDK scripting tools. For host-based controls, I will be focusing on Windows.

Full Command-Line Logging

Utilize free tools such as Sysmon to perform full command-line logging. I setup a default install of Sysmon, and it caught the running of JRunscript in my home lab as seen in the screenshot below. These logs will need to be sent to a Security Information & Event Management (SIEM) system where they can be processed and appropriate alerts can be created.

Sysmon Output on My Home Lab Machine

Process Monitoring

Monitor for process creation events containing "jrunscript.exe" or "jjs.exe" However, keep in mind that these files can be renamed and executed as well with appropriate file system permissions.

Filtering on JRunscript Process

User Agent String Monitoring

When utilizing the file download (cat & cp) and remote script loading (load) global functions in JRunscript, the user agent used is "Java/<jdk version>". Rules for detection of this user agent can be implemented.

Apache Logs Showing User Agent String

Application Whitelisting

Implement a robust application whitelisting policy that includes the blocking of JRunscript and JJS. For example, with AppLocker you will need to tweak beyond the default executable rules shown below, as the default rule to allow executable files located in the "Program Files" and "Program Files (x86)" directories would still permit the JDK Scripting Tools to execute.

AppLocker Default Executable Rules

Uninstall JDK

Survey the inventory of hosts in your enterprise and uninstall the JDK where not needed to reduce your risk exposure.


Tuesday, May 8, 2018

Persistence with Sticky Notes Registry Value

Sticky Notes is a Windows utility that can be used by users in order to keep track of notes. When Sticky Notes is started, it writes a registry value called "RESTART_STICKY_NOTES" to  "HKCU\Software\Microsoft\Windows\CurrentVersion\Run". This registry value contains the full path to the Sticky Notes executable (C:\Windows\System32\stikynot.exe), so that when a user logs in after logging off or system reboot, the Sticky Notes are visible automatically for the user. The registry value can be modified, so that upon a user logging in, it executes a program of your choosing rather than Sticky Notes. When the user starts their Sticky Notes application again to display their notes, it will restore the value back to the full path of the Sticky Notes application. This process needs repeated the next time persistence is desired (e.g., before the user will logoff or machine restarts again). 

This can be taken advantage of as a persistence trigger that will blend in with normal behavior on Windows 7 and Windows 8.1, especially if utilizing a signed Microsoft binary to execute a payload (e.g., MSBuild) to hide from utilities like Sysinternals Autoruns. This does not apply to Windows 10.

Procmon Analysis of Sticky Notes Running

While analyzing the operations performed when running Sticky Notes with Sysinternals Procmon, an observation was made that it created a registry value of "RESTART_STICKY_NOTES" in the "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" registry key as seen below.

Procmon Analysis - Sticky Notes Creating Registry Value

Additionally, it was also observed that upon closing any Sticky Notes that were up, the "RESTART_STICKY_NOTES" registry value was deleted. Therefore, this registry value only remains present when a user has active Sticky Notes displayed.
Procmon Analysis - Sticky Notes Deleting Registry Value

Sticky Notes Registry Value Upon Startup

The below screenshot shows the initial registry value "RESTART_STICKY_NOTES" that is created and populated via Sticky Notes.
Registry Value When Sticky Notes is Started

You can see how this looks in Autoruns while showing Windows entries. Autoruns by default does not show Windows entries, so you have to change this filter.
Autoruns Showing Windows Entries w/ Sticky Notes Registry Value

Updating Sticky Notes Registry Value

You can update the registry value with a program of your choosing. In this example, we are just updating it with the execution of calc. No elevated permissions are required in order to do this.

reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v RESTART_STICKY_NOTES /t REG_SZ /d "C:\Windows\System32\cmd.exe /c calc.exe" /f
Modified Sticky Notes Registry Value

Program Execution Upon Login via Modified Sticky Notes Registry Value

Now you can see upon the user logging in, calc runs via our registry change.
Calc Starting After Login

Automatic Reverting of Sticky Notes Registry Value

Once the user interacts with (starts) Sticky Notes again, the registry value will be overwritten with the full path to the Sticky Notes executable again. If you need persistence after the next logoff/logon or system restart, then you will need to repeat the process of updating the registry value before that occurs.

Defensive Considerations

Although the "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" registry key should be actively monitored for abnormal entries along with other known registry persistence locations, the Sticky Notes entry may be ignored as it is normal behavior for Sticky Notes to populate its "RESTART_STICKY_NOTES" value. Therefore, additional monitoring of that registry value should be performed, in order to ensure that it remains the full path of the Sticky Notes executable. Any other file path that is populated should be investigated.