AD2019: DoNotMarkWritableSectionsAsShared¶
Summary¶
| Property | Value |
|---|---|
| ID | AD2019 |
| Name | DoNotMarkWritableSectionsAsShared |
| Category | Security |
| Severity | Error |
| Applies to | PE (Windows) |
Description¶
Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process.
If you do not actually require that a section be both writable and shared, remove one or both of these attributes.
How It Works¶
The rule examines each section in the PE file and checks for the combination of:
IMAGE_SCN_MEM_WRITE(0x80000000)IMAGE_SCN_MEM_SHARED(0x10000000)
Sections should not have both flags set simultaneously.
Why This Matters¶
Shared writable sections break the fundamental security boundary between processes. A section that is both shared and writable allows one process to modify data that another process trusts, enabling devastating privilege escalation attacks.
Process Isolation Fundamentals¶
Modern operating systems isolate processes:
| Isolation Property | Purpose |
|---|---|
| Separate address spaces | One process can't access another's memory |
| Access control | Permissions checked on IPC |
| Privilege levels | Users can't access admin processes |
Shared writable sections break all of these protections.
Attack Scenario: Privilege Escalation¶
1. Low-privilege process and high-privilege process share a DLL
2. DLL has a shared writable section (e.g., configuration data)
3. Low-privilege process modifies shared data
4. High-privilege process reads and trusts the data
5. High-privilege process does something dangerous
Result: Low-privilege attacker controls high-privilege behavior
Specific Attack Patterns¶
Function pointer corruption:
// In shared writable section
struct SharedConfig {
void (*logFunction)(const char*); // Attacker can redirect this
char logPath[260];
};
Attacker in low-privilege process overwrites logFunction with address of system(), and logPath with "cmd.exe /c malicious_command".
Data trust violation:
// High-privilege service trusts this configuration
struct SharedSettings {
bool requireAuthentication; // Attacker sets to false
char allowedUsers[1024]; // Attacker adds their account
};
Why This Configuration Exists¶
Legitimate uses of shared sections:
| Use Case | Proper Configuration |
|---|---|
| Shared read-only data | Shared + Read-only |
| IPC | Named pipes, file mapping with ACLs |
| Shared counters | Interlocked operations, proper ACLs |
None of these require uncontrolled shared-writable sections.
Detection in the Wild¶
This vulnerability has been found in:
- Legacy DLLs using
#pragma data_segincorrectly - Old inter-process communication libraries
- Shared configuration mechanisms
Proper Alternatives¶
Instead of shared writable sections, use:
| Need | Proper Solution |
|---|---|
| Shared configuration | Registry, files with proper ACLs |
| IPC | Named pipes, Windows messages |
| Shared state | Named file mapping with DACL |
| Cross-process calls | COM with impersonation |
These alternatives provide controlled access with proper security checks.
Performance Considerations¶
There is no performance benefit to shared writable sections that justifies the security risk. Proper IPC mechanisms have negligible overhead for legitimate use cases.
Resolution¶
Remove Shared Attribute¶
If the section doesn't need to be shared:
Make Section Read-Only¶
If the section must be shared, make it read-only:
Use Separate Sections¶
Separate shared data from writable data:
#pragma section("shared", read, shared)
#pragma section("writable", read, write)
__declspec(allocate("shared")) const int sharedData = 42;
__declspec(allocate("writable")) int writableData = 0;
Project Properties¶
- Open Project Properties
- Navigate to Linker → Advanced
- Review "Section Attributes" settings
When to Suppress¶
This rule may be suppressed for:
- IPC mechanisms: Documented inter-process communication
- Shared memory by design: After security review
- Legacy requirements: Old protocols requiring shared memory
Caveats¶
- Some legacy DLLs use shared sections intentionally
- Certain Windows components may require shared sections
- Named shared memory (
CreateFileMapping) is a safer alternative
Safe Shared Memory Alternatives¶
Instead of shared sections, use:
// Named shared memory with proper security
HANDLE hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE,
&securityAttributes, // Proper DACL
PAGE_READWRITE,
0, size,
L"MySharedMemory");
void* pData = MapViewOfFile(hMapFile, ...);