Skip to content

Commit

Permalink
Merge pull request #1346 from Paradoxis/feature/added-copy-command
Browse files Browse the repository at this point in the history
Added a copy file command
  • Loading branch information
rkervella committed Jul 12, 2023
2 parents a2c3263 + aed28b0 commit 452ce12
Show file tree
Hide file tree
Showing 15 changed files with 3,043 additions and 2,612 deletions.
82 changes: 82 additions & 0 deletions client/command/filesystem/cp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package filesystem

/*
Sliver Implant Framework
Copyright (C) 2019 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 (
"context"

"google.golang.org/protobuf/proto"

"github.com/spf13/cobra"

"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
)

func CpCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) (err error) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
}

if len(args) != 2 {
con.PrintErrorf("Please specify a source and destination filename.\n")
return
}

src := args[0]
dst := args[1]

cp, err := con.Rpc.Cp(context.Background(), &sliverpb.CpReq{
Request: con.ActiveTarget.Request(cmd),
Src: src,
Dst: dst,
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}

cp.Src, cp.Dst = src, dst

if cp.Response != nil && cp.Response.Async {
con.AddBeaconCallback(cp.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, cp)
if err != nil {
con.PrintErrorf("Failed to decode response %s\n", err)
return
}
})
con.PrintAsyncResponse(cp.Response)
} else {
PrintCp(cp, con)
}

return
}

func PrintCp(cp *sliverpb.Cp, con *console.SliverConsoleClient) {
if cp.Response != nil && cp.Response.Err != "" {
con.PrintErrorf("%s\n", cp.Response.Err)
return
}

con.PrintInfof("Copied '%s' to '%s' (%d bytes written)\n", cp.Src, cp.Dst, cp.BytesWritten)
}
19 changes: 19 additions & 0 deletions client/command/sliver.go
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,25 @@ func SliverCommands(con *client.SliverConsoleClient) console.Commands {
carapace.ActionValues().Usage("path to dest file (required)"),
)

cpCmd := &cobra.Command{
Use: consts.CpStr,
Short: "Copy a file",
Long: help.GetHelpFor([]string{consts.CpStr}),
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
filesystem.CpCmd(cmd, con, args)
},
GroupID: consts.FilesystemHelpGroup,
}
sliver.AddCommand(cpCmd)
Flags("", false, cpCmd, func(f *pflag.FlagSet) {
f.Int64P("timeout", "t", defaultTimeout, "grpc timeout in seconds")
})
carapace.Gen(cpCmd).PositionalCompletion(
carapace.ActionValues().Usage("path to source file (required)"),
carapace.ActionValues().Usage("path to dest file (required)"),
)

lsCmd := &cobra.Command{
Use: consts.LsStr,
Short: "List current directory",
Expand Down
1 change: 1 addition & 0 deletions client/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ const (

LsStr = "ls"
MvStr = "mv"
CpStr = "cp"
RmStr = "rm"
MkdirStr = "mkdir"
CdStr = "cd"
Expand Down
68 changes: 68 additions & 0 deletions implant/sliver/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,74 @@ func mvHandler(data []byte, resp RPCResponse) {
resp(data, err)
}

func cpHandler(data []byte, resp RPCResponse) {
cpReq := &sliverpb.CpReq{}
err := proto.Unmarshal(data, cpReq)
if err != nil {
// {{if .Config.Debug}}
log.Printf("error decoding message: %v", err)
// {{end}}
return
}

copy := &sliverpb.Cp{
Src: cpReq.Src,
Dst: cpReq.Dst,
}

srcFile, err := os.Open(cpReq.Src)
if err != nil {
// {{if .Config.Debug}}
log.Printf("failed to open source file: %v", err)
// {{end}}

copy.Response = &commonpb.Response{Err: err.Error()}
data, err = proto.Marshal(copy)
resp(data, err)
return
}

dstFile, err := os.Create(cpReq.Dst)
if err != nil {
// {{if .Config.Debug}}
log.Printf("failed to open destination file: %v", err)
// {{end}}

copy.Response = &commonpb.Response{Err: err.Error()}
data, err = proto.Marshal(copy)
resp(data, err)
return
}

bytesWritten, err := io.Copy(dstFile, srcFile)
if err != nil {
// {{if .Config.Debug}}
log.Printf("failed to copy bytes to destination file: %v", err)
// {{end}}

copy.Response = &commonpb.Response{Err: err.Error()}
data, err = proto.Marshal(copy)
resp(data, err)
return
}

err = dstFile.Sync()
if err != nil {
// {{if .Config.Debug}}
log.Printf("failed to sync destination file: %v", err)
// {{end}}

copy.Response = &commonpb.Response{Err: err.Error()}
data, err = proto.Marshal(copy)
resp(data, err)
return
}

copy.BytesWritten = bytesWritten
data, err = proto.Marshal(copy)
resp(data, err)
}

func mkdirHandler(data []byte, resp RPCResponse) {
mkdirReq := &sliverpb.MkdirReq{}
err := proto.Unmarshal(data, mkdirReq)
Expand Down
1 change: 1 addition & 0 deletions implant/sliver/handlers/handlers_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var (
pb.MsgRmReq: rmHandler,
pb.MsgMkdirReq: mkdirHandler,
pb.MsgMvReq: mvHandler,
pb.MsgCpReq: cpHandler,
pb.MsgIfconfigReq: ifconfigHandler,
pb.MsgExecuteReq: executeHandler,
pb.MsgEnvReq: getEnvHandler,
Expand Down
1 change: 1 addition & 0 deletions implant/sliver/handlers/handlers_generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var (
sliverpb.MsgRmReq: rmHandler,
sliverpb.MsgMkdirReq: mkdirHandler,
sliverpb.MsgMvReq: mvHandler,
sliverpb.MsgCpReq: cpHandler,
sliverpb.MsgExecuteReq: executeHandler,
sliverpb.MsgSetEnvReq: setEnvHandler,
sliverpb.MsgEnvReq: getEnvHandler,
Expand Down
1 change: 1 addition & 0 deletions implant/sliver/handlers/handlers_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ var (
sliverpb.MsgRmReq: rmHandler,
sliverpb.MsgMkdirReq: mkdirHandler,
sliverpb.MsgMvReq: mvHandler,
sliverpb.MsgCpReq: cpHandler,
sliverpb.MsgTaskReq: taskHandler,
sliverpb.MsgIfconfigReq: ifconfigHandler,
sliverpb.MsgExecuteReq: executeHandler,
Expand Down
1 change: 1 addition & 0 deletions implant/sliver/handlers/handlers_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ var (
sliverpb.MsgPwdReq: pwdHandler,
sliverpb.MsgRmReq: rmHandler,
sliverpb.MsgMvReq: mvHandler,
sliverpb.MsgCpReq: cpHandler,
sliverpb.MsgMkdirReq: mkdirHandler,
sliverpb.MsgExecuteReq: executeHandler,
sliverpb.MsgReconfigureReq: reconfigureHandler,
Expand Down
Loading

0 comments on commit 452ce12

Please sign in to comment.