Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,16 @@ $ 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:

1. the pwn script, which uses `"pwnscriptname"`, and is typically generated with the `pwn` command
2. the crypto script, which uses `"cryptoscriptname"`, and is typically generated with the `crypto` command
3. the notes, which are saved in the .ret/notes.json file, and are typically populated with the `notes` command
4. the flag, which is saved in the .ret/flag.json file, and is typically set with the `capture` command

🔗 https://github.com/rerrorctf/ret/blob/main/commands/share.go

Expand Down
65 changes: 35 additions & 30 deletions commands/share.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package commands

import (
"fmt"
"log"
"os"
"ret/config"
"ret/theme"
Expand All @@ -16,54 +15,60 @@ func init() {
Func: Share,
Help: ShareHelp,
Arguments: nil,
SeeAlso: []string{"notes", "capture", "chat", "gist", "pwn"}})
SeeAlso: []string{"notes", "capture", "chat", "gist", "pwn", "crypto"}})
}

func ShareHelp() string {
return "share task progress with ret\n\n"
return "share task progress with ret\n\n" +
"if you have captured a flag with the " + theme.ColorGreen + "`capture`" + theme.ColorReset + " command this will be sent using the " + theme.ColorGreen + "`chat`" + theme.ColorReset + " command\n\n" +
"if you have a valid " + theme.ColorYellow + "`\"gisttoken\"`" + theme.ColorReset + " this command will also make a gist and include the url in the chat message\n\n" +
"the gist will attempt to include the following files:\n\n" +
"1. the pwn script, which uses " + theme.ColorYellow + "`\"pwnscriptname\"`" + theme.ColorReset + ", and is typically generated with the " + theme.ColorGreen + "`pwn`" + theme.ColorReset + " command\n" +
"2. the crypto script, which uses " + theme.ColorYellow + "`\"cryptoscriptname\"`" + theme.ColorReset + ", and is typically generated with the " + theme.ColorGreen + "`crypto`" + theme.ColorReset + " command\n" +
"3. the notes, which are saved in the " + theme.ColorCyan + ".ret/notes.json" + theme.ColorReset + " file, and are typically populated with the " + theme.ColorGreen + "`notes`" + theme.ColorReset + " command\n" +
"4. the flag, which is saved in the " + theme.ColorCyan + ".ret/flag.json" + theme.ColorReset + " file, and is typically set with the " + theme.ColorGreen + "`capture`" + theme.ColorReset + " command\n"
}

func Share(args []string) {
if len(config.GistToken) == 0 {
log.Fatalf("💥 " + theme.ColorRed + "error" + theme.ColorReset + ": no gist token in ~/.config/ret\n")
flag, err := util.GetCurrentFlag()
if err != nil {
flag = config.FlagFormat
}

files := map[string]interface{}{}
gistUrl := ""

buffer, err := os.ReadFile(config.PwnScriptName)
if err == nil {
files[config.PwnScriptName] = map[string]interface{}{
"content": string(buffer),
if len(config.GistToken) > 0 {
files := map[string]interface{}{}

buffer, err := os.ReadFile(config.PwnScriptName)
if err == nil {
files[config.PwnScriptName] = map[string]interface{}{
"content": string(buffer),
}
}
}

buffer, err = os.ReadFile(config.CryptoScriptName)
if err == nil {
files[config.CryptoScriptName] = map[string]interface{}{
"content": string(buffer),
buffer, err = os.ReadFile(config.CryptoScriptName)
if err == nil {
files[config.CryptoScriptName] = map[string]interface{}{
"content": string(buffer),
}
}
}

buffer, err = os.ReadFile(config.NotesFileName)
if err == nil {
// does not like .ret/notes.json
files["notes.json"] = map[string]interface{}{
"content": string(buffer),
buffer, err = os.ReadFile(config.NotesFileName)
if err == nil {
// does not like .ret/notes.json
files["notes.json"] = map[string]interface{}{
"content": string(buffer),
}
}
}

flag, err := util.GetCurrentFlag()
if err != nil {
flag = config.FlagFormat
} else {
files["flag.txt"] = map[string]interface{}{
"content": string(flag),
}
}

gistUrl := ""
if len(files) > 0 {
gistUrl = "**" + util.Gist(files) + "**"
if len(files) > 0 {
gistUrl = "**" + util.Gist(files) + "**"
}
}

Chat([]string{fmt.Sprintf("🏁 `%s`\n%s", flag, gistUrl)})
Expand Down