package main import ( "context" "fmt" "io" "log" "math/rand" "net/http" "os" "os/exec" "regexp" "strings" "time" "github.com/radareorg/r2pipe-go" ) func main() { http.HandleFunc("/", handler) port := os.Getenv("BACKEND_PORT") if port == "" { port = "8080" } log.Println("Starting server on port", port) http.ListenAndServe(":"+port, nil) } func handler(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { command1 := r.FormValue("command1") argument1 := r.FormValue("argument1") command2 := r.FormValue("command2") argument2 := r.FormValue("argument2") if !isValidCommand(command1) || !isValidCommand(command2) { http.Error(w, "Invalid command", http.StatusBadRequest) return } if !isValidArgument(argument1) || !isValidArgument(argument2) { http.Error(w, "Invalid argument", http.StatusBadRequest) return } r2Commands := []string{ "oo+", "e cfg.sandbox=all", // idea from pancake "aaaa", fmt.Sprintf("%s %s", command1, argument1), fmt.Sprintf("%s %s", command2, argument2), } randomName := fmt.Sprintf("/tmp/adams_%d", rand.Intn(10000)) err := copyFile("adams", randomName) if err != nil { http.Error(w, "Error copying adams binary", http.StatusInternalServerError) return } defer os.Remove(randomName) r2Output, err := executeR2Commands(randomName, r2Commands) if err != nil { if strings.Contains(err.Error(), "timeout") { http.Error(w, "Radare2 commands execution timed out", http.StatusRequestTimeout) return } http.Error(w, fmt.Sprintf("Error executing radare2 commands: %s", err), http.StatusInternalServerError) return } r2Output = strings.TrimSpace(r2Output) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() cmd := exec.Command(randomName) cmd.Stderr = os.Stderr output, err := cmd.Output() if err != nil { if ctx.Err() == context.DeadlineExceeded { cmd.Process.Kill() http.Error(w, "Command execution timed out", http.StatusRequestTimeout) return } http.Error(w, fmt.Sprintf("Error executing final binary: %s", err), http.StatusInternalServerError) return } response := "Radare2 Output:\n" + r2Output + "\n\nFinal Binary Output:\n" + string(output) w.Header().Set("Content-Type", "text/plain") w.Write([]byte(response)) } else { html := ` Radare2 Command Runner

Radare2 Command Runner

Running GIF Radare2
Anything can be a web challenge after all
` fmt.Fprint(w, html) } } func isValidCommand(command string) bool { if len(command) > 4 { return false } var blackList = []string{"cat", "ls", "lu", "ll", "lr", "le", "pwd", "cd"} for _, black := range blackList { if strings.ToLower(command) == black { return false } } match, _ := regexp.MatchString("^[a-zA-Z0-9]+$", command) return match } func isValidArgument(argument string) bool { if len(argument) > 16 { return false } match, _ := regexp.MatchString("^[a-zA-Z0-9 ]*$", argument) return match } func copyFile(src, dst string) error { sourceFile, err := os.Open(src) if err != nil { return err } defer sourceFile.Close() destFile, err := os.Create(dst) if err != nil { return err } defer destFile.Close() _, err = io.Copy(destFile, sourceFile) if err != nil { return err } err = destFile.Sync() if err != nil { return err } sourceInfo, err := os.Stat(src) if err != nil { return err } return os.Chmod(dst, sourceInfo.Mode()) } func executeR2Commands(binaryPath string, commands []string) (string, error) { log.Default().Println("Executing radare2 commands:", commands, "on", binaryPath) _, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() r2p, err := r2pipe.NewPipe(binaryPath) if err != nil { return "", err } defer r2p.Close() var output string for _, cmd := range commands { out, err := r2p.Cmd(cmd) if err != nil { return "", err } output += out + "\n" } return output, nil }