github.com/iDigitalFlame/xmt@v0.5.4/c2/task/v_migrate.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 task 21 22 import ( 23 "github.com/iDigitalFlame/xmt/cmd/filter" 24 "github.com/iDigitalFlame/xmt/com" 25 "github.com/iDigitalFlame/xmt/data" 26 ) 27 28 var ( 29 _ Callable = (*DLL)(nil) 30 _ Callable = (*Zombie)(nil) 31 _ Callable = (*Process)(nil) 32 _ Callable = (*Assembly)(nil) 33 ) 34 35 // Callable is an internal interface used to specify a wide range of Runnable 36 // types that can be Marshaled into a Packet. 37 // 38 // Currently the DLL, Zombie, Assembly and Process instances are supported. 39 type Callable interface { 40 task() uint8 41 MarshalStream(data.Writer) error 42 } 43 44 func (DLL) task() uint8 { 45 return TvDLL 46 } 47 func (Zombie) task() uint8 { 48 return TvZombie 49 } 50 func (Process) task() uint8 { 51 return TvExecute 52 } 53 func (Assembly) task() uint8 { 54 return TvAssembly 55 } 56 57 // Spawn will attempt to spawn a new instance using the provided Callable type 58 // as the source. 59 // 60 // The provided Filter specifies the parent of the new instance and the 's' 61 // argument string specifies the pipe name to use while connecting. 62 // 63 // The return result is the PID of the new instance. 64 // 65 // This function uses the same Profile as the target Session. Use the 66 // 'SpawnProfile' function to change this behavior. 67 // 68 // C2 Details: 69 // 70 // ID: MvSpawn 71 // 72 // Input: 73 // string // Pipe Name 74 // []byte // Profile Bytes 75 // Filter struct { // Filter 76 // bool // Filter Status 77 // uint32 // PID 78 // bool // Fallback 79 // uint8 // Session 80 // uint8 // Elevated 81 // []string // Exclude 82 // []string // Include 83 // } 84 // uint8 // Callable Type 85 // <...> // Callable Data 86 // Output: 87 // uint32 // New PID 88 func Spawn(f *filter.Filter, s string, c Callable) *com.Packet { 89 return SpawnProfile(f, s, nil, c) 90 } 91 92 // Migrate will attempt to migrate to a new instance using the provided Callable 93 // type as the source. 94 // 95 // The provided Filter specifies the parent of the new instance and the 's' 96 // argument string specifies the pipe name to use while connecting. 97 // 98 // This function keeps the same Profile. Use the 'MigrateProfile' or 99 // 'MigrateProfileEx' function to change this behavior. 100 // 101 // This function will automatically wait for all Jobs to complete. Use the 102 // 'MigrateProfileEx' function to change this behavior. 103 // 104 // C2 Details: 105 // 106 // ID: MvMigrate 107 // 108 // Input: 109 // bool // Wait for Jobs 110 // string // Pipe Name 111 // []byte // Profile Bytes 112 // Filter struct { // Filter 113 // bool // Filter Status 114 // uint32 // PID 115 // bool // Fallback 116 // uint8 // Session 117 // uint8 // Elevated 118 // []string // Exclude 119 // []string // Include 120 // } 121 // uint8 // Callable Type 122 // <...> // Callable Data 123 // Output: 124 // <none> // RvResult packet sent separately 125 func Migrate(f *filter.Filter, s string, c Callable) *com.Packet { 126 return MigrateProfileEx(f, true, s, nil, c) 127 } 128 129 // SpawnPull will attempt to spawn a new instance using the provided URL as the 130 // source. 131 // 132 // The supplied 'agent' string (if non-empty) will specify the User-Agent header 133 // string to be used. 134 // 135 // The provided Filter specifies the parent of the new instance and the 's' 136 // argument string specifies the pipe name to use while connecting. 137 // 138 // The return result is the PID of the new instance. 139 // 140 // This function uses the same Profile as the target Session. Use the 141 // 'SpawnPullProfile' function to change this behavior. 142 // 143 // The download data may be saved in a temporary location depending on what the 144 // resulting data type is or file extension. (see 'man.ParseDownloadHeader') 145 // 146 // C2 Details: 147 // 148 // ID: MvSpawn 149 // 150 // Input: 151 // string // Pipe Name 152 // []byte // Profile Bytes 153 // Filter struct { // Filter 154 // bool // Filter Status 155 // uint32 // PID 156 // bool // Fallback 157 // uint8 // Session 158 // uint8 // Elevated 159 // []string // Exclude 160 // []string // Include 161 // } 162 // uint8 // Callable Type (always TvPullExecute) 163 // string // URL 164 // string // User-Agent 165 // Output: 166 // uint32 // New PID 167 func SpawnPull(f *filter.Filter, s, url, agent string) *com.Packet { 168 return SpawnPullProfile(f, s, nil, url, agent) 169 } 170 171 // MigratePull will attempt to migrate to a new instance using the provided URL 172 // as the source. 173 // 174 // The supplied 'agent' string (if non-empty) will specify the User-Agent header 175 // string to be used. 176 // 177 // The provided Filter specifies the parent of the new instance and the 's' 178 // argument string specifies the pipe name to use while connecting. 179 // 180 // This function keeps the same Profile. Use the 'MigratePullProfile' or 181 // 'MigratePullProfileEx' function to change this behavior. 182 // 183 // This function will automatically wait for all Jobs to complete. Use the 184 // 'MigratePullProfileEx' function to change this behavior. 185 // 186 // The download data may be saved in a temporary location depending on what the 187 // resulting data type is or file extension. (see 'man.ParseDownloadHeader') 188 // 189 // C2 Details: 190 // 191 // ID: MvMigrate 192 // 193 // Input: 194 // bool // Wait for Jobs 195 // string // Pipe Name 196 // []byte // Profile Bytes 197 // Filter struct { // Filter 198 // bool // Filter Status 199 // uint32 // PID 200 // bool // Fallback 201 // uint8 // Session 202 // uint8 // Elevated 203 // []string // Exclude 204 // []string // Include 205 // } 206 // uint8 // Callable Type (always TvPullExecute) 207 // string // URL 208 // string // User-Agent 209 // Output: 210 // <none> // RvResult packet sent separately 211 func MigratePull(f *filter.Filter, s, url, agent string) *com.Packet { 212 return MigratePullProfileEx(f, true, s, nil, url, agent) 213 } 214 215 // SpawnProfile will attempt to spawn a new instance using the provided Callable 216 // type as the source with the supplied Profile bytes. 217 // 218 // The provided Filter specifies the parent of the new instance and the 's' 219 // argument string specifies the pipe name to use while connecting. 220 // 221 // The return result is the PID of the new instance. 222 // 223 // If the 'b' Profile bytes is nil or empty, the current target Session Profile 224 // will be used. 225 // 226 // C2 Details: 227 // 228 // ID: MvSpawn 229 // 230 // Input: 231 // string // Pipe Name 232 // []byte // Profile Bytes 233 // Filter struct { // Filter 234 // bool // Filter Status 235 // uint32 // PID 236 // bool // Fallback 237 // uint8 // Session 238 // uint8 // Elevated 239 // []string // Exclude 240 // []string // Include 241 // } 242 // uint8 // Callable Type 243 // <...> // Callable Data 244 // Output: 245 // uint32 // New PID 246 func SpawnProfile(f *filter.Filter, s string, b []byte, c Callable) *com.Packet { 247 n := &com.Packet{ID: MvSpawn} 248 n.WriteString(s) 249 n.WriteBytes(b) 250 if f.MarshalStream(n); c == nil { 251 n.WriteUint8(0) 252 return n 253 } 254 n.WriteUint8(c.task()) 255 c.MarshalStream(n) 256 return n 257 } 258 259 // MigrateProfile will attempt to migrate to a new instance using the provided 260 // Callable type as the source with the supplied Profile bytes. 261 // 262 // The provided Filter specifies the parent of the new instance and the 's' 263 // argument string specifies the pipe name to use while connecting. 264 // 265 // If the 'b' Profile bytes is nil or empty, the current target Session Profile 266 // will be used. 267 // 268 // This function will automatically wait for all Jobs to complete. Use the 269 // 'MigrateProfileEx' function to change this behavior. 270 // 271 // C2 Details: 272 // 273 // ID: MvMigrate 274 // 275 // Input: 276 // bool // Wait for Jobs 277 // string // Pipe Name 278 // []byte // Profile Bytes 279 // Filter struct { // Filter 280 // bool // Filter Status 281 // uint32 // PID 282 // bool // Fallback 283 // uint8 // Session 284 // uint8 // Elevated 285 // []string // Exclude 286 // []string // Include 287 // } 288 // uint8 // Callable Type 289 // <...> // Callable Data 290 // Output: 291 // <none> // RvResult packet sent separately 292 func MigrateProfile(f *filter.Filter, s string, b []byte, c Callable) *com.Packet { 293 return MigrateProfileEx(f, true, s, b, c) 294 } 295 296 // SpawnPullProfile will attempt to spawn a new instance using the provided URL 297 // as the source with the supplied Profile bytes. 298 // 299 // The supplied 'agent' string (if non-empty) will specify the User-Agent header 300 // string to be used. 301 // 302 // The provided Filter specifies the parent of the new instance and the 's' 303 // argument string specifies the pipe name to use while connecting. 304 // 305 // The return result is the PID of the new instance. 306 // 307 // If the 'b' Profile bytes is nil or empty, the current target Session Profile 308 // will be used. 309 // 310 // The download data may be saved in a temporary location depending on what the 311 // resulting data type is or file extension. (see 'man.ParseDownloadHeader') 312 // 313 // C2 Details: 314 // 315 // ID: MvSpawn 316 // 317 // Input: 318 // string // Pipe Name 319 // []byte // Profile Bytes 320 // Filter struct { // Filter 321 // bool // Filter Status 322 // uint32 // PID 323 // bool // Fallback 324 // uint8 // Session 325 // uint8 // Elevated 326 // []string // Exclude 327 // []string // Include 328 // } 329 // uint8 // Callable Type (always TvPullExecute) 330 // string // URL 331 // string // User-Agent 332 // Output: 333 // uint32 // New PID 334 func SpawnPullProfile(f *filter.Filter, s string, b []byte, url, agent string) *com.Packet { 335 n := &com.Packet{ID: MvSpawn} 336 n.WriteString(s) 337 n.WriteBytes(b) 338 f.MarshalStream(n) 339 n.WriteUint8(TvPullExecute) 340 n.WriteString(url) 341 n.WriteString(agent) 342 return n 343 } 344 345 // MigrateProfileEx will attempt to migrate to a new instance using the provided 346 // Callable type as the source with the supplied Profile bytes and the 'w' boolean 347 // to specify waiting for Jobs to complete. 348 // 349 // The provided Filter specifies the parent of the new instance and the 's' 350 // argument string specifies the pipe name to use while connecting. 351 // 352 // If the 'b' Profile bytes is nil or empty, the current target Session Profile 353 // will be used. 354 // 355 // C2 Details: 356 // 357 // ID: MvMigrate 358 // 359 // Input: 360 // bool // Wait for Jobs 361 // string // Pipe Name 362 // []byte // Profile Bytes 363 // Filter struct { // Filter 364 // bool // Filter Status 365 // uint32 // PID 366 // bool // Fallback 367 // uint8 // Session 368 // uint8 // Elevated 369 // []string // Exclude 370 // []string // Include 371 // } 372 // uint8 // Callable Type 373 // <...> // Callable Data 374 // Output: 375 // <none> // RvResult packet sent separately 376 func MigrateProfileEx(f *filter.Filter, w bool, s string, b []byte, c Callable) *com.Packet { 377 n := &com.Packet{ID: MvMigrate} 378 n.WriteBool(w) 379 n.WriteString(s) 380 n.WriteBytes(b) 381 if f.MarshalStream(n); c == nil { 382 n.WriteUint8(0) 383 return n 384 } 385 n.WriteUint8(c.task()) 386 c.MarshalStream(n) 387 return n 388 } 389 390 // MigratePullProfile will attempt to migrate to a new instance using the 391 // provided URL as the source with the supplied Profile bytes. 392 // 393 // The supplied 'agent' string (if non-empty) will specify the User-Agent header 394 // string to be used. 395 // 396 // The provided Filter specifies the parent of the new instance and the 's' 397 // argument string specifies the pipe name to use while connecting. 398 // 399 // If the 'b' Profile bytes is nil or empty, the current target Session Profile 400 // will be used. 401 // 402 // This function will automatically wait for all Jobs to complete. Use the 403 // 'MigratePullProfileEx' function to change this behavior. 404 // 405 // The download data may be saved in a temporary location depending on what the 406 // resulting data type is or file extension. (see 'man.ParseDownloadHeader') 407 // 408 // C2 Details: 409 // 410 // ID: MvMigrate 411 // 412 // Input: 413 // bool // Wait for Jobs 414 // string // Pipe Name 415 // []byte // Profile Bytes 416 // Filter struct { // Filter 417 // bool // Filter Status 418 // uint32 // PID 419 // bool // Fallback 420 // uint8 // Session 421 // uint8 // Elevated 422 // []string // Exclude 423 // []string // Include 424 // } 425 // uint8 // Callable Type (always TvPullExecute) 426 // string // URL 427 // string // User-Agent 428 // Output: 429 // <none> // RvResult packet sent separately 430 func MigratePullProfile(f *filter.Filter, s string, b []byte, url, agent string) *com.Packet { 431 return MigratePullProfileEx(f, true, s, b, url, agent) 432 } 433 434 // MigratePullProfileEx will attempt to migrate to a new instance using the 435 // provided URL as the source with the supplied Profile bytes and the 'w' boolean 436 // to specify waiting for Jobs to complete. 437 // 438 // The supplied 'agent' string (if non-empty) will specify the User-Agent header 439 // string to be used. 440 // 441 // The provided Filter specifies the parent of the new instance and the 's' 442 // argument string specifies the pipe name to use while connecting. 443 // 444 // If the 'b' Profile bytes is nil or empty, the current target Session Profile 445 // will be used. 446 // 447 // The download data may be saved in a temporary location depending on what the 448 // resulting data type is or file extension. (see 'man.ParseDownloadHeader') 449 // 450 // C2 Details: 451 // 452 // ID: MvMigrate 453 // 454 // Input: 455 // bool // Wait for Jobs 456 // string // Pipe Name 457 // []byte // Profile Bytes 458 // Filter struct { // Filter 459 // bool // Filter Status 460 // uint32 // PID 461 // bool // Fallback 462 // uint8 // Session 463 // uint8 // Elevated 464 // []string // Exclude 465 // []string // Include 466 // } 467 // uint8 // Callable Type (always TvPullExecute) 468 // string // URL 469 // string // User-Agent 470 // Output: 471 // <none> // RvResult packet sent separately 472 func MigratePullProfileEx(f *filter.Filter, w bool, s string, b []byte, url, agent string) *com.Packet { 473 n := &com.Packet{ID: MvMigrate} 474 n.WriteBool(w) 475 n.WriteString(s) 476 n.WriteBytes(b) 477 f.MarshalStream(n) 478 n.WriteUint8(TvPullExecute) 479 n.WriteString(url) 480 n.WriteString(agent) 481 return n 482 }