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
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,8 @@ jobs:
- name: Vet
run: go vet ./...

- name: Verify module
run: go mod verify

- name: Test
run: go test ./...
20 changes: 16 additions & 4 deletions examples/main.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,35 @@
package main

// running some tests on the lib
import (
"context"
"fmt"
"log"
"os"

"github.com/arisinghackers/goxploit/pkg/metasploit"
"github.com/arisinghackers/goxploit/pkg/msfrpc"
)

func env(key, fallback string) string {
if v := os.Getenv(key); v != "" {
return v
}
return fallback
}

func main() {
host := env("MSF_HOST", "127.0.0.1")
port := 3000
ssl := env("MSF_SSL", "false")
webURI := env("MSF_WEB_URI", "/api")
user := env("MSF_USER", "msf")
pass := env("MSF_PASS", "msf")

client := msfrpc.NewMsfRpcClient("killodds", "false", "veemweaver", "127.0.0.1", 3000, "/api")
client := msfrpc.NewMsfRpcClient(pass, ssl, user, host, port, webURI)
typedClient := metasploit.NewClient(client)
ctx := context.Background()

login, err := typedClient.Auth.LoginContext(ctx, "veemweaver", "killodds")
login, err := typedClient.Auth.LoginContext(ctx, user, pass)
if err != nil {
log.Fatalf("Error authenticating: %v", err)
}
Expand All @@ -27,5 +40,4 @@ func main() {
log.Fatal(err)
}
fmt.Printf("Metasploit Core Version: %s (ruby=%s api=%s)\n", version.Version, version.Ruby, version.API)

}
17 changes: 14 additions & 3 deletions internal/generator/library.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ func (g *LibraryGenerator) GenerateLibrary() error {
builder := &strings.Builder{}

builder.WriteString("// Code generated by goxploit msfrpc LibraryGenerator. DO NOT EDIT.\n\n")
builder.WriteString("package metasploit\n\n")
builder.WriteString("package generated\n\n")
builder.WriteString("import (")
builder.WriteString("\n\t\"context\"")
builder.WriteString("\n\t\"errors\"")
builder.WriteString("\n\t\"fmt\"")
builder.WriteString("\n\t\"github.com/arisinghackers/goxploit/pkg/msfrpc\"")
Expand Down Expand Up @@ -81,6 +82,7 @@ func (g *LibraryGenerator) GenerateLibrary() error {
funcName := toCamelCase(rawMethod)

params := []string{}
paramNames := []string{}
args := []string{fmt.Sprintf(`"%s"`, method[0])}
requiresAuth := false

Expand All @@ -93,6 +95,7 @@ func (g *LibraryGenerator) GenerateLibrary() error {
}
args = append(args, param)
params = append(params, fmt.Sprintf("%s string", param))
paramNames = append(paramNames, param)
continue
}

Expand All @@ -102,13 +105,21 @@ func (g *LibraryGenerator) GenerateLibrary() error {
args = append(args, val)
}
params = append(params, fmt.Sprintf("%s string", val))
paramNames = append(paramNames, val)
}

// Non-context wrapper delegates to context version.
builder.WriteString(fmt.Sprintf("func (c *%s) %s(%s) (map[string]interface{}, error) {\n", className, funcName, strings.Join(params, ", ")))
builder.WriteString(fmt.Sprintf("\treturn c.%sContext(context.Background(), %s)\n", funcName, strings.Join(paramNames, ", ")))
builder.WriteString("}\n\n")

// Context version with the actual implementation.
contextParams := append([]string{"ctx context.Context"}, params...)
builder.WriteString(fmt.Sprintf("func (c *%s) %sContext(ctx context.Context, %s) (map[string]interface{}, error) {\n", className, funcName, strings.Join(contextParams, ", ")))
if requiresAuth {
builder.WriteString(fmt.Sprintf("\tresp, err := c.AuthenticatedRequest(%s)\n", buildArgsString(args)))
builder.WriteString(fmt.Sprintf("\tresp, err := c.AuthenticatedRequestContext(ctx, %s)\n", buildArgsString(args)))
} else {
builder.WriteString(fmt.Sprintf("\tresp, err := c.MsfRequest(%s)\n", buildArgsString(args)))
builder.WriteString(fmt.Sprintf("\tresp, err := c.MsfRequestContext(ctx, %s)\n", buildArgsString(args)))
}
builder.WriteString("\tif err != nil {\n\t\treturn nil, err\n\t}\n")
builder.WriteString("\tif result, ok := resp[\"result\"]; ok && result == \"failure\" {\n")
Expand Down
22 changes: 17 additions & 5 deletions pkg/metasploit/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,27 @@ func readInt(resp map[string]interface{}, key string, required bool) (int64, err
}
}

var errRPCFailed = fmt.Errorf("rpc call returned failure")

func checkRPCFailure(resp map[string]interface{}) error {
if result, ok := resp["result"]; ok && fmt.Sprintf("%v", result) == "failure" {
if msg, exists := resp["error_message"]; exists {
return fmt.Errorf("%v", msg)
v, ok := resp["result"]
if !ok {
return nil
}
switch s := v.(type) {
case string:
if s != "failure" {
return nil
}
return fmt.Errorf("rpc call returned failure")
case []byte:
if string(s) != "failure" {
return nil
}
default:
return nil
}
if msg, ok := resp["error_message"]; ok {
return fmt.Errorf("%v", msg)
}
return nil
return errRPCFailed
}
7 changes: 4 additions & 3 deletions pkg/msfrpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
type MsfRpcClient struct {
UserPassword string
Token *string
SSL string
UseSSL bool
UserName string
IP string
Port int
Expand All @@ -25,15 +25,16 @@ type MsfRpcClient struct {
}

func NewMsfRpcClient(userPassword, ssl, userName, ip string, port int, webServerURI string) *MsfRpcClient {
useSSL := ssl == "true"
protocol := "http://"
if ssl == "true" {
if useSSL {
protocol = "https://"
}
baseURL := fmt.Sprintf("%s%s:%d%s", protocol, ip, port, webServerURI)

return &MsfRpcClient{
UserPassword: userPassword,
SSL: protocol,
UseSSL: useSSL,
UserName: userName,
IP: ip,
Port: port,
Expand Down
39 changes: 32 additions & 7 deletions pkg/msfrpc/generated/auth.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 42 additions & 9 deletions pkg/msfrpc/generated/console.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading