Symantec Endpoint Protection Manager – CVE-2013-1612 – Remote Buffer Overflow – PoC
Do want to help me to turn this PoC into reliable exploit code ? Here is the short story about CVE-2013-1612, a remote buffer overflow that I’ve reported to Symantec in June 2013. The vulnerability impacts Symantec Endpoint Protection Manager (SEPM, a.k.a. the central SEP server) versions 12.1.0 to 12.1.2. Here are some references about the bug:
The PoC code (provided below), simply overwrite EIP by using a SEH-based technique. Unfortunately, due to memory protection mechanisms, I wasn’t able to create a stable exploit using this technique since all modules are compiled using the /SafeSEH flag and workarounds (that I knew) were found useless.
Pointer overwriting approach
I finally tried a second approach which only requires to bypass DEP and stack canary protections (/GS). Btw, Symantec DLL aren’t compiled with ASLR. So, instead of triggering a memory access violation by filling the stack (as for a usual SEH-based overflow), I’ve observed the process behavior when only a few bytes are overwritten and realized that an interesting pointer is overwritten. This pointer is a “destination address” argument passed to a memcpy() call, a few instructions after the the overflow. On top of that, the “source address” given to memcpy() points to our shellcode! So, I have the pleasant capability to copy “anything” “anywhere”, as illustrated by the following screenshot. The source pointer contains to the shellcode address and destination pointer is currently set to 0xAAAACCCC.
Using this memcpy(), my goal was to overwrite the “saved return address” value of the memcpy() frame, with the first instruction of my ROP chain. Therefore, as soon as memcpy() returns, it starts executing my payload. By doing this, no Stack-Guard cookies are broken :-) (do you get the big picture?).
Using this approach, /GS protections is bypassed and a classical ROP can be used to circumvent DEP. So far so good excepted that I need to know the address of the memcpy() frame, and here comes the problem. By default, SEPM runs 330 threads, and each of them use its own stack based-address. Therefore, the address of the memcpy() frame is different for each thread. So, I need to know which thread is dealing with my HTTP request :-/
Can I use a brute-force approach ? Yes. The service restarts automatically upon crash (example: if I write at the wrong address). However, it will take a while and the service remains unavailable during the attack (constantly restarting).
There is however something interesting to know here. I have observed that right after the service restart, the first HTTP request sent to the server is “most of the time” handled by a predictable thread ID and therefore, a predictable stack-based address ! When you find it, only a few attempts are needed to write at the correct memcpy() frame address. Unfortunately, this knowledge was still found useless to me because the thread ID that serves the first request seems to be hardware-dependent. Actually, I have no idea how Windows allocates new threads and this is where I stuck in this approach… My exploit works in my labs, but won’t work in yours. I’ve observed totally different thread ID on other platforms :-/
If you have any brilliant idea or find another approach, please give it a try ! (and please keep me informed :-) ). The PoC code and a vulnerable version of the software is provided below.
- PoC code: Download the SEH-based PoC code here. There is an encryption key (KCS) to provide to the obfuscation function. The PoC will let you know where to find your environment key. (Exploit-db mirror)
- Vulnerable SEPM version: A copy of the vulnerable software can be found here. You will find two httpd processes running, one of them has 330 threads. Attach your debugger to that one.
© 2014 – 2015, Fun Over IP. All rights reserved.