Qakbot ์ ์ฑ์ฝ๋ ๋ถ์ ๋ง์ง๋ง ํฌ์คํ ์ ๋๋ค.
์ด๋ฒ ํฌ์คํ ์์๋ ์ ์ฑ์ฝ๋๊ฐ C2 ํต์ ํ๋ ๊ณผ์ ๊ณผ ํ์ง ํํผ ๋ฐ ์ง์์ฑ์ ํ๋ณดํ๋ ๋ถ๋ถ์ ๋ถ์ํด๋ณด๊ฒ ์ต๋๋ค.
์ํ ํด์(SHA256)๋ 73e4969db4253f9aeb2cbc7462376fb7e26cc4bb5bd23b82e2af0eaaf5ae66a8์ ๋๋ค.
[๊ณต๊ฐํค ๋ณตํธ]
๋ถ์ ์ค ์ ์ฑ์ฝ๋๊ฐ Crypto API๋ฅผ ํธ์ถํ๋ ๋ถ๋ถ์ ๋ฐ๊ฒฌํ์ต๋๋ค.
ํด๋น ์๋ธ๋ฃจํด์ธ sub_100084AF์ ๋ค์ด๊ฐ๋ณด๊ฒ ์ต๋๋ค.
sub_100084AF ์๋ธ๋ฃจํด ๋ด๋ถ์์ ์ํธ ๊ด๋ จ API๋ค์ ํธ์ถํ๊ณ ์์ต๋๋ค.
- CryptDecodeObjectEx
- ์ฃผ์ด์ง ์ธ์ฝ๋ฉ๋ ๋ฐ์ดํฐ๋ฅผ ์ง์ ๋ ๊ตฌ์กฐ์ฒด ํ์์ผ๋ก ๋์ฝ๋ฉํ๋๋ฐ ์ฌ์ฉ
- ์ฃผ์ด์ง ์ธ์ฝ๋ฉ๋ ๋ฐ์ดํฐ๋ฅผ ์ง์ ๋ ๊ตฌ์กฐ์ฒด ํ์์ผ๋ก ๋์ฝ๋ฉํ๋๋ฐ ์ฌ์ฉ
- CryptDecodeObjectEx ํจ์ ๊ตฌ์กฐ
BOOL CryptDecodeObjectEx(
DWORD dwCertEncodingType, // ์ธ์ฝ๋ฉ ํ์
์ง์
LPCSTR lpszStructType, // ๋์ฝ๋ฉํ ๋ฐ์ดํฐ์ ๊ตฌ์กฐ์ฒด ํ์ ์ง์
const BYTE *pbEncoded, // (๋์ฝ๋ฉํ ) ์ธ์ฝ๋ฉ๋ ๋ฐ์ดํฐ์ ๋ํ ํฌ์ธํฐ
DWORD dwEncodedSize, // ์ธ์ฝ๋ฉ๋ ๋ฐ์ดํฐ์ ํฌ๊ธฐ
DWORD dwFlags, // ๋์ฝ๋ฉ ์์
๊ด๋ จ ์์
(ex. ๋ฉ๋ชจ๋ฆฌ ์๋ ํ ๋น ์ฌ๋ถ, ์ ํจ์ฑ ๊ฒ์ฌ ์ฌ๋ถ ๋ฑ)
PCRYPT_DECODE_PARA pDecodePara, // ๋์ฝ๋ฉ ์์
์ ๋ํ ์ถ๊ฐ ์ ๋ณด
void *pvStructInfo, // ๋์ฝ๋ฉ ์ ๋ณด๋ฅผ ์ ์ฅํ ๊ตฌ์กฐ์ฒด์ ํฌ์ธํฐ
DWORD *pdwStructInfo // ๋ฐํ๋ ๊ตฌ์กฐ์ฒด์ ํฌ๊ธฐ(๋ณ์)์ ํฌ์ธํฐ
);
- CryptAcquireContext
- ์ํธํ ์๋น์ค๋ฅผ ์ ๊ณตํ๋ ํ๋ก๋ฐ์ด๋(CSP)๋ฅผ ํ๋ํ๋๋ฐ ์ฌ์ฉ
- ์ํธํ ์๋น์ค๋ฅผ ์ ๊ณตํ๋ ํ๋ก๋ฐ์ด๋(CSP)๋ฅผ ํ๋ํ๋๋ฐ ์ฌ์ฉ
- CryptAcquireContext ํจ์ ๊ตฌ์กฐ
BOOL CryptAcquireContext(
HCRYPTPROV *phProv, // ํ๋ก๋ฐ์ด๋ ํธ๋ค
LPCSTR pszContainer, // ์ปจํ
์ด๋ ์ด๋ฆ (NULL์ด๋ฉด ๊ธฐ๋ณธ ์ปจํ
์ด๋ ์ฌ์ฉ)
LPCSTR pszProvider, // ํ๋ก๋ฐ์ด๋ ์ด๋ฆ (NULL์ด๋ฉด ๊ธฐ๋ณธ ํ๋ก๋ฐ์ด๋ ์ฌ์ฉ)
DWORD dwProvType, // ํ๋ก๋ฐ์ด๋ ์ ํ
DWORD dwFlags // ํ๋๊ทธ
);
- CryptImportPublicKeyInfo
- ๊ณต๊ฐ ํค ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋๋ฐ(import) ์ฌ์ฉ
- ์ฃผ๋ก X.509 ์ธ์ฆ์์์ ๊ณต๊ฐ ํค๋ฅผ ์ถ์ถํ์ฌ ์ด๋ฅผ ์ํธํ ์์
์ ์ฌ์ฉ
- CryptImportPublicKeyInfo ํจ์ ๊ตฌ์กฐ
BOOL CryptImportPublicKeyInfo(
DWORD dwCertEncodingType, // ์ธ์ฝ๋ฉ ํ์
PCERT_PUBLIC_KEY_INFO pki, // ๊ณต๊ฐ ํค ์ ๋ณด ๊ตฌ์กฐ์ฒด
HCRYPTKEY *phKey // ๋ฐํ๋ ๊ณต๊ฐ ํค ํธ๋ค
);
- CryptCreateHash
- ํด์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋๋ฐ ์ฌ์ฉ
- ํด์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋๋ฐ ์ฌ์ฉ
- CryptCreateHash ํจ์ ๊ตฌ์กฐ
BOOL CryptCreateHash(
HCRYPTPROV *phProv, // ํ๋ก๋ฐ์ด๋ ํธ๋ค
ALG_ID Algid, // ํด์ ์๊ณ ๋ฆฌ์ฆ์ ์๋ณ์
HCRYPTKEY hKey, // (์ ํ ์ฌํญ) ์ํธํ ํค (์ผ๋ถ ์๊ณ ๋ฆฌ์ฆ์๋ง ํ์)
DWORD dwFlags, // ํ๋๊ทธ (์: CryptCreateHash ๋์ ์ ์ด)
HCRYPTHASH *phHash // ํด์ ๊ฐ์ฒด ํธ๋ค (์ถ๋ ฅ ํ๋ผ๋ฏธํฐ)
);
- CryptHashData
- ํด์ ๊ฐ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ์
๋ ฅํ์ฌ ํด์ ๊ฐ์ ๊ณ์ฐํ๋๋ฐ ์ฌ์ฉ
- ํด์ ๊ฐ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ์
๋ ฅํ์ฌ ํด์ ๊ฐ์ ๊ณ์ฐํ๋๋ฐ ์ฌ์ฉ
- CryptHashData ํจ์ ๊ตฌ์กฐ
BOOL CryptHashData(
HCRYPTHASH hHash, // ํด์ ๊ฐ์ฒด ํธ๋ค
const BYTE *pbData, // ํด์ฑํ ๋ฐ์ดํฐ
DWORD dwDataLen, // ๋ฐ์ดํฐ ๊ธธ์ด
DWORD dwFlags // ํ๋๊ทธ
);
- CryptVerifySignatureA
- ๋์งํธ ์๋ช
๊ฒ์ฆ์ ์ํํ๋๋ฐ ์ฌ์ฉ
- ๋์งํธ ์๋ช
๊ฒ์ฆ์ ์ํํ๋๋ฐ ์ฌ์ฉ
- CryptVerifySignatureA ํจ์ ๊ตฌ์กฐ
BOOL CryptVerifySignatureA(
PCCERT_CONTEXT pCertContext, // ์๋ช
์ ์ธ์ฆ์์ ์ปจํ
์คํธ
const BYTE *pbSignature, // ๋์งํธ ์๋ช
DWORD dwSigLen, // ์๋ช
์ ๊ธธ์ด
const BYTE *pbData, // ์๋ช
๊ฒ์ฆ ๋์ ๋ฐ์ดํฐ
DWORD dwDataLen, // ๊ฒ์ฆ ๋์ ๋ฐ์ดํฐ์ ๊ธธ์ด
LPCSTR szProvider // (์ ํ ์ฌํญ) ํ๋ก๋ฐ์ด๋ ์ด๋ฆ
);
sub_100084AF ์๋ธ๋ฃจํด์ Crypto API๋ฅผ ์ด์ฉํ์ฌ C2 ํต์ ๊ณผ ๊ด๋ จ๋ ๊ณต๊ฐ ํค๋ฅผ ์ฒ๋ฆฌํ๊ณ ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ 36๋ฒ์งธ ์ค์์๋ ์ํธํ๋ ๋ฌธ์์ด๋ค์ XOR ์ฐ์ฐํฉ๋๋ค. XOR ์ฐ์ฐ๋๋ ์ํธํ๋ ๋ฐ์ดํฐ mw_encrypted_string_1๋ .data ์น์ ์ ์ ์ฅ๋์ด ์๊ณ , ํค mw_encrypted_string_2๋ .rdata ์น์ ์ ์ ์ฅ๋์ด ์์ต๋๋ค.
์ด ์ํธํ๋ ๋ฐ์ดํฐ๋ฅผ Python ์คํฌ๋ฆฝํธ๋ฅผ ์ด์ฉํ์ฌ ๋ณตํธํํด๋ณด๊ฒ ์ต๋๋ค. (Alexandre Borges์ "Malware Analysis Series(MAS) – Article 2" ์ฐธ์กฐ)
import pefile
import binascii
from Crypto.IO import PEM
data_seg_start = ''
rdata_seg_start = ''
# Decrypter routine used to decode the stored data.
def simple_decrypter(data_string, data_key):
decoded = ''
for i in range(0, len(data_string)):
decoded += chr((data_string[i]) ^ (data_key[i % len(data_key)]))
return (binascii.b2a_hex(decoded.encode('latin-1')))
# Routine responsible for extracting encoded bytes from .data section.
def extract_data(filename):
pe = pefile.PE(filename)
for section in pe.sections:
if '.data' in section.Name.decode(encoding='utf-8').rstrip('x00'):
return (section.get_data(section.VirtualAddress, section.SizeOfRawData))
# Routine responsible for extracting encoded bytes from .rdata section
def extract_rdata(filename):
pe2 = pefile.PE(filename)
for section2 in pe2.sections:
if 'rdata' in section2.Name.decode(encoding='utf-8').rstrip('x00'):
return (section2.get_data((section2.VirtualAddress + 0x168), section2.SizeOfRawData))
# This routine calculates the offset from start of the section until the address of the data.
def calc_offsets(x_seg_start, x_start):
data_offset = hex(int(x_start, 16) - int(x_seg_start, 16))
return data_offset
def main():
data_2 = b''
rdata_2 = b''
# Defines start of each section (.data and .rdata section) and encrypted data (data and key).
data_seg_start = '0x1001D000'
rdata_seg_start = '0x10018168'
data_start = '0x1001E528'
rdata_start = '0x1001B868'
# Calculates offset of data and key related to the start of each respective section.
data_rel = calc_offsets(data_seg_start, data_start)
rdata_rel = calc_offsets(rdata_seg_start, rdata_start)
# Defines a varialbe to hold the sample's path
filename = r"C:\Users\user\Desktop\mas2_sample_unpack\rundll32_047A0000_from_VirtualProtect.bin"
# Call extract routine to fetch all necessary bytes from .data and .rdata section.
data_1 = extract_data(filename)
rdata_1 = extract_rdata(filename)
# Looking for the end of data and key bytes.
d_off = 0x0
rd_off = 0x0
if (b'\x00\x00' in data_1[int(data_rel, 16):]):
d_off = (data_1[int(data_rel, 16):]).index(b'\x00\x00')
if (b'\x00\x00' in rdata_1[int(rdata_rel, 16):]):
rd_off = (rdata_1[int(rdata_rel, 16):]).index(b'\x00\x00')
# Collects encrypted data and key.
data_2 = data_1[int(data_rel, 16):int(data_rel, 16) + d_off]
rdata_2 = rdata_1[int(rdata_rel, 16):int(rdata_rel, 16) + d_off]
# Calls function responsible for decoding the encrypted data.
decoded_data = simple_decrypter(data_2, rdata_2)
# Format the extracted data as a public key in PEM Format.
marker = "RSA PUBLIC KEY"
pem_key = PEM.encode(decoded_data, marker, passphrase=None, randfunc=None)
print(pem_key)
if __name__ == '__main__':
main()
RSA ๊ณต๊ฐ ํค๊ฐ ์ ๋ณตํธํ๋์์ต๋๋ค.
[C2 ํต์ ์ค๋น]
๋ ๋ค๋ฅธ ์๋ธ๋ฃจํด sub_1000D9B1์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
ํด๋น ์๋ธ๋ฃจํด ๋ด๋ถ์์ mw_w_decode_string_table_1 ์๋ธ๋ฃจํด์ ํตํด ๋ณตํธํํ๋ ๋ฌธ์์ด์ด ์์ต๋๋ค. ‘SELECT * FROM Win32_OperatingSystem’๊ณผ ‘ROOT\CIMv2’ ๊ฐ์ด WMI์ ๊ด๋ จ๋ ๋ฌธ์์ด์ ๋๋ค.
- WMI (Windows Management Instrumentation)
- Microsoft Windows ์ด์์ฒด์ ์์ ์ ๊ณตํ๋ ๊ด๋ฆฌ ๋ฐ ๋ชจ๋ํฐ๋ง ์์คํ
- ์์คํ ๊ด๋ฆฌ ๋ฐ ์ ๋ณด ์์ง, ๋ชจ๋ํฐ๋ง, ์ ์ด ๋ฑ์ ์ํ ํ๋ ์์ํฌ
- ์์คํ ํ๋์จ์ด, ์ํํธ์จ์ด, ๋คํธ์ํฌ, ํ๋ก์ธ์ค ๋ฐ ๋ค๋ฅธ ์์คํ ์์์ ๋ํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ฉฐ, ์์คํ ๊ด๋ฆฌ์๋ ๊ฐ๋ฐ์๊ฐ ์๊ฒฉ์ง์์ ์์คํ ์ ๋ชจ๋ํฐ๋งํ๊ณ ์ ์ดํ ์ ์๋๋ก ์ง์
๋ค๋ฅธ ์ ๋ณด๋ฅผ ์ป๊ธฐ ์ํด 12๋ฒ์งธ ์ค์ mw_COM_IWbemLocator (sub_1000D6D0) ์๋ธ๋ฃจํด์ ๋ถ์ํด๋ณด๊ฒ ์ต๋๋ค.
12๋ฒ์งธ ์ค์ rclsid์ riid๋ฅผ ๋ฐ๊ฒฌํ์ต๋๋ค.
- RCLSID(Reference to Class Identifier): CLSID๋ฅผ ์ฐธ์กฐํ๋ ํฌ์ธํฐ
- CLSID(Class Identifier): COM ๊ฐ์ฒด์ ํด๋์ค๋ฅผ ์๋ณํ๋ GUID(Globally Unique Identifier)
- CLSID(Class Identifier): COM ๊ฐ์ฒด์ ํด๋์ค๋ฅผ ์๋ณํ๋ GUID(Globally Unique Identifier)
- RIID(Reference to Interface Identifier): IID๋ฅผ ์ฐธ์กฐํ๋ ํฌ์ธํฐ
- IID(Interface Identifier ID): COM ๊ฐ์ฒด์ ์ธํฐํ์ด์ค๋ฅผ ์๋ณํ๋ GUID
๋ฐ๊ฒฌํ ID ์ ๋ณด๋ ํด๋์ค ID: 4590F811-1D3A-11D0-891F-00AA004B2E24, ์ธํฐํ์ด์ค ID: DC12A687-737F-11CF-884D-00AA004B2E24์ ๋๋ค.
ํด๋์ค ID๋ Microsoft Management Console (MMC) ActiveX Control๋ฅผ ๋ํ๋ด๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
- Microsoft Management Console (MMC) ActiveX Control
- Microsoft Management Console (MMC): Windows์์ ์์คํ ๊ด๋ฆฌ ๋ฐ ๊ด๋ฆฌ ๋๊ตฌ๋ฅผ ์ ๊ณตํ๋ ํ๋ ์์ํฌ
- ActiveX Control: ์น ๋ธ๋ผ์ฐ์ ๋ ์์ฉ ํ๋ก๊ทธ๋จ์์ ๋ค์ํ ๋์ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ์ํํธ์จ์ด ์ปดํฌ๋ํธ
- MMC ๊ธฐ๋ฐ์ ๊ด๋ฆฌ ๋๊ตฌ์ ๊ด๋ จ๋ ์น ๊ด๋ฆฌ ๊ธฐ๋ฅ์ ์ ๊ณต
- ์์คํ ๊ด๋ฆฌ ๋๋ ์๊ฒฉ ๊ด๋ฆฌ์ ๊ด๋ จ๋ ์์ ์์ ์ฌ์ฉ
๋ํ ์ธํฐํ์ด์ค ID๋ IWbemLocator ์ธํฐํ์ด์ค๋ฅผ ์ฐธ์กฐํ๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
- IWbemLocator
- WMI์์ ์ฌ์ฉ๋๋ COM ์ธํฐํ์ด์ค๋ก ์์คํ ๊ด๋ฆฌ, ์ํ ๋ชจ๋ํฐ๋ง ๋ฐ ์๋ํ๋ฅผ ์ํ API
- ํด๋ผ์ด์ธํธ ์ ํ๋ฆฌ์ผ์ด์ ์ด WMI ๋ค์์คํ์ด์ค์ ์ฐ๊ฒฐํ๊ณ WMI ์๋น์ค์ ์ ๊ทผํ ์ ์๋๋ก ์ง์
์ด ์ ๋ณด๋ฅผ ํ ๋๋ก ppv์ ptr_buffer ํ์ ์ ๋ฐ๊ฟ ์ฝ๋๋ฅผ ์ดํดํ๊ธฐ ์ฝ๊ฒ ๋ง๋ค์์ต๋๋ค.
14๋ฒ์งธ ์ค์ ConnectServer ๋ฉ์๋๋ฅผ ๋ฐ๊ฒฌํ ์ ์์ต๋๋ค.
- ConnectServer
- WMI ๋ค์์คํ์ด์ค์ ์ฐ๊ฒฐํ๊ณ , ์ฐ๊ฒฐ๋ IWbemServices ์ธํฐํ์ด์ค๋ฅผ ๋ฐํ
- ํด๋น ๋ฉ์๋๋ฅผ ํตํด WMI ์๋น์ค ์ฐ๊ฒฐ์ ์ค์ ํ์ฌ WMI ์์
์ ์ํ
- ConnectServer ํจ์ ๊ตฌ์กฐ
HRESULT ConnectServer(
const BSTR strNetworkResource, // ๋คํธ์ํฌ ๋ฆฌ์์ค
const BSTR strUser, // ์ฌ์ฉ์ ์ด๋ฆ
const BSTR strPassword, // ๋น๋ฐ๋ฒํธ
const BSTR strLocale, // ์ง์ญ ์ค์
long lSecurityFlags, // ๋ณด์ ํ๋๊ทธ
const BSTR strAuthority, // ์ธ์ฆ ์ ๋ณด
IWbemContext* pCtx, // WMI ์ปจํ
์คํธ
IWbemServices** ppServices // ์ฐ๊ฒฐ๋ WMI ์๋น์ค ๊ฐ์ฒด ๋ฐํ
);
IWbemLocator ์ธํฐํ์ด์ค๋ IWbemLocator::ConnectServer ๋ฉ์๋๋ฅผ ํตํด WMI ๋ค์์คํ์ด์ค์ ์ฐ๊ฒฐ์ ์์ฑํ๊ณ , ๋ฐํ๋๋ IWbemServices๋ฅผ ํตํด WMI ์ฟผ๋ฆฌ๋ ์์ ์ ์คํํ๋๋ฐ ์ฌ์ฉํฉ๋๋ค.
์ฒ์์ ๋ณธ 'ROOT\CIMv2’ ๋ฌธ์์ด์ ConnectServer์ ์ฒซ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์ธ strNetworkResource๋ฅผ ํตํด ์ ๋ฌ๋๋๋ฐ, ํด๋น ํ๋ผ๋ฏธํฐ๋ WMI ๋ค์์คํ์ด์ค์ ๊ฐ์ฒด ๊ฒฝ๋ก๋ฅผ ํฌํจํ๋ ๋คํธ์ํฌ ๋ฆฌ์์ค๋ฅผ ์๋ฏธํฉ๋๋ค.
mw_COM_IWbemLocator์ ๋ํผ ํจ์์ธ sub_1000DCE9 (mw_w_COM_IWbemLocator) ์๋ธ๋ฃจํด์ ๋ค์ด๊ฐ๋ณด๊ฒ ์ต๋๋ค.
IWbemLocator์ธ ๊ฒ์ ํ์ ํ์ผ๋ ๋ณ์ ํ์ ๊ณผ ์ด๋ฆ์ ๊ทธ์ ๋ง๊ฒ ๋ฐ๊ฟ์ค์ ๊ฐ๋ ์ฑ์ ๋์ฌ๋ณด๊ฒ ์ต๋๋ค.
49๋ฒ์งธ ์ค์ mw_COM_IWbemLocator ํจ์ ๊ฒฐ๊ณผ ํ์ ์ IWbemServices *์ด๋ฏ๋ก result ๋ณ์ ํ์ ์ IWbemServices *์ผ๋ก ๋ณ๊ฒฝํด์ฃผ์์ต๋๋ค.
๋ํ 80๋ฒ์งธ ์ค์ v7 ๋ณ์ ํ์ ์ IWbemServices **๋ก ๋ณ๊ฒฝํด์ฃผ๋ฉด ์๋ ๊ทธ๋ฆผ์ 82๋ฒ์งธ ์ค์์ IWbemServices::ExecQuery๊ฐ ํธ์ถ๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
- ExecQuery
- WMI์ ๋ํด ์ง์ํ์ฌ ๊ทธ ๊ฒฐ๊ณผ๋ก ๋ฐํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ๋ฉ์๋
- WMI์ ๋ํด ์ง์ํ์ฌ ๊ทธ ๊ฒฐ๊ณผ๋ก ๋ฐํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ๋ฉ์๋
- ExecQuery ํจ์ ๊ตฌ์กฐ
HRESULT ExecQuery(
const BSTR strQueryLanguage, // ์ฟผ๋ฆฌ ์ธ์ด๋ฅผ ์ง์ ํ๋ ๋ฌธ์์ด
const BSTR strQuery, // ์คํํ ์ฟผ๋ฆฌ ๋ฌธ์์ด
long lFlags, // ์ฟผ๋ฆฌ ์คํ์ ๋ํ ํ๋๊ทธ
IWbemContext *pCtx, // IWbemContext ๊ฐ์ฒด์ ๋ํ ํฌ์ธํฐ
IWbemObjectSet **ppResults // ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ด์ IWbemObjectSet์ ๋ํ ํฌ์ธํฐ
);
76๋ฒ์งธ ์ค์์ ๋ฌธ์์ด ๋ณตํธํ ๋ฃจํด์ ํตํด 'WQL' ๋ฌธ์์ด์ด ๋ณตํธํ๋์๋๋ฐ ์ด๋ WMI์์ ์ฌ์ฉํ๋ ์ฟผ๋ฆฌ ์ธ์ด๋ก, ExecQuery์ ํ๋ผ๋ฏธํฐ๋ก ์ง์ ๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
82๋ฒ์งธ ์ค์์ ๋ณด์ด๋ฏ์ด ExecQuery์ ๋ฐํ๊ฐ ppEum์ IEumWbemClassObject **ํ์ ์ ๋๋ค. ppEum์ ์ด๋ฏธ ์ฐธ์กฐ๊ฐ ์๊ธฐ ๋๋ฌธ์ ppEum์ ํจ๊ป 84๋ฒ์งธ ์ค v9 ๋ณ์์ ํ์ ์ IEumWbemClassObject *์ผ๋ก ๋ณ๊ฒฝํด์ฃผ์์ต๋๋ค.
๊ทธ๋ฌ๋ฉด 91๋ฒ์งธ ์ค์ IEumWbemClassObject::Next ๋ฉ์๋๊ฐ ์ ๋ณด์ ๋๋ค.
- Next
- IWbemObjectSet์ ๊ฒฐ๊ณผ ๊ฐ์ฒด ์งํฉ์์ ๋ค์ ๊ฐ์ฒด๋ก ์ด๋ํ๊ฑฐ๋ ๋ค์ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐ ์ฌ์ฉ
- IWbemObjectSet์ ๊ฒฐ๊ณผ ๊ฐ์ฒด ์งํฉ์์ ๋ค์ ๊ฐ์ฒด๋ก ์ด๋ํ๊ฑฐ๋ ๋ค์ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐ ์ฌ์ฉ
- Next ํจ์ ๊ตฌ์กฐ
HRESULT Next(
long lTimeout, // ๋๊ธฐ ์๊ฐ (๋ฐ๋ฆฌ์ด ๋จ์, 0์ด๋ฉด ์ฆ์ ๋ฐํ)
long lNumObjectsRequested, // ์์ฒญํ ๊ฐ์ฒด์ ์
IWbemClassObject **ppObjects, // ๋ฐํ๋ ๊ฐ์ฒด๋ค์ ๋ฐฐ์ด
long *plNumObjectsReturned // ์ค์ ๋ฐํ๋ ๊ฐ์ฒด ์
);
Next๋ ๋น์ทํ๊ฒ ์ธ ๋ฒ์งธ ์ธ์์ธ v38์ ํ์ ์ด IWbemClassObject **์ด์ง๋ง ์ฐธ์กฐ๊ฐ ์กด์ฌํ๋ฏ๋ก, IWbemClassObject *์ผ๋ก ๋ณ๊ฒฝํด์ฃผ๊ฒ ์ต๋๋ค.
๊ทธ๋ฌ๋ฉด 99๋ฒ์งธ ์ค์ IWbemClassObject::GetNames์ 106๋ฒ์งธ ์ค์ Release ๋ฉ์๋๊ฐ ๋ณด์ ๋๋ค.
- GetNames
- WMI ํด๋์ค์ ์์ฑ ์ด๋ฆ์ ๊ฐ์ ธ์ค๋๋ฐ ์ฌ์ฉ
- GetNames ๋ฉ์๋๋ ๊ฐ ์์ฑ์ ๋ํด IWbemClassObject::Get ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ ๊ทผํ ์ ์๋๋ก ํจ
- GetNames ๋ฉ์๋๋ฅผ ํตํด ์์ฑ ์ด๋ฆ์ ๊ฐ์ ธ์ค๊ณ , Get ๋ฉ์๋๋ฅผ ํตํด ๊ฐ ์์ฑ์ ๊ฐ์ ๊ฐ์ ธ์ด
- GetNames ๋ฉ์๋๋ฅผ ํตํด ์์ฑ ์ด๋ฆ์ ๊ฐ์ ธ์ค๊ณ , Get ๋ฉ์๋๋ฅผ ํตํด ๊ฐ ์์ฑ์ ๊ฐ์ ๊ฐ์ ธ์ด
- GetNames ํจ์ ๊ตฌ์กฐ
HRESULT GetNames(
BSTR strQualifierType, // ์๊ฒฉ ์ ํ (๋ณดํต NULL์ ์ฌ์ฉ)
long lFlags, // ํ๋๊ทธ (๊ธฐ๋ณธ๊ฐ 0)
IWbemContext *pCtx, // ์ฟผ๋ฆฌ ์ปจํ
์คํธ (๊ธฐ๋ณธ๊ฐ NULL)
SAFEARRAY **pNames // ์์ฑ ์ด๋ฆ์ด ์ ์ฅ๋ SAFEARRAY ๋ฐฐ์ด
);
- Release
- COM ๊ฐ์ฒด์ ์ฐธ์กฐ ์นด์ดํธ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฉ์๋
- COM ์ธํฐํ์ด์ค์์ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉ๋จ
[๊ธฐํ ํ์ ๋ถ์]
โ ๋ ์ง์คํธ๋ฆฌ ์ค์
sub_1000A23A (mw_RC4_Reg) ์๋ธ๋ฃจํด ๋ด๋ถ๋ฅผ ๋ณด๋ ๋ ์ง์คํธ๋ฆฌ ๊ด๋ จ API๋ค์ด ๋ณด์ด๊ณ , ์ด์ ํฌ์คํ ์์ ๋ถ์ํ๋ SHA1 ๋ฐ RC4 ๊ด๋ จ ์๋ธ๋ฃจํด๋ค์ด ๋ณด์ ๋๋ค. ์ด๋ฅผ ํตํด ๋ ์ง์คํธ๋ฆฌ ํญ๋ชฉ์ ์๋ณตํธํํ๊ธฐ ์ํด ๋๊ฐ์ ์๋ณตํธํ ๋ฐฉ์(key → SHA1 → RC4)์ ์ฌ์ฉํ๊ณ ์๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
โ Defender ํ์ง ํํผ
์ด๊ธฐ ํค๋ sub_10004C5A ์๋ธ๋ฃจํด์์ ํผํด์์ ์ปดํจํฐ ์ด๋ฆ, ๊ณ์ , ๋ณผ๋ฅจ ์ ๋ณด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก SHA1 ํด์ ํจ์๋ฅผ ํตํด ์์ฑ๋ฉ๋๋ค.
๋ํ ๋ฌธ์์ด "SOFTWARE\Microsoft\Microsoft Antimalware\Exclusions\Paths"์ ๋ณตํธํํ๋ ๊ฒ์ผ๋ก ๋ณด์ ์ ์ฑ์ฝ๋ ์์ ์ Windows Defender์์ ์์ธ๋ก ์ค์ ํ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
โ ์ธ์ด(๊ตญ๊ฐ) ์ ๋ณด ์์ง
sub_10002E98 (mw_GetKeyBoardLayoutList) ์๋ธ๋ฃจํด์๋ GetKeyBoardLayoutList API๋ฅผ ํตํด ํค๋ณด๋ ๋ ์ด์์์ ํ์ธํ๋ ์ฝ๋๊ฐ ์์ต๋๋ค.
- GetKeyboardLayoutList
- ํ์ฌ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ ํค๋ณด๋ ๋ ์ด์์์ ๋ฐฐ์ด ํํ๋ก ๋ฐํ
ํค๋ณด๋ ๋ ์ด์์์ ํ์ธํ์ฌ 24-28๋ฒ์งธ ์ค์ ์ฐ์ฐ์ ํตํด ํผํด PC์ ์ธ์ด ์ค์ ์ ์์๋ด๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
์ ์ฑ์ฝ๋ ๊ฐ๋ฐ์๋ v6 ๋ฐฐ์ด์ ๊ตญ๊ฐ ๋ชฉ๋ก์ ๋ฏธ๋ฆฌ ์ง์ ํด๋๊ณ , ํด๋น ๊ตญ๊ฐ์ ์ธ์ด๋ฅผ ์ฌ์ฉํ๋ ์ฌ์ฉ์๋ผ๋ฉด ์ ์ฑ ํ์๋ฅผ ์งํํ๋๋ก ์ค์ ํ์์ต๋๋ค. ์ฃผ๋ก ๊ตฌ์๋ จ ๊ตญ๊ฐ๋ค๊ณผ ๊ด๋ จ์ด ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
LCID | ๊ตญ๊ฐ | ์ธ์ด |
0x4019 | ๋ฌ์์ (Russia) | ๋ฌ์์์ด |
0x4023 | ๋ฒจ๋ผ๋ฃจ์ค (Belarus) | ๋ฒจ๋ผ๋ฃจ์ค์ด |
0x403F | ์ฐํฌ๋ผ์ด๋ (Ukraine) | ์ฐํฌ๋ผ์ด๋์ด |
0x402C | ์นด์ํ์คํ (Kazakhstan) | ์นด์ํ์ด |
0x402B | ์์ ๋ฅด๋ฐ์ด์ (Azerbaijan) | ์์ ๋ฅด๋ฐ์ด์์ด |
0x4037 | ํ์งํค์คํ (Tajikistan) | ํ์งํฌ์ด |
0x4043 | ์ฐ์ฆ๋ฒ ํค์คํ (Uzbekistan) | ์ฐ์ฆ๋ฒก์ด |
0x4028 | ๋ชฝ๊ณจ (Mongolia) | ๋ชฝ๊ณจ์ด |
0x4042 | ์๊ตญ (United Kingdom) | ์์ด |
0x4022 | ๊ทธ๋ฃจ์ง์ผ (Georgia) | ๊ทธ๋ฃจ์ง์ผ์ด |
0x401A | ์๋ฅด๋ฉ๋์ (Armenia) | ์๋ฅด๋ฉ๋์์ด |
0x4040 | ์กฐ์ง์ (Georgia) | ์กฐ์ง์์ด |
โ Avast ํ์ง ํํผ ๋ฐ ์ง์์ฑ ํ๋ณด
sub_10004FB9 ์๋ธ๋ฃจํด์์๋ ๋ฌธ์์ด ๋ณตํธ ๋ฃจํด์ ํตํด aswhooka.dll, aswhokkx.dll ๋ฌธ์์ด์ ๋ณตํธํํ ํ, ํด๋น DLL๋ค์ ๋ํด ํธ๋ค์ ์ป๊ณ ์์ต๋๋ค. ํด๋น DLL๋ค์ ๋ณด์ ์ํํธ์จ์ด Avast์ ๊ด๋ จ์ด ์๊ธฐ ๋๋ฌธ์ ํธ๋ค์ ์ป์ด ๋ณด์ ํ๋ก๊ทธ๋จ์ ํ์ง ํํผ, ๋นํ์ฑํ ๋ฐ ์ ์ด ๋ฑ์ ํ์๋ฅผ ํ ๊ฒ์ผ๋ก ์ถ์ธก๋ฉ๋๋ค.
๋ํ ์์ ์ค์ผ์ค ์ค์ ๊ณผ ๊ด๋ จ๋ "C:\Windows\system32\schtasks.exe” /Create /RU "NT AUTHORITY\SYSTEM" /tn <random name> /tr <program path> /SC ONCE /Z /ST <(start)hour:min> /ET <(terminate)hour:min>, regsvr32.exe -s ๋ฌธ์์ด์ ๋ณตํธํํ๊ณ , 152๋ฒ์งธ ์ค์์ mw_CreateProcess (sub_1000AAC1)๋ฅผ ํธ์ถํ์ฌ ์ค์ผ์ค ๋ช ๋ น์ ํ๋ก์ธ์ค๋ก ์คํํฉ๋๋ค. ์ด๋ ๊ฒ ์ง์์ฑ์ ํ๋ณดํ๋ ๋ถ๋ถ๋ ํ์ธํ์์ต๋๋ค.
์๋๋ mw_CreateProcess ์๋ธ๋ฃจํด์ ๋๋ค.
- CreateProcessW
- ์๋ก์ด ํ๋ก์ธ์ค๋ฅผ ์์ฑ
- ์ ๋์ฝ๋ ๋ฌธ์์ด์ ์ฌ์ฉํ๋ ๋ฒ์
- CreateProcess: ANSI ๋ฌธ์์ด์ ์ฌ์ฉํ๋ ๋ฒ์
- CreateProcess: ANSI ๋ฌธ์์ด์ ์ฌ์ฉํ๋ ๋ฒ์
- CreateProcessW ํจ์ ๊ตฌ์กฐ
BOOL CreateProcessW(
LPCWSTR lpApplicationName, // ์คํํ ์ ํ๋ฆฌ์ผ์ด์
์ ๊ฒฝ๋ก (์ ๋์ฝ๋ ๋ฌธ์์ด)
LPWSTR lpCommandLine, // ์คํํ ๋ช
๋ น ์ค (์ ๋์ฝ๋ ๋ฌธ์์ด)
LPSECURITY_ATTRIBUTES lpProcessAttributes, // ํ๋ก์ธ์ค ๋ณด์ ์์ฑ (NULL์ด๋ฉด ๊ธฐ๋ณธ๊ฐ)
LPSECURITY_ATTRIBUTES lpThreadAttributes, // ์ค๋ ๋ ๋ณด์ ์์ฑ (NULL์ด๋ฉด ๊ธฐ๋ณธ๊ฐ)
BOOL bInheritHandles, // ๋ถ๋ชจ ํ๋ก์ธ์ค์ ํธ๋ค ์์ ์ฌ๋ถ (TRUE/FALSE)
DWORD dwCreationFlags, // ํ๋ก์ธ์ค ์์ฑ ํ๋๊ทธ (์: CREATE_NEW_CONSOLE)
LPVOID lpEnvironment, // ์ ํ๋ก์ธ์ค์ ํ๊ฒฝ ๋ณ์ (NULL์ด๋ฉด ๋ถ๋ชจ ํ๊ฒฝ ์ฌ์ฉ)
LPCWSTR lpCurrentDirectory, // ์ ํ๋ก์ธ์ค์ ํ์ฌ ๋๋ ํฐ๋ฆฌ (NULL์ด๋ฉด ๋ถ๋ชจ ๋๋ ํฐ๋ฆฌ ์ฌ์ฉ)
LPSTARTUPINFO lpStartupInfo, // ์ ํ๋ก์ธ์ค์ ์์ ์ ๋ณด (์ฐฝ ๋ชจ์ ๋ฑ ์ค์ )
LPPROCESS_INFORMATION lpProcessInformation // ์ ํ๋ก์ธ์ค์ ์ ๋ณด (ํธ๋ค, ํ๋ก์ธ์ค ID ๋ฑ ๋ฐํ)
);
Ref. "Malware Analysis Series(MAS) – Article 2", Alexandre Borges