天天看點

.NET版“ShellCode”編寫

0x000 前言

近幾年大家都喜歡用CS來進行後滲透,是以對于ShellCode大家應該不會陌生。

但是可能很多人并不懂CS它的功能是什麼,CS生成的ShellCode是一段下載下傳者。

主要功能為下載下傳becon.dll,然後記憶體加載,我們所用的相關功能都在becon裡。

ShellCode可能采用彙編或VC編寫後轉成機器碼提取關鍵機器碼,優勢在于體積小

體積小就可以直接結合漏洞使用,什麼Word文檔、MS17010溢出、IE漏洞挂馬等

都可以直接結合CS來使用,直接CS上線,而不是非要先做其它操作再植入CS。

網上關于彙編或VC編寫ShellCode的文章很多,但是.NET的"ShellCode"很少見

本文将教大家如何用操作碼實作.NET版"ShellCode"的編寫。

0x001 指令、操作碼、位元組碼

在正式開始前,先給大家科普一下指令、操作碼、機器碼等的差別

指令: 指令cpu幹什麼,是由操作碼字段和位址碼字段(操作數字段)組成

操作碼(Opcode): 就是執行某種操作的指令代碼

BYTECODE(位元組碼):與機器代碼相同,除了它主要由基于軟體的解釋器(如Java或CLR)使用

程式集:有兩個“程式集” – 一個彙程式設計式是一系列的助記符和操作數,它們被饋送到“彙程式設計式”,

“彙程式設計式”将助記符和操作數“彙編成可執行的機器代碼”.可選地,“連結器”連結元件并生成可執行檔案.

CLR語言:(.NET語言)中的第二個“程式集”是一系列CLR代碼,其中注入了中繼資料資訊,可執行代碼庫,但不能直接執行.

0x002 Payload ShellCode

機器碼(溢出常用的ShellCode): 就是指令的二進制代碼(包括操作碼和位址碼),功能打開和關閉計算機中的開關的數字序列,以執行某些工作 – 例如增加數字,分支,乘法等等.這是純機器特有的,由處理器的實作者.

K8了解的ShellCode是子彈,用槍發射(好比處理器執行); 無論你用的是哪種子彈(ShellCode),都是用槍來射(處理器執行)。

Payload: K8的了解是彈藥,彈藥可裝填到彈殼裡用,也可直接點然,也可圈起來當成炮仗點燃,但是彈藥不能直接被槍發射。

PS:發現很多搞安全的對很多概念搞混,如很多文章常把payload和shellcode混為一談

看了以上釋義,您應該了解明顯shellcode隻是payload中的一種了,不可能屬于同一個。

很多人把操作碼誤解為ShellCode還可以了解,起碼長得像還有點類似,但真不是。

不要看到二進制、16進制或者byte數組就說是shellcode,長得像人都不定是人呢。

0x003 .NET函數代碼

.NET包含多種語言,這裡我使用C#的代碼做為例子

public int Add(int x, int y)
            {
                x = x * y;
                return x  + y;
            }
           

0x003 反彙編得到IL指令

指令速查表:https://www.jb51.net/article/86802.htm

IL語言,可了解為.NET的彙編,無論你使用的是C#還是VB.NET或者F#開發功能,都可以将其反編譯成IL代碼。使用ildasm.exe工具反編譯,可以看到IL代碼和彙編差不多,可能是常用.NET吧,感覺比彙編簡單好多。

// Method begins at RVA 0x2170
  // Code size       9 (0x9)
  .maxstack  8
  IL_0000:  /* 03   |                  */ ldarg.1
  IL_0001:  /* 04   |                  */ ldarg.2
  IL_0002:  /* 5A   |                  */ mul
  IL_0003:  /* 10   | 01               */ starg.s    x
  IL_0005:  /* 03   |                  */ ldarg.1
  IL_0006:  /* 04   |                  */ ldarg.2
  IL_0007:  /* 58   |                  */ add
  IL_0008:  /* 2A   |                  */ ret
} // end of method MethodBodyDemo::Add
           

0x004 IL指令轉.NET操作碼

如同VC反彙編提取機器碼一樣,我們将對應16進制複制出來,然後再對比指令速查表提取關鍵操作碼

0x02,0x03,0x5A,0x10,0x00,0x02,0x03,0x58,0x2A
           

0x005 操作碼加載

private static Func<int, int, int> LoadByteAssmbly(byte[] bytes)
        {
            var asmName = new AssemblyName("DynamicAssembly");
            var asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
            var module = asmBuilder.DefineDynamicModule("DynamicModule");
            var typeBuilder = module.DefineType("DynamicType");
            var method = typeBuilder.DefineMethod("DynamicMethod",
                MethodAttributes.Public | MethodAttributes.Static,
                typeof(int),
                new[] { typeof(int), typeof(int) });
            method.CreateMethodBody(bytes, bytes.Length);
            var type = typeBuilder.CreateType();

            return (Func<int, int, int>)type.GetMethod("DynamicMethod").CreateDelegate(typeof(Func<int, int, int>));
        }
           

0x006 執行效果

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-0BJP9b92-1578751271469)(http://k8gege.org/k8img/Other/ilcode.PNG)]

繼續閱讀