This tool helps you solve ctf tasks by automating workflow and basic analysis and providing useful utilities.

You can get the latest binary from https://github.com/rerrorctf/ret/releases.
$ go build
This will produce the ret
binary. This single file is all you need to use ret
.
There is also a build.sh
that I use to create the binaries that get uploaded to github.
$ ./build.sh
You can list all the commands by using -h
, --help
, help
or simply providing no arguments:
$ ret help
You can get help for a command by prefixing help
to the command:
$ ret help command
$ ret abi [architecture=x64] [os=linux]
view abi details with ret
output includes calling conventions, register volatility and more
for architecture specify one of x86
, 32
, x64
, 64
, arm64
, aapcs64
~ the default is x64
for os specify one of linux
, windows
, mac
~ the default is linux
for example:
$ ret abi x64 linux
$ ret abi 32 windows
$ ret abi arm64 mac
๐ https://github.com/rerrorctf/ret/blob/main/commands/abi.go
$ ret add file1 [file2 file3...]
add one or more files to the current task with ret
performs the following steps:
- analyze each file to determine if it is an elf or not by examining the file's magic bytes
- generate a sha-2-256 hash for each file
- added files are copied into the hidden directory
.ret/files
inside a subfolder that is named using the sha-2-256 hex digest of the file content - save metadata about the files, specifically their length, location and file type (i.e. elf or not), in the files json file in the hidden
.ret
directory - uses strings, with widths of 8, 16 and 32 bits per character, in combination with grep to search for flags added files are subject to processing by other commands that operate on the set of added files
adding a file does not prevent changes from occurring to the source file nor does it detect them for you, like a version control system would
you can track several version of a file by adding each of them remembering that they are addressed according to the hash of their content
you can restore a specific version of a file by copying it from the subdirectory in which a copy of it was made when the file was added
๐ https://github.com/rerrorctf/ret/blob/main/commands/add.go
$ ret capture [flag]
set or query a task's flag with ret
supply no arguments to see the current flag
note that task metadata is stored in hidden directory .ret
and therefore scoped to the cwd
task metadata is stored in the .ret/task.json
file
๐ https://github.com/rerrorctf/ret/blob/main/commands/capture.go
$ ret category [task-category]
set or query a task's category with ret
supply no arguments to see the current category
note that task metadata is stored in hidden directory .ret
and therefore scoped to the cwd
task metadata is stored in the .ret/task.json
file
๐ https://github.com/rerrorctf/ret/blob/main/commands/category.go
$ ret --1 --2 --3 chat [-] [message1 message2 message3...]
chat via a discord webhook with ret
use - to read from stdin
requires a valid webhook this is typically "chatwebhookurl"
from ~/.config/ret
however the command supports up to 3 webhooks using $ ret --1 chat
, $ ret --2 chat
and $ ret --3 chat
if no numerical override is specified the "chatwebhookurl"
webhook is used by default
webhooks 2 and 3 are set with "chatwebhookurl2"
and "chatwebhookurl3"
respectively
requires that "username"
from ~/.config/ret
is set to valid string
when data is read from stdin, due to the use of the - argument, it will be sent as an embed with an accurate timestamp and a random color
color codes, such as the ones used by this tool, are stripped by this code prior to sending
for more information please see https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks
๐ https://github.com/rerrorctf/ret/blob/main/commands/chat.go
$ ret chef [-] [text1 text2 text3...]
open cyberchef with ret
use file - to read from stdin
for example:
$ echo "hello, world!" | base64 | ret chef -
$ ret chef aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1kUXc0dzlXZ1hjUQ==
generates a cyberchef url by appending your input, raw base64 encoded, to https://gchq.github.io/CyberChef/#input=
you can set "chefurl"
in ~/.config/ret
to use another instance of cyberchef
if you provide a custom url it should be the equivalent of https://gchq.github.io/CyberChef/
๐ https://github.com/rerrorctf/ret/blob/main/commands/chef.go
$ ret ctftime [url]
adds a ctftime url with ret
the ctftime urls are stored in ~/.config/ret
using the "ctftimeurls"
field
the command will use the ctftime.org api to fetch details about all the currently set ctftime urls and then display them
the ctf's title, start time and finish time will be displayed along with an indication of the time to the start or finish depending on the context
for more details please see https://ctftime.org/api/
the ctftime urls will be used to aid in the generation of writeups with the writeup
command
๐ https://github.com/rerrorctf/ret/blob/main/commands/ctftime.go
$ ret description [task-description]
set or query a task's description with ret
supply no arguments to see the current description
note that task metadata is stored in hidden directory .ret
and therefore scoped to the cwd
task metadata is stored in the .ret/task.json
file
๐ https://github.com/rerrorctf/ret/blob/main/commands/description.go
$ ret docker [ip] [port]
create a dockerfile from a template with ret
๐ https://github.com/rerrorctf/ret/blob/main/commands/docker.go
$ ret event [ctftime-url]
set or query a task's event with ret
supply no arguments to see the task's current event
note that task metadata is stored in hidden directory .ret
and therefore scoped to the cwd
task metadata is stored in the .ret/task.json
file
๐ https://github.com/rerrorctf/ret/blob/main/commands/event.go
$ ret factor [--n]
factor integers with ret
values can be supplied as either base 10 or base 16 strings and the base will be inferred automatically
for example FEED01234 will be treated as a base 16 string and 123456789 will be treated as a base 10 string
you can supply values the most common prefixes i.e. n= -n= --n=
multiple values can be supplied as a list or with multiple argument prefixes e.g. -n=1,2,3 or -n=1 -n=2 -n=3
for example:
$ ret factor -n=1807415580361109435231633835400969
$ ret factor -n=0x591ccab6e6a72f019cf942f99f09
$ ret factor -n=147879229115615272273161474028448405953
๐ https://github.com/rerrorctf/ret/blob/main/commands/factor.go
$ ret ghidra [file1 file2 file3...]
adds files specified as arguments to this command, creates a ghidra project within the hidden .ret subdirectory, analyzes all added files then opens ghidra with ret
requires that https://ghidra-sre.org/ is installed
this command uses two configurable references to a typical ghidra installation both of which come from ~/.config/ret
-
"ghidrarun"
who's default value is ghidra bash should be able to use this name to find ghidraRun on your path this is typically located at /opt/ghidra/ghidraRun -
"ghidraanalyzeheadless"
who's default value is ghidra-analyzeHeadless bash should be able to use this name to find analyzeHeadless on your path this is typically located at /opt/ghidra/support/analyzeHeadless
๐ https://github.com/rerrorctf/ret/blob/main/commands/ghidra.go
$ ret gist file1 [file2 file3...]
make private gists with ret specify the path of one or more files to upload
๐ https://github.com/rerrorctf/ret/blob/main/commands/gist.go
$ ret ida file1 [file2 file3...]
opens all added files then opens ida with ret
๐ https://github.com/rerrorctf/ret/blob/main/commands/ida.go
$ ret init
init a task with ret
๐ https://github.com/rerrorctf/ret/blob/main/commands/init.go
$ ret name [task-name]
set or query a task's name with ret
supply no arguments to see the current name
note that task metadata is stored in hidden directory .ret
and therefore scoped to the cwd
task metadata is stored in the .ret/task.json
file
๐ https://github.com/rerrorctf/ret/blob/main/commands/name.go
$ ret notes [-] [note1 note2 note3...]
take notes with ret use - to read from stdin
๐ https://github.com/rerrorctf/ret/blob/main/commands/notes.go
$ ret pwn [ip=127.0.0.1] [port=9001]
create a pwntools script template with ret
the file this command creates is named using "pwnscriptname"
from ~/.config/ret
and is "go.py"
by default
this command attempts to guess the name of the main task binary using the list of added files and their types
you can specify the path of a custom template with "pwnscripttemplate"
this command will do the follow substitutions in custom templates:
/%BINARY%/binary
/%IP%/ip
/%PORT%/port
for example:
"remote("%IP%", %PORT%)"
would become"remote("127.0.0.1", 9001)"
"process("./%BINARY%")"
would become"process("./task")"
๐ https://github.com/rerrorctf/ret/blob/main/commands/pwn.go
$ ret readme
make the readme with ret
๐ https://github.com/rerrorctf/ret/blob/main/commands/readme.go
$ ret remote [ip=127.0.0.1] [port=9001]
set or query a task's ip and port with ret
supply no arguments to see the current ip and port
note that task metadata is stored in hidden directory .ret
and therefore scoped to the cwd
task metadata is stored in the .ret/task.json
file
๐ https://github.com/rerrorctf/ret/blob/main/commands/remote.go
$ ret rmctf [url]
remove a ctf with ret
the ctftime url will be removed from the list, if it exists in the list, that is stored in ~/.config/ret
in the "ctftimeurls"
you can also manually remove ctftime urls from this list by directly editing ~/.config/ret
๐ https://github.com/rerrorctf/ret/blob/main/commands/rmctf.go
$ ret share
share task progress with ret
if you have captured a flag with the capture
command this will be sent using the chat
command
if you have a valid "gisttoken"
this command will also make a gist and include the url in the chat message
the gist will attempt to include the following files:
- the pwn script, which uses
"pwnscriptname"
, and is typically generated with thepwn
command - the notes, which are saved in the .ret/notes.json file, and are typically populated with the
notes
command - the flag, which is saved in the .ret/task.json file, and is typically set with the
capture
command
๐ https://github.com/rerrorctf/ret/blob/main/commands/share.go
$ ret status
displays the status for the current task with ret
๐ https://github.com/rerrorctf/ret/blob/main/commands/status.go
$ ret writeup
create a markdown writeup using a template with ret
the writeup will be saved in a file called writeup.md
if a file called writeup.md
already exists the command will abort
there is a small window for a time-of-check/time-of-use race here - you have been warned!
๐ https://github.com/rerrorctf/ret/blob/main/commands/writeup.go
ret
will parse ~/.config/ret
:
{
"ghidrarun": "",
"ghidraanalyzeheadless": "",
"ghidraproject": "",
"idainstallpath": "",
"pwnscriptname": "",
"pwnscripttemplate": "",
"username": "",
"chatwebhookurl": "",
"chatwebhookurl2": "",
"chatwebhookurl3": "",
"gisttoken": "",
"chefurl": "",
"ctftimeurls": []
}