diff --git a/filesystem_manipulation.go b/filesystem_manipulation.go new file mode 100644 index 0000000..14ad99f --- /dev/null +++ b/filesystem_manipulation.go @@ -0,0 +1,61 @@ +package peirates + +import ( + "fmt" + "os" +) + +func displayFile(filePath string) error { + // Open the file + file, err := os.Open(filePath) + if err != nil { + return fmt.Errorf("failed opening file: %w", err) + } + defer file.Close() + + // Read the file content + content, err := os.ReadFile(filePath) + if err != nil { + return fmt.Errorf("failed reading file: %w", err) + } + + // Print the content of the file + fmt.Println(string(content)) + return nil +} + +func listDirectory(dirPath string) error { + // Open the directory + dir, err := os.Open(dirPath) + if err != nil { + return fmt.Errorf("failed opening directory: %w", err) + } + defer dir.Close() + + // Read the directory contents + files, err := dir.Readdir(-1) + if err != nil { + return fmt.Errorf("failed reading directory: %w", err) + } + + // Print the names of the files and directories + for _, file := range files { + fmt.Println(file.Name()) + } + return nil +} + +func changeDirectory(dirPath string) error { + if err := os.Chdir(dirPath); err != nil { + return fmt.Errorf("failed to change directory: %w", err) + } + return nil +} + +func getCurrentDirectory() (string, error) { + cwd, err := os.Getwd() + if err != nil { + return "", fmt.Errorf("failed to get current directory: %w", err) + } + return cwd, nil +} diff --git a/menu.go b/menu.go index 34d2b51..bee03c5 100644 --- a/menu.go +++ b/menu.go @@ -33,6 +33,7 @@ Menu | [ curl ] Make an HTTP request (GET or POST) to a user-specified URL [ tcpscan ] Run a simple all-ports TCP port scan against an IP address [ enumerate-dns ] Enumerate services via DNS * +[ cd , pwd , ls , cat ] Manipulate the filesystem via Golang-native commands [ shell ] Run a shell command [ full ] Switch to full (classic menu) with a longer list of commands @@ -91,6 +92,7 @@ Off-Menu + [92] Deactivate "auth can-i" checking before attempting actions [set-auth-can-i] [93] Run a simple all-ports TCP port scan against an IP address [tcpscan] [94] Enumerate services via DNS [enumerate-dns] * +[] Manipulate the filesystem [ cd , pwd , ls , cat ] [] Run a shell command [shell ] [short] Reduce the set of visible commands in this menu @@ -270,6 +272,11 @@ func setUpCompletionMainMenu() *readline.PrefixCompleter { readline.PcItem("tcpscan"), // [94] Enumerate services via DNS [enumerate-dns] * readline.PcItem("enumerate-dns"), + // [ cd __ , pwd , ls ___ , cat ___ ] Manipulate the filesystem via Golang-native commands + readline.PcItem("cd"), + readline.PcItem("pwd"), + readline.PcItem("ls"), + readline.PcItem("cat"), // [] Run a shell command [shell ] readline.PcItem("shell"), // [short] Reduce the set of visible commands in this menu diff --git a/peirates.go b/peirates.go index 56e1be4..3d41b52 100644 --- a/peirates.go +++ b/peirates.go @@ -27,7 +27,7 @@ var UseAuthCanI bool = true // Main starts Peirates[] func Main() { // Peirates version string - var version = "1.1.22" + var version = "1.1.23" var err error @@ -227,6 +227,101 @@ func Main() { continue } + // + // Handle built-in filesystem commands before the switch menu + // + + const pwd = "pwd" + if input == pwd { + // Print the current working directory + cwd, error := getCurrentDirectory() + if error != nil { + println("Error getting current directory: " + error.Error()) + continue + } + println(cwd) + pauseToHitEnter(interactive) + continue + } + + const cdSpace = "cd " + if strings.HasPrefix(input, cdSpace) { + + // Trim off the newline - should we do this for all input anyway? + input = strings.TrimSuffix(input, "\n") + // Trim off the cd, then grab the argument. + // This will fail if there are spaces in the directory name - TODO: improve this. + argumentsLine := strings.TrimPrefix(input, cdSpace) + arguments := strings.Fields(argumentsLine) + directory := arguments[0] + // remove the cd, then try to change to that directory + changeDirectory(directory) + + // Get the new directory and print its name + cwd, error := getCurrentDirectory() + if error != nil { + println("Error getting current directory: " + error.Error()) + continue + } + println(cwd) + + pauseToHitEnter(interactive) + continue + } + + // cat to display files + const catSpace = "cat " + if strings.HasPrefix(input, catSpace) { + // Trim off the newline - should we do this for all input anyway? + input = strings.TrimSuffix(input, "\n") + // remove the cat, then split the rest on whitespace + argumentsLine := strings.TrimPrefix(input, catSpace) + spaceDelimitedSet := strings.Fields(argumentsLine) + for _, file := range spaceDelimitedSet { + err := displayFile(file) + if err != nil { + println("Error displaying file: " + file + " due to " + err.Error()) + } + } + pauseToHitEnter(interactive) + continue + } + + // ls to list directories - treat this differently if it has no arguments + + const lsSpace = "ls " + if strings.HasPrefix(input, lsSpace) { + // Trim off the newline - should we do this for all input anyway? + input = strings.TrimSuffix(input, "\n") + // remove the ls, then split the rest on whitespace + argumentsLine := strings.TrimPrefix(input, lsSpace) + spaceDelimitedSet := strings.Fields(argumentsLine) + for _, dir := range spaceDelimitedSet { + // Check for flags - reject them + if strings.HasPrefix(dir, "-") { + println("ERROR: Flags are not supported in this version of ls.") + continue + } + err := listDirectory(dir) + if err != nil { + println("Error listing directory: " + dir + " due to " + err.Error()) + } + } + pauseToHitEnter(interactive) + continue + } + + // ls with no arguments means list the current directory + const ls = "ls" + if strings.HasPrefix(input, ls) { + error := listDirectory(".") + if error != nil { + println("Error listing directory: " + error.Error()) + } + pauseToHitEnter(interactive) + continue + } + // Handle shell commands before the switch menu const shellSpace = "shell " const shell = "shell"