ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

27
Application Security Forum - 2012 Western Switzerland 7-8 novembre 2012 Y-Parc / Yverdon-les-Bains https://www.appsec-forum.ch Abusing Twitter API Nicolas Seriot One year later…

Transcript of ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

Page 1: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

Application Security Forum - 2012Western Switzerland

7-8 novembre 2012Y-Parc / Yverdon-les-Bainshttps://www.appsec-forum.ch

AbusingTwitter APINicolas Seriot

One year later…

Page 2: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

AppSec 2012Twitter relied on OAuth to control 3rd party clients.

Bad idea! secret tokens are easy to extract.

Leaked consumer secrets can result in API abuses, DoS and

session fixation attacks.

Page 3: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

@boblord

HITB 2013 Amsterdam

Page 4: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

HITB, April 10th April 23rd, 2013

Page 5: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

Some App. Twitter

invalidate_token

user_timeline

violet token is for Some App.

consumer_secret

consumer_key

bearer_token

App

. Onl

yA

uthe

ntic

atio

ntoken

Use the consumer tokens to get the bearer token and exhaust the limits. Denial of service.

And now you can invalidate the bearer token.

Denial of servicefor “Some App.”! ht

tps:

//dev

.twitt

er.c

om/d

ocs/

auth

/app

licat

ion-

only

-aut

h

Page 7: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

Core Text Crasher

$ gdb Twitter

(gdb) rStarting program: /Applications/Twitter.app/Contents/MacOS/Twitter

Program received signal EXC_BAD_ACCESS, Could not access memory.Reason: KERN_INVALID_ADDRESS at address: 0x00000001084e80080x00007fff9432ead2 in vDSP_sveD ()

(gdb) bt#0 0x00007fff9432ead2 in vDSP_sveD ()#1 0x00007fff934594fe in TStorageRange::SetStorageSubRange ()#2 0x00007fff93457d5c in TRun::TRun ()#3 0x00007fff934579ee in CTGlyphRun::CloneRange ()#4 0x00007fff93466764 in TLine::SetLevelRange ()#5 0x00007fff93467e2c in TLine::SetTrailingWhitespaceLevel ()#6 0x00007fff93467d58 in TRunReorder::ReorderRuns ()#7 0x00007fff93467bfe in TTypesetter::FinishLineFill ()#8 0x00007fff934858ae in TFramesetter::FrameInRect ()#9 0x00007fff93485110 in TFramesetter::CreateFrame ()#10 0x00007fff93484af2 in CTFramesetterCreateFrame ()...

Page 8: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

The vulnerable code has probably been in the wild for yonks; some people noticed it six months ago and it appeared on some slides [PDF] in April for a Hack In The Box conference presentation. Barely anyone took any notice back then - but it started to spread around the web over the weekend after a trigger string appeared on a Russian website.

http://www.theregister.co.uk/2013/09/04/unicode_of_death_crash/

Page 11: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

Twitter

request_token

access_token

home_timeline green tokens are for@nst021 with

My.app

consumer_secret

consumer_key

access_secret

access_key

request_key

Rev

erse

Aut

h.

iOS_secret

iOS_key

My.app Server

My.app Server

My.app

✓ CS is not shipped with My.app.

✗ Users unknowingly grants My.app access to her DMs.

http

s://d

ev.tw

itter

.com

/doc

s/io

s/us

ing-

reve

rse-

auth

Page 12: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

Twitter / iOS Integration

• How does Twitter identify the application sending requests through iOS frameworks ?

• TWRequest (iOS 5) adds an application_id param to each request (eg. ch.seriot.myApp)

• SLRequest (iOS 6+) does not!

Page 13: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

Accounts Creation

Web iOS Settings

CaptchaNo

Captcha

Page 15: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

POST https://api.twitter.com/1/account/generate.json

Authorization: OAuth \ oauth_nonce="C4E16213-9058-49E8-A06E-65A5D961EED0", \ oauth_signature_method="HMAC-SHA1", \ oauth_timestamp="1378598935", \ oauth_consumer_key="IHUYavQ7mmPBhNiBBlF9Q", \ oauth_token="8285392-niqOtDvwwUXOzQJsCvDxcPndUBHb4dWrTLXw1nTw", \ oauth_signature="V6ySPsviDz%2BJnTvBFoE2qpHJv70%3D", \ oauth_version="1.0"

adc: paddiscoverable_by_email: 0email: EMAILgeo_enabled: 0lang: enname: NAMEpassword: PASSWORDscreen_name: SCREEN_NAMEsend_error_codes: truetime_zone: CEST

Related consumer secret is easy to find with GDB

attached to iOS Simulator.

No need to fill captchas anymore :)

Page 16: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

Weird Consumer Identity

WTF?!

Page 17: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

