Interacting with Metasploit
msf.go
package rpc import ( "bytes" "fmt" "gopkg.in/vmihailenco/msgpack.v2" "net/http" ) // Build the Go types to handle both the request and response data. type sessionListReq struct { _msgpack struct{} `msgpack:",asArray"` Method string Token string } type SessionListRes struct { ID uint32 `msgpack:",omitempty"` Type string `msgpack:"type"` TunnelLocal string `msgpack:"tunnel_local"` TunnelPeer string `msgpack:"tunnel_peer"` ViaExploit string `msgpack:"via_exploit"` ViaPayload string `msgpack:"via_payload"` Description string `msgpack:"desc"` Info string `msgpack:"info"` Workspace string `msgpack:"workspace"` SessionHost string `msgpack:"session_host"` SessionPort int `msgpack:"session_port"` Username string `msgpack:"username"` UUID string `msgpack:"uuid"` ExploitUUID string `msgpack:"exploit_uuid"` } // Defining Request and Response Methods type loginReq struct { _msgpack struct{} `msgpack:",asArray"` Method string Username string Password string } type loginRes struct { Result string `msgpack:"result"` Token string `msgpack:"token"` Error bool `msgpack:"error"` ErrorClass string `msgpack:"error_class"` ErrorMessage string `msgpack:"error_message"` } type logoutReq struct { _msgpack struct{} `msgpack:",asArray"` Method string Token string LogoutToken string } type logoutRes struct { Result string `msgpack:"result"` } // Creating a configuration Struct and an RPC Method type Metasploit struct { host string user string pass string token string } // Performing Remote send using serialization, deserializatiion, and HTTP communication logic. func (msf *Metasploit) send(req interface{}, res interface{}) error { buf := new(bytes.Buffer) msgpack.NewEncoder(buf).Encode(req) dest := fmt.Sprintf("http://%s/api", msf.host) r, err := http.Post(dest, "binary/message-pack", buf) if err != nil { return err } defer r.Body.Close() if err := msgpack.NewDecoder(r.Body).Decode(&res); err != nil { return err } return nil } // Metasploit API calls implementation func (msf *Metasploit) Login() error { ctx := &loginReq{ Method: "auth.login", Username: msf.user, Password: msf.pass, } var res loginRes if err := msf.send(ctx, &res); err != nil { return err } msf.token = res.Token return nil } func (msf *Metasploit) Logout() error { ctx := &logoutReq{ Method: "auth.logout", Token: msf.token, LogoutToken: msf.token, } var res logoutRes if err := msf.send(ctx, &res); err != nil { return err } msf.token = "" return nil } func (msf *Metasploit) SessionList() (map[uint32]SessionListRes, error) { req := &sessionListReq{ Method: "session.list", Token: msf.token, } res := make(map[uint32]SessionListRes) if err := msf.send(req, &res); err != nil { return nil, err } for id, session := range res { session.ID = id res[id] = session } return res, nil } // Initializing the client with embedding Metasploit login func New(host, user, pass string) (*Metasploit, error) { msf := &Metasploit{ host: host, user: user, pass: pass, } if err := msf.Login(); err != nil { return nil, err } return msf, nil }
Client - main.go
package main import ( "fmt" "log" "metasploit-minimal/rpc" "os" ) func main() { host := os.Getenv("MSFHOST") pass := os.Getenv("MSFPASS") user := "msf" if host == "" || pass == "" { log.Fatalln("Missing required environment variable MSFHOST or MSFPASS") } msf, err := rpc.New(host, user, pass) if err != nil { log.Panicln(err) } defer msf.Logout() sessions, err := msf.SessionList() if err != nil { log.Panicln(err) } fmt.Println("Sessions:") for _, session := range sessions { fmt.Printf("%5d %s\n", session.ID, session.Info) } }
exploit the target windows before running this client code.
Run this metasploit-minimal client program successfully.