Constants
A constant is like a variable, except that its value cannot change throughout the runtime of the program.
In DuckyScript, a constant is initialized using the
DEFINE
command. One may consider the use of a DEFINE
within a payload like a find-and-replace just before the time of compile - within what is called the preprocessor.
DEFINE
can be used to more easily expose or abstract configuration options used throughout your payload. This means to change a constant value that is described by a DEFINE
you only need to change it in one location no matter how many times its used throughout your payload.DEFINE LABEL VALUE
- 1.
DEFINE
denotes the start of a constant definition - 2.
LABEL
is the label or key to be used by the compiler to locate usage within your payload - 3.
VALUE
is the value to replace matching instances ofLABEL
throughout your payload. TheVALUE
is everything pastLABEL
to the end of the line (minus the first space).
With this in mind its best to keep your
LABEL
as descriptive as possible. Remember - it will be replaced with the given VALUE
- the length of the LABEL
will have no affect on the actual length of your compiled payload.
PayloadStudio takes the guess work out of what will get replaced where by automatically annotating lines that are modified by
DEFINE
statements throughout your payload. 
PayloadStudio Annotation
This also gives you the chance to spot any misconfigurations when compiling your payload as PayloadStudio will list these in the console upon generating your
inject.bin

PayloadStudio on Compile
Depending on the format of your
LABEL
, DEFINE
will behave differently in it's find-and-replace method. This is to significantly reduce the likelihood that your DEFINE
statement has negative unintended side-affects. DEFINE #LABEL
will replace any instance of #LABEL
(except another DEFINE)DEFINE #myConstant TEST
Using this syntax, #myURLConstant
will be replaced anywhere within your payload even if it is touching other characters. This is because the LABEL
starts with #
DEFINE #myURLConstant example.com
STRING https://www.#myURLConstant
This will result in
https://www.example.com
because #myURLConstant
starts with a #

PayloadStudio Annotation
DEFINE LABEL
will replace any instance of LABEL
as its own word separated by spaces (except another DEFINE)DEFINE myURLConstant TEST
Using this syntax,
myURLConstant
will be replaced anywhere it is not touching other characters (is its own individual word) within your payload. This is because the LABEL
does not start with #
DEFINE myURLConstant example.com
STRING my website name is myURLConstant
this will result in
my website name is example.com

PayloadStudio Annotation
Best practice is to start your label with
#
While this method is still supported, it is no longer best practice.
Usage of a given LABEL
becomes very hard to spot mid-payload making your payload more ambiguous without the help of PayloadStudio.
Consider the following example:
DEFINE test 123
STRING This is a test showing the ambiguity
Result:
This is a 123 showing the ambiguity
The instance of test
in the above STRING
will be replaced but it is not obvious if the DEFINE
is not directly above it.
REM Example Boolean
DEFINE #BLINK_ON_FINISH TRUE
DuckyScript developers may find it useful to include defines at the top of their payload which determine whether or not a function will run. This makes it easier for the end-user to customize a shared payload.
REM Integer
DEFINE #DELAY_SPEED 2000
In this example, one may imagine the
DELAY_SPEED
constant will be used in conjunction with one or more DELAY
commands.
DEFINE #MESSAGE example.com
STRING https://
STRING #MESSAGE
DEFINE #MESSAGE example.com
STRING https://#MESSAGE
In both cases this will result in "
https://example.com
" being typed because the label used starts with a #
See above
REM Example constants using DEFINE
ATTACKMODE HID STORAGE
DEFINE #SPEED 2000
DEFINE #MESSAGE1 Hello,
DEFINE #MESSAGE2 World! Written with a define!
DELAY #SPEED
STRING #MESSAGE1
DELAY #SPEED
SPACE
STRING #MESSAGE2
- The payload will begin with a 2 second delay, then type "
Hello, World! Written with a define!
" with a 2 second delay in between#MESSAGE1
and#MESSAGE2
. - Changing the string values of
#MESSAGE1
and#MESSAGE2
will change the outcome of the payload. - Changing the integer value of
#SPEED
will change the delay between the first and second message.
Considering
DEFINE
is a effectively an automatic find-and-replace step prior to compile, the VALUE
of a DEFINE
is not limited to any specific datatypes. Any valid DuckyScript syntax can be the VALUE
of a DEFINE
DEFINE #FINISHED_PAYLOAD_LED LED_G
...Payload...
#FINISHED_PAYLOAD_LED

PayloadStudio Annotation
Configurable payload options should be specified in variables or defines at the top of the payload.
Define labels should start with
#
for easy identification throughout your payload.When writing a payload that calls external resources which may vary depending on the operator, such as a website to open or address to establish a reverse shell with, it is best to use
DEFINE
.In addition to comment blocks (like the
REM
title/author/description lines in the above example), putting your DEFINE
commands at the top of your payload makes it easier for someone else to use your payload effectively. Even more so if the constants are commented!
- Internal variables begin with an underscore, so it is best practice to avoid this style.
- Spaces cannot be used in naming a constant — however underscore makes for a suitable replacement. For example:
DEFINE #REMOTE_HOST 192.168.1.100
. - Labels should descriptive. For example,
#RHST
is better than#R
, and#REMOTE_HOST
is better than#RHOST
. - Be careful when using the uppercase letter
O
or lowercase letterl
as they may be confused with the numbers0
and1
. - Avoid using the names of commands or internal variables (e.g.
ATTACKMODE
,STRING
,WINDOWS
,MAC
,$_BUTTON_ENABLED
). See the full command and variable reference.
DEFINE myURLConstant example.com
STRING https://www.myURLConstant
This will result in
https://www.myURLConstant
because myURLConstant
was not its own word and does not start with #
DEFINEs are excluded from being substituted by other DEFINEs
DEFINE #TEST 123
DEFINE #TEST2 #TEST
This will not replace the value of
#TEST2
with 123