“Almost” OAuth3.2. Verifying Requests

Servers receiving an authenticated request MUST validate it by: (...)

o If using the "HMAC-SHA1" or "RSA-SHA1" signature methods, ensuring that the combination of nonce/timestamp/token (if present) received from the client has not been used before in a previous request (the server MAY reject requests with stale timestamps as described in Section 3.3).

3.3. Nonce and Timestamp

(...) A nonce is a random string, uniquely generated by the client to allow the server to verify that a request has never been made before and helps prevent replay attacks when requests are made over a non-secure channel. The nonce value MUST be unique across all requests with the same timestamp, client credentials, and token combinations.

http://tools.ietf.org/html/rfc5849

✗ (nonce, timestamp, token)can be reused across requests.

✗ nonce can be fixed.

Page 18: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

Ad

No Ad

Promoted Contents

Page 19: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

Undocumented API?$ strings Twitter ...activity/about_me.jsonactivity/by_friends.jsonconversation/show.jsondiscover/highlight.jsondiscover/universal.jsonstatuses/:id/activity/summary.jsonstatuses/media_timeline.jsonstatuses/mentions_timeline.jsontimeline/home.jsontrends/available.jsonusers/recommendations.json...

Page 20: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

Looking for Ads• Still no clues about promoted contents.

Let’s start our favorite SSL proxy!

• Does’t work because of certificate pinning.

• Binary patching FTW!

Twitter.app SSL proxy api.twitter.com

Page 21: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

-[ABHTTPRequest connection:willSendRequestForAuthenticationChallenge:] ... 0x00260cd4 45F2EA50 movw r0, #0x55ea 0x00260cd8 3246 mov r2, r6 0x00260cda C0F23900 movt r0, #0x39 0x00260cde 7844 add r0, pc ; 0x5f62cc 0x00260ce0 0168 ldr r1, [r0] ; @selector(_isPinnedCertificateChain:) 0x00260ce2 2046 mov r0, r4 0x00260ce4 B0F1DEEC blx imp___picsymbolstub4__objc_msgSend

; BOOL isPinned = [self _isPinnedCertificateChain:object];

0x00260ce8 0446 mov r4, r0 0x00260cea 2846 mov r0, r5 0x00260cec B0F1FAEC blx imp___picsymbolstub4__objc_release

0x00260cf0 14F0FF0F tst.w r4, #0xff ; Z = (r4 & 0xff) == 0 ; Z = (r4 == 0) 0x00260cf4 40F08E80 bne.w 0x260e14 ...

; if(isPinned) { ; goto 0x260e14; // continue handling the request ; } else { ; return error; ; }

Page 22: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

https://ece.uwaterloo.ca/~ece222/ARM/ARM7-TDMI-manual-pt3.pdf

ARM THUMB Instruction Set

Page 23: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

Crafting Opcode1110 0... .... .... ; opcode format

0x00260e14 - 0x00260cf4 = 0x120 ; offset

0000 0001 0010 0000 ; 0x1200000 0000 1001 0000 ; 0x120 >> 11110 0... .... .... ; format___________________1110 0000 1001 0000 ; 0xE0900xE 0x0 0x9 0x0

-> 0x90E0 little endian

Page 24: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

-[ABHTTPRequest connection:willSendRequestForAuthenticationChallenge:] ... 0x00260cd4 45F2EA50 movw r0, #0x55ea 0x00260cd8 3246 mov r2, r6 0x00260cda C0F23900 movt r0, #0x39 0x00260cde 7844 add r0, pc ; 0x5f62cc 0x00260ce0 0168 ldr r1, [r0] ; @selector(_isPinnedCertificateChain:) 0x00260ce2 2046 mov r0, r4 0x00260ce4 B0F1DEEC blx imp___picsymbolstub4__objc_msgSend

; BOOL isPinned = [self _isPinnedCertificateChain:object];

0x00260ce8 0446 mov r4, r0 0x00260cea 2846 mov r0, r5 0x00260cec B0F1FAEC blx imp___picsymbolstub4__objc_release

- 0x00260cf0 14F0FF0F tst.w r4, #0xff ; Z = (r4 & 0xff) == 0 ; Z = (r4 == 0)+ 0x00260cf0 90E0FF0F b 0x260e14 ; jump to happy path (FF0F is unused) 0x00260cf4 40F08E80 bne.w 0x260e14 ; never reached ...

; goto 0x260e14; // continue handling the request ; ; ; return error; ;

Page 25: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

My 2 Bytes

Page 26: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

Promoted Contents Secret

&pc=true

Page 27: ASFWS 2013 Rump Session - Abusing Twitter API One year later… Nicolas Seriot

Twitter: @nst021

Web: http://seriot.ch/abusing_twitter_api.php

Slides: http://www.slideshare.net/ASF-WS/presentations