Documentation
¶
Index ¶
Constants ¶
View Source
const SQL_INSERT_HISTORY = `INSERT INTO history (executable, arguments, environment) VALUES (?, ?, ?)`
View Source
const SQL_INSERT_OUTPUT = `INSERT INTO output (history_id, stdout, stderr, exitcode) VALUES (?, ?, ?, ?)`
View Source
const SQL_UPSERT_OUTPUT = `` /* 197-byte string literal not displayed */
View Source
const VERSION = "2025.02.17"
Variables ¶
View Source
var DocCmd = &cobra.Command{ Use: "doc", Short: fmt.Sprintf("Build documentation under %s", documentationBasepath), Long: fmt.Sprintf(`Generate documentation for command line usage under %s`, documentationBasepath), PersistentPreRun: func(cmd *cobra.Command, args []string) { CallPersistentPreRun(cmd, args) }, Run: func(cmd *cobra.Command, args []string) { err := os.MkdirAll(documentationBasepath, 0750) if err != nil { log.Fatal(err) } err = doc.GenMarkdownTree(cmd.Root(), documentationBasepath) if err != nil { log.Fatal(err) } }, }
View Source
var ExecuteCmd = &cobra.Command{ Use: "execute", Short: "Wrap and collect executing command and resulting output", Long: "Provided with a command to execute, record it and the returned output from execution (including exitcode)", DisableFlagParsing: true, Run: func(_ *cobra.Command, args []string) { executable := args[0] db, err := util.CreateSQLite3Database() if db != nil { defer db.Close() } if err != nil { fmt.Printf("error creating database: %v", err) return } arguments := strings.Join(args[1:], " ") envVars := os.Environ() environment := strings.Join(envVars, ":") result, err := db.Exec(SQL_INSERT_HISTORY, executable, arguments, environment) if err != nil { fmt.Printf("error inserting record: %v", err) return } historyId, err := result.LastInsertId() if err != nil { fmt.Printf("error obtaining historyId: %v", err) return } cmd := exec.Command(executable, args[1:]...) stdoutPipe, err := cmd.StdoutPipe() if err != nil { log.Fatalf("Failed to create stdout pipe: %v", err) } stderrPipe, err := cmd.StderrPipe() if err != nil { log.Fatalf("Failed to create stderr pipe: %v", err) } ptmx, err := pty.Start(cmd) if err != nil { log.Fatalf("Failed to start pty: %v", err) } defer ptmx.Close() var stdoutOutput, stderrOutput string go func() { buf := make([]byte, 1024) for { n, err := ptmx.Read(buf) if err != nil { break } os.Stdout.Write(buf[:n]) stdoutOutput += string(buf[:n]) } }() go func() { scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { _, err = db.Exec(SQL_UPSERT_OUTPUT, historyId, stdoutOutput, stderrOutput, 99) if err != nil { fmt.Printf("error inserting record: %v", err) return } stdoutOutput = "" stderrOutput = "" commandLine := scanner.Text() args := strings.Split(commandLine, " ") result, err := db.Exec(SQL_INSERT_HISTORY, args[0], strings.Join(args[1:], " "), "") if err != nil { fmt.Printf("error inserting record: %v", err) return } historyId, err = result.LastInsertId() if err != nil { fmt.Printf("error obtaining historyId: %v", err) return } if _, err := io.WriteString(ptmx, commandLine+"\n"); err != nil { log.Fatalf("Failed to write to pty: %v", err) } } }() go func() { stdoutScan := bufio.NewScanner(stdoutPipe) for stdoutScan.Scan() { data := stdoutScan.Text() + "\n" os.Stdout.WriteString(data) stdoutOutput += data } }() go func() { stderrScan := bufio.NewScanner(stderrPipe) for stderrScan.Scan() { data := stderrScan.Text() + "\n" os.Stderr.WriteString(data) stderrOutput += data } }() var exitcode = -1 if err := cmd.Wait(); err != nil { if exitError, ok := err.(*exec.ExitError); ok { exitcode = exitError.ExitCode() fmt.Fprintln(os.Stderr, exitError.Stderr) } else { err := fmt.Sprintf("Error waiting for command: %v", err) fmt.Fprintln(os.Stderr, err) stderrOutput += err exitcode = cmd.ProcessState.ExitCode() } } else { exitcode = cmd.ProcessState.ExitCode() } _, err = db.Exec(SQL_UPSERT_OUTPUT, historyId, stdoutOutput, stderrOutput, exitcode) if err != nil { fmt.Printf("error inserting record: %v", err) return } }, }
View Source
var NoteCmd = &cobra.Command{ Use: "note", Short: "Record history as notes for a project", Long: `Having used the 'execute' command to record execution, record the results to a project`, PersistentPreRun: func(cmd *cobra.Command, args []string) { CallPersistentPreRun(cmd, args) config.Load() if rootConfig.Setting.Debug { util.Logger.SetReportCaller(true) config.Setting.Print() } }, Run: func(cmd *cobra.Command, args []string) { if !config.Setting.Local { if config.Setting.SSHKey == "" || config.Setting.SSHUser == "" || config.Setting.IP == "" || config.Setting.Port == "" { util.Logger.Error("When not in local mode - sshkey, sshuser, ip, and port are all required") os.Exit(1) } if config.Setting.SSHUser != "" { usernamePlain, _, projectId := util.GetUsernameProjectIfPresent(config.Setting.SSHUser) config.Setting.SSHUser = usernamePlain if config.Setting.ProjectId == "" { config.Setting.ProjectId = projectId } } } if config.Setting.ProjectId == "" { util.Logger.Error("project id is required") os.Exit(2) } if config.Setting.Export { if config.Setting.Local { _ = app.SetupPocketbase(config.Setting.StoragePath) data, err := database.GetNotesAsMarkdown(config.Setting.ProjectId) if err != nil { util.Logger.Error(fmt.Sprintf("error reading note: %v", err)) os.Exit(3) } fmt.Println(string(data)) } else { err := util.ReadNote(config.Setting.SSHUser, config.Setting.SSHKey, config.Setting.ProjectId, config.Setting.IP, config.Setting.Port) if err != nil { util.Logger.Error(fmt.Sprintf("error reading note: %v", err)) os.Exit(3) } } } else { db, err := util.CreateSQLite3Database() if db != nil { defer db.Close() } if err != nil { util.Logger.Error(fmt.Sprintf("error creating database: %v", err)) os.Exit(3) } historySelection, err := util.GetHistory(db, 2000) if err != nil { util.Logger.Error(fmt.Sprintf("error querying database: %v", err)) os.Exit(3) } var options []huh.Option[util.HistorySelection] var selectedHistoryItems []util.HistorySelection for _, cmd := range historySelection { options = append(options, huh.NewOption(fmt.Sprintf("%d] %s", cmd.Id, cmd.Command), cmd)) } var noteTitle = "" var noteComment = "" _ = tea.ClearScreen() form := huh.NewForm( huh.NewGroup( huh.NewInput(). Title("Title"). Placeholder("The title for the note"). Value(¬eTitle). Description("The contents of the following commands/arguments + output if any will be used to create the note"), huh.NewText(). Title("Comment"). Placeholder("Any context you wish to add for the command('s) that were executed"). CharLimit(5000). Value(¬eComment). WithHeight(5), huh.NewMultiSelect[util.HistorySelection](). Title("Select 1..N to create a new note"). Description("If a command starts with `[!]` - its exitcode was none 0"). Height(25). Value(&selectedHistoryItems). Key("Id"). Options(options...), ), ).WithTheme(huh.ThemeCharm()) if err := form.Run(); err != nil { if form.State == huh.StateAborted { util.Logger.Error("aborting note selection/upload") os.Exit(0) } util.Logger.Error(fmt.Sprintf("error querying database: %v", err)) os.Exit(4) } sort.Slice(selectedHistoryItems, func(x, y int) bool { return selectedHistoryItems[x].Id > selectedHistoryItems[y].Id }) var ids []int for _, c := range selectedHistoryItems { ids = append(ids, c.Id) } note, err := util.GetNote(db, ids, noteTitle, noteComment) if err != nil { util.Logger.Error(fmt.Sprintf("error querying database: %v", err)) os.Exit(4) } if config.Setting.Local { _ = app.SetupPocketbase(config.Setting.StoragePath) err := database.AddNote(config.Setting.ProjectId, noteTitle, note) if err != nil { util.Logger.Error(fmt.Sprintf("error saving note: %v", err)) os.Exit(5) } } else { note = fmt.Sprintf("%s\r\n%s", noteTitle, note) err = util.SendNote(note, config.Setting.SSHUser, config.Setting.SSHKey, config.Setting.ProjectId, config.Setting.IP, config.Setting.Port) if err != nil { util.Logger.Error(fmt.Sprintf("error sending note: %v", err)) os.Exit(5) } } } }, }
View Source
var RootCmd = &cobra.Command{ Version: VERSION, Use: "hexer", Short: "A place to organize HTB activities", Long: "Leverage SSH or just stay local - an organize those HTB labs", PersistentPreRun: func(cmd *cobra.Command, args []string) { CallPersistentPreRun(cmd, args) config.Load() logger := util.SetLogger(fmt.Sprintf("%s/system.log", config.Setting.LogBasepath)) if logger == nil { logger := util.SetLogger("./system.log") if logger == nil { err := cmd.Help() if err != nil { log.Fatal(err) os.Exit(1) } os.Exit(0) } } if config.Setting.Debug { config.Setting.Print() } }, Run: func(cmd *cobra.Command, args []string) { if len(args) == 0 { err := cmd.Help() if err != nil { util.Logger.Error(err) os.Exit(1) } os.Exit(0) } version, _ := cmd.Flags().GetBool("version") if version { util.Logger.Infof("Version %s\n", VERSION) os.Exit(0) } }, }
View Source
var ServeCmd = &cobra.Command{ Use: "serve", Short: "Start the server on the desired ip/port", Long: `Leveraging the goodness of Golang and SSH - setup a local server for recording HTB credentials & flags`, PersistentPreRun: func(cmd *cobra.Command, args []string) { CallPersistentPreRun(cmd, args) config.Load() if rootConfig.Setting.Debug { util.Logger.SetReportCaller(true) config.Setting.Print() } }, Run: func(cmd *cobra.Command, args []string) { err := app.NewApplication().Start() if err != nil { util.Logger.Error(err) } }, }
Functions ¶
func CallPersistentPreRun ¶
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.