示例#1
0
        // http://www.exploit-monday.com/2013/08/writing-optimized-windows-shellcode-in-c.html
        private static byte[] CompileToShellcode(TargetArch targetArch, IShellcodeCCxxSourceIParameterlessCFunction ccxxSource, IEnumerable <ObjectFile> additionalShellcodeObjectFiles, bool optimize)
        {
            // __chkstk will be linked if large portion of the stack used. Still POC if we statically link crt


            additionalShellcodeObjectFiles = additionalShellcodeObjectFiles ?? new List <ObjectFile>();

            var source = new CCxxSource(((IShellcodeCCxxSource)ccxxSource).SourceFiles);

            var shellcodeEntryFunction = ccxxSource.Name;

            // Compile
            Compiler.Config compilerConfig;
            if (optimize)
            {
                compilerConfig = new Compiler.Config(
                    GL: true, O1: true, Os: true,                                                                              // Optimizations that differ
                    O2: false, Og: false, Ot: false, Od: false, Oy: true, Oi: true,                                            // Optimizations that are the same
                    GF: true, Gy: true, GS: false, sdl: null, Zl: false, FA: true, runtime: Compiler.Config.RunTimeLibrary.MT, // Necessary for PIE
                    callingConvention: null, EHa: null, EHs: null, EHc: null, EHr: null                                        // unsure of the effect of these, so leaving as unspecified
                    );
            }
            else
            {
                compilerConfig = new Compiler.Config(
                    GL: false, O1: false, Os: false,                                                                           // Optimizations that differ
                    O2: false, Og: false, Ot: false, Od: false, Oy: true, Oi: true,                                            // Optimizations that are the same
                    GF: true, Gy: true, GS: false, sdl: null, Zl: false, FA: true, runtime: Compiler.Config.RunTimeLibrary.MT, // Necessary for PIE
                    callingConvention: null, EHa: null, EHs: null, EHc: null, EHr: null                                        // unsure of the effect of these, so leaving as unspecified
                    );
            }

            Linker.Config linkerConfig;
            if (optimize)
            {
                linkerConfig = new Linker.Config(
                    LTCG: Linker.Config.Ltcg.ON, // Optimizations that differ
                    OPTREF: true, OPTICF: 1,     // Optimizations that are the same
                    ENTRY: "Begin", SUBSYSTEM: Linker.Config.Subsystem.CONSOLE, MAP: true, SAFESEH: false, NODEFAULTLIB: true, ORDER: new List <string>()
                {
                    "Begin", shellcodeEntryFunction
                },                                                                                                                                                                            // Necessary for PIE
                    additionalDependencies: new List <string> {
                    "libucrt.lib", "libvcruntime.lib", "libcmt.lib"
                }
                    );
            }
            else
            {
                linkerConfig = new Linker.Config(
                    LTCG: Linker.Config.Ltcg.OFF, // Optimizations that differ
                    OPTREF: true, OPTICF: 1,      // Optimizations that are the same
                    ENTRY: "Begin", SUBSYSTEM: Linker.Config.Subsystem.CONSOLE, MAP: true, SAFESEH: false, NODEFAULTLIB: true, ORDER: new List <string>()
                {
                    "Begin", shellcodeEntryFunction
                },                                                                                                                                                                            // Necessary for PIE
                    additionalDependencies: new List <string> {
                    "libucrt.lib", "libvcruntime.lib", "libcmt.lib"
                }
                    );
            }

            Executable exe;

            switch (targetArch)
            {
            case TargetArch.x64:
            {
                var additionalShellcodeObjectFiles64 = new StaticLibrary <Win64ObjectFile>(additionalShellcodeObjectFiles.Cast <Win64ObjectFile>());
                var staticLibrary = ((ICCxxCompiler <Win64ObjectFile>) new Compiler(compilerConfig)).Compile(source);
                // Since this is x64, we need to ensure that the stack is aligned before we execute our C/C++'s entry function
                var alignStackAsm = new AlignRSPMasmAssemblySource(shellcodeEntryFunction);
                var alignStackSL  = ((IAssembler <MASM, Win64ObjectFile>) new Masm()).Assemble(alignStackAsm);
                var linkerInput   = new List <StaticLibrary <Win64ObjectFile> >()
                {
                    staticLibrary, additionalShellcodeObjectFiles64, alignStackSL
                };
                exe = ((ILinker <Win64ObjectFile, Executable>) new Linker(linkerConfig)).Link(linkerInput);
                break;
            }

            case TargetArch.x86:
            {
                var additionalShellcodeObjectFiles32 = new StaticLibrary <Win32ObjectFile>(additionalShellcodeObjectFiles.Cast <Win32ObjectFile>());
                source.FindAndReplace("BeginExecutePayload", shellcodeEntryFunction);
                var staticLibrary = ((ICCxxCompiler <Win32ObjectFile>) new Compiler(compilerConfig)).Compile(source);
                var linkerInput   = new List <StaticLibrary <Win32ObjectFile> >()
                {
                    staticLibrary, additionalShellcodeObjectFiles32
                };
                exe = ((ILinker <Win32ObjectFile, Executable>) new Linker(linkerConfig)).Link(linkerInput);
                break;
            }

            default:
                throw new ArgumentException("Invalid TargetArch valid");
            }

            // Check if Position Independent Code was generate
            // Sometimes when building for 32-bit, char[] initialzied with an arrary of a certain length gets placed in the data section ...
            // Seems to be when the strlen >= 15  (>= 16 with null byte)
            // Possible solution, split up array into multiple smalle rarrarys?
            if (exe.Map.Split("Publics by Value")[1].Split("entry point")[0].Contains("0002:") || exe.Map.Split("Publics by Value")[1].Split("entry point")[0].Contains("0003:"))
            {
                Console.Error.Write(exe.Map);
                throw new Exception("Failed to generate shellcode: code dependent on data section. See Map file for more info");
            }
            // 'Begin' is the entry point to our shellcode
            if (!exe.Map.Split("Publics by Value")[1].Split("0001:")[1].Split("\n")[0].Contains("Begin"))
            {
                Console.Error.Write(exe.Map);
                throw new Exception("Failed to generate shellcode: function 'Begin' is not the first function in the CODE section. See Map file for more info");
            }

            // Extract shellcoode
            var shellcodeBytes      = PeCode.Extract(exe);
            var codeLengthHexString = exe.Map.Split("CODE")[0].Split("H ")[0].Split(" ")[^ 1];
 // Merges input source into this object
 public MutexSingletonShellcodeCCxxSource(IShellcodeCCxxSourceIParameterlessCFunction functionSource, string mutexName = @"Global\MutexSingleton")
     : base(MergeSourceFiles(MutexSingletonCCxxSource.CreateSource((IParameterlessCFunction)functionSource, mutexName), new List <ICCxxSource>() { functionSource }))
 {
     FindAndReplace(SourceFiles, FunctionNamePlaceholder, ((ICFunction)this).Name);
 }
示例#3
0
 // Merges input source into this object
 public CreateThreadShellcodeCCxxSource(IShellcodeCCxxSourceIParameterlessCFunction functionSource)
     : base(MergeSourceFiles(CreateThreadCCxxSource.CreateSource((IParameterlessCFunction)functionSource), new List <ICCxxSource>() { functionSource }))
 {
     FindAndReplace(SourceFiles, FunctionNamePlaceholder, ((ICFunction)this).Name);
 }