pywebfuzz v0.6.0

I just uploaded pywebfuzz version 0.6.0. There are a few improvements to the file reads happening to retrieve data in the fuzzdb.py module. The fuzzing data was also updated to reflect svn 167 of fuzzdb. Also added in this version is additions to the make_request function in the utils.py module. It now suppors expanded method support beyond GET and POST as well as error handling. You can download the updated version from here: http://code.google.com/p/pywebfuzz As always if you find bugs or problems please let me know. Thanks.

ViVOtech ViVOPay Terminal DoS

I didn’t really think this deserved an entire blog post but it was a bit too much for a Twitter post. It never ceases to amaze me that no matter how far software comes, it still has so far to go. You’d think that modern software shouldn’t break so easily. It’s just too easy to break things that are software dependent, even if that software processes credit cards every day and is PCI compliant.

I ran across these ViVOtech ViVOpay 8800 terminals at a local retailer. They look like this:

4995116770_9fa0da1ffc

I found out that you could create a denial of service condition by performing functions out of order. The DoS is bad enough that it causes the connected computer to require a reboot. There are 4 steps:
  • Swipe Card
  • Hit the Ok/Accept soft button
  • Sign your signature
  • Hit the Ok/Accept soft button

The payment screen starts to print like it was successful then locks up (as seen in the picture above). Not sure if it would time-out at some point, the clerk I was dealing with didn’t seem to have that much patience. I verified this multiple times and the store was running out of terminals. I figured it was probably better to just pay for my product and leave.

You would think items like this would get caught in QA somewhere, but in a world of rushing products out the door it didn’t get caught. These were newer devices so I am assuming the software is recent but who knows.

It makes you think about other items you use every day and how easily you can make them fail just by modifying usage. Oh well, that’s life in a world run by software.

Enumerating Dropbox Resources

4175012762_56fb9c40dc_m

Ok, first order of business, I love
Dropbox. If you are unfamiliar with Dropbox it is a popular cloud based syncing / storage / sharing application for your files. It allows you to store files, roll back changes, etc. You can get more familiar with them by visiting their sitehttps://www.getdropbox.com

Now that I am done singing the praises of Dropbox, it’s time to get to the nitty gritty. This issue isn’t necessarily devastating for Dropbox, but could lead to some larger issues with other cloud based providers. The reason I am writing about this issue is because I think it can aid other individuals in the design of their applications. Let’s face it, cloud based applications and storage aren’t going anywhere.

What You Should Notice

One of the first things you should notice after installing Dropbox is that it sets up some files and folder structure for you.

4176774670_50305e7038_o

A few of the folders are
Documents, Photos, and Public. A couple of files that show up are This is your Dropbox.txt and if you have installed the iPhone app you get the iPhone intro.pdf. Your Public folder is where you can put files that you want to share with via a public URL.

4176014629_476ca0acdd_o

So by default you get a Public folder with a public file that is shared called “Top Secret.txt”. If you go to the Dropbox menu you can obtain a link for the public file that has the following structure:

http://dl.dropbox.com/u/
{acct number}/Top%20Secret.txt

So now you have a known resource  with a known location. By simply requesting this resource and changing the account number you can enumerate through valid accounts. In doing this it will become apparent relatively quickly that account numbers are sequential. You would also notice that most people do not delete any of pre-installed default files even though they are unnecessary. These files are Dropbox’s way of communicating with you about what the folder should be for or about something the application does.

It is fairly simple to enumerate through account numbers and come up with a list of valid users, you could do this in just a couple of lines of
Python code:
#!/usr/bin/env python
 
import httplib
 
f =
open("dropbox_accts.txt", "w")
 
for num in range(1440000, 1450000):
request_string =
"/u/{0}/Top%20Secret.txt".format(num)
conn =
httplib.HTTPConnection("dl.dropbox.com")
conn.
request("GET", request_string)
req = conn.
getresponse()
if req.status == 200:
print(req.status)
f.
write("{0}\n".format(num))

What this does is enumerate through account numbers from 1440000 to 1450000, and if there is a return on Top Secret.txt, it records the number in to a file called dropbox_accts.txt.

Why This Is A Problem

This is a problem for multiple reasons. First of all, it allows an attacker to determine valid accounts on the system. This gives an attacker a starting point for an attack on an account. Another thing to note is that it shows accounts are created sequentially which could lead to other issues.

