OS X版本的OceanLotus(海蓮花木馬)

wyzsk發表於2020-08-19
作者: virustracker · 2016/02/24 14:58

https://www.alienvault.com/open-threat-exchange/blog/oceanlotus-for-os-x-an-application-bundle-pretending-to-be-an-adobe-flash-update

2015年5月,奇虎360的研究人員公佈了一份關於OceanLotus木馬的研究報告。在報告中,他們詳細的分析了這個攻擊了中國組織機構的木馬。報告中還介紹了一個針對OS X系統的木馬,這個木馬樣本在幾個月前被上傳到了VirusTotal上。有意思的是,截至2016年2月8日,VirusTotal上的55種防毒解決方案仍然無法檢測出這個惡意樣本。因此,我們決定調查一番這個OS X版本的OceanLotus木馬。

0x00 分析


OS X版本的OceanLotus是一個偽裝成Adobe Flash更新的應用程式包(Application Bundle)。在這個應用程式包中有很多不同的檔案,下面是我們感興趣的幾個:

  • FlashUpdate.app/Contents/MacOS/EmptyApplication
  • FlashUpdate.app/Contents/Resources/en.lproj/.en_icon
  • FlashUpdate.app/Contents/Resources/en.lproj/.DS_Stores

0x01 載入程式(Loader)


如下,EmptyApplication是一個通用二進位制(universal binary),既可以在i386架構,也可以在x86_64架構下執行。這是一個非常簡單的程式,首先,這個程式會使用ROL3演算法解碼出兩個“檔案”: .en_iconDS_Stores;然後再執行這些檔案。

#!bash
$file EmptyApplication
EmptyApplication: Mach-O universal binary with 2 architectures
EmptyApplication (for architecture x86_64): Mach-O 64-bit executable x86_64
EmptyApplication (for architecture i386): Mach-O executable i386

在混淆演算法上,EmptyApplication使用了“xc”作為XOR演算法的加密秘鑰,混淆了二進位制中的字串。下面是一個簡單的解密函式。

p1

在64位版本中,8位元組長度以內的字串會儲存成整數值(integer value)。超過8位元組長度的字串會加密儲存在相鄰變數中,解密函式在讀取變數時會以8個位元組為界。如下所示,&v34被傳遞給瞭解密函式,但是,函式實際上解密了v34和v35組合。

p2

在解碼了.en_icon之後,EmptyApplication會將其寫到一個名稱是“pboard”的臨時目錄(可能是為了偽裝成OS X系統中的貼上板守護程式),並執行二進位制檔案。然後,EmptyApplication會刪除自身,解碼.DS_Stores,並把解碼得到的二進位制寫為“EmptyApplication”-替換掉原來的EmptyApplication可執行檔案。最後,透過呼叫NSTask.launch()就可以啟動新的EmptyApplication。解密後的.DS_Stores二進位制在功能上與原有的EmptyApplication並沒有太多區別,只是新的EmptyApplication不會查詢.DS_Stores

0x02 木馬


加密字串

解碼後的.en_icon檔案就是主木馬。這個木馬具備反除錯功能,能夠處理CC連線。後面我們會談到,這個木馬利用了幾個OS X命令和API呼叫,所以說,這個木馬很明顯是專門針對OS X製作的,而不是從其他系統上移植的。

還有一點,二進位制中的大部分字串都使用了XOR演算法進行加密,但是,這個二進位制使用了多個不同的秘鑰,並且這些秘鑰本身也經過了XOR加密。事實上,這個木馬做的第一件事就是解密幾個XOR秘鑰。有趣的是,用於設定解密秘鑰的程式碼會透過使用C++靜態構造器(static constructor)在“main”入口點之前執行。這個程式碼引用在mach-o二進位制檔案的__mod_init_func部分。

p3

從上圖中可以看出,整個可執行檔案主要使用的解密秘鑰是“Variable”。但是,這裡出現了幾個不同的"Variable" 字串,這樣能夠方便木馬作者使用不同的解密秘鑰來更新程式碼。雖然,XOR解密不難,但是,這種方案能夠增加逆向工程的繁瑣程度。下面這個解密函式與EmptyApplication使用的函式很類似,只不過,下面這個版本採用了一個變數解密秘鑰:

p4

反除錯

為了避免連線到除錯程式,木馬使用了PT_DENY_ATTACH引數來呼叫ptrace()。此外,木馬會建立一個signal handler來捕捉SIGTRAPs,呼叫“int 3”來投放一個SIGTRAPs,在SIGTRAP處理器中設定flag並在繼續執行之前檢查flag值。就反除錯而言,這種方法非常有效。

接下來,在執行程式碼之前,木馬會透過檢視二進位制檔案的後27位位元組,從而執行簽名檢查。在這27個位元組中,前11位元組必須匹配二進位制的一個硬編碼值,後16個位元組必須是二進位制的MD5雜湊值減去這27個位元組所得到的值。

木馬維持

木馬的第一個功能就是設定一個Launch Agent(啟動代理)來維持木馬-每次使用者登入時,這個Launch Agent就會執行。木馬會把自己複製到~/Library/Logs/.Logs/corevideosd(如果木馬有root許可權,則會複製到/Library/Logs/.Logs/corevideosd),並在~/Library/LaunchAgents/com.google.plugins.plist(或/Library/LaunchAgents/com.google.plugins.plist)中建立一個Launch Agent plist來引用corevideosd可執行檔案。

