Skip to content

Commit

Permalink
Add upgrade_cc command (#362)
Browse files Browse the repository at this point in the history
* download release tarball from GitHub

need an installer

* feat: add command to upgrade emp3r0r C2 from GitHub

* add checksum for release tarballs
  • Loading branch information
jm33-m0 authored Jan 3, 2025
1 parent 53cec33 commit b39aa8b
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 3 deletions.
10 changes: 10 additions & 0 deletions core/emp3r0r
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,16 @@ uninstall() {
install() {
[[ "$EUID" -eq 0 ]] || error "You must be root to install emp3r0r"
info "emp3r0r will be installed to $prefix"

# check if tmux is installed
if ! command -v tmux >/dev/null 2>&1; then
error "tmux not found"
fi

# check if emp3r0r is running
if tmux has-session -t emp3r0r 2>/dev/null; then
tmux kill-session -t emp3r0r || error "Failed to kill emp3r0r"
fi
mkdir -p "$build_dir" || error "Failed to mkdir $build_dir"
cp -avR tmux "$data_dir" || error "tmux"
cp -avR modules "$data_dir" || error "modules"
Expand Down
2 changes: 1 addition & 1 deletion core/lib/agent/ftp.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func DownloadViaCC(file_to_download, path string) (data []byte, err error) {
log.Printf("DownloadViaCC: saved %s to %s (%d bytes)", url, path, resp.Size())
return
case <-t.C:
log.Printf("%.02f%% complete\n", resp.Progress()*100)
log.Printf("%.02f%% complete", resp.Progress()*100)
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/lib/cc/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ start:
default:
readlineErr = CmdHandler(line)
if readlineErr != nil {
color.Red(readlineErr.Error())
CliPrintError(readlineErr.Error())
}
}
fmt.Printf("\n")
Expand Down
8 changes: 8 additions & 0 deletions core/lib/cc/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var CommandHelp = map[string]string{
"run": "Run selected module, make sure you have set required options",
"info": "What options do we have?",
"upgrade_agent": "Upgrade agent on selected target",
"upgrade_cc": "Upgrade emp3r0r from GitHub",
"ls": "List current directory of selected agent",
"mv": "Move a file to another location on selected target",
"cp": "Copy a file to another location on selected target",
Expand Down Expand Up @@ -98,6 +99,13 @@ func CmdHandler(cmd string) (err error) {
switch {
case cmd == "":
return

case cmd == "upgrade_cc":
err = UpdateCC()
if err != nil {
return
}

case cmdSplit[0] == HELP:
if len(cmdSplit) > 2 {
CliPrintError("WTF?")
Expand Down
2 changes: 1 addition & 1 deletion core/lib/cc/tmux.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ func TmuxSetPaneTitle(title, pane_id string) error {
return err
}

// TmuxNewWindow split tmux window, and run command in the new pane
// TmuxNewWindow run command in a new window
func TmuxNewWindow(name, cmd string) error {
if os.Getenv("TMUX") == "" ||
!util.IsCommandExist("tmux") {
Expand Down
117 changes: 117 additions & 0 deletions core/lib/cc/update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package cc

import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"os/exec"
"time"

"github.com/cavaliergopher/grab/v3"
"github.com/jm33-m0/emp3r0r/core/lib/util"
)

const (
LatestRelease = "https://api.github.com/repos/jm33-m0/emp3r0r/releases/latest"
)

func GetTarballURL() (string, error) {
// get latest release
resp, err := http.Get(LatestRelease)
if err != nil {
return "", err
}

// parse JSON
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
}

var release struct {
Assets []struct {
BrowserDownloadURL string `json:"browser_download_url"`
} `json:"assets"`
}
if err := json.Unmarshal(body, &release); err != nil {
return "", err
}

if len(release.Assets) == 0 {
return "", fmt.Errorf("no assets found in the latest release")
}

return release.Assets[0].BrowserDownloadURL, nil
}

func UpdateCC() (err error) {
CliPrintInfo("Requesting latest emp3r0r release from GitHub...")
// get latest release
tarballURL, err := GetTarballURL()
if err != nil {
return err
}

// download path
path := "/tmp/emp3r0r.tar.zst"
lock := fmt.Sprintf("%s.downloading", path)

// check if lock exists
if util.IsFileExist(lock) {
err = fmt.Errorf("lock file %s exists, another download is in progress, if it's not the case, manually remove the lock", lock)
return
}

// create lock file
os.Create(lock)
defer os.Remove(lock)

// download tarball using grab
client := grab.NewClient()
if client.HTTPClient == nil {
err = fmt.Errorf("failed to initialize HTTP client")
return
}
req, err := grab.NewRequest(path, tarballURL)
if err != nil {
err = fmt.Errorf("create grab request: %v", err)
return
}
CliPrint("Downloading %s to %s...", tarballURL, path)
resp := client.Do(req)

// progress
t := time.NewTicker(5 * time.Second)
defer func() {
t.Stop()
if !util.IsExist(path) {
err = fmt.Errorf("target file '%s' does not exist, download may have failed", path)
}
}()
for !resp.IsComplete() {
select {
case <-resp.Done:
err = resp.Err()
if err != nil {
err = fmt.Errorf("download finished with error: %v", err)
return
}
CliPrintSuccess("Saved %s to %s (%d bytes)", tarballURL, path, resp.Size())
case <-t.C:
CliPrintInfo("%.02f%% complete at %.02f KB/s", resp.Progress()*100, resp.BytesPerSecond()/1024)
}
}
CliPrintInfo("Download complete, installing emp3r0r...")

install_cmd := fmt.Sprintf("bash -c 'tar -I zstd -xvf %s -C /tmp && cd /tmp/emp3r0r-build && sudo ./emp3r0r --install; sleep 5'", path)
CliPrint("Running installer command: %s", install_cmd)
err = exec.Command("x-terminal-emulator", "-e", install_cmd).Run()
if err != nil {
return fmt.Errorf("failed to update emp3r0r: %v", err)
}

return nil
}
6 changes: 6 additions & 0 deletions core/upload.sh
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,9 @@ echo "Uploading asset... "
GH_ASSET="https://uploads.github.com/repos/$owner/$repo/releases/$id/assets?name=$(basename $filename)"

curl "$GITHUB_OAUTH_BASIC" --data-binary @"$filename" -H "Authorization: token $github_api_token" -H "Content-Type: application/octet-stream" $GH_ASSET

# Upload checksum of asset
checksum=$(sha256sum $filename | cut -d ' ' -f 1)
echo "Uploading checksum... "
GH_ASSET="https://uploads.github.com/repos/$owner/$repo/releases/$id/assets?name=$(basename $filename).sha256"
curl "$GITHUB_OAUTH_BASIC" --data-binary @"$filename.sha256" -H "Authorization: token $github_api_token" -H "Content-Type: application/octet-stream" $GH_ASSET

0 comments on commit b39aa8b

Please sign in to comment.