識別SigFlip生成的惡意文件

最近在移植 med0x2e/SigFlip 的過程中發現了一個有意思的點,可以用來作爲檢測的手段

在 SigFlip 項目的 Detect/Prevent 一節中作者有提到一些檢測防禦手段

https://docs.microsoft.com/en-us/security-updates/SecurityAdvisories/2014/2915720?redirectedfrom=MSDN

Once the patch is installed and proper registry keys are set, No system restarts are required, you only need to restart the Cryptographic Services. The Applocker service will be also restarted as it depends on the cryptographic services.(@p0w3rsh3ll)

Yara rule by Adrien; https://twitter.com/Int2e_/status/1330975808941330432

從 SigFlip 源碼中,其實也能發現一個點

SigFlip 依賴一串特定的字節來定位shellcode的位置,詳見 Native/SigLoader/SigLoader/SigLoader.cpp#L102Native/SigFlip/SigFlip/SigFlip.cpp#L232

for (_index = 0; _index < _CertTableSize; _index++) {
		if (*(_pePtr + _index) == 0xfe && *(_pePtr + _index + 1) == 0xed && *(_pePtr + _index + 2) == 0xfa && *(_pePtr + _index + 3) == 0xce) {
			printf("[*]: Tag Found 0x%x%x%x%x", *(_pePtr + _index), *(_pePtr + _index+1), *(_pePtr + _index+2), *(_pePtr + _index+3));
			_dataOffset = _index + 8;
			break;
		}
	}
memcpy(_encryptedData, "\xFE\xED\xFA\xCE\xFE\xED\xFA\xCE", 8);
crypt((unsigned char*)_data, _dataSize, _key, _keySize, (unsigned char*)_encryptedData + 8);

也就是說我們在證書表中定位到 \xFE\xED\xFA\xCE\xFE\xED\xFA\xCE 這段特徵就可以斷定它疑似 SigFlip 生成的 payload 了,想要更精準一些可以結合 https://twitter.com/Int2e_/status/1330975808941330432 中提到的長度特徵。

另外很有意思的一點是,這個項目是有問題的(截至20211103 commit e24a1fc),詳見 Native/SigFlip/SigFlip/SigFlip.cpp#L164Native/SigFlip/SigFlip/SigFlip.cpp#L260,很多情況下該項目根本沒法正常使用,因爲pe文件的RVA和FOA之間的關係作者並沒有進行處理,只有當pe文件中的 ~~SectionAlignment~~~~FileAlignment~~ 一樣時,RVA纔等於FOA,導致的結果是,可能使用工具後簽名會失效。錯誤的位置,加上上面的特徵碼,這個更加是一個強特徵了。公雞隊之家修改後的 CrackerCat/sigFile 也沒有修正這個bug。

上面是我莽撞了,IMAGE_DIRECTORY_ENTRY_SECURITY 這個結構的 VirtualAddress 就是相對於文件開頭的偏移,可參見 Does DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress actually mean file offset?SigThief 的相關實現,所以這個並不是bug

另外還有一個bug,注意在 Native/SigFlip/SigFlip/SigFlip.cpp#L149-L159

//Security entry seems to be located at the 7th offset (Data_Dir) for For x64 PE files, and the 5th offset for x86 PE files. just a quick workaround to make the script work for different PE archs.
if (IsWow64(GetCurrentProcess())) {
	if (_optHeader.Magic == 0x20B) {
		_DT_SecEntry_Offset = 2;
	}
}
else {
	if (_optHeader.Magic == 0x10B) {
		_DT_SecEntry_Offset = -2;
	}
}
...
//Get IMAGE_DIRECTORY_ENTRY_SECURITY field and retrieve the RVA and SIZE of the Certificate Table (WIN_CERTIFICATE).
_CertTableRVA = _optHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY + _DT_SecEntry_Offset].VirtualAddress;
_CertTableSize = _optHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY + _DT_SecEntry_Offset].Size;

但是實際上看到的基本都是 IMAGE_DIRECTORY_ENTRY_SECURITY 在第五個,而沒有他這裏的情況,並且就算是有這種情況,註釋和代碼寫得也不相符。

最後一句,Native跑不起來,DotNet的實現是正確的

最後的 yara 規則大家可以自己研究下

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章