Detecting Wine via internal and legacy APIs

Many malicious samples try to detect sandbox environment and to do so they use an avalanche of tricks that are either generic (f.ex. checking a number of processors) or very specific (f.ex. VMWare backdoor). One of the environments they try to detect using specific tricks is Wine.

The Wine detection is simple: check if kernel32.dll or ntdll.dll exports one of internal Wine APIs.

Looking at the data obtained from sandboxing of many samples, I noticed that the combos (not necessarily correct) that are used to detect the Wine environment are as follows:

  • kernel32.dll!wine_get_unix_file_name
  • ntdll.dll!wine_get_unix_file_name
  • ntdll.dll!wine_get_version
  • ntdll.dll!wine_nt_to_unix_file_name
  • ntdll.dll!wine_server_call

This made me think that there may be more possibilities and to confirm that I downloaded the latest snapshot of Wine source code.

Turns out that there are actually more internal functions available.

Grepping all *.spec files for the ‘# Wine.*?extensions’ regex gives us the following list of candidates:

dlls\gdi32\gdi32.spec

################################################################
# Wine extensions: Win16 functions that are needed by other dlls
#
@ stdcall GetDCHook(long ptr)
@ stdcall SetDCHook(long ptr long)
@ stdcall SetHookFlags(long long)

################################################################
# Wine internal extensions
#
# All functions must be prefixed with '__wine_' (for internal functions)
# or 'wine_' (for user-visible functions) to avoid namespace conflicts.

# GDI objects
@ cdecl __wine_make_gdi_object_system(long long)
@ cdecl __wine_set_visible_region(long long ptr ptr ptr)

# Graphics drivers
@ cdecl __wine_set_display_driver(long)

# OpenGL
@ cdecl __wine_get_wgl_driver(long long)

dlls\imm32\imm32.spec

################################################################
# Wine internal extensions
@ stdcall __wine_get_ui_window(ptr)

dlls\kernel32\kernel32.spec

################################################################
# Wine internal extensions
#
# All functions must be prefixed with '__wine_' (for internal functions)
# or 'wine_' (for user-visible functions) to avoid namespace conflicts.

# 16-bit relays (for backwards compatibility)
@ cdecl -i386 -private __wine_dll_register_16(ptr str)
@ cdecl -i386 -private __wine_dll_unregister_16(ptr)
@ stub -i386 __wine_call_from_16_regs

# Unix files
@ cdecl wine_get_unix_file_name(wstr)
@ cdecl wine_get_dos_file_name(str)

# Init code
@ cdecl __wine_kernel_init()

dlls\krnl386.exe16\krnl386.exe16.spec

################################################################
# Wine internal extensions
#
# All functions must be prefixed with '__wine_' (for internal functions)
# or 'wine_' (for user-visible functions) to avoid namespace conflicts.

# DOS support
@ cdecl -arch=win32 __wine_call_int_handler(ptr long)
@ cdecl -arch=win32 __wine_load_dos_exe(str str)

# VxDs
@ cdecl -arch=win32 -private __wine_vxd_open(wstr long ptr)
@ cdecl -arch=win32 -private __wine_vxd_get_proc(long)

dlls\ntdll\ntdll.spec

##################
# Wine extensions
#
# All functions must be prefixed with '__wine_' (for internal functions)
# or 'wine_' (for user-visible functions) to avoid namespace conflicts.

# Relays
@ cdecl -i386 __wine_enter_vm86(ptr)

# Server interface
@ cdecl -norelay wine_server_call(ptr)
@ cdecl wine_server_fd_to_handle(long long long ptr)
@ cdecl wine_server_handle_to_fd(long long ptr ptr)
@ cdecl wine_server_release_fd(long long)
@ cdecl wine_server_send_fd(long)
@ cdecl __wine_make_process_system()

# Version
@ cdecl wine_get_version() NTDLL_wine_get_version
@ cdecl wine_get_build_id() NTDLL_wine_get_build_id
@ cdecl wine_get_host_version(ptr ptr) NTDLL_wine_get_host_version

# Codepages
@ cdecl __wine_init_codepages(ptr ptr ptr)

# signal handling
@ cdecl __wine_set_signal_handler(long ptr)

# Filesystem
@ cdecl wine_nt_to_unix_file_name(ptr ptr long long)
@ cdecl wine_unix_to_nt_file_name(ptr ptr)
@ cdecl __wine_init_windows_dir(wstr wstr)

dlls\ntoskrnl.exe\ntoskrnl.exe.spec

################################################################
# Wine internal extensions
#
# All functions must be prefixed with '__wine_' (for internal functions)
# or 'wine_' (for user-visible functions) to avoid namespace conflicts.

@ cdecl wine_ntoskrnl_main_loop(long)

dlls\user32\user32.spec

################################################################
# Wine internal extensions
#
# All functions must be prefixed with '__wine_' (for internal functions)
# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
#
@ cdecl __wine_send_input(long ptr)
@ cdecl __wine_set_pixel_format(long long)

Now that we have a list of all internal functions, we can create a simple program that will try to detect Wine by attempting to resolve these API names.

Running it on Win7 we get the following results:

wine_detect1

Running it on Wine under Ubuntu gives us the following result:

wine_detect2

So, it looks like we have quite a lot of combos to use!

  • kernel32.dll!__wine_dll_register_16
  • kernel32.dll!__wine_dll_unregister_16
  • kernel32.dll!__wine_call_from_16_regs
  • kernel32.dll!wine_get_unix_file_name
  • kernel32.dll!wine_get_dos_file_name
  • kernel32.dll!__wine_kernel_init
  • ntdll.dll!__wine_enter_vm86
  • ntdll.dll!wine_server_call
  • ntdll.dll!wine_server_fd_to_handle
  • ntdll.dll!wine_server_handle_to_fd
  • ntdll.dll!wine_server_release_fd
  • ntdll.dll!wine_server_send_fd
  • ntdll.dll!__wine_make_process_system
  • ntdll.dll!wine_get_version
  • ntdll.dll!wine_get_build_id
  • ntdll.dll!wine_get_host_version
  • ntdll.dll!__wine_init_codepages
  • ntdll.dll!__wine_set_signal_handler
  • ntdll.dll!wine_nt_to_unix_file_name
  • ntdll.dll!wine_unix_to_nt_file_name
  • ntdll.dll!__wine_init_windows_dir

The title of this post refers to both internal and legacy APIs.

Here’s a thing – there exist APIs that used to be present in the old versions of Windows but have been removed and are no longer exported by the OS libraries. Yet, Wine continues to offer them as an export – most likely for compatibility reasons.

A perfect example of such API are RegisterServiceProcess and OpenVxDHandle that used to be exported by kernel32.dll on Windows 9x/ME, but are not present on the NT/2000/XP/Vista/Win7/8/10.

Yup. This fact alone allows us to leverage them for the detection of Wine (and potentially other sandboxes).

wine_detect3

This is obviously a tip of an iceberg – many other APIs like this can be found all over the place.

You can download the test tool here.

Enter Sandbox – part 10: Removable devices & clickbait file names

Infection of removable drives is an old trick and no point explaining what it is. What is interesting though is looking at creativity of guys who leverage this infection vector and not the ones that exploit the autorun.inf mechanism (yawns!), but the one that focuses on social engineering.

Assuming that a potential victim of ‘removable device infection’ is typically not a very computer savvy individual is actually quite easy. We all know that it’s the guys like these that are a typical pray for malware authors.

But are they the only ones?

There is so many things one can do to place clickbaitfiles on the removable drive that the victim will end up clicking. It is stronger than us. Whether a rookie or a pro. You have seen it, I have seen it – the guys clicking, clicking… until it works. I have done it too.

Infection via a removable device is still a perfect social engineering platform and I’d say it is not going away anytime soon.

Looking at some of the sandboxes samples I have analyzed I created a short list of tricks I have spotted so far (send me more if you know others, and care to share).

  • hide the folder, create an .exe with the same name and ensure the .exe is using a folder icon
  • use ‘current’ and ‘directory up’ file names i.e. ‘..exe’ and ‘…exe’
  • use important-looking file names, also in foreign languages

匆删(重要资料).exe

  • leverage desktop.ini to change the appearance of the folder (f.ex. bin folder)
[.ShellClassInfo]
CLSID={645FF040-5081-101B-9F08-00AA002F954E}
  • use various file extensions: .exe, .scr, .pif, .lnk
  • double .exe (.exe.exe), triple .exe (.exe.exe.exe)
  • intriguing names (sex&pr0n in general, controversy&scandal)
  • use attractive looking icons – yup, it’s thats imple
  • Fake Recycler folders
  • obviously, a randomized autorun.inf is a norm now
[AutoRun]
;FLvfB ysQiGKArLcs 
sheLl\open\commAnD = ukxfqq.pif
;fWJoARTstov kivfsp 
SHeLL\oPEn\dEfault=1
;tCcl bcaolB WdIa BdqhbkeGrp
Shell\explorE\COmmand= ukxfqq.pif
;ngFiihrOUk 
open =AutoRun.exe
;KyGpw
shEll\AutOpLAY\COMMaND=ukxfqq.pif
shell\1=Open
shell\1\Command=AutoRun.exe
shell\2\=Browser
shell\2\Command=AutoRun.exe
shellexecute=AutoRun.exe
;YtGyagvMMf ceqdP ymhOtYeaQn

Look at the screenshot below.

Be honest.

What you would NOT click?

mind you – it is good ol’ Windows XP!

removable

and same – on Windows 7

removablew7

 

 

Update

What does the topic of this post have in common with sandboxing?

It would be cool for sandboxes to highlight these artifacts (if they don’t, yet)…

If any sample drops its copy on a removable drive or another well-known file associated with social engineering i.e. exhibits one of the behaviors described above (and more, subject to more analysis) the ‘maliciousness’ score can easily go up.

Everyone wins. I hope 🙂