mirror of
https://github.com/Adaptix-Framework/AdaptixC2
synced 2026-06-08 10:20:39 +00:00
TsTerminal API upgrade
This commit is contained in:
@@ -64,7 +64,7 @@ func (ex *AdaptixExtender) ExAgentTunnelCallbacks(agentData adaptix.AgentData, t
|
||||
return module.AgentTunnelCallbacks()
|
||||
}
|
||||
|
||||
func (ex *AdaptixExtender) ExAgentTerminalCallbacks(agentData adaptix.AgentData) (func(int, string, int, int) (adaptix.TaskData, error), func(int, []byte) (adaptix.TaskData, error), func(int) (adaptix.TaskData, error), error) {
|
||||
func (ex *AdaptixExtender) ExAgentTerminalCallbacks(agentData adaptix.AgentData) (func(int, string, int, int, int) (adaptix.TaskData, error), func(int, int, []byte) (adaptix.TaskData, error), func(int) (adaptix.TaskData, error), error) {
|
||||
|
||||
module, ok := ex.agentModules[agentData.Name]
|
||||
if !ok {
|
||||
|
||||
@@ -64,7 +64,7 @@ type ExtAgent interface {
|
||||
AgentPivotPackData(pivotId string, data []byte) (adaptix.TaskData, error)
|
||||
|
||||
AgentTunnelCallbacks() (func(int, int, int, string, int) adaptix.TaskData, func(int, int, int, string, int) adaptix.TaskData, func(int, []byte) adaptix.TaskData, func(int, []byte) adaptix.TaskData, func(int) adaptix.TaskData, func(int, int) adaptix.TaskData, error)
|
||||
AgentTerminalCallbacks() (func(int, string, int, int) (adaptix.TaskData, error), func(int, []byte) (adaptix.TaskData, error), func(int) (adaptix.TaskData, error), error)
|
||||
AgentTerminalCallbacks() (func(int, string, int, int, int) (adaptix.TaskData, error), func(int, int, []byte) (adaptix.TaskData, error), func(int) (adaptix.TaskData, error), error)
|
||||
}
|
||||
|
||||
type AdaptixExtender struct {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -80,7 +81,7 @@ func (ts *Teamserver) TsAgentTerminalCreateChannel(terminalData string, wsconn *
|
||||
return err
|
||||
}
|
||||
|
||||
taskData, err := terminal.handlerStart(terminal.TerminalId, program, sizeH, sizeW)
|
||||
taskData, err := terminal.handlerStart(terminal.TerminalId, program, sizeH, sizeW, OemCP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -115,7 +116,7 @@ func (ts *Teamserver) TsTerminalGetPipe(AgentId string, terminalId string) (*io.
|
||||
return terminal.prSrv, terminal.pwTun, nil
|
||||
}
|
||||
|
||||
func (ts *Teamserver) TsTerminalConnResume(agentId string, terminalId string) {
|
||||
func (ts *Teamserver) TsTerminalConnResume(agentId string, terminalId string, ioDirect bool) {
|
||||
agent, err := ts.getAgent(agentId)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -130,7 +131,26 @@ func (ts *Teamserver) TsTerminalConnResume(agentId string, terminalId string) {
|
||||
return
|
||||
}
|
||||
|
||||
relayWebsocketToTerminal(ts, agent, terminal, terminalId)
|
||||
relayWebsocketToTerminal(ts, agent, terminal, terminalId, ioDirect)
|
||||
}
|
||||
|
||||
func (ts *Teamserver) TsTerminalConnData(terminalId string, data []byte) {
|
||||
value, ok := ts.terminals.Get(terminalId)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
terminal, ok := value.(*Terminal)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
terminal.mu.Lock()
|
||||
defer terminal.mu.Unlock()
|
||||
|
||||
if terminal.closed || terminal.pwTun == nil {
|
||||
return
|
||||
}
|
||||
_, _ = terminal.pwTun.Write(data)
|
||||
}
|
||||
|
||||
func (ts *Teamserver) TsTerminalConnClose(terminalId string, status string) error {
|
||||
@@ -151,31 +171,41 @@ func closeTerminalResources(terminal *Terminal) {
|
||||
if terminal == nil {
|
||||
return
|
||||
}
|
||||
|
||||
terminal.mu.Lock()
|
||||
if terminal.closed {
|
||||
terminal.mu.Unlock()
|
||||
return
|
||||
}
|
||||
terminal.closed = true
|
||||
terminal.mu.Unlock()
|
||||
|
||||
if terminal.wsconn != nil {
|
||||
_ = terminal.wsconn.Close()
|
||||
}
|
||||
if terminal.prSrv != nil {
|
||||
_ = terminal.prSrv.Close()
|
||||
}
|
||||
if terminal.pwSrv != nil {
|
||||
_ = terminal.pwSrv.Close()
|
||||
if terminal.pwTun != nil {
|
||||
_ = terminal.pwTun.Close()
|
||||
}
|
||||
if terminal.prTun != nil {
|
||||
_ = terminal.prTun.Close()
|
||||
}
|
||||
if terminal.pwTun != nil {
|
||||
_ = terminal.pwTun.Close()
|
||||
if terminal.pwSrv != nil {
|
||||
_ = terminal.pwSrv.Close()
|
||||
}
|
||||
if terminal.prSrv != nil {
|
||||
_ = terminal.prSrv.Close()
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
func relayWebsocketToTerminal(ts *Teamserver, agent *Agent, terminal *Terminal, terminalId string) {
|
||||
var closeOnce sync.Once
|
||||
func relayWebsocketToTerminal(ts *Teamserver, agent *Agent, terminal *Terminal, terminalId string, direct bool) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
var once sync.Once
|
||||
var wsWriteMu sync.Mutex
|
||||
|
||||
closeAll := func() {
|
||||
closeOnce.Do(func() {
|
||||
finish := func() {
|
||||
once.Do(func() {
|
||||
cancel()
|
||||
ts.terminals.Delete(terminalId)
|
||||
closeTerminalResources(terminal)
|
||||
|
||||
@@ -187,42 +217,67 @@ func relayWebsocketToTerminal(ts *Teamserver, agent *Agent, terminal *Terminal,
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer closeAll()
|
||||
defer finish()
|
||||
if terminal.wsconn == nil || terminal.pwSrv == nil {
|
||||
return
|
||||
}
|
||||
for {
|
||||
_, msg, err := terminal.wsconn.ReadMessage()
|
||||
if err != nil {
|
||||
return
|
||||
break
|
||||
}
|
||||
if terminal.pwSrv == nil {
|
||||
return
|
||||
}
|
||||
if _, err = terminal.pwSrv.Write(msg); err != nil {
|
||||
return
|
||||
if _, err := terminal.pwSrv.Write(msg); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
_ = terminal.pwSrv.Close()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer closeAll()
|
||||
defer finish()
|
||||
if terminal.wsconn == nil || terminal.prTun == nil {
|
||||
return
|
||||
}
|
||||
buf := ts.TunnelManager.GetBuffer()
|
||||
defer ts.TunnelManager.PutBuffer(buf)
|
||||
|
||||
for {
|
||||
if terminal.prTun == nil {
|
||||
return
|
||||
}
|
||||
n, err := terminal.prTun.Read(buf)
|
||||
if err != nil {
|
||||
return
|
||||
if n > 0 {
|
||||
wsWriteMu.Lock()
|
||||
writeErr := terminal.wsconn.WriteMessage(websocket.BinaryMessage, buf[:n])
|
||||
wsWriteMu.Unlock()
|
||||
if writeErr != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
wsWriteMu.Lock()
|
||||
writeErr := terminal.wsconn.WriteMessage(websocket.BinaryMessage, buf[:n])
|
||||
wsWriteMu.Unlock()
|
||||
|
||||
if writeErr != nil {
|
||||
return
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
if !direct {
|
||||
go func() {
|
||||
buf := ts.TunnelManager.GetBuffer()
|
||||
defer ts.TunnelManager.PutBuffer(buf)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
n, err := terminal.prSrv.Read(buf)
|
||||
if n > 0 {
|
||||
taskData, writeErr := terminal.handlerWrite(terminal.TerminalId, terminal.CodePage, buf[:n])
|
||||
if writeErr == nil {
|
||||
tunnelManageTask(agent, taskData)
|
||||
}
|
||||
relayPipeToTaskData(agent, terminal.TerminalId, taskData)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +159,9 @@ type Terminal struct {
|
||||
TerminalId int
|
||||
CodePage int
|
||||
|
||||
agent *Agent
|
||||
agent *Agent
|
||||
mu sync.Mutex
|
||||
closed bool
|
||||
|
||||
wsconn *websocket.Conn
|
||||
|
||||
@@ -169,8 +171,8 @@ type Terminal struct {
|
||||
pwTun *io.PipeWriter
|
||||
prTun *io.PipeReader
|
||||
|
||||
handlerStart func(terminalId int, program string, sizeH int, sizeW int) (adaptix.TaskData, error)
|
||||
handlerWrite func(terminalId int, data []byte) (adaptix.TaskData, error)
|
||||
handlerStart func(terminalId int, program string, sizeH int, sizeW int, oemCP int) (adaptix.TaskData, error)
|
||||
handlerWrite func(terminalId int, oemCP int, data []byte) (adaptix.TaskData, error)
|
||||
handlerClose func(terminalId int) (adaptix.TaskData, error)
|
||||
}
|
||||
|
||||
|
||||
@@ -2004,14 +2004,23 @@ func TunnelReverse(tunnelId int, port int) ([]byte, error) {
|
||||
|
||||
/// TERMINAL
|
||||
|
||||
func TerminalStart(terminalId int, program string, sizeH int, sizeW int) ([]byte, error) {
|
||||
return nil, errors.New("Function Remote Terminal not supported")
|
||||
func TerminalStart(terminalId int, program string, sizeH int, sizeW int, oemCP int) ([]byte, error) {
|
||||
programArgs := ModuleObject.ts.TsConvertUTF8toCp(program, oemCP)
|
||||
array := []interface{}{COMMAND_SHELL_START, terminalId, programArgs}
|
||||
return PackArray(array)
|
||||
}
|
||||
|
||||
func TerminalWrite(terminalId int, data []byte) ([]byte, error) {
|
||||
return nil, errors.New("Function Remote Terminal not supported")
|
||||
func TerminalWrite(terminalId int, oemCP int, data []byte) ([]byte, error) {
|
||||
dataEncode := ModuleObject.ts.TsConvertUTF8toCp(string(data), oemCP)
|
||||
if oemCP > 0 {
|
||||
dataEncode = strings.ReplaceAll(dataEncode, "\n", "\r\n")
|
||||
}
|
||||
|
||||
array := []interface{}{COMMAND_SHELL_WRITE, terminalId, len(dataEncode), []byte(dataEncode)}
|
||||
return PackArray(array)
|
||||
}
|
||||
|
||||
func TerminalClose(terminalId int) ([]byte, error) {
|
||||
return nil, errors.New("Function Remote Terminal not supported")
|
||||
array := []interface{}{COMMAND_JOBS_KILL, terminalId}
|
||||
return PackArray(array)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
@@ -99,6 +100,12 @@ type Teamserver interface {
|
||||
TsTunnelConnectionData(channelId int, data []byte)
|
||||
TsTunnelConnectionAccept(tunnelId int, channelId int)
|
||||
|
||||
TsTerminalConnExists(terminalId string) bool
|
||||
TsTerminalGetPipe(AgentId string, terminalId string) (*io.PipeReader, *io.PipeWriter, error)
|
||||
TsTerminalConnResume(agentId string, terminalId string, ioDirect bool)
|
||||
TsTerminalConnData(terminalId string, data []byte)
|
||||
TsTerminalConnClose(terminalId string, status string) error
|
||||
|
||||
TsConvertCpToUTF8(input string, codePage int) string
|
||||
TsConvertUTF8toCp(input string, codePage int) string
|
||||
TsWin32Error(errorCode uint) string
|
||||
@@ -318,12 +325,12 @@ func TunnelMessageReverse(tunnelId int, port int) adaptix.TaskData {
|
||||
|
||||
/// TERMINAL
|
||||
|
||||
func (m *ModuleExtender) AgentTerminalCallbacks() (func(int, string, int, int) (adaptix.TaskData, error), func(int, []byte) (adaptix.TaskData, error), func(int) (adaptix.TaskData, error), error) {
|
||||
func (m *ModuleExtender) AgentTerminalCallbacks() (func(int, string, int, int, int) (adaptix.TaskData, error), func(int, int, []byte) (adaptix.TaskData, error), func(int) (adaptix.TaskData, error), error) {
|
||||
return TerminalMessageStart, TerminalMessageWrite, TerminalMessageClose, nil
|
||||
}
|
||||
|
||||
func TerminalMessageStart(terminalId int, program string, sizeH int, sizeW int) (adaptix.TaskData, error) {
|
||||
packData, err := TerminalStart(terminalId, program, sizeH, sizeW)
|
||||
func TerminalMessageStart(terminalId int, program string, sizeH int, sizeW int, oemCP int) (adaptix.TaskData, error) {
|
||||
packData, err := TerminalStart(terminalId, program, sizeH, sizeW, oemCP)
|
||||
if err != nil {
|
||||
return adaptix.TaskData{}, err
|
||||
}
|
||||
@@ -337,8 +344,8 @@ func TerminalMessageStart(terminalId int, program string, sizeH int, sizeW int)
|
||||
return taskData, nil
|
||||
}
|
||||
|
||||
func TerminalMessageWrite(channelId int, data []byte) (adaptix.TaskData, error) {
|
||||
packData, err := TerminalWrite(channelId, data)
|
||||
func TerminalMessageWrite(terminalId int, oemCP int, data []byte) (adaptix.TaskData, error) {
|
||||
packData, err := TerminalWrite(terminalId, oemCP, data)
|
||||
if err != nil {
|
||||
return adaptix.TaskData{}, err
|
||||
}
|
||||
|
||||
@@ -1545,14 +1545,14 @@ func TunnelReverse(tunnelId int, port int) ([]byte, error) {
|
||||
|
||||
/// TERMINAL
|
||||
|
||||
func TerminalStart(terminalId int, program string, sizeH int, sizeW int) ([]byte, error) {
|
||||
func TerminalStart(terminalId int, program string, sizeH int, sizeW int, oemCP int) ([]byte, error) {
|
||||
packerData, _ := msgpack.Marshal(ParamsTerminalStart{TermId: terminalId, Program: program, Height: sizeH, Width: sizeW})
|
||||
cmd := Command{Code: COMMAND_TERMINAL_START, Data: packerData}
|
||||
return msgpack.Marshal(cmd)
|
||||
}
|
||||
|
||||
func TerminalWrite(terminalId int, data []byte) ([]byte, error) {
|
||||
return nil, nil
|
||||
func TerminalWrite(terminalId int, oemCP int, data []byte) ([]byte, error) {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func TerminalClose(terminalId int) ([]byte, error) {
|
||||
|
||||
@@ -331,12 +331,12 @@ func TunnelMessageReverse(tunnelId int, port int) adaptix.TaskData {
|
||||
|
||||
/// TERMINAL
|
||||
|
||||
func (m *ModuleExtender) AgentTerminalCallbacks() (func(int, string, int, int) (adaptix.TaskData, error), func(int, []byte) (adaptix.TaskData, error), func(int) (adaptix.TaskData, error), error) {
|
||||
func (m *ModuleExtender) AgentTerminalCallbacks() (func(int, string, int, int, int) (adaptix.TaskData, error), func(int, int, []byte) (adaptix.TaskData, error), func(int) (adaptix.TaskData, error), error) {
|
||||
return TerminalMessageStart, TerminalMessageWrite, TerminalMessageClose, nil
|
||||
}
|
||||
|
||||
func TerminalMessageStart(terminalId int, program string, sizeH int, sizeW int) (adaptix.TaskData, error) {
|
||||
packData, err := TerminalStart(terminalId, program, sizeH, sizeW)
|
||||
func TerminalMessageStart(terminalId int, program string, sizeH int, sizeW int, oemCP int) (adaptix.TaskData, error) {
|
||||
packData, err := TerminalStart(terminalId, program, sizeH, sizeW, oemCP)
|
||||
if err != nil {
|
||||
return adaptix.TaskData{}, err
|
||||
}
|
||||
@@ -350,8 +350,8 @@ func TerminalMessageStart(terminalId int, program string, sizeH int, sizeW int)
|
||||
return taskData, nil
|
||||
}
|
||||
|
||||
func TerminalMessageWrite(channelId int, data []byte) (adaptix.TaskData, error) {
|
||||
packData, err := TerminalWrite(channelId, data)
|
||||
func TerminalMessageWrite(terminalId int, oemCP int, data []byte) (adaptix.TaskData, error) {
|
||||
packData, err := TerminalWrite(terminalId, oemCP, data)
|
||||
if err != nil {
|
||||
return adaptix.TaskData{}, err
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ type Teamserver interface {
|
||||
|
||||
TsAgentTerminalCloseChannel(terminalId string, status string) error
|
||||
TsTerminalConnExists(terminalId string) bool
|
||||
TsTerminalConnResume(agentId string, terminalId string)
|
||||
TsTerminalConnResume(agentId string, terminalId string, ioDirect bool)
|
||||
TsTerminalGetPipe(AgentId string, terminalId string) (*io.PipeReader, *io.PipeWriter, error)
|
||||
|
||||
TsTunnelGetPipe(AgentId string, channelId int) (*io.PipeReader, *io.PipeWriter, error)
|
||||
|
||||
@@ -401,7 +401,7 @@ func (handler *TCP) handleConnection(conn net.Conn, ts Teamserver) {
|
||||
return
|
||||
}
|
||||
|
||||
ts.TsTerminalConnResume(agentId, terminalId)
|
||||
ts.TsTerminalConnResume(agentId, terminalId, true)
|
||||
|
||||
pr, pw, err := ModuleObject.ts.TsTerminalGetPipe(agentId, terminalId)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user