Skip to content

Commit

Permalink
Refactored file system cmds
Browse files Browse the repository at this point in the history
  • Loading branch information
moloch-- committed Jul 3, 2021
1 parent 48dc187 commit de8acdc
Show file tree
Hide file tree
Showing 12 changed files with 986 additions and 782 deletions.
851 changes: 426 additions & 425 deletions client/command/commands.go

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions client/command/filesystem/README.md
@@ -1,5 +1,4 @@
Filesystem
==========

This package implements file system commands such as `ls`, `cd`, `rm`, `download`, `upload`, etc.

This package implements file system commands such as `ls`, `cd`, `rm`, `download`, `upload`, etc.
109 changes: 109 additions & 0 deletions client/command/filesystem/cat.go
@@ -0,0 +1,109 @@
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"
"fmt"
"os"

"github.com/alecthomas/chroma/formatters"
"github.com/alecthomas/chroma/lexers"
"github.com/alecthomas/chroma/styles"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/util/encoders"

"github.com/desertbit/grumble"
)

func CatCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.ActiveSession.GetInteractive()
if session == nil {
return
}

filePath := ctx.Args.String("path")
if filePath == "" {
con.PrintErrorf("Missing parameter: file name\n")
return
}

download, err := con.Rpc.Download(context.Background(), &sliverpb.DownloadReq{
Request: con.ActiveSession.Request(ctx),
Path: filePath,
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if download.Encoder == "gzip" {
download.Data, err = new(encoders.Gzip).Decode(download.Data)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
}
if ctx.Flags.Bool("colorize-output") {
if err = colorize(download); err != nil {
con.Println(string(download.Data))
}
} else {
con.Println(string(download.Data))
}
// if ctx.Flags.Bool("loot") && 0 < len(download.Data) {
// err = AddLootFile(rpc, fmt.Sprintf("[cat] %s", filepath.Base(filePath)), filePath, download.Data, false)
// if err != nil {
// con.PrintErrorf("Failed to save output as loot: %s", err)
// } else {
// fmt.Printf(clearln + Info + "Output saved as loot\n")
// }
// }
}

func colorize(f *sliverpb.Download) error {
lexer := lexers.Match(f.GetPath())
if lexer == nil {
lexer = lexers.Analyse(string(f.GetData()))
if lexer == nil {
lexer = lexers.Fallback
}
}
style := styles.Get("monokai")
if style == nil {
style = styles.Fallback
}
formatter := formatters.Get("terminal16m")
if formatter == nil {
formatter = formatters.Fallback
}
if lexer != nil {
iterator, err := lexer.Tokenise(nil, string(f.GetData()))
if err != nil {
return err
}
err = formatter.Format(os.Stdout, style, iterator)
if err != nil {
return err
}
} else {
return fmt.Errorf("no lexer found")
}
return nil
}
46 changes: 46 additions & 0 deletions client/command/filesystem/cd.go
@@ -0,0 +1,46 @@
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"

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

"github.com/desertbit/grumble"
)

func CdCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.ActiveSession.GetInteractive()
if session == nil {
return
}
filePath := ctx.Args.String("path")

pwd, err := con.Rpc.Cd(context.Background(), &sliverpb.CdReq{
Request: con.ActiveSession.Request(ctx),
Path: filePath,
})
if err != nil {
con.PrintErrorf("%s\n", err)
} else {
con.PrintInfof("%s\n", pwd.Path)
}
}
107 changes: 107 additions & 0 deletions client/command/filesystem/download.go
@@ -0,0 +1,107 @@
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"
"fmt"
"os"
"path"
"path/filepath"

"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/util/encoders"
"gopkg.in/AlecAivazis/survey.v1"

"github.com/desertbit/grumble"
)

func DownloadCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.ActiveSession.GetInteractive()
if session == nil {
return
}

remotePath := ctx.Args.String("remote-path")
localPath := ctx.Args.String("local-path")

src := remotePath
fileName := filepath.Base(src)
dst, _ := filepath.Abs(localPath)
fi, err := os.Stat(dst)
if err != nil && !os.IsNotExist(err) {
con.PrintErrorf("%s\n", err)
return
}
if err == nil && fi.IsDir() {
dst = path.Join(dst, fileName)
}

if _, err := os.Stat(dst); err == nil {
overwrite := false
prompt := &survey.Confirm{Message: "Overwrite local file?"}
survey.AskOne(prompt, &overwrite, nil)
if !overwrite {
return
}
}

ctrl := make(chan bool)
con.SpinUntil(fmt.Sprintf("%s -> %s", fileName, dst), ctrl)
download, err := con.Rpc.Download(context.Background(), &sliverpb.DownloadReq{
Request: con.ActiveSession.Request(ctx),
Path: remotePath,
})
ctrl <- true
<-ctrl
if err != nil {
con.PrintErrorf("%s\n", err)
return
}

if download.Encoder == "gzip" {
download.Data, err = new(encoders.Gzip).Decode(download.Data)
if err != nil {
con.PrintErrorf("Decoding failed %s", err)
return
}
}
dstFile, err := os.Create(dst)
if err != nil {
con.PrintErrorf("Failed to open local file %s: %s\n", dst, err)
return
}
defer dstFile.Close()
n, err := dstFile.Write(download.Data)
if err != nil {
con.PrintErrorf("Failed to write data %v\n", err)
} else {
con.PrintInfof("Wrote %d bytes to %s\n", n, dstFile.Name())
}

// if ctx.Flags.Bool("loot") && 0 < len(download.Data) {
// err = AddLootFile(rpc, fmt.Sprintf("[download] %s", filepath.Base(remotePath)), remotePath, download.Data, false)
// if err != nil {
// con.PrintErrorf("Failed to save output as loot: %s", err)
// } else {
// fmt.Printf(Info + "Output saved as loot\n")
// }
// }
}

0 comments on commit de8acdc

Please sign in to comment.