Est. 2002 Intermediate

Sleep

Sleep is a small Perl-inspired scripting language for the Java platform, written by Raphael Mudge over a weekend in April 2002 so that his Java IRC client could have a scripting engine - and now best known as the substrate of Aggressor Script, the language red teams write inside Cobalt Strike

Created by Raphael Mudge, who wrote Sleep as the scripting engine for his Java IRC client jIRCii and later founded Strategic Cyber LLC, the company behind Cobalt Strike. The Sleep licence carries the notice 'Copyright 2002-2020 Raphael Mudge'

Paradigm Multi-paradigm scripting, principally procedural, with first-class closures, coroutines and continuations, and a message-passing object notation borrowed from Objective-C for reaching into the Java class library. The homepage calls it 'a multi-paradigm scripting language for the Java Platform'
Typing Dynamic. Scalars are sigil-typed in the Perl manner - $scalar, @array, %hash - and hold strings, integers, doubles, Java objects or closures interchangeably, with conversion on demand. An optional taint mode marks data from external sources
First Appeared 2002. The manual states that 'Sleep started out as a weekend long hack fest in April 2002', and the last line of the project changelog reads '06 Apr 02 - Initial Release? :)'
Latest Version Sleep 2.1 'update 5', dated 29 February 2020 on the project download page. This was a two-item release - a fix to generated code for && and || in predicates, and the relicensing of the project under the BSD licence

Sleep is a small scripting language for the Java Virtual Machine with Perl’s syntax on the outside and the entire Java class library on the inside. It was written by Raphael Mudge in April 2002 for the most ordinary of reasons - he was building a Java IRC client, he wanted it to be scriptable, and none of the JVM languages available at the time looked anything like Perl. It never became a general-purpose language and it stopped being released in 2020. It is nevertheless still run every day, because a language built on it is the extension mechanism of Cobalt Strike, one of the most widely used commercial red-team platforms in the world.

What Sleep Is

The project homepage summarises Sleep in five lines:

  • a multi-paradigm scripting language for the Java Platform
  • easy to learn, with Perl and Objective-C inspired syntax
  • executes scripts fast with a small package size (~250 KB)
  • excels at data manipulation, component integration, and distributed communication
  • seamlessly uses Java objects and 3rd party libraries

The download page lists the prebuilt sleep.jar at 251K, and the file it serves is 256,095 bytes, which makes the size claim checkable. The speed claim is not - no published benchmark accompanies it, and it should be read as the author’s characterisation rather than a measured result.

The tagline the site settled on is blunter: Duct Tape for the Java platform.

History and Origins

The Sleep 2.1 manual tells the origin story in its own words:

The java world currently has Jacl for TCL, Jython for Python, and JRuby for Ruby. One offering is missing from this bunch: what Java scripting language exists for the Perl hackers of the world? […] Sleep started out as a weekend long hack fest in April 2002. When nothing like Perl was available to build a scriptable Internet Relay Chat client, I set out to build the scripting language I wanted.

The changelog agrees, ending with 06 Apr 02 - Initial Release? :) - the question mark and the smiley are in the original. For roughly two years Sleep existed only as the scripting engine inside jIRCii, shaped by what IRC script authors asked for. The manual’s acknowledgements thank a list of jIRCii scripters by handle, mostly nicknames, “for finding the issues so others don’t have to.”

The second act begins with a changelog entry dated 20 March 2004: Initial Release, Take II. Over the following months Sleep acquired the machinery of a standalone language - @ARGV, a -jar manifest so the console could be started directly, break and continue, eval(), the @_ argument array, date functions ported over from jIRCii rather than the other way round.

The decisive change arrived on 13 March 2005 with Sleep 2.0-b1 and an experimental interface with a deliberately unserious name: HOES, the Haphazard Object Extensions for Sleep. HOES let a script instantiate and message arbitrary Java objects. Mudge was cautious about it in the changelog itself, warning that “Sleep is a language meant to provide an easy to learn abstraction of an application’s API” and that HOES “should not be solely relied on to provide a solid scripting interface for an application.” Users ignored the caution, as users do, and object expressions became one of the defining features of the language.

Sleep 2.1 was a long project - twenty-seven betas between June 2006 and May 2008, a rewritten interpreter using proper stack frames, coroutines, and a release on 16 June 2008. Six maintenance updates followed over the next twelve years - numbered 1, 2, 2.5, 3, 4 and 5 - the last on 29 February 2020.

The Language

Sigils and scalars

