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  }