除了使用“隱藏”目錄,木馬還會呼叫corevideosd檔案和com.google.plugins.plist檔案的chflags(檔名,UF_HIDDEN)。為了降低自己暴露的可能,木馬最後還會呼叫'xattr -d -r com.apple.quarantine "PATH to corevideosd"' 來移除corevideosd檔案上的審查擴充套件屬性(quarantine extended attribute)。如果Launch Agent已經執行,在重啟corevideosd之前,Launch Agent會使用命令“/bin/launchctl unload “/Library/LaunchAgents/com.google.plugins.plist”來解除安裝自己。

CC通訊

木馬會嘗試聯絡多個CC伺服器(C2)來獲取命令和其他有效載荷。木馬首先會使用HTTP連線埠80上的第一個C2:kiifd[.]pozon7[.]net。下面的例子就是一個check-in請求:

p5

在這裡,1AD6A35F4C2D73593912F9F9E1A55097是IOPlatformUUID的MD5雜湊。IOPlatformUUID是透過執行下面的OS X命令獲取到的:

#!bash
/usr/sbin/ioreg -rd1 -c IOPlatformExpertDevice | grep 'IOPlatformUUID'

這個UUID還會寫到本地的~/Library/Preferences/.fDTYuRs。在寫入磁碟之前,UUID還要經過XOR加密,使用的秘鑰是“pth”。

目前,kiifd[.]pozon7[.]net已經下線了,但是如果C2能夠聯絡到木馬,木馬就可以變更程式碼,從而下載和執行其他的有效載荷。木馬克制執行一個可執行檔案或開啟一個壓縮的應用程式包(.app應用)。

在聯絡了第一個C2後,木馬會檢查一個本地檔案~/Library/Parallels/.cfg(或/Library/Parallels/.cfg),獲取需要執行的可執行檔案或應用列表。從本質上來說,~/Library/Parallels/.cfg是一個”啟動專案(Startup Items)”檔案,在這個檔案中包含有木馬首次啟動時會執行的程式列表。雖然中方在報告中稱,OceanLotus MAC木馬能夠檢測出Parallels虛擬機器,但是我們持不同意見。OceanLotus MAC只是簡單地把隱藏的配置檔案儲存在了/Library/Parallels/目錄下。

接下來,木馬會請求連線一個“加密的”C2。首先,木馬會嘗試連線到shop[.]ownpro[.]net,但是,如果主機已經下線,木馬就會再連線pad[.]werzo[.]net。木馬的網路通訊是透過埠443實現的,但是沒有使用SSL。相反,資料使用了一個單位元組的XOR秘鑰-0x1B。在初始請求階段,受害者不會傳送任何關於受害主機的資訊。

在確定成功聯絡到C2時,木馬會為處理C2發來的命令做準備。首先,木馬會建立一個“保持活動”(keep-alive)執行緒,每分鐘“ping”一次C2。然後,木馬會收集下面的系統資訊和當前使用者資訊:

  • 產品名稱和版本(讀取自/System/Library/CoreServices/SystemVersion.plist)
  • 機器名稱
  • 是否是root使用者
  • 使用者的名稱(User’s name,讀取自pw_gecos)
  • 使用者名稱(username)
  • IOPlatformUUID的MD5雜湊(如果沒有找到IOPlatformUUID,則使用使用者名稱和機器名作為受害者的身份標識ID)

除了系統和使用者資訊,木馬會根據www.microsoft.com獲取當前時間。為了獲取時間資訊,木馬會傳送一個HTTP請求到www.microsoft.com,並解析響應中的Data標頭。實際上,在請求中存在一個錯誤-傳送到www.microsoft.com的請求是這樣的:

p6

你會發現,在請求中沒有任何路徑,並且伺服器響應了一個400。因為木馬只關心響應中的Data標頭,所以,這個有問題的請求也是可以用的。解析後的資料會轉換成epoch時間,並儲存在~/Library/Hash/.Hashtag/.hash (或/Library/Hash/.Hashtag/.hash)。在這裡,程式碼中還存在另一個錯誤,導致木馬會從~/Library/Hash/.hash中讀取時間資訊,而真正的目錄中應該有.HashTag。除了時間戳,值“th”和1也儲存在這個檔案中,所有的內容都使用了XOR加密,秘鑰是“camon”。

木馬會把系統資訊和使用者資訊傳送到C2,並最後建立一個執行緒來處理C2發來的命令。下面的轉儲就是加密的C2通訊:

p7

使用秘鑰0x1B解碼了系統資訊塊後,我們得到了下面的資料-加粗的部分是產品名稱,OS版本,使用者名稱,機器名和IOPlatformUUID的MD5雜湊。

\x02\x10\x00\x00\x00Mac OS X 10.10.5\x00\x02\x00\x00\x00av\t\x00\x00\x00lab _osx_1 \x00\x00\x001AD6A35F4C2D73593912F9F9E1A55097\xcb\xf2\x81V\x00\x00\x00\x00@\x00\x00\x00\x02\x00\x00\x00th\x00\x00\x00\x00

在向C2傳送了系統資訊和使用者資訊後,這個執行緒每秒都會嘗試讀取C2資訊,但是,C2似乎每隔5秒才會傳送一次資料。如果C2響應的資料中包含有命令指令,木馬就會執行某條命令。下面的這些字串是從二進位制檔案中解密獲得的,很可能屬於C2端的一個互動命令控制檯(console)。

p8

除了幾個命令之外,這些命令的作用都是一目瞭然的。

  • “exec”透過呼叫系統("open

相關文章