Man vs. web app

For me, it’s hard to downplay my joy from successfully assailing a web application and finding valuable faults: more so when nothing of value is reported from scanning using the most expensive app scanners.

On a recent gig I was focusing on finding issues with a couple of forms. Wielding BURP, I was intercepting all the GETs and POSTs and noticed the server responding with JSON data (i.e. http://[…]/data.json)

I tossed the JSON blob into an online JSON validator (http://www.jsonlint.com/) to make it easier to read (below is a small snippet).

"sanitized": 
  { aaaDetail": 
    { "aa_id": "276060", 
      "bb_id": "103065", 
      "cc_id": "515ad8933c821b2f72a8cbb7054zed3c", 
      "x_time": "2009-08-12 21:42:40",
      "y_time": "2009-08-12 21:47:34",
      "full_name": "T H", 
      "comment": null, 
      "country": "United States", 
      "state": "Colorado",
       "city": "Broomfield"
       [...]
     }
  } 

I soon realized the JSON objects contained great information for crafting precision attacks.

The JSON data reads like they are database column values. I wondered for a moment what would happen if I just use the strings in the JSON objects for POST keys, came up with logical values matching the keys, then started POSTing the modified form data.

Bingo. By simply intercepting POST requests and appending new key/value pairs to the list of key/value pairs already being submitted I was able to modify database values unattended by the developers. In this case, it meant I was able to modify information inserted and owned by other users of the site.

I’m not espousing Harry Potter skills here, rather illustrating one of many examples of why Man is needed to go beyond where automated web app scanners stop.

Posted by tate Sat, 22 Aug 2009 22:59:00 GMT


Comments

  1. Jim Manico about 17 hours later:

    The funny thing, we coders are often encouraged to write generic code for core needs like data management, instead of writing specific queries for each endpoint. In fact, it is often called “good coding” since you save a dramatic amount of time writing generic layers of this nature. Luckily in this case, the mitigation is (most likely) very easy - an additional where clause added to the generic query engine to include the current userId from session should do the trick.

    I can only imagine your wonder when you realized “I own this database”, none-the-less. And I could never call a lack of data layer access control good coding, either. :) Nice work!

  2. Clerkendweller 2 days later:

    Very clever (man). Do you know if there is a list of common database field (and table) names, in the same way OWASP DirBuster provides directory names which could be used to compare with full or partial application variable names?

  3. Tate Hansen 3 days later:

    @Clerkendweller: I do not know of any such lists. Great idea though.