ASLR and Windows System DLLs for non-aware executables? - windows

From a Microsoft article:
Address Space Layout Randomization (ASLR)
ASLR moves executable images into random locations when a system
boots, making it harder for exploit
code to operate predictably. For a
component to support ASLR, all
components that it loads must also
support ASLR. For example, if A.exe
consumes B.dll and C.dll, all three
must support ASLR. By default, Windows
Vista and later will randomize system
DLLs and EXEs, but DLLs and EXEs
created by ISVs must opt in to support
ASLR using the /DYNAMICBASE linker
option.
I don't quite get it. Take the base system DLLs loaded by every process on WIndows: NtDll.dll and kernel32.dll.
If a have a non-aware executable, will these system DLLs use ASLR? That is, will they load at a different base address after every system reboot on Win 7 for this executable or will they always load at the same base address after system reboot like they do on Win XP?
To make it more clear what I mean: My typical dummy program's startup stack will look like this:
write_cons.exe!wmain() Line 8 C++
write_cons.exe!__tmainCRTStartup() Line 583 + 0x19 bytes C
write_cons.exe!wmainCRTStartup() Line 403 C
> kernel32.dll!_BaseProcessStart#4() + 0x23 bytes
Looking at the asm of BaseProcessStart, I see on my XP box here:
_BaseProcessStart#4:
7C817054 push 0Ch
7C817056 push 7C817080h
7C81705B call __SEH_prolog (7C8024D6h)
7C817060 and dword ptr [ebp-4],0
...
Now what interests me is the following:
On Windows XP, the address will always be 0x7C817054, regardless of how many times I reboot this machine. If I were on Win7 with ASLR, will this address change between reboots if the executable that loads kernel32.dll is not enabled for ASLR?
(Note: For me, atm., there is only one minor use-case this address would be useful for: In Visual Studio, I can only set a "Data Breakpoint" for assembly level functions, that is a breakpoint # 0x7... - If I want to break in a specific ntdll.dll or kernel32.dll function, in Windows XP I do not have to adjust my breakpoints between reboots. With ASLR kicking in (the scope of this question) I would have to change the Data Breakpoints between reboots.)

Technically whether the system dlls get relocated or not, it shouldn't matter, as the linker will bind to symbols, not addresses. These symbols are resolved by the runtime loader into to addresses for the instanced system dlls, thus your binary should be none the wiser. From what i've seen however, windows 7 will reset the base randomization every reboot, including system dlls(note: this is from debuging WOW64 apps on widows server 2008 R2). You can also do a system wide disabling of ASLR via some registery edits, but thats not really relevant...
Update:
the section on ASLR in this article explains what gets relocated and when.
it doesn't mention if the base will reset every reboot, but for system dlls, its never going to be guaranteed to load at the same address twice, reboot or no reboot.
the important thing is according to article, everything needs to opt-in to ASLR for system dll's to be relocated.

Your program will resolve calls into system DLLs wherever they happen to be loaded. But, unless your executable is linked with /DYNAMICBASE, it will not be given a randomized base address. In other words, your exe will always load at the same base address.
If you want your exe to load at a randomized address, then you have to link it with /DYNAMICBASE, and every DLL that it references must also have been linked with /DYANMICBASE. The system DLLs (starting in Vista) are all linked with /DYNAMICBASE.

Related

Can I manually insert ImageBase value of PE file?

Can I manually insert ImageBase value of PE file?
Basically..
ImageBase of DLL = 10000000
ImageBase of EXE = 00400000
If can, I want change ImageBase to random address.
I wonder How to do.
You can easily change the base address AND prevent Windows from relocating your executable module to a random base. I should stress that if you have access to the build environment, you should prefer specifying the base address and preventing the DYNAMICBASE flag from being placed in the module to begin with at build time, allowing the linker to make the proper optimizations. To do this with MSVC, you'd specify linker flags:
/BASE:400000
/DYNAMICBASE:NO
Altering the image base after the fact CAN be done and will work for simple modules, but in some instances could result in crashes depending on how the code was generated. Sometimes there is little choice when one does not have access to the original source code.
The code and data accesses may hardcode values based on the original ImageBase linked with. If you want to modify a module after it has been build, read on.
While Address Space Layout Randomization (ASLR) behavior was introduced in Windows Vista, the modifications suggested here WILL work on ANY version of Windows.
NOTE: The preceding statement assumes Microsoft, in the future, doesn't start randomizing image base addresses without regard to the relevant PE flags in the header or refuse to load these modules altogether. As of the present versions of Windows 10, Windows currently honors images that DO NOT contain IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag, preventing dynamic relocation.
Using a hex editor, a tool like MSVC's editbin, or even your own code, the following modifications should be made to the PE headers of the desired module to set a FIXED base-load address:
-set desired IMAGE_OPTIONAL_HEADER -> ImageBase (e.g. 0x400000)
i.e. editbin.exe /rebase:base=0x400000 <YOUR_MODULE>
-remove the the 0x0040 (DYNAMIC_BASE) bit from the IMAGE_OPTIONAL_HEADER -> DllCharacteristics flags or use editbin:
i.e.: editbin /dynamicbase:no <YOUR_MODULE>
-if not using editbin, you will need to recalculate the header checksum or just leave at zero for any non-driver or start-up Windows service; editbin updates the checksum automatically.
NOTES:
-manually changing the module's base address may require that you walk the .reloc section entries and perform manual fixups for your new base address either statically or at runtime (simulating what the Windows loader does); not doing so could result in crashes. To avoid this hassle, just remove the DYNAMIC_BASE flag and leave the base address the same as when the module was built. Then you still prevent ASLR, even if the original base address doesn't change.
-the editbin version must have come from MSVC 2005 SP1 (8.0.50727.161) to support the /dynamicbase argument; any free modern version of the MSVC C++ toolset's editbin will have this feature; my experience is that the /rebase option might report the cryptic "LNK1175: failed to rebase ; error 487" even for modules without a .reloc section - this ultimately forces you to use a PE editor to change ImgBase.
-The changes above may break embedded digital signature checks or anything that verifies the integrity of the original file since we've modified it.
As far as I remember, windows PE loader decides on base loading address(ImageBase in your question) and you cannot select it manually unless you write PE loader yourself.
Starting Windows Vista, windows uses address randomizer for selecting a random base loading address. So it is not like 0x10000000 or 0x00400000 anymore and it changes in every run unless the process is started in special situations like debug mode.

Bypassing Windows ASLR by determining the library address using shared pages

I am quite familiar with ASLR, but today I heard a new interesting fact about the implementation of ASLR in Windows.
In order to optimize performance if process A and B load the same dll Windows will only load it once to physical memory and both processes will share the same instance via shared pages.
This is old news .. But the interesting part is that both process A and B will load the shared library in the same virtual address (why ??).
It seems to me that any local attack (e.g. privilege escalation) can easily bypass ASLR by the following way:
1. Create a new dummy process
2. Check the address of dlls of interest (kernel32, user32 ..)
3. Attack the privileged process and bypass ASLR with the information from step 2.
I have done some simple tests using Olly and found that shared libraries are indeed loaded in the same virtual address.
If this is really the case, is ASLR useless for local exploitation ?
You are correct, ASLR is little defense against a local attacker. It is primarily designed to thwart hard-coded addresses in remote exploits.
Edit: Some details in my previous answer were incorrect, though the point above still stands. An ASLR-enabled DLL's base address is actually a function of both: (1) a random offset chosen by Windows from a set of 256 possible values at boot time; and (2) the order in which the DLL is loaded, which for known DLLs is randomized by the Session Manager during system startup. Knowing just the random offset is therefore not sufficient to compute the base address of an arbitrary ASLR'd DLL. However, if you are able to directly observe the address of a target DLL in shared memory, as you describe, then all bets are off anyway.
Sources:
http://www.symantec.com/avcenter/reference/Address_Space_Layout_Randomization.pdf
Windows Internals, 6th Edition

Is DLL loaded in kernel mode or user mode?

I was asked such a question in an interview:
In windows, suppose there is an exe which depends on some dlls, when you start
the exe, and then the dependent dlls will be loaded, are these dlls
loaded in kernel mode or user mode?
I am not quite sure about the question, not the mention the answer - could you help to explain?
Thanks.
I'm not an expert about how Windows internally works, but for what i know the correct answer is user mode, simply because only the processes related to your Operative System are admitted in the kernel space http://en.wikibooks.org/wiki/Windows_Programming/User_Mode_vs_Kernel_Mode
Basically if it's not an OS process, it's going to be allocated in the user space.
The question is very imprecise/ambiguous. "In Windows" suggests something but isn't clear what. Likely the interviewer was referring to the Win32 subsystem - i.e. the part of Windows that you usually get to see as an end-user. The last part of the question is even more ambiguous.
Now while process and section objects (in MSDN referred to as MMF, loaded PE images such as .exe and .dll and .sys) are indeed kernel objects and require some assistance from the underlying executive (and memory manager etc) the respective code in the DLL (including that in DllMain) will behave exactly the same as for any other user mode process, when called from a user mode process. That is, each thread that is running code from the DLL will transition to kernel mode to make use of OS services eventually (opening files, loading PE files, creating events etc) or do some stuff in user mode whenever that is sufficient.
Perhaps the interviewer was even interested in the memory ranges that are sometimes referred to as "kernel space" and "user space", traditionally at the 2 GB boundary for 32bit. And yes, DLLs usually end up below the 2 GB boundary, i.e. in "user space", while other shared memory (memory mapped files, MMF) usually end up above that boundary.
It is even possible that the interviewer fell victim to a common misunderstanding about DLLs. The DLL itself is merely a dormant piece of memory, it isn't running anything on its own ever (and yes, this is also true for DllMain). Sure, the loader will take care of all kinds of things such as relocations, but in the end nothing will run without being called explicitly or implicitly (in the context of some thread of the process loading the DLL). So for all practical purposes the question would require you to ask back.
Define "in Windows".
Also "dlls loaded in kernel mode or user mode", does this refer to the code doing the loading or to the end result (i.e. where the code runs or in what memory range it gets loaded)? Parts of that code run in user mode, others in kernel mode.
I wonder whether the interviewer has a clear idea of the concepts s/he is asking about.
Let me add some more information. It seems from the comments on the other answer that people have the same misconception that exists about DLLs also about drivers. Drivers are much closer to the idea of DLLs than to that of EXEs (or ultimately "processes"). The thing is that a driver doesn't do anything on its own most of the time (though it can create system threads to change that). Drivers are not processes and they do not create processes.
The answer is quite obviously User mode for anybody who does any kind of significant application development for windows. Let me explain two things.
DLL
A dynamic link library is closely similar to a regular old link library or .lib. When your application uses a .lib it pastes in function definitions just after compile time. You typically use a .lib to store API's and to modify the functions with out having to rebuild the whole project, just paste new .lib with same name over the old and as long as the interface(function name and parameters) hasn't changed it still works. Great modularity.
A .dll does exactly the same thing however it doesn't require re-linking or any compilation. You can think of a .dll as essentially a .lib which gets compiled to an .exe just the same as applications which use it. Simply put the new .dll which shares the name and function signatures and it all just works. You can update your application simply by replacing .dlls. This is why most windows software consists of .dlls and a few exe's.
The usage of a .dll is done in two ways
Implicit linking
To link this way if you had a .dll userapplication.dll you would have an userapplication.lib which defines all the entry points in the dll. You simply link to the static link library and then include the .dll in the working directory.
Explicit linking
Alernatively you can programmatically load the .dll by first calling LoadLibrary(userapplication.dll) which returns a handle to your .dll. Then GetProcAddress(handle, "FunctionInUserApplicationDll") which returns a function pointer you can use. This way your application can check stuff before attempting to use it. c# is a little different but easier.
USER/KERNEL MODES
Windows has two major modes of execution. User mode and Kernel modes (kernel further divided into system and sessions). For user mode the physical memory address is opaque. User mode makes use of virtual memory which is mapped to real memory spaces. User mode driver's are coincidentally also .dll's. A user mode application typically gets around 4Gb of virtual addressing space to work with. Two different applications can not meaningfully use those address because they are with in context of that application or process. There is no way for a user mode application to know it's physical memory address with out falling back to kernel mode driver. Basically everything your used to programming (unless you develop drivers).
Kernel mode is protected from user mode applications. Most hardware drivers work in the context of kernel mode and typically all windows api's are broken into two categories user and kernel. Kernel mode drivers use kernel mode api's and do not use user mode api's and hence don't user .dll's(You can't even print to a console cause that is a user mode api set). Instead they use .sys files which are drivers and essentially work exactly the same way in user mode. A .sys is an pe format so basically an .exe just like a .dll is like an .exe with out a main() entry point.
So from the askers perspective you have two groups
[kernel/.sys] and [user/.dll or .exe]
There really isn't .exe's in kernel because the operating system does everything not users. When system or another kernel component starts something they do it by calling DriverEntry() method so I guess that is like main().
So this question in this sense is quite simple.