Sleep borrows Perl’s variable notation without apology. $scalar holds a single value, @array a list, %hash a map. Scalars are dynamically typed and hold strings, integers, doubles, Java objects and closures alike.

1
2
3
4
5
6
7
8
$name = "world";
println("Hello $name");

@list = @("a", "b", "c");
%map  = %(host => "example.com", port => 6667);

println(size(@list));       # 3
println(%map["host"]);      # example.com

Subroutines, anonymous arguments and named arguments

Functions take arguments positionally as $1, $2, $3, with @_ holding all of them:

1
2
3
4
5
6
sub add
{
   return $1 + $2;
}

$x = add(3, 4);

Arguments are passed by reference, a fact the manual flags with an entire warning section: assigning to $1 inside a subroutine changes the caller’s variable. Sleep offers a &watch function specifically to catch this class of accident. Named arguments use a key-value operator that injects the value straight into the callee’s local scope:

1
2
3
4
5
6
sub team
{
   println("$first is a member of team: $team");
}

team($first => "James", $team => "ramrod");

Closures, coroutines and continuations

Closures are ordinary values in Sleep, and 2.1 added a yield keyword that suspends a closure and resumes execution at that point on the next call - genuine coroutines, in a language that otherwise reads like a Perl one-liner. Continuations get their own section of the manual’s chapter on functions.

Object expressions: the Objective-C part

The Perl half of Sleep’s syntax stops at the square bracket. To touch a Java object, Sleep uses a message-send notation lifted from Objective-C:

1
2
3
4
5
6
7
[[System out] println: "Hello World!"];

$scalar = [new java.util.StringTokenizer: "this is a test", " "];

import java.awt.Point;
$point = [new Point: 3, 4];
setField($point, x => 33, y => 45);

The form is [target message] or [target message: arg, arg, ...]. The target may be a scalar, a class, or another object expression. Sleep imports java.lang, java.util and sleep.runtime by default, understands import java.awt.* wildcards, has a class-literal syntax (^String for java.lang.String) and an isa predicate for instance checks. Scalars have object representations too, so ["this is a String" lastIndexOf: "i"] works exactly as the equivalent Java method call would.

Third-party jars can be pulled in at runtime with import ... from:, using a classpath-manipulation trick that the changelog credits to Ralph Becker’s classpath extension for Sleep so that multiple jars loaded this way can see each other’s resources.

Taint mode

Sleep inherits Perl’s taint concept as well as its sigils. Running with -Dsleep.taint=true marks data arriving from external sources as tainted, and some standard functions - &eval, &expr, &compile_closure, &include - refuse to accept tainted values. For a language whose largest deployments are in security tooling, this turned out to be an appropriate inheritance.

Running scripts

$ java -jar sleep.jar hello.sl

The interpreter takes a script file, an expression via -e/-x, or - to read from standard input, and offers --ast to dump the abstract syntax tree, --check to syntax-check without running, --profile for runtime statistics and --time for total runtime. Sleep 2.1 also implements JSR-223, so with sleep.jar on the classpath a script can be launched through Java’s generic scripting interface with jrunscript -l sleep -f hello.sl.

Where Sleep Actually Ran

Sleep’s public profile is small; its installed base is not, because of a chain of projects that each embedded it.

jIRCii came first and stayed longest - the client Sleep was written for, scriptable in Sleep for its whole life.

After the Deadline was the commercial detour. Mudge’s contextual spelling, style and grammar checker went public in 2009, written - according to the project’s own source-code tour - “in a combination of Sleep and Java”; Automattic announced the acquisition on 8 September 2009 and wired it into WordPress.com’s proofreading. The engine was open sourced after the acquisition. It is an unusual entry on any language’s résumé: a natural-language service in a Perl-flavoured JVM scripting language.

Armitage and Cortana moved Sleep into security work. Armitage, the collaborative Metasploit front end, ships sleep.jar in its lib directory, and Cortana - its scripting engine, funded through DARPA’s Cyber Fast Track program and released at DEF CON 20 in August 2012 - is built on the Sleep runtime. The header comment on cortana/Main.java still carries the credit: “Funded by DARPA’s Cyber Fast Track Program (jEAH bABY)”.

Cobalt Strike and Aggressor Script are the reason Sleep still matters. Cobalt Strike 3.0, released 24 September 2015, was a rewrite that abandoned Armitage as a base and replaced Cortana with Aggressor Script - “the spiritual successor to Cortana,” in the vendor’s own documentation, and built on Sleep just as Cortana was. Aggressor Script is not a veneer: the product documentation states that most popup menus and the presentation of events in the client are managed by the Aggressor Script engine. Its script console commands are documented as evaluating “a sleep predicate” and “a sleep statement.”

