從剖析cs木馬生成到開發免殺工具

廣州錦行科技發表於2020-07-07

作者:錦行-夜影實驗室(安全平臺部)-t43M!ne

木馬是駭客實施網路攻擊的常用兵器之一,有些木馬可以透過免殺技術的加持躲過防毒軟體的查殺。本文由錦行科技的安全研究團隊提供,旨在透過剖析CS木馬生成過程以及開發免殺工具,幫助大家更好地理解CS木馬的Artifact生成機制。

Cobaltstrike是用於紅隊行動、APT攻擊模擬的軟體,它具備很強大的協同能力和難以置信的可擴充套件性。
從剖析cs木馬生成到開發免殺工具
無論是編寫 shellcode,建立自定義的 C2二進位制可執行檔案,還是修改程式碼來隱藏惡意程式,它們都是紅隊日常工作的一部分,閱讀和理解成熟的C2框架程式碼也是理所當然的事情。


CobaltStrike是如何生成ShellCode的

CS是使用Swing進行UI開發的,程式碼中直接找對話方塊對應操作類。
+ `aggressor\dialogs\WindowsExecutableDialog.class`

從剖析cs木馬生成到開發免殺工具

可以看到很清晰的生成邏輯。

protected byte[] stager;

@Override
public void dialogAction(final ActionEvent actionEvent, final Map options) {
    this.options = options;
    this.stager = DialogUtils.getStager(options);
    if (this.stager.length == 0) {
        return;
    }
    final String string = options.get("output") + "";
    String s = "";
        if (string.indexOf("EXE") > -1) {
            s = "artifact.exe";
        }
        else if (string.indexOf("DLL") > -1) {
            s = "artifact.dll";
        }
        SafeDialogs.saveFile(null, s, this);
    }

透過 DialogUtils.getStager() 獲得生成的 stager 然後透過 saveFile 儲存檔案。
getStager() 方法呼叫了 aggressor\DataUtils.shellcode() ,而這裡其實是Stagers的介面。

return Stagers.shellcode(s, "x86", b);

最終在 stagers\Stagers.shellcode() 根據監聽器型別,
例項化了繼承自的 GenericStager 的 stagers\GenericHTTPStager 類,並由 generate() 生成shellcode

從剖析cs木馬生成到開發免殺工具

shellcode生成時,讀取了resources/httpstager.bin,並根據監聽器的host和port等值組合為Packer
最終替換到多個X、Y佔位的bin檔案中,最後返回bytes[] 型別的shellcode

Patch Artifact

shellcode生成完成後,回到原點,可以看到根據使用者的選擇,對不同的 artifact 模板進行 patch ,以 x86 的模板為例,
繼續跟進 patchArtifact

new ArtifactUtils(this.client).patchArtifact(this.stager, "artifact32.exe", s);

+ `common\BaseArtifactUtils.class`

public byte[] patchArtifact(final byte[] array, final String s) {
    final Stack<Scalar> stack = new Stack<Scalar>();
    stack.push(SleepUtils.getScalar(array));
    stack.push(SleepUtils.getScalar(s));
    final String format = this.client.getScriptEngine().format("EXECUTABLE_ARTIFACT_GENERATOR", stack);
    if (format == null) {
        return this.fixChecksum(this._patchArtifact(array, s));
    }
    return this.fixChecksum(CommonUtils.toBytes(format));
}

稍微看一下 fixChecksum ,是透過 PE 編輯器修復了校驗碼。
這裡不贅述了,對編輯器實現感興趣的可以去看看 pe\PEEditor.class

final PEEditor peEditor = new PEEditor(array);
peEditor.updateChecksum();
return peEditor.getImage();

注意看這裡 this._patchArtifact(array, s) ,呼叫了同名方法,PS:差點以為在看Python

從剖析cs木馬生成到開發免殺工具

讀取了 resources 資料夾下的 artifact32.exe 作為模板檔案,根據重複的1024個 A 來定位shellcode 位置。
與生成shellcode時類似,使用common/CommonUtils.replaceAt()對bytes流轉為的字串進行編輯替換。

public static String replaceAt(final String s, final String s2, final int n) {
  final StringBuffer sb = new StringBuffer(s);
  sb.delete(n, n + s2.length());
  sb.insert(n, s2);
  return sb.toString();
}

使用16進位制編輯器可以直接看到用於標誌存放 shellcode 的位置。

從剖析cs木馬生成到開發免殺工具

值得一提的是,替換shellcode之後的pe檔案,因為shellcode長度沒有完全覆蓋到標識的1024個A,一般生成的exe都會殘留部分字元,當然這並不會影響shellcode的執行。

從剖析cs木馬生成到開發免殺工具

Shellcode Launcher

利用載入器遠端回連獲取下一階段 payload 載入到記憶體中執行以規避殺軟的探測,這種 VirtualAlloc到 WriteProcessMemory 的分配記憶體模式早已被眾多遠控木馬軟體廣泛利用。
CS開發者在其最新的介紹影片中披露了部分 artifact 的原始碼,並演示瞭如何透過修改載入器繞過了Defender 的查殺。
他透過用 HeapAlloc 來代替 VitualAlloc ,躲避了大部分的殺軟。

從剖析cs木馬生成到開發免殺工具

在這個基礎上,我們新增了對shellcode進行異或加密的功能,顯然一個非常精簡的基於c++的shellcode載入器就成形了。
然後參考CS的方式,在本應放置shellcode的buf中,置入大量重複的佔位符作為定位。

python -c "print(1024*'A')"

用VisualStudio或MingW將其編譯為 template.exe

開發免殺小工具

然後新建一個 JavaFx 的專案,樣式與部分程式碼參考某chaos免殺小助手。
捋下流程,首先需要對CS或MSF的shellcode進行預處理,然後進行異或加密,讀取模板檔案,定位到shellcode位置,進行覆蓋,最後儲存。

從剖析cs木馬生成到開發免殺工具

有很多類直接可以從CS複製過來就能用。

從剖析cs木馬生成到開發免殺工具

從剖析cs木馬生成到開發免殺工具

重點看下xor,為了跟launcher解密一致,需要先轉換為int型別進行異或,然後再轉回hex,最終打包為 jar

從剖析cs木馬生成到開發免殺工具
生成veil型別的payload,複製貼上,生成, 儲存。

從剖析cs木馬生成到開發免殺工具

從剖析cs木馬生成到開發免殺工具

最終免殺效果取決於Launcher模板,作為一個非常精簡、沒什麼改動的模板,效果已經出乎意料了。
畢竟目的並非追求免殺效果,而應注重於理解CS木馬的Artifact生成機制。

相關文章