DLL shared sections: a ghost of the past
(research notes; Gynvael Coldwind, 19 May 2012; updated 21 May 2012)
Summary: A section in a PE module with the IMAGE_SCN_MEM_SHARED flag set is a
memory area shared between all processes that have loaded the given PE module (be it a DLL
or an executable file) regardless of whether the process is owned by the same or a different
user (however this is confined to a given session). This results in certain insecurity where an
untrusted user can interact directly with the given memory area used by a process owned by
another user - actually this is an old and well-known security problem. The author decided to
revisit this bug class and see if there are still applications that use PE shared sections in an
insecure way. One of the discovered cases is described.
Note: All experiments were conducted on Windows 7 Ultimate 64-bit using 32-bit WoW64
applications, unless noted otherwise.
Note: Please note that DLL shared sections and named shared memory mappings are different
mechanism. The main difference is that a named shared memory mapping has ACLs and can
be set to be shared between sessions, while DLL shared sections themselves don't have ACLs,
cannot be shared between sessions and are tied to the DLL file itself. If you are interested in
named shared memory fuzzing check out Jesse Burns presentation from Black Hat 2006 [0].
A ghost of the past
It has been known for quite a while that DLL shared sections introduce a security problem, as
written e.g. on Wikipedia [1]:
Optionally, data sections can be made shared, allowing inter-process communication via this shared
memory area. However, because user restrictions do not apply to the use of shared DLL memory, this
creates a security hole; namely, one process can corrupt the shared data, which will likely cause all other
sharing processes to behave undesirably. For example, a process running under a guest account can in
this way corrupt another process running under a privileged account. This is an important reason to avoid
the use of shared sections in DLLs.
There is also a blog post by Microsoft's own Raymond Chen about it [2]:
Many people will recommend using [DLL] shared data sections as a way to share data between multiple
instances of an application. This sounds like a great idea, but in fact it's a security hole.
The post quoted above was published 8 years ago. I decided to visit this vulnerability class and
see if it's a solved security problem (i.e. there are no applications that use this feature or only
1
use it in a safe and secure manner) or if vulnerabilities of this class can still be encountered in
applications.
Shared section in DLLs
A PE file usually consists of a couple of sections, like the .text/CODE section
that contains machine code, .data/DATA section that contains read-write data,
and so on. Each section is described inter alia by a set of attributes placed in the
IMAGE_SECTION_HEADER.Characteristics field. One of the possible attributes is
IMAGE_SCN_MEM_SHARED, which informs the PE loader that “[t]he section can be shared in
memory” [3].
In other words, every process that loads the exact given DLL file will share the memory area
used by that section; this is the case even if the different processes are owned/run by different
users (however, starting from Windows 2000, this is limited to a single session [4], so the
shared section is not mapped between different users logging into a terminal server; also,
starting from Windows Vista the services are run in a different session).
This creates a certain security problem where the attacker is able to directly manipulate a
certain portion of memory used by a process owned by another user or, to be more specific
- the attacker can change the values of certain variables used by the other user's process.
Depending on the variable types and on how are they used this might allow the attacker to
either slightly influence the other processes behavior, crash it or execute code in its context
(which is an elevation of privileges).
That being said, it's worth noting that shared sections can be either read-only or readable/
writable.
Read/write shared sections
The read/write sections work as expected - the section is a shared memory area and so a
change of a variable placed in the section in one process will be visible in another.
One exception here is changing the data in a debugger which seems to break the sharing.
Read-only shared sections
A read-only shared section seems to either be unmodifiable or to break the mapping on
modification attempt. I have tested the following three methods of writing data to a read-only
shared section (with no results or the breaking the mapping1):
● Change the access rights with VirtualProtect to read/write followed by a simple memory
write (via MOV instruction). This resulted in breaking the mapping.
● Use WriteProcessMemory to write the new value. The function finished with an error
(998 ERROR_NOACCESS - Invalid access to memory location).
1Or
perhaps the mapping has never existed in the first place, I haven't checked.
2
●
Attach a debugger and change the value. This resulted in breaking the mapping.
For the purpose of this research I will assume that a shared read-only section behaves as
a standard copy-on-write section and hence is not interesting from a security perspective.
Perhaps it is nothing more than a physical-memory-usage optimisation hint.
Tools created
For the purpose of finding PE files with shared sections and testing for potential problems I
have created a couple of simple tools. These tools have been released as open source and are
available at: http://code.google.com/p/dll-shared-sections/
FindShared
FindShared is a tool that traverses the directory tree looking for PE files with shared+writable
sections. By default it looks only at files with .exe, .dll, .scr, .cpl and .ocx extensions, but it can
also be set to scan all files (this is more time consuming though).
I have used this tool to make a list of all interesting PE modules in my test environment.
StressShared
This is a simple naive fuzzer that loads a given DLL module and rapidly overwrites the shared
section data with random bytes. It overwrites only the first N bytes of the section, where N is
equal to the IMAGE_SECTION_HEADER.VirtualSize field value from the given section's header
since - as observed, compilers tend to set it to a value indicating the actual size taken by the
variables in the section and not to a page-aligned value.
For testing purposes I have also created a variant of this tool which used byte 0x41 to overwrite
the section data (to be able to easily distinguish the controllable parts of the environment).
Results
FindShared returned a short list of DLLs with shared/writable sections which belonged to just
a few applications. Most of these used the shared sections to store only a few uninteresting
variables, mostly various handles.
FindShared by gynvael.coldwind//vx
[...]
d:\bin\cwRsync\bin\cygwin1.dll
[/19
] rva=00216000 vsz=0000a260 ch=d0600040
d:\bin\cwRsyncServer\Bin\cygwin1.dll
[/19
] rva=00216000 vsz=0000a260 ch=d0600040
[...]
The most interesting shared section belonged to a Cygwin-based project and resided in
cygwin1.dll - the shared section contained quite a lot of variables or various types. I decided to
focus on this DLL.
3
Cygwin's cygwin1.dll
Since this was a DLL belonging to the Cygwin project I decided to focus on the original Cygwin
environment (and not on the cwRsync project). The DLL version used for tests was cygwin120120123.dll - it was the newest snapshot version available at the time of writing. Additionally
there were debugger symbols available for this DLL.
Initial tests with StressShared crashed most apps that used the given cygwin1.dll - the crashes
mostly took place when an app was initializing.
After digging into cygwin documentation I found this note [5]:
5.9. How secure is Cygwin in a multi-user environment?
As of version 1.5.13, the Cygwin developers are not aware of any feature in the cygwin dll that would allow users to
gain privileges or to access objects to which they have no rights under Windows. However there is no guarantee that
Cygwin is as secure as the Windows it runs on. Cygwin processes share some variables and are thus easier
targets of denial of service type of attacks.
After looking deeper into the discovered behavior I could confirm that the consequences
of using shared variables were not limited to a simple denial of service - there are quite a
few "write" vectors around which could allow to overwrite certain values placed in different
memory location (ideally I was searching for a write-what-where condition).
One of the promising pieces of code that came up during a session with StressShared was a
*swprintf-based copy from a UNICODE_STRING placed in the shared section to a buffer placed
on the stack - this suggests a possibility of a buffer overflow scenario.
cygwin-src/winsup/cygwin/shared.cc:
HANDLE
get_shared_parent_dir ()
{
...
WCHAR bnoname[MAX_PATH];
__small_swprintf (bnoname, L"\\BaseNamedObjects\\%s%s-%S",
cygwin_version.shared_id,
_cygwin_testing ? cygwin_version.dll_build_date : "",
&installation_key);
The installation_key variable is the mentioned UNICODE_STRING object placed in the shared
section. It's defined in the same source file.
UNICODE_STRING installation_key __attribute__((section
(".cygwin_dll_common"), shared));
Since the attacker controls everything that is in the shared section (including installation_key's
Length, MaximumLength fields and Buffer pointer) this is a classical stack-based buffer
overflow. On top of that, there seem to be no security cookies on the stack for the cygwin1.dll
4
available on the project page, which simplifies exploitation.
Note: A PoC has been created and this has been confirmed to be a local elevation of privilege
vulnerability. A demo is available here.
Workarounds and fixes
The simplest workaround for this would be to advise users to revoke access to cygwin1.dll
file to other users (e.g. install cygwin in c:\users\USER\ directory or just change the ACLs of
cygwin1.dll to restrict access to it).
A proper fix would include switching from a DLL shared section to another IPC mechanism
(preferably one having proper ACLs) and introduce proper data validation. However, if
communication between various users is desired setting restrictive ACLs will not be possible.
Finally, the way proposed and chosen by the Cygwin maintainers was to limit the impact of
the vulnerability by either removing certain variables from the shared section or changing their
nature. Thanks to such changes the attacker possibilities are limited to DoS-class only.
Cygwin vulnerability timeline
2012-02-13: Mailed cygwin@ list to query for a security contact (couldn't find one on the
project's page).
2012-02-13: Received & verified security contact. Sent initial mail with details, exchanged a
couple of e-mails.
2012-02-14: Continued e-mail exchange. Bug is now fixed.
2012-03-02: Sent additional notes.
2012-03-05: Additional code hardening. Continued e-mail exchange. Publication postponed until
May.
2012-05-11: Sent pre-release heads up to contact. E-mail exchange.
2012-05-17: Sent final pre-release heads up.
2012-05-19: Sent a draft of this document.
2012-05-19: Release.
Conclusion
While this vulnerability class is not yet dead, it's close to being so. Very few applications use
DLL shared sections and even then most of these use them only for a couple of not really
interesting variables.
However, as has been proved, it is still possible to find a vulnerability of this class in modern
software. Even so, the severity of these is rather low with exploitation being limited to certain
situations only.
That being said, I believe that I do not have enough data to make a final call on this class. I
encourage you to conduct further research as well as scan your system for other applications
that use DLL shared sections (e.g. using the released tools).
5
References
[0] Jesse Burns, 2006. "Fuzzing Selected Win32 Interprocess Communication Mechanisms",
https://www.blackhat.com/presentations/bh-usa-06/BH-US-06-Burns.pdf
[1] Wikipedia. "Dynamic-link library. Memory management", http://en.wikipedia.org/wiki/
Dynamic-link_library#Memory_management
[2] Raymond Chen, 2004. "Why .shared sections are a security hole", http://blogs.msdn.com/b/
oldnewthing/archive/2004/08/04/208003.aspx
[3] Microsoft MSDN. http://msdn.microsoft.com/en-us/library/windows/desktop/
ms680341(v=vs.85).aspx
[4] Microsoft Support, 2007. http://support.microsoft.com/kb/251045
[5] Cygwin FAQ, http://cygwin.com/faq-nochunks.html#faq.api.secure
Thanks to
Corinna Vinschen for an interesting e-mail conversation and feedback on this document.
Unavowed and Mateusz "j00ru" Jurczyk for feedback.
Changelog
2012-05-21: Corrected the timeline (the bug was fixed 2012-02-14, and not 2012-03-02 as
implied). Changed "Additional code changes" to "Additional code hardening" in the timeline,
since the code changes weren't related to any specific bug. Added a note about Vista and
services running in separate session. Thanks goes to Corinna Vinschen for pointing these out.
Disclaimer
The views expressed here are mine alone and not those of my employer.
6
© Copyright 2026 Paperzz