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)
Background
First, let's cover a couple basics when it comes to the Java Development Kit and the Java Runtime Environment (JRE).
Java Runtime Environment
The JRE is the Java Virtual Machine (JVM) where Java programs run on, along with browser plugins for applet execution
Java Development Kit
The 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 History - https://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
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
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.
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.
Usage/Examples
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 (https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/applocker/executable-rules-in-applocker) |
Uninstall JDK
Survey the inventory of hosts in your enterprise and uninstall the JDK where not needed to reduce your risk exposure.
References
- https://gist.github.com/frohoff/8e7c2bf3737032a25051
- https://gist.github.com/frohoff/a976928e3c1dc7c359f8
- https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/api.html
- https://www.javaworld.com/article/2074165/core-java/jrunscript-and-groovy.html
- http://apprize.info/javascript/scripting/10.html
- https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/shell.html
- https://docs.oracle.com/javase/7/docs/technotes/tools/index.html
- https://docs.oracle.com/javase/8/docs/technotes/tools/
- https://docs.oracle.com/javase/9/tools/scripting-commands.htm#JSWOR749
- http://apprize.info/javascript/scripting/11.html
- https://github.com/shekhargulati/java8-the-missing-tutorial/blob/master/10-nashorn.md
- https://www.n-k.de/riding-the-nashorn/
- https://gist.github.com/h4wkst3r/d1fb53060f777dfb23b0e3234ffada61
- https://gist.github.com/h4wkst3r/c2a9b86ad8de5e11ff57115da78acc5e
- https://gist.github.com/h4wkst3r/7f383a1808585a2059777fdd4e5f9531
- https://gist.github.com/h4wkst3r/27f997627bc6158ee7372629685cb804
- https://gist.github.com/h4wkst3r/fb79d4bac99b459f061a530feee60a74
- https://gist.github.com/h4wkst3r/2c2cae2e3a32bf64576d5faa01f2df8e
- https://gist.github.com/h4wkst3r/d6fa08e41bdcb591909c5f93b5f1716a