season-lab / bluepill

BluePill: Neutralizing Anti-Analysis Behavior in Malware Dissection (Black Hat Europe 2019, IEEE TIFS 2020)
GNU Lesser General Public License v3.0
120 stars 22 forks source link

An issue about Pin: INJECTOR_ERR_NO_ACTIVE_SERVER #5

Closed snbst-git closed 3 years ago

snbst-git commented 3 years ago

Hello @dcdelia Having read your paper On the Dissection of Evasive Malware , I'm quite interested in BluePill. However when I tried to run it on my PC, there were some issues, which might be caused by Pin. May I still ask you for help?

Setting up

To be brief, I make a few subtle changes both in BluePill and Pin. As the downloading page of Pin doesn't keep the official link of Pin 3.11, I used the link https://software.intel.com/sites/landingpage/pintool/downloads/pin-3.11-97998-g7ecce2dac-msvc-windows.zip inferred from searching results. And then, because I'm using Visual Studio 2017 and Windows SDK 10.0.17763.0, I had to convert the vsSolution of bluepill. That's to say:

  1. WinHPath from C:/Program Files(x86)/Windows Kits/8.1/Include/um to C:/Program Files (x86)/Windows Kits/10/Include/10.0.17763.0/um
  2. PlatformToolSets to Visual Studio 2017(v141) And then the compiling worked well, with bluepill32.dll generated.

    Problem

    At first, I directly ran pin.exe -t bluepill32.dll -evasions -leak -- example.exe. Then the log file evasions.log was generated, but it had only one line Starting analysis.... Actually the example wasn't really executed. Then, I also tried to run \intel64\bin\pin.exe -t bluepill32.dll -evasions -leak -- example.exe. Then the error message was as below, where I thought the type INJECTOR_ERR_NO_ACTIVE_SERVER matters.

    E: Failed to allocate Injector, Error = INJECTOR_ERR_NO_ACTIVE_SERVER
    E: Pin is exiting due to fatal error

    Other Pintools

    Also, I used cygwin(both 32/64-bit version) to compile \source\tools\ManualExamples through command make, in order to test other Pintools. I added several paths (of VS/Windows Kit) to the enviroment variables PATH, INCLUDE and LIB。Also, when using the link.exe of cygwin, it always failed because of the option/NODEFAULTLIB. So I renamed it as the suggestion. Take itrace.dll for example: pin.exe -t itrace.dll -- example.exe resulted in error message as below.

    Failure to map DLL C:\Pin311\itrace.dll
    E:       System error 216 :

    As for\intel64\bin\pin.exe -t itrace.dll -- example.exe , the result was the same no matter which dll I chose.

E: Failed to allocate Injector, Error = INJECTOR_ERR_NO_ACTIVE_SERVER
E: Pin is exiting due to fatal error

All in all, I don't think my pin works normally, which means I can't use bluepill then. I'm wondering if you ever meet this problem and how to solve it. Thank you for reading and it couldn't be better if you could give me some suggestions.

dcdelia commented 3 years ago

Hi @snbst-git and thanks for your interest in BluePill!

The build part seems okay. Intel tends to keep the links for the most recent versions only. I can confirm that up to Pin 3.15 (and VS2017) the setup described in the README works out of the box, while for Pin 3.16+ they altered some build components that need changes to the build options of the solution. I plan to write at some point an automatic configuration script to do that, so that our users can choose whether to stick to older (well-tested by us) Pin versions or try new ones.

I think your problem is related to mixing a 32-bit and 64-bit for two among {pintool, application, Pin runtime}. If you are testing 32-bit malware, just try ia32\bin\pin.exe when top-level pin.exe doesn't work. What you can also try is first checking if you are using the right pin.exe by running the program without any pintool attached (e.g. ia32\bin\pin.exe -- sample.exe) and then add the -t pintool.dll option to look for wrong DLL errors. Let me know if that helps!

snbst-git commented 3 years ago

Hello @dcdelia Thank you for replying so quickly. Actually what you said is the key, it's exactly the improper use of 32/64-bit version caused the issue. But sorrowfully, I can't run BluePill normally still.

Version

I've understood that it requires the version of {Pin runtime, Pintools, Application} to be the same 32/64-bit. So now pin works normally with a few pintools (opcodemix&itrace) loaded. If the versions of Pin and Pintools don't match, then Pin fails to map the dll. If the versions of Pin and Application don't match, then Pin fails to allocate Injector. Additionally, the version of top-level pin.exe relies on the application. (32/64-bit apps call the 32/64-bit pin.exe.) image

BluePill

Then I use 32-bit pin.exe&bluepill32.dll&application, it's weird that bluepill can't work normally. As described earlier, only the initial log Starting analysis... was generated, and the application didn't run. The application GetSystemTime.exe is a simple program calls API GetSystemTime in Kernel32/Kernalbase.dll. image image

Other PinTool

I also tried to compile other pintools, but the makefile seemed to generate obj-intel64 pintools only. So I haven't test any 32-bit pintool except blupill, that is, there is still probability that my pin doesn't work normally. When I manually make a ia-32 pintool with command make obj-ia32\itrace.dll TARGET=ia32 or all tools under a folder with make TARGET=ia32 , the compile always ended up with fatal error LNK1112: module machine type 'x86' conflicts with target machine type 'X64'. In addition, I also tried to use the solution PinTools.sln in \source\tools, which wasn't compiled successfully. But it should not be hard to solve.


The problem may be caused by my environment, which is not complicated but is quite tedious. If you have other suggestions, I'd love to test. Thank you for your help!

dcdelia commented 3 years ago

Thanks for the detailed filing, and apologies for the late reply this time! I am wondering whether this may be a Windows 10 related issue (we officially support Windows 7 at the moment, while extensions for 10 are on their way).

Can you confirm which Windows version are you using for your tests?

You may try to selectively comment out some portions of main.cpp in the main() function to help us pinpoint where the crash is happening. I'm suspecting line 240 with SYSHOOKING::Init(); but there are also some WMI-related parts that are specific to a Windows release. Try also commenting out line 243 for hooking of special instructions and 246-247 for API functions, but those should be mostly agnostic to the Windows version in use. I'll try to debug the code myself shortly.

snbst-git commented 3 years ago

Hello @dcdelia Thank you for replying! And I'm exactly using Win10, which caused the issue. And I'm now trying to use BluePill as a sandbo to log the behavior of sample.

Version

I have switched to Win7 Professional SP1 with KB4474419 installed (so that Visual Studio 2017 can be installed), both of WDK8.1/10.0.17763.0 works. And I can execute samples (which don't check the virtual environment) in both VMWare and VirtualBox.

Question

I'm sorry to ask this naive question without understanding the source code at first. To facilitate the progress of learning, I want to know what kind of information can bluepill log?

( I think there should be explicit techniques such as cpuid and NtQuerySystemInformation.)

Before collecting an evasive malware, I just tested a few simple samples ,which called the API listed in the supplementary material, and then check the evasions.log. But I don't know why nothing was recorded except the behavior LoadLibrary. image

Here are the Samples:

  1. NtQuerySystemInformation With parameter CLASS=3, the API retrieve information about time. Firstly, GetProcAddress was called to get the address of it from ntdll. Then it was called. But only loading library was logged, without NtQuerySystemInformation itself. image
  2. GetSystemTimeAsFileTime/GetSystemTime The latter was not listed in the table, but the former was. I just called it but nothing logged. image

    Another Sample

    In addition, I tested the sample Olympic with MD5 cfdd16225e67471f5ef54cab9b3a5558, which you used for evaluation. I excecuted it with the following evasions.log:

    Starting analysis...
    Loadlibrary within Windows DLL! Happening at 75656010 in:
    ==> c:\windows\syswow64\usp10.dll
    Loadlibrary within Windows DLL! Happening at 763e4908 in:
    ==> c:\windows\syswow64\kernel32.dll
    Loadlibrary within Windows DLL! Happening at 7621468e in:
    ==> c:\windows\syswow64\advapi32.dll
    Loadlibrary within Windows DLL! Happening at 7621468e in:
    ==> c:\windows\syswow64\advapi32.dll
    Loadlibrary within Windows DLL! Happening at 76803a6b in:
    ==> c:\windows\syswow64\shell32.dll
    Loadlibrary within Windows DLL! Happening at 76803a6b in:
    ==> c:\windows\syswow64\shell32.dll
    Loadlibrary within Windows DLL! Happening at 760f0bf3 in:
    ==> c:\windows\syswow64\rpcrt4.dll
    Loadlibrary within Windows DLL! Happening at 7621468e in:
    ==> c:\windows\syswow64\advapi32.dll
    Loadlibrary within Windows DLL! Happening at 7621468e in:
    ==> c:\windows\syswow64\advapi32.dll
    Loadlibrary within Windows DLL! Happening at 743e4f3d in:
    ==> c:\windows\syswow64\cryptsp.dll
    Loadlibrary within Windows DLL! Happening at 743a58d0 in:
    ==> c:\windows\syswow64\rsaenh.dll
    Loadlibrary within Windows DLL! Happening at 743a58d0 in:
    ==> c:\windows\syswow64\rsaenh.dll
    Loadlibrary within Windows DLL! Happening at 743a58d0 in:
    ==> c:\windows\syswow64\rsaenh.dll
    Loadlibrary within Windows DLL! Happening at 743a58d0 in:
    ==> c:\windows\syswow64\rsaenh.dll
    Loadlibrary within Windows DLL! Happening at 760f0bf3 in:
    ==> c:\windows\syswow64\rpcrt4.dll
    Loadlibrary within Windows DLL! Happening at 758314a0 in:
    ==> c:\windows\syswow64\ole32.dll
    Loadlibrary within Windows DLL! Happening at 751d28f2 in:
    ==> c:\windows\syswow64\credui.dll
    Loadlibrary within Windows DLL! Happening at 751d28f2 in:
    ==> c:\windows\syswow64\credui.dll
    Loadlibrary within Windows DLL! Happening at 751d28f2 in:
    ==> c:\windows\syswow64\credui.dll
    Loadlibrary within Windows DLL! Happening at 751d28f2 in:
    ==> c:\windows\syswow64\credui.dll
    Loadlibrary within Windows DLL! Happening at 758314a0 in:
    ==> c:\windows\syswow64\ole32.dll
    Loadlibrary within Windows DLL! Happening at 74ed1c19 in:
    ==> c:\windows\syswow64\napinsp.dll
    Loadlibrary within Windows DLL! Happening at 74ed1c19 in:
    ==> c:\windows\syswow64\napinsp.dll
    Loadlibrary within Windows DLL! Happening at 74e79ae6 in:
    ==> c:\windows\syswow64\mswsock.dll
    Loadlibrary within Windows DLL! Happening at 74ed1c19 in:
    ==> c:\windows\syswow64\napinsp.dll
    Loadlibrary within Windows DLL! Happening at 74ed1c19 in:
    ==> c:\windows\syswow64\napinsp.dll
    Loadlibrary within Windows DLL! Happening at 752f71f3 in:
    ==> c:\windows\syswow64\dnsapi.dll
    Loadlibrary within Windows DLL! Happening at 752f71f3 in:
    ==> c:\windows\syswow64\dnsapi.dll
    Loadlibrary within Windows DLL! Happening at 761c9d9d in:
    ==> c:\windows\syswow64\ws2_32.dll
    Loadlibrary within Windows DLL! Happening at 758314a0 in:
    ==> c:\windows\syswow64\ole32.dll
    Loadlibrary within Windows DLL! Happening at 758314a0 in:
    ==> c:\windows\syswow64\ole32.dll
    Loadlibrary within Windows DLL! Happening at 74ee204a in:
    ==> c:\windows\syswow64\rasadhlp.dll
    [GetKeyboardLayout-lib] - from library

Hope the samples and results listed above could help you understand my misunderstanding of bluepill. It couldn't be better if you could tell me what should the evasions.log be like. Thank you a lot for the help!

dcdelia commented 3 years ago
  1. NtQuerySystemInformation With parameter CLASS=3, the API retrieve information about time. Firstly, GetProcAddress was called to get the address of it from ntdll. Then it was called. But only loading library was logged, without NtQuerySystemInformation itself.

An application can call disparate time APIs, either directly or indirectly when the call originates in some other API called by the program. So we opted in most cases not to hook (and thus log) them, but rather rewrite the rdtsc instruction outputs at the lowest level. This design choice comes from the fact that you can poke time using heterogeneous API sources and combine their results (both for evasion or consistency checking). In our TODO list for the public codebase we will log time-related API calls happening directly from program code even if we don't alter explicitly their value, ruling out internal ones using the interval tree facility that we added to the tree after the BlackHat talk. At the moment BluePill fakes time values without telling the user.

2. GetSystemTimeAsFileTime/GetSystemTime The latter was not listed in the table, but the former was. I just called it but nothing logged.

Yes in functions.cpp we define TIMEASFILE_INDEX that we use in the DLL API hooking routine at line 266 to register a callback whose body at 1247 is however commented out. You can see some isInsideMainIMG primitive that we used, prior to the interval tree adoption, to filter out internal calls because these can be very noisy. However the approach was not good enough (it considers only .text) as it misses calls from dynamically allocated code regions, hence we added the interval tree (details in another paper we worked on: https://arxiv.org/abs/2005.00323) but did not finish updating this part yet.

Hope the samples and results listed above could help you understand my misunderstanding of bluepill. It couldn't be better if you could tell me what should the evasions.log be like.

I can try recovering the logs used for the paper and compile & run BluePill from the internal commit we used back then. The project has been evolving and we miss a regression test strategy for our logs at the moment, so on some versions they are less informative than on others. BTW can you see malicious activity from Olympic in logs from third-party monitoring tools, e.g. created registry keys or files?

snbst-git commented 3 years ago

@dcdelia Thank you for reply.

So we opted in most cases not to hook (and thus log) them, but rather rewrite the rdtsc instruction outputs at the lowest level.

I understand it. BluePill focuses on solving the problem of time itself rather than recording.

Yes in functions.cpp we define TIMEASFILE_INDEX that we use in the DLL API hooking routine at line 266 to register a callback whose body at 1247 is however commented out.

And in line 1251 of functions.cpp, I find that ProcInfo::getInstance()->isInsideMainIMG(retAddr) was unable to use now. Still, I guess we can insert code there to get noticed once the program call GetSystemTimeAsFileTime, is that right?

BTW can you see malicious activity from Olympic in logs from third-party monitoring tools, e.g. created registry keys or files?

Would you please tell me what tools do you used to use?——So that I can use the same tool in order to compare the results, which might be more helpful. Here, I used DynamoRIO with command drrun.exe -t drstrace -- ed….exe(the file named after Olympic's SHA256), with two log files generated. And there was NtCreateFile indeed. image Does this mean that the issue is caused by the difference in compilation of bluepill? BTW, when I compiled bluepill, there was a warning.

pin.lib(pin_client.obj) : warning LNK4217: locally defined symbol ?cout@std@@3V?$basic_ostream@DV?$char_traits@D@std@@@1@A (class std::basic_ostream<char,class std::char_traits<char> > std::cout) imported in function "void __cdecl LEVEL_PINCLIENT::DumpPinVersion(void)" (?DumpPinVersion@LEVEL_PINCLIENT@@YAXXZ) 
dcdelia commented 3 years ago

@snbst-git my apologies, your reply totally slipped during my (long) Christmas break. Sorry!

I hope your experience with BluePill has been fruitful. Regarding your GetSystemTimeAsFileTime question, yes, you can add further instrumentation to be notified when an event occurs and act accordingly. Regarding NtCreateFile, BluePill won't log all of its invocations but only those involving evasive queries (e.g. opening a path related to VirtualBox guest additions). We did not use the DynamoRIO tracer as it has a few DBI artifacts that could spook malware. There could be spurious calls also when evasions take place (for some of the samples in our dataset, if I remember correctly, using the hash as filename could lead to one). For our validation we mostly tried a combination of standard monitoring tools (e.g. ProcMon, RegShot, Process Hacker, Wireshark), manual filesystem and registry inspection, and some debugging. Regarding the compilation warning, that one is fine.

snbst-git commented 3 years ago

@dcdelia It doesn't matter! Glad to hear that you had a good holiday. I used a few tools instead, to catch the information I needed. Thank you for the suggestion on monitoring tools. In addition, I am still learning to use BluePill, focusing on the debugging and taint analysis functions. But when I tried to connect to IDA Pro, IDA Pro popped up the MessageBox The file can't be loaded by the debugger plugin…, and then pin exited with the message source\debugger-protocol\gdb-packet\gdb-packet.cpp:2252: assertion "0" failed. Did you ever meet the same issue? pic1 I guess this issue might be caused by the environment of my virtual machine, and relate to remote gdb debugger.

dcdelia commented 3 years ago

Thank you :-) We have not encountered this assertion failure before, that's weird.

What IDA version are you using? To make sure that it's a BluePill problem and not some setup issue, try to run Pin with no pintool and only the -appdebug -appdebug_server_port 23946 options (or maybe only the first one, and Pin will select and show to screen a random port number). The Pin install folder also comes with an advanced debugging extensions for Visual Studio package, but I guess they are not strictly needed here: if the procedure above doesn't work, you may give it a try and install them anyway, then retry after a reboot.

P.S. For the taint analysis part I hope we can soon push upstream a new graphical component that we are writing from scratch (unfortunately we couldn't release the old one as a third party was involved) so at the moment with the public source you'll have to try "manual" tainting using our logging primitives.

snbst-git commented 3 years ago

@dcdelia I tested Pin311/313/315 and IDA Pro v7.0/7.5. Additionally, I'm using the portable versions (compressed as zip files). The issue seems to be caused by Pin or debugger, because I didn't set up the environment other than decompressing Pin and IDA.


In the virtual machine, I tested Pin without specifying bluepill, which ended up with the same assertion. While IDA Pro popped up the same error messageboxs as follow. pic2 If I click Yes, then the copying will not succeed. pic3 However in Win10, pin didn't exit or show the assertion. But other errors were the same.

dcdelia commented 3 years ago

Oh, we always used the same machine for both debugging and running the sample. "Remote" is only for the GDB protocol we use to communicate with IDA. I think if you run IDA alongside Pin you should be good to go? BluePill - hopefully :-) - will hide it.

snbst-git commented 3 years ago

@dcdelia Yes, I also used the same machine each time. I tested 2 virtual machines (Win7) and 1 physical machine (Win10), which resulted in the same error. So I believe that it's a problem in setting up the environment. Sorry for the unfamiliarity with IDA and Pin.

dcdelia commented 3 years ago

So it could be a problem in how you load the files, we never got the copying window from your screenshot below. What we normally do is opening the sample in IDA, selecting the Remote GDB server option as debugger, then inspecting Debugger -> Process options to double-check paths and the port number. Finally, Debugger -> Start process and IDA will recognize that the executable is already running under Pin (so make sure Pin is ready by then). Hope this helps!

snbst-git commented 3 years ago

@dcdelia Thanks for the advice even you didn't meet the problem. I followed these steps.

Steps

1.Loading the executable in IDA image 2.Selecting debugger image There's a warning about memory then, but i think it doesn't matter. image 3.Starting debugging with pin (Step 3 can also be done before step 1) image 4.Setting up Process options image 5.Starting process in IDA There's a warning, which I believe doesn't matter either. image 6.Error Finally the warning of loading file comes up. (In Win10, the copyting window and its failure comes firstly.) image


Since the steps described in your document is quite clear, I don't think the problem is caused by these steps. That is, I should then try to find some other reasons on my own. Thank you for all the help! I'll find a way.

snbst-git commented 3 years ago

Hi @dcdelia , I also wonder if we can run BluePill together with other pintools? For example, using a pintool to record the path of executing, and using bluepill to guarantee the reliability. PS: I simply use command -t bluepill32.dll -t ***.dll, and it doesn't work. So perhaps pin can only use 1 pintool each time.

dcdelia commented 3 years ago

I don't think Pin allows that, you should try to combine the instrumentations of the pintools in a single DLL and make sure that there are no conflicting parts. I think there is enough modularity in the hooking of instructions, syscalls, and context switches in BluePill that adding further callbacks within ours should be easy.

JonElliott2k commented 1 year ago

Hey there! @dcdelia @snbst-git Did anyone ever find a solution to the Windows 10 x64 pintool issue? I am struggling with the same issue as above. I can run pin.exe (C:\Pin316\intel64\bin\pin.exe) without any pintool attached, but when I attempt to add bluepill32.dll I receive the same error E: Failure to map DLL C:\Pin316\bluepill32.dll E: System error 216 : bluepill-cmd My primary goal is to identify and log any executed binaries that perform sandbox awareness behaviors like red pill. I'm not concerned with fooling the binary since these behaviors are often associated with malware. I'm willing to accept a higher false positive rate as well.

Besides downgrading to Windows 7, are there any workarounds to achieve basic detection and logging even if the sample successfully recognizes the DBI artifacts and implements anti-forensic countermeasures? I'm including a screenshot of systeminfo output below for added clarity. I'm open to any suggestions. Thank you!

systeminfo

snbst-git commented 1 year ago

System error 216

You have to use a 64-bit pintool to analyze a 64-bit program. It seemed that a 64-bit pin.exe is used with a 32-bit bluepill32.dll.