System DLLs address space

I wonder what is the range of address space of the system DLLs in the Microsoft Windows operating systems. Also, if a DLL is reallocated, does that mean, that the applications using it would crash?
DLL relocation is a common occurrence and simply means that the DLL is loaded in to memory at a location that is not the preferred base location specified by the DLL (typically because another DLL already occupies the part of the address space that the DLL would "like" to use). Unless the DLL is making some seriously flawed assumptions about where it will be loaded, all should be well and no crashes will occur.
Use ProcExp or similar to see the address spaces used by the various DLLs of a process.

Microsoft's ASLR is weird

I watched a ASLRed dll images's based address for 32bit Process.
It's not a fully randomization. It just randomizated 1/2 probability.
For example, once I load a dll then the image is loaded on 0x12345678.
And I load the image again, the image is loaded on 0x23456789.(Base address is changed!)
But I load the image again
0x12345678
0x23456789
0x12345678
0x23456789
...
Why they did implement like this?
Is it for a crash report's frequency?(For getting same crash addresses of re-deployed dlls)
This is by design. Normally, Windows selects a preferred base address for an ASLR DLL when the DLL is first loaded, and then it keeps using that address until the system is rebooted. That way the DLL will be mapped at the same address in every process that loads it, allowing code pages to be shared.
However, if a DLL has been unloaded from every process, the system may sometimes select a different base address the next time the DLL is loaded. It does this to reduce virtual address space fragmentation, not for security reasons. This is what seems to be happening in your case.
It's documented as being at one of 1 of 256 possible starting addresses.
But i didn't think it even applied to a process, but to shared DLL's.
ASLR: is not on by default for process images. It's an opt-in thing, for compatiblity.(3)
Address Space Layout Randomization
(ASLR)
ASLR moves executable images into
random locations when a system boots,
making it harder for exploit code to
operate predictably. For a component
to support ASLR, all components that
it loads must also support ASLR. For
example, if A.exe consumes B.dll and
C.dll, all three must support ASLR. By
default, Windows Vista and later will
randomize system DLLs and EXEs, but
DLLs and EXEs created by ISVs must opt
in to support ASLR using the
/DYNAMICBASE linker option.
ASLR also randomizes heap and stack
memory:
When an application creates a heap in
Windows Vista and later, the heap
manager will create that heap at a
random location to help reduce the
chance that an attempt to exploit a
heap-based buffer overrun succeeds.
Heap randomization is enabled by
default for all applications running
on Windows Vista and later.
When a
thread starts in a process linked with
/DYNAMICBASE, Windows Vista and later
moves the thread's stack to a random
location to help reduce the chance
that a stack-based buffer overrun
exploit will succeed.
Had installed new Win8 RC x64 yesterday.
Watch out!
Kernel32.dll (64-bit version) have different base address in different processes (in single session, of course). Only ntdll.dll base address remains constant. I had to change the code, you can no longer rely on the permanent address Loadlibrary.

Resources