Working on account enumeration it would be possible for an attacker or someone tracking Dropbox to determine how many new users they have per a certain period of time just by starting where they left off with their previous enumeration activities.

The issue might allow an attacker to try to obtain some information about a particular user through sifting through their public files, if they were guessed. Yes, an attacker would have to guess the name of a valid file but we as humans tend to name files descriptively, so it may be easier than it seems. There is no randomness attached to the filename /URI that would deter this type of activity. After sifting through this data it may be possible to determine the name of the individual who owns the account. Another thing you might find from this activity is an email address associated with the login of the account. If they were to obtain the email they would have the login (email), account number, and the person’s real name. It would not completely out of the question to find something like resume.doc in a user’s Public folder. This is a lot more than an attacker should have.

Now this shouldn’t be a huge deal because it is a “public” folder, it should be assumed that everything in there could be accessed by anyone, but people don’t always make the best choices when it comes to sharing. Many people who use Dropbox use this folder to share things with their friends, not the entire world.

Probably most important, is that they are using known resources and locations. This can be a particularly bad issue for cloud based applications due to their public nature. Every Dropbox account has several folders set up by default along with several files added. These rarely get changed and just get utilized by users. Giving an attacker known resources and locations goes a long way to a successful attack. It allows an attacker to gauge success or failure of a given attack and gives them ready-made resources on which to focus their attacks.

Dropbox uses these files in their private directory structure as well, which opens the doors for some interesting possibilities. I have not really dug in to their API or too much in to their web interface to really say where this might be an issue, but the groundwork can be done in relatively small period of time.

Without having any kind of knowledge how the back end of Dropbox works, it’s hard to tell whether any of the information (ie Account Number) that can be be enumerated can be used to attack user files at rest. It may be hugely important or totally innocuous. I am assuming they have probably thought of this, but you never know.

What’s The Takeaway

People designing cloud based applications and storage should be aware that creating items with known locations could increase their attack surface by giving attackers something to work with. This should be kept to a minimum. Users should be defining the structure of their storage and setting up names for their resources. If you need to communicate with users, it should be done in a message format vs leaving a standard named file in a known location.

Public resources, even though they are public should have some form of randomness added to their resource locations. This way, it is not extremely easy for an attacker to enumerate resources and gain information about the application and its users. It would be a better idea to take the approach that 
Flickr does with it’s randomized URLs for photos. That way it is not easy to map a resource to a given user or account number.

When numbers associated with accounts are exposed, they should take on some form of randomness or there should at least not be any exposed method that would allow someone to enumerate through them easily.

Threat modeling should be done on the application during the design phase allowing for the identification of issues before they get worked in to production. Always think about how the application could be abused. You would think this would be second nature by now, but so many organizations are not doing this.

If you are Dropbox user you should delete the default files that are created by Dropbox, especially the Top Secret.txt that is in your Public folder.

In Closing

In closing not extremely devastating on the surface for Dropbox, but definitely food for thought for anyone working on the design of cloud based applications. Issues like this are definitely not isolated to Dropbox. I wrote a tool about a year and a half ago (that I had forgotten about by the way) for pulling valid users and data out of Apple’s
MobileMe service. An issue that still exists to this day. Cloud providers need to be thinking about this stuff in the design phase because it is hard to make changes after deployment.

Removing Duplicates with Python

3837063601_d7dbcdba6e_o

I haven’t really written much about
Python lately. I have a feeling that is about to change icon_wink Python is great because it is powerful and allows you to do things very quickly. I figured I would write a short post to show how to remove duplicates by just using the set type. This is probably the quickest and easiest way of removing duplicates in Python.

I don’t think I need to get in to how useful it can be to easily remove duplicates. I have used this many times in the past for doing everything from removing duplicate values from a list of SQL Injection checks to just determining how many unique occurrences I have for a given test.

set

Python has a type called a
set. A set is basically an unordered collection of unique values. You can create a set by specifying a new empty set and adding values to it or by converting another type. The set conversion can be done over any iterable object.

Create a new empty set called myset:

myset = set()
You can add values to your set by using add or update:
myset.add("hello")
myset.
update("world")
Convert another type to a set called newset:
newset = set(another_type)

Sets in Python are nice for a couple of reasons. The first being they only keep unique values. This means that any type you convert to a set or anything you add to a set is unique. It will discard duplicate values. Secondly, you can test for membership in the set. Testing for membership will give you a True / False response based on whether a value exists in the set.

Here are some examples

Converting a list to a set.
3840174182_cb7434d80c_o

Even strings are iterable objects in Python. String conversion to set.

3840174228_21beaa1de1_o

The following shows True / False values for membership tests from the previous string conversion.

3840174280_15905c6989_o

Practical Example

Let’s say you wanted to write a small program that took a file, removed the duplicates, and created a new file with only unique values. The file that contains the duplicates has one value per line, which means there is a newline at the end of each item. You want to maintain the newline in the new unique file that you are writing to as well. You will see the newlines in the following specified by “\n”.

The following is an example:

#!/usr/bin/env python
 
import sys
 
if len(sys.argv) < 3:
print "Usage: remove_dups.py original_file.txt unique_file.txt"
sys.exit(1)
 
file1 =
open(sys.argv[1])
file2 =
open(sys.argv[2], "w")
 
unique =
set(file1.read().split("\n"))
 
file2.
write("".join([line + "\n" for line in unique]))
file2.
close()

I will explain a bit of what’s happening here. Let’s say we have copied this in to a file called remove_dups.py. This program takes two arguments, your original file and the name of the file you want to create without the duplicates. If it doesn’t have the two arguments the program exits.

Next both files are opened, with the second file opened for writing. The first file is read in splitting on newlines. The unique variable now contains the unique values. We then write to the second file every line concatenating a newline on the end. This makes the second file contain the unique values one per line.

You now now how to remove duplicates in Python using the set type. Knowing is half the battle
icon_smile

Update

I wrote this post very quickly and didn’t explain about my use of read() vs using readlines(). Marcin pointed out yesterday that it wasn’t clear. I wanted to show how you could use read() and split on newline characters. My hope was that you would see how you could split on any character when reading a file like commas, semicolons, asterisks, or anything really.

In the code example above, if you wanted to read in a file per line instead of splitting on the “\n” character you could just use readlines() instead.

MonkeyFist Fu: The Intro

3814323619_7a1f60ee5e_o

MonkeyFist is a dynamic request attack tool. It allows you to do some interesting things with various forms of cross-site requests and play them back to the user’s browser. These requests may contain session information bypassing Cross-Site Request Forgery protection mechanisms. It’s really a lot more simple than it seems.

MonkeyFist is basically a small web server that performs some attacks on the data it receives based on information you provide in the payloads.xml file. To do a deeper dive in to the issues that MonkeyFist exploits you can refer to the white paper we wrote prior to Black Hat on Dynamic CSRF located on the docs page of Hexsec
http://hexsec.com/docs

The best way to get familiar with MonkeyFist is just to dive right in. If you haven’t done so, you can go here to download it from the Hexsec Labs page
http://hexsec.com/labs

MonkeyFist requires you be intimately familiar with the request you want to forge. This should be painfully obvious because you need to tell the tool how to construct the request in order for it to be successful.

The Files

There isn’t much to MonkeyFist, all of the files are pretty small. There are a few items in the zip file, but you really only need to worry about MonkeyFist.py and payloads.xml. All of the configuration for payloads in MonkeyFist is done through payloads.xml. We will get in to syntax in another post. In case you didn’t notice the .py extension, MonkeyFist is written in Python. So if your operating system doesn’t have Python installed (Probably just Windows systems) you are going to need it. I suggest version 2.5 or greater. The version that comes with most Linux distributions and OSX is fine. As a final note about the files, ensure that you run MonkeyFist from the same directory as the other files that come with it. Otherwise, it won’t know where they are located
icon_wink

Dependencies

In the beginning there were no further dependencies but I a saw it was necessary to potentially need to do some more complex parsing for the fixation payload. For that reason I decided to add
lxml. I could have gotten away with a more simple parser, but was trying to think ahead a bit. To use the Fixation payload you are going to need to install a 2.x version of lxml. This would be different depending on your operating system. If you are using Ubuntu / Debian don’t just to to apt install lxml, it will give you an old version. Python setuptools helps a lot, it’s just a good idea to use that anyway.

For OSX Leopard (Make sure you have the development tools installed) I just ran:

sudo easy_install lxml


For Ubuntu you have to take a few other steps because you need a few dependencies and the development headers for Python.

If you don’t have setuptools installed:

sudo apt-get install python-setuptools


Then you need to apt-get install the following if you do not have them installed: libxml2-dev libxslt1-dev python2.5-dev

After that you can go ahead and:

sudo easy_install lxml


If you have build problems you probably don’t have the build tools installed:

sudo apt-get install build-essential


Then run easy_install again.

If you decide not to run lxml or do not have the ability to install it, the tool will still run you just won’t be able to use the Fixation handler without a nice failure and error message
icon_smile

Payload Types

There are several types of payloads you can construct with MonkeyFist. Each of these would depend on what the goal of the attack would be or the type of content on a site you would have control over. The basic payload types are dynamic redirect, POST construct, dynamic page, and fixation.

Dynamic Redirect

The dynamic redirect payload simply parses any cross-domain information looking for session data to dynamically construct in to a GET based payload to send back to the user’s browser. Basically, the user would request something and the tool would respond with a 302 redirect to a location. The location value would be the constructed payload. The user’s browser would just request content like normal and follow the redirect and execute the payload.

This payload type is best used in instances where you have the ability to add images tags or other HTML to a site. This way it could be relatively hidden from a user’s browser.

Dynamic Page

This payload constructs a page that performs several functions depending on what type of attack you are performing. You can either have the page perform a GET or a POST for an attack. Both the GET and POST types will be submitted by the user’s browser. So what does the page do? The attack that you construct gets embedded in the page and after the attack happens the user is immediately redirected to a location of your choice. So you could perform an attack and immediately send someone to the Benny Lava video
icon_wink This could be combined with an URL shortener for further obfuscation.

This payload is best used in instances where you have the ability to embed hyperlinks to pages. Another thing to note about the dynamic page payload is that it makes POST based CSRF a whole lot easier to pull off. If you thought submitted data as a POST was a protection mechanism for CSRF you might want to rethink you point of view
icon_wink

POST Construct

This payload is a bit different because the POST request is made by the tool and not the user’s browser. This needs to be kept in mind when using it. You will not have the advantage of the browser being helpful and submitting header information. If the cross-domain leakage is enough that you can perform an entire POST request without the user’s browser then this payload can be used. Otherwise, it will be pretty useless to you
icon_smile

Fixation

The fixation payload allows you to make a request for data that you fixate on to the attack you send to the user. This is still experimental and only works in some narrow situations. This will be expanded later. This works as a modified page payload that performs and extra request and parses the response and gains the necessary information to perform the attack. This would be commonly used to make a request for tokens that you can fixate on to a request forged by the user’s browser.

Default Payload
The default payload gets matched when there is no cross-domain information for the tool to match with your entries in the payloads.xml file. It’s best to not perform an attack with this icon_wink The best thing to do is to make this a link to some real content like an image. This can make the tool a bit more stealthy.
You need to specify a default payload. Not doing so would be like crossing the streams. Well maybe not that bad, but it wouldn’t be good.
MonkeyFist Running Options

There are only a couple of running options with MF and well, all of them do not work as of yet. So, the main one you need to be familiar with is -s. This is the standard attack mode. The -p option specifies the port you would like MF to run on. You won’t need privileged access unless you are trying to run on a low order port. The following would run MonkeyFist on port 8080 using standard attack mode:

./MonkeyFist -p 8080 -s


You can get the about information by running -a, just in case you were curious about what version you are running.

./MonkeyFist -a


Of course, if you need some reference there is always the ole’ help with -h

./MonkeyFist -h


There are a couple of other options that are planned for the future. A testing mode and a random mode will be added as well, but currently, they are not implemented.

Payloads

The payloads.xml file is where you define your attacks. This is where all of your work will be done. The exact options that are specified in this file are still being worked out. This is because as content goes, there needs to be flexibility when identifying these issues. There is a basic set of options that allow you to pull of some attacks even as MonkeyFist sits at version 0.4. Expect some changes in these options. The payloads.xml file will be covered in more detail in a future post.

The Others

You will notice a few other files in the MonkeyFist zip file. You might not want to delete them or you may have some unintended consequences. The page2.html file is blank, but it won’t be if you pull off any Page attacks. Contents are put in to this file dynamically and change per attack. Markup.py is something I didn’t write, it just allowed me to quickly generate some HTML. This was before I made the decision to use lxml. For now I am going to leave it in there, even though it is not the best option. FistLib.py is the most important. This is the workhorse that takes care of all the work.
In Closing

I think that’s it for a small intro on MonkeyFist. In future posts I will explain more about the payloads and how they are constructed. If you notice any problems while running MF please let me know. You can send an email to monkeyfist {at} hexsec {dot} com. This is still a work in progress so please don’t beat me up too bad. I do welcome your feedback though. Thanks.