The through-line, which Mudge has acknowledged, runs from scriptable IRC clients and bots all the way to red-team automation. Aggressor Script’s design goal - long-running bots that act as virtual team members - is the IRC bot idea, transplanted.

Current Status

Sleep is dormant. The last release is dated 29 February 2020 and consisted of a predicate code-generation fix plus a move to the BSD licence. There is no public source repository under the author’s GitHub account, no Maven Central artifact, and no packaged distribution: the language is a zip of source and a single jar on sleep.dashnine.org, which is still online and still serving the 2.1 manual, JavaDoc, reference card and full changelog. The Google Group and the #jIRCii channel on EFnet that the manual points to are quiet.

The descendant is another story. Cobalt Strike passed to HelpSystems - now Fortra - on 4 March 2020, and remains under active development; version 4.13 shipped in June 2026, still scripted with Aggressor Script, still adding Aggressor functions release by release. Sleep therefore occupies a strange position: a language whose own development stopped, whose name most of its users have never heard, and whose runtime semantics are relied on daily by professional operators and, less happily, by the many criminal groups that use cracked Cobalt Strike builds.

Why It Matters

Sleep is a good example of a category that language surveys tend to miss: the application extension language. Nobody chooses Sleep to write an application in. Applications choose Sleep so their users can write scripts, and the users learn it because it is the language in the box. TCL, Lua, Emacs Lisp and mIRC script all live in this category, and it is a category where a language’s reach has almost nothing to do with its popularity as a language.

Three things about Sleep are worth taking seriously on their own terms.

The first is the embedding story. Sleep’s Java API - script loaders, per-script environments, bridges for adding native functions, a documented taint interface - was designed for the host application rather than the script author, which is why so many hosts adopted it. An entire manual chapter is devoted to embedding.

The second is the syntax mashup. Perl sigils and regular expressions on one side, Objective-C message sends on the other, with the seam falling exactly where the language stops being about text and starts being about objects. It is not elegant in a design-award sense, but it is unusually legible: you can tell at a glance whether a line of Sleep is manipulating data or driving the JVM.

The third is what durability actually looks like. Sleep has had no release since 2020 and no community to speak of, yet its execution model is a load-bearing part of a commercial product with a June 2026 release. A language can be finished without being dead. Sleep is one of the clearest cases of the distinction, and its author - who moved on from language design to security tooling and then to other work entirely - built something small enough that it did not need him to keep going.

Timeline

2002
Raphael Mudge writes the first version of Sleep. The Sleep 2.1 manual gives the motive plainly: 'The java world currently has Jacl for TCL, Jython for Python, and JRuby for Ruby. One offering is missing from this bunch: what Java scripting language exists for the Perl hackers of the world?' He needed a scripting engine for a Java IRC client, found nothing Perl-like on the JVM, and built one. The changelog dates the first release to 6 April 2002
2004
After roughly two years of use inside jIRCii, Sleep gets a second start - the changelog entry for 20 March 2004 reads 'Initial Release, Take II'. A burst of work over the rest of that year adds the pieces that make it usable as a general scripting language rather than a chat-client macro facility: @_ and anonymous arguments in subroutines, the @ARGV array, break and return inside loops, eval() and expr(), the x string-repetition operator, and a manifest so that java -jar sleep.jar starts a console
2005
Sleep 2.0-b1, released 13 March 2005, introduces HOES - 'Haphazard Object Extensions for Sleep' - the bracketed [target message: arguments] notation that lets a script create and call arbitrary Java objects. This is the feature that turns Sleep from a language embedded in one application into a way to script the entire Java class library, and it is the reason the site later describes Sleep as 'Duct Tape for the Java platform'
2006
Development of Sleep 2.1 opens with beta 1 on 16 June 2006. It is a substantial rewrite: the interpreter is reworked to use stack frames rather than one shared environment stack, and coroutines are added by way of a yield keyword that suspends a closure and resumes it where it left off on the next call. Betas continue, with long gaps, through 2007 and into 2008
2008
Sleep 2.1 reaches release on 16 June 2008 after twenty-seven betas. Along the way it picks up JSR-223 support, so Sleep scripts can be launched with Java 6's jrunscript; a taint mode toggled with -Dsleep.taint; sublists backed by a purpose-built List implementation; and a global regular-expression pattern cache. Four maintenance updates follow before the year is out - updates 1, 2, 2.5 and 3 - several of them driven by bug reports from the jIRCii scripting community
2009
Sleep 2.1 update 4 lands on 30 April, largely a concurrency release - semaphores switch to notifyAll() to clear a deadlock seen on a multicore machine, fork() stops leaking closure scope into the child environment, and the in operator is overloaded so that a hash can be probed without the read turning into a write. In the same year Mudge's After the Deadline - a contextual spelling, style and grammar checker written, in its own documentation's words, 'in a combination of Sleep and Java' - goes public; Automattic announces the acquisition on 8 September 2009 (the deal itself closed that July) and puts it behind WordPress.com's proofreader
2012
Sleep becomes infrastructure for offensive security tooling. Cortana, a scripting language for Armitage and Metasploit funded by a contract through DARPA's Cyber Fast Track program, is released at DEF CON 20 in August 2012. Its source is unambiguous about the foundation - cortana/Main.java imports sleep.runtime.SleepUtils, and sleep.jar sits in the Armitage lib directory. GitHub's language statistics for the Armitage repository still count roughly 300 KB of .sl source alongside its Java, although GitHub's linguist labels the extension 'Slash' rather than Sleep
2015
Cobalt Strike 3.0 ships on 24 September 2015 as a ground-up rewrite that drops Armitage as a foundation, and with it comes Aggressor Script - described in the product documentation as 'the spiritual successor to Cortana' and built, like Cortana, on Sleep. Its console commands still speak of evaluating 'a sleep predicate' and 'a sleep statement'. Most of the popup menus and event presentation in the new client are managed by the Aggressor Script engine
2020
Two things happen to Sleep's world in the same few weeks. On 4 March, HelpSystems (later Fortra) announces the acquisition of Strategic Cyber LLC, putting Cobalt Strike - and by extension Aggressor Script - under corporate ownership. On 29 February, Mudge publishes what is still the last release of Sleep itself, update 5, which fixes code generation for && and || in predicates and moves the project from its previous terms to the BSD licence
2026
Sleep has had no release in six years and its Google Group and EFnet channel are long quiet, but the language is not gone. Cobalt Strike 4.13, released in June 2026, is still scripted with Aggressor Script, still documents a Sleep-evaluating script console, and continues to add Aggressor functions with each version - which makes Sleep one of the more widely executed dormant languages in the world, almost entirely by people who have never visited its homepage

Notable Uses & Legacy

jIRCii

The Java IRC client Sleep was invented for. jIRCii is fully scriptable in Sleep, and its community of script authors was the language's first and longest-serving user base - the Sleep manual notes that 'the jIRCii community put up with a very rough scripting language a few years ago' and thanks a list of scripters by handle 'for finding the issues so others don't have to', and several 2.1 fixes are credited to jIRCii compatibility problems

Cobalt Strike (Aggressor Script)

Aggressor Script, the scripting language built into Cobalt Strike 3.0 and later, builds directly on Sleep. Red teams use it to write bots that hack alongside them and to extend the Cobalt Strike client's menus, event handlers and reporting. It is by a wide margin the most-used descendant of Sleep, and large public collections of .cna Aggressor scripts exist on GitHub

Armitage and Cortana

Armitage, the collaborative graphical front end for the Metasploit Framework, embeds sleep.jar and exposes Cortana - a DARPA Cyber Fast Track-funded scripting language written on top of Sleep - so that operators can automate Metasploit and host scripted bots in a shared engagement

After the Deadline

Mudge's contextual proofreading service, written - per its own source-code tour - in a combination of Sleep and Java, with a dozen .sl files making up the dictionary, tagger, spellcheck and rule-engine layers. Automattic announced its acquisition on 8 September 2009 and the engine was open sourced afterwards; it went on to power the proofreading feature on WordPress.com and was distributed as a WordPress plugin and browser extension

SleepyBot

Described on the Sleep community page as 'a scriptable pIRC bot' and hosted on Ralph Becker's ululatus.org, it is listed among the site's projects alongside jIRCii, After the Deadline and Cobalt Strike - one of a family of chat-adjacent tools that took Sleep for the same reason its author wrote it, namely that users wanted Perl-flavoured scripting on a JVM

Language Influence

Influenced By

Influenced

Cortana Aggressor Script

Running Today

Run examples using the official Docker image:

docker pull
Last updated: