[MinGW-Notify] [mingw] #40446: Obscure issue compiling/linking Windows binaries from Linux using mingw

Back to archive index
MinGW Notification List mingw****@lists*****
Tue May 26 18:50:13 JST 2020


#40446: Obscure issue compiling/linking Windows binaries from Linux using mingw

  Open Date: 2020-05-26 07:19
Last Update: 2020-05-26 10:50

URL for this Ticket:
    https://osdn.net//projects/mingw/ticket/40446
RSS feed for this Ticket:
    https://osdn.net/ticket/ticket_rss.php?group_id=3917&tid=40446

---------------------------------------------------------------------

Last Changes/Comment on this Ticket:
2020-05-26 10:50 Updated by: keith
 * Status Update from Open to Closed

 * Resolution Update from None to Invalid


Comment:

I'm sorry, but this

    COLLECT_GCC=x86_64-w64-mingw32-gcc

is not a MinGW product; indeed, that "mingw" appears in its name is a trademark
infringement. As the legitimate owners of that trademark, we do not support
such illegitimately distributed products.



---------------------------------------------------------------------
Ticket Status:

      Reporter: thecolonial
         Owner: (None)
          Type: Issues
        Status: Closed
      Priority: 3
     MileStone: (None)
     Component: (None)
      Severity: 5 - Medium
    Resolution: Invalid
---------------------------------------------------------------------

Ticket details:

Hi,

I've recently been working on providing support to build Windows Meterpreter
binaries using mingw via CMake on Linux. The project source can be found here:
https://github.com/OJ/metasploit-payloads/tree/cross-compile-linux/c/
meterpreter

I think it's fair to say that the kind of stuff Meterpreter does is a little
"non standard" compared to most C/C++ projects and so I expected to come up
against some edge case issues.For the most part it has gone very well, but I
stumbled on something yesterday that has taken me a solid day of debugging to
get to the bottom of. I'll do my best to describe in detail and provide links
to the relevant things so that the mingw developers can get themselves to the
point that I was to reproduce the issue.

Meterpreter is made up of a number of components. A core component called
metsrv is what's loaded first, and from there a number of other components
(extensions) can be loaded on the fly. One of the extensions is called kiwi,
which is made up of functionality pulled from a project called Mimikatz by Ben
Delpy, the source if which can be found here: https://github.com/gentilkiwi/
mimikatz

The kiwi extension makes some modifications to this project allowing it be
loaded using Reflective DLL Injection. This technique was developer by Stephen
Fewer, the source can be found here: https://github.com/stephenfewer/
ReflectiveDLLInjection

So metsrv is loaded via RDI, it can then load kiwi via RDI. Nothing too complex
so far.

The kiwi source is definitely complex. Mimikatz does crazy things with the
internals of Windows via obscure APIs. In order to support various versions of
Windows it has to include a few custom made libraries that are shipped with the
project in the lib subfolder.

Prior to undertaking this task, we were able to build all the components of the
project cleanly with VS 2013/2017/2019 and the binaries would work as expected.
I was having the same experience porting things to mingw on Linux until I
reached the kiwi extension, which resulted in the issue that I thought I'd log
here.

Invocation of the features of the binary would result in the program crashing.
After debugging, I realised that all IAT function pointers that should have
been imported from advapi32.dll were set to NULL. This seemed a little strange,
because all other IAT entries looked fine. Then after many hours of digging, I
noticed that there was something odd going on with the Import descriptors.
Please refer to the following image:

https://i.imgur.com/zXynXJp.png

This image is a screenshot from PE-Bear, a PE analysis tool, and it shows the
imports for the resulting ext_server_kiwi.x64.dll binary that is generated from
mingw. Things to note:

  • Only 6 functions are imported from WINSTA.dll, though PE Bear reports that
    it has 105.
  • The list of functions that are imported contain references to functions
    loaded from advapi32.dll.
  • The RVA of the first thunk for advapi32.dll appears in the list of
    functions for winsta.dll.

Ultimately, the root of the issue is that the import descriptor for winsta.dll
is not terminted with a NULL entry. So what happens at runtime is that the DLL
loader iterates through all the winsta.dll functions first, correcty resolves
them using LoadLibrary and GetProcAddress, and stores the pointers in the IAT.
As soon as it hits the first entry for advapi32.dll (in this case A_SHAFinal)
it attempts to call GetProcAddress with an invalid module base (because it's
reusing WINSTA.dll's base) and hence the call will result in NULL. The net
result is that all of the advapi32.dll import entries are set to NULL.

I modified the reflective DLL injection code so that it doesn't assume that a
NULL terminator is present. It will also look at the next set of import
characteristics and make sure that it doesn't go past the first thunk. This
change resulted in everything working fine.

This problem isn't present in the VS compilers/linkers I've used and hence I
think it might be an issue specific to mingw. I do have a working solution, but
I think there could be something that may impact other people if we don't get
to the bottom of it. Hopefully it's specific to my project alone, however I
don't think it is. Maybe it's an edge case that mingw doesn't yet cover.

I think this is a linker issue rather than a compiler issue, but that's
obviously up to people with more knowledge than me to determine. I wouldn't
consider this the highest priority, given that it's rather edge case and you
probably haven't seen it before despite the long history of the mingw project.

If you need any more clarification on the issue, or links to sources etc,
please let me know. I can provide binaries if required.

Many thanks for your time and for the great work you folks do this project.

Best regards

OJ / @TheColonial



-- 
Ticket information of MinGW - Minimalist GNU for Windows project
MinGW - Minimalist GNU for Windows Project is hosted on OSDN

Project URL: https://osdn.net/projects/mingw/
OSDN: https://osdn.net

URL for this Ticket:
    https://osdn.net/projects/mingw/ticket/40446
RSS feed for this Ticket:
    https://osdn.net/ticket/ticket_rss.php?group_id=3917&tid=40446



More information about the MinGW-Notify mailing list
Back to archive index