Friday, August 5, 2011

Ammonite

Ammonite is a security scanner extension for Fiddler that allows you to detect all the usual suspects including SQLi, XSS, file inclusion, buffer overflows etc. It has some pretty cool features I haven't seen elsewhere. My favs are exporting requests to python urllib2 code, breadth first vuln search, and scanner throttling. In breadth first search mode, the scanner only looks for the first instance of a vuln for a given session. This is great on a pentest where you don't have much time and want to get as deep as you can in the shortest possible time. Throttling is useful in a variety of scenarios but the most common one is where you are testing in an unstable environment and too many requests per second knock the thing over or make your results unreliable. It also fuzzes XML and JSON POST bodies which are now standard on most recently created apps.

Friday, April 1, 2011

Cross Cloud Scripting

XCS or Cross-Cloud Scripting is one of the more recent threats affecting cloud applications delivered as a service enhancing RoI. Applications exchange information in the cloud, specifically cross-cloud applications, in an effort to increase business and IT productivity, data productivity, context and business objects.

Before we can understand XCS, a thorough understanding of BI, SaaS and digital DNA must be grasped. Cloud platforms and cloud infrastructure are relatively immature and suffer from the same vulnerabilities as traditional distributed point to point applications. Complex data management and quality requirements dictate the methodologies employed by cloud products and service providers.

Agile software development processes must be tweaked to address the problem of XCS if the industry is to succeed. Finally, Ask not what your cloud can do for you, but what you can do for your cloud.

Thursday, February 24, 2011

Django User Enumeration

Django sites that run the built-in admin site prior to r15639 are vulnerable to user enumeration. The Django team was notified and corrected this in SVN revision 15639. Details here: http://code.djangoproject.com/changeset/15639. By specifying a content type id of 3 and enumerating object IDs beginning with 1, the view responds with redirects containing usernames (ex: /admin/r/3/[USERID]/). No authentication is required to exploit this vulnerability.

Django sites should either upgrade to the latest SVN or manually modify django/trunk/django/contrib/admin/sites.py changing:

url(r'^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$', 'django.views.defaults.shortcut'),

to

url(r'^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$', wrap(contenttype_views.shortcut)),

Better still, bind the admin site to 127.0.0.1 and access it over SSH.

Sunday, February 20, 2011

Tracing Objective-C

I don't know much about Objective-C and decided to get my learn on. Here are some discoveries I made.

Objective-C is dynamic. Objects and classes support some degree of introspection at runtime. Methods / messages are routed and dispatched. They are not hardcoded addresses as in C++.

Objective-C is message oriented. All those fancy Object Oriented / Message passing calls end up going through one of a few functions. When you compile

[self printMessageWithString:@"Hello World!"];

it is translated to something like

objc_msgSend(self,@selector(printMessageWithString:),@"Hello World!");

I borrowed those snippets from http://cocoasamurai.blogspot.com/2010/01/understanding-objective-c-runtime.html without permission.

This is good news. It means just about every OO operation in ObjC will pass through this function. Way to make hooking/tracing easy. I then asked Google if anyone else has been talking about this sort of thing. It looks like I am late to the game - http://www.dribin.org/dave/blog/archives/2006/04/22/tracing_objc/.

Specifically:

If you set the NSObjCMessageLoggingEnabled environment variable to "YES", the Objective-C runtime will log all dispatched Objective-C messages to a file named /tmp/msgSends-.


You can even enable message logging from within a debugging session using:

(gdb) call (void)instrumentObjcMessageSends(YES)


It gets better. The Apple objc runtime also includes support for a custom logger. This might be useful logging the parameters of certain messages of interest.

I also found good general information on reversing objc here: http://culater.net/wiki/moin.cgi/CocoaReverseEngineering. New bits here are class-dump and FScript. The former will dump a header file close enough for use, the latter (through FScriptAnywhere) allows you to introspect and modify apps at runtime.

Friday, February 11, 2011

Finding the Heap of an iPhone Application

Often when doing mobile application assessments it is necessary to check that sensitive data is properly discarded when no longer in use. This data is often found on the heap. While it would be nice to dump core of a running process and strings/grep the dump this is tough on a jailbroken iphone. The gdb from Cydia does not include core dump commands (generate-core-file, gcore).

Building gcore-arm from source is pretty easy with Xcode, however, it runs into trouble when making kernel syscalls on the iphone. Specifically, task_for_pid fails. I'm not sure why but I suspect it's related to some missing entitlements. A concept I don't fully understand just yet. Somehow Cydia's gdb has all the right entitlements. It would be great if there was a gcore package from Cydia.

Anyway, here's a trick for finding the heap when you need to. First, attach to your app running on the phone with

gdb -p [PID]

Set a breakpoint on malloc with

break malloc

Do something with the app so that the malloc breakpoint triggers. Once triggered, run till return with 'finish'. Inspect r0 with 'info reg r0'. The r0 register stores a function's return value on ARM platforms. The return value from malloc is an address somewhere on the heap. To find the base of the heap, use:

info mach-region [RETURNVAL]

This should show the start and end of the region. You can then dump the heap to a file with:

dump binary memory [FILENAME] [STARTADDR] [ENDADDR]

Sunday, January 9, 2011

Fun with M2Crypto

Here is one way to load an RSA public key from a string with M2Crypto in python.

from M2Crypto import RSA, BIO

def _load_pub_key(ks):
ks = ks.encode('utf-8')
return RSA.load_pub_key_bio(BIO.MemoryBuffer(ks))

If ks contains unicode characters the operation will fail hence the recoding of ks.

Verifying a signature is a little tricky. The verify function is documented as accepting a data parameter. The parameter name is misleading. It is actually expecting data to contain a hash. The same hash used to generate the signature. Here is an example.

>>> from M2Crypto import RSA, BIO
>>> k = RSA.load_key('bank_cert.pem')
>>> data = "easy like sunday morning"
>>> from hashlib import sha1
>>> signature = k.sign(sha1(data).digest(), 'sha1')
>>> k.verify(sha1(data).digest(), signature, 'sha1')
1

Friday, December 24, 2010

Python Prime Number Generator

Here's an interesting prime number generator that I created. It avoids multiplication and modulo arithmetic. It does not sieve a preallocated set of integers (ex. find all primes up to N). You can serialize it and then resume generating (no need to specify an upper bound).


Its internal state consists of 2 lists and an integer representing the current candidate. The lists are a list of primes and a corresponding list of prime multiples. For a given candidate, the algorithm compares the candidate to current prime multiples. If the candidate is less than a multiple, the prime multiple is increased additively to its next multiple (p + p + ... + p) where p is the prime root. If the multiple is equal to the candidate, the candidate is not prime. If there's no match, the candidate is prime and added to the list (p**2 added to the list of multiples).


class PrimeGen:
p = [ ] # primes found
m = [ ] # current multiple of each prime

def prime(self, i):
for j in xrange(0, len(self.p)):
if (i + i) < self.m[j]: break
if i > self.m[j]: self.m[j] += self.p[j]
if i == self.m[j]: return 0
self.p.append(i)
self.m.append(i ** 2)
return 1

def gen(self):
"""A prime generator"""
i = 2
while 1:
if self.prime(i): yield(i)
i += 1


The drawback is running time. Sieves (ex. Eratosthenes) are faster. This one generates the first million primes (<= 15,485,863) in about 10 minutes on modest hardware.