Closed syyoo84 closed 1 year ago
Great find! I'm pretty sure this has been broken since I first implemented imphash in YARA back in 2014. I based it off the Mandiant blog post, which I'm pretty sure did not say anything about this case. Turns out the pefile code has been ignoring names that are empty strings, or otherwise evaluate to false in python, for at least the last 10 years (according to blame): https://github.com/erocarrera/pefile/blob/593d094e35198dad92aaf040bef17eb800c8a373/pefile.py#L5871-L5872
I've put up a fix for this along with a test case so we shouldn't regress on it in the future either.
Great find! I'm pretty sure this has been broken since I first implemented imphash in YARA back in 2014. I based it off the Mandiant blog post, which I'm pretty sure did not say anything about this case. Turns out the pefile code has been ignoring names that are empty strings, or otherwise evaluate to false in python, for at least the last 10 years (according to blame): https://github.com/erocarrera/pefile/blob/593d094e35198dad92aaf040bef17eb800c8a373/pefile.py#L5871-L5872
I've put up a fix for this along with a test case so we shouldn't regress on it in the future either.
Here's another case. If the IAT function name contains null bytes as well as a ' mark, it is ignored and an imphash hash is judged to be created. So yara imphash and pefile imphash are different. https://www.virustotal.com/gui/file/10fdf28e81f443299fb2753fa06065d2913d8275a322f27556728e6db32510e7/detai
import_details
[0]
library_name = "KERNEL32.dll"
number_of_functions = 91
functions
[0]
rva = 4120
ordinal = YR_UNDEFINED
name = "FoldStringW"
[1]
rva = 4124
ordinal = YR_UNDEFINED
name = "SetWaitaleTimer" [2] rva = 4128 ordinal = YR_UNDEFINED name = "WaitNamedPipeA" [3] rva = 4132 ordinal = YR_UNDEFINED name = "\x98omm\x98onfigDialogW" [4] rva = 4136 ordinal = YR_UNDEFINED name = "SetSystemTimeAdjustment" [5] rva = 4140 ordinal = YR_UNDEFINED name = "SearchPathA" [6] rva = 4144 ordinal = YR_UNDEFINED name = "EnumResourceTypesA" [7] rva = 4148 ordinal = YR_UNDEFINED name = "Get\x98PInfoExA" [8] rva = 4152 ordinal = YR_UNDEFINED name = "EnumResourceTypesW" [9] rva = 4156 ordinal = YR_UNDEFINED name = "GetModuleFileNameA" [10] rva = 4160 ordinal = YR_UNDEFINED name = "Write\x98onsoleOutput\x98haracterW" [11] rva = 4164 ordinal = YR_UNDEFINED name = "Get\x98onsoleAliasesLengthA" [12] rva = 4168 ordinal = YR_UNDEFINED name = "DeleteFileA" [13] rva = 4172 ordinal = YR_UNDEFINED name = "Fill\x98onsoleOutput\x98haracterW" [14] rva = 4176 ordinal = YR_UNDEFINED name = "D\x03LocalAlloc" [15] rva = 4180 ordinal = YR_UNDEFINED name = "GetProcAddress" [16] rva = 4184 ordinal = YR_UNDEFINED name = "GetModuleHandleW" [17] rva = 4188 ordinal = YR_UNDEFINED name = "LoadLi
raryW"
[18]
rva = 4192
ordinal = YR_UNDEFINED
name = "AddRefAct\x98tx"
[19]
rva = 4196
ordinal = YR_UNDEFINED
name = "Get\x98onsoleAliasW"
[20]
rva = 4200
ordinal = YR_UNDEFINED
name = "FindFirst\x98hangeNotificationA"
[21]
rva = 4204
ordinal = YR_UNDEFINED
name = "WritePrivateProfileStringW"
[22]
rva = 4208
ordinal = YR_UNDEFINED
name = "EnumResourceNamesA"
[23]
rva = 4212
ordinal = YR_UNDEFINED
name = "lstrcpynA"
[24]
rva = 4216
ordinal = YR_UNDEFINED
name = "AddAtomA"
[25]
rva = 4220
ordinal = YR_UNDEFINED
name = "Get\x98onsoleAliasesLengthW"
[26]
rva = 4224
ordinal = YR_UNDEFINED
name = "Free\x98onsole"
[27]
rva = 4228
ordinal = YR_UNDEFINED
name = "asesLengthW"
[28]
rva = 4232
ordinal = YR_UNDEFINED
name = "FindNextFileW"
[29]
rva = 4236
ordinal = YR_UNDEFINED
name = "SetPriority\x98lass"
[30]
rva = 4240
ordinal = YR_UNDEFINED
name = "Build\x98ommD\x98BAndTimeoutsW"
[31]
rva = 4244
ordinal = YR_UNDEFINED
name = "OpenJoO
jectW"
[32]
rva = 4248
ordinal = YR_UNDEFINED
name = "t\x98omputerNameExW"
[33]
rva = 4252
ordinal = YR_UNDEFINED
name = "FindResourceExW"
[34]
rva = 4256
ordinal = YR_UNDEFINED
name = "Set\x98onsoleMode"
[35]
rva = 4260
ordinal = YR_UNDEFINED
name = "_lclose"
[36]
rva = 4264
ordinal = YR_UNDEFINED
name = "Set\x98ommMask"
[37]
rva = 4268
ordinal = YR_UNDEFINED
name = "Get\x98onsoleTitleW"
[38]
rva = 4272
ordinal = YR_UNDEFINED
name = "\x98reateDirectoryExA"
[39]
rva = 4276
ordinal = YR_UNDEFINED
name = "HeapAlloc"
[40]
rva = 4280
ordinal = YR_UNDEFINED
name = "HeapSize"
[41]
rva = 4284
ordinal = YR_UNDEFINED
name = "HeapReAlloc"
[42]
rva = 4288
ordinal = YR_UNDEFINED
name = "Get\x98ommandLineW"
[43]
rva = 4292
ordinal = YR_UNDEFINED
name = "HeapSetInformation"
[44]
rva = 4296
ordinal = YR_UNDEFINED
name = "GetStartupInfoW"
[45]
rva = 4300
ordinal = YR_UNDEFINED
name = "IsProcessorFeaturePresent"
[46]
rva = 4304
ordinal = YR_UNDEFINED
name = "EncodePointer"
[47]
rva = 4308
ordinal = YR_UNDEFINED
name = "SetUnhandledExceptionFilter"
[48]
rva = 4312
ordinal = YR_UNDEFINED
name = "ExitProcess"
[49]
rva = 4316
ordinal = YR_UNDEFINED
name = "DecodePointer"
[50]
rva = 4320
ordinal = YR_UNDEFINED
name = "WriteFile"
[51]
rva = 4324
ordinal = YR_UNDEFINED
name = "GetStdHandle"
[52]
rva = 4328
ordinal = YR_UNDEFINED
name = "GetModuleFileNameW"
[53]
rva = 4332
ordinal = YR_UNDEFINED
name = "FreeEnvironmentStringsW"
[54]
rva = 4336
ordinal = YR_UNDEFINED
name = "GetEnvironmentStringsW"
[55]
rva = 4340
ordinal = YR_UNDEFINED
name = "SetHandle\x98ount"
[56]
rva = 4344
ordinal = YR_UNDEFINED
name = "Initialize\x98riticalSectionAndSpin\x98ount"
[57]
rva = 4348
ordinal = YR_UNDEFINED
name = "GetFileType"
[58]
rva = 4352
ordinal = YR_UNDEFINED
name = "Delete\x98riticalSection"
[59]
rva = 4356
ordinal = YR_UNDEFINED
name = "TlsAlloc"
[60]
rva = 4360
ordinal = YR_UNDEFINED
name = "TlsGetValue"
[61]
rva = 4364
ordinal = YR_UNDEFINED
name = "TlsSetValue"
[62]
rva = 4368
ordinal = YR_UNDEFINED
name = "TlsFree"
[63]
rva = 4372
ordinal = YR_UNDEFINED
name = "InterlockedIncrement"
[64]
rva = 4376
ordinal = YR_UNDEFINED
name = "SetLastError"
[65]
rva = 4380
ordinal = YR_UNDEFINED
name = "Get\x98urrentThreadId"
[66]
rva = 4384
ordinal = YR_UNDEFINED
name = "GetLastError"
[67]
rva = 4388
ordinal = YR_UNDEFINED
name = "InterlockedDecrement"
[68]
rva = 4392
ordinal = YR_UNDEFINED
name = "Heap\x98reate"
[69]
rva = 4396
ordinal = YR_UNDEFINED
name = "QueryPerformance\x98ounter"
[70]
rva = 4400
ordinal = YR_UNDEFINED
name = "GetTick\x98ount"
[71]
rva = 4404
ordinal = YR_UNDEFINED
name = "Get\x98urrentProcessId"
[72]
rva = 4408
ordinal = YR_UNDEFINED
name = "GetSystemTimeAsFileTime"
[73]
rva = 4412
ordinal = YR_UNDEFINED
name = "Get\x98PInfo"
[74]
rva = 4416
ordinal = YR_UNDEFINED
name = "GetA\x98P"
[75]
rva = 4420
ordinal = YR_UNDEFINED
name = "GetOEM\x98P"
[76]
rva = 4424
ordinal = YR_UNDEFINED
name = "IsValid\x98odePage"
[77]
rva = 4428
ordinal = YR_UNDEFINED
name = "UnhandledExceptionFilter"
[78]
rva = 4432
ordinal = YR_UNDEFINED
name = "IsDeuggerPresent" [79] rva = 4436 ordinal = YR_UNDEFINED name = "TerminateProcess" [80] rva = 4440 ordinal = YR_UNDEFINED name = "Get\x98urrentProcess" [81] rva = 4444 ordinal = YR_UNDEFINED name = "Leave\x98riticalSection" [82] rva = 4448 ordinal = YR_UNDEFINED name = "Enter\x98riticalSection" [83] rva = 4452 ordinal = YR_UNDEFINED name = "n" [84] rva = 4456 ordinal = YR_UNDEFINED name = "Sleep" [85] rva = 4460 ordinal = YR_UNDEFINED name = "RtlUnwind" [86] rva = 4464 ordinal = YR_UNDEFINED name = "RaiseException" [87] rva = 4468 ordinal = YR_UNDEFINED name = "Wide\x98harToMultiByte" [88] rva = 4472 ordinal = YR_UNDEFINED name = "L\x98MapStringW" [89] rva = 4476 ordinal = YR_UNDEFINED name = "MultiByteToWide\x98har" [90] rva = 4480 ordinal = YR_UNDEFINED name = "GetStringTypeW" [1] library_name = "USER32.dll" number_of_functions = 2 functions [0] rva = 4488 ordinal = YR_UNDEFINED name = "\x98lientToScreen" [1] rva = 4492 ordinal = YR_UNDEFINED name = "ScreenTo\x98lient" [2] library_name = "ADVAPI32.dll" number_of_functions = 4 functions [0] rva = 4096 ordinal = YR_UNDEFINED name = "\x98loseEventLog" [1] rva = 4100 ordinal = YR_UNDEFINED name = "DeregisterEventSource" [2] rva = 4104 ordinal = YR_UNDEFINED name = "GetNum
erOfEventLogRecords"
[3]
rva = 4108
ordinal = YR_UNDEFINED
name = "GetEventLogInformation"
[3]
library_name = "WINHTTP.dll"
number_of_functions = 2
functions
[0]
rva = 4500
ordinal = YR_UNDEFINED
name = "WinHttpSetTimeouts"
[1]
rva = 4504
ordinal = YR_UNDEFINED
name = "WinHttpReadData"
Ok, I'll take a look in a bit. Thanks for bringing it up!
Thanks for pointing these out! I've updated the PR to reflect this and I think we are now aligned with pefile (which I would argue is the definitive implementation of imphash and import parsing we should try to align with).
Thank you for your support. Thank you for being able to contribute to the Yara community by reporting bugs at NSHC Threat Research Lab.
Describe the bug yara imphash and pefile imphash are different So you can't use imphash in yara rule. Any reason? sha256: 803d740df04cc995fd7010473be6b06e190c7ca5114a525d951ae11e7394ab12 yara imphash: ecb1f45f310c2bf07612a019ce157b0f pefile imphash: b22fdcce4de8993adbff1ff244d1b4a5 https://www.virustotal.com/gui/file/803d740df04cc995fd7010473be6b06e190c7ca5114a525d951ae11e7394ab12/details
To Reproduce Steps to reproduce the behavior:
Expected behavior A clear and concise description of what you expected to happen.
Screenshots If applicable, add screenshots to help explain your problem.
Please complete the following information:
Additional context Add any other context about the problem here.