Droid in the middle

Door Slurpgeit op vrijdag 12 juli 2013 00:15 - Reacties (16)
Categorie: -, Views: 6.415

Aangezien ik de laatste paar dagen druk bezig ben geweest met het verkeer van mobiele devices onderscheppen, leek het me wel leuk om hier een verhaaltje over te tikken. Vooral ook omdat er soms echt rare dingen gebeuren op de achtergrond.

Zoals altijd gebruik ik ook dit keer weer een Ubuntu 12.04 VM, samen met een HTC Desire met een Cyanogenmod 10.1 rom (Android 4.2.2). Op Ubuntu ga ik wat software installeren om er een WiFi Access Point van te maken. Als adapter heb ik een Alfa (deze).

Eerst, wat software installeren:
sudo apt-get -y install hostapd isc-dhcp-server

Hostapd is software voor het opzetten van een access point, en isc-dhcp-server is, zoals de naam misschien al doet vermoeden, een DHCP server. Na de installatie, zorg ik er ook gelik voor dat hostapd niet elke keer automatisch opstart als het systeem dat doet:
sudo update-rc.d hostapd disable

Vervolgens maak ik een configuratie aan voor hostapd, waar ik wat settings over mijn access point in zit:
sudo nano /etc/hostapd.conf


code:
1
2
3
4
5
6
7
8
9
ssid=Henk
channel=1
wpa=2
wpa_passphrase=qwertyuiop
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
interface=wlan0
driver=nl80211
hw_mode=g


Deze settings zorgen voor een Access Point met als SSID 'Henk' op kanaal 1, met WPA2-AES en als sleutel 'qwertyuiop'. Dit alles gaat gebeuren op de interface wlan0 (Mijn Alfa).

Hierna is het ook nog nodig om een configuratie voor de DHCP server te maken. Eerst gooi ik de oude weg, dit is toch maar een example config die veel te vol staat met allerlei rotzooi:
sudo rm /etc/dhcp/dhcpd.conf

Vervolgens open ik daar een nieuw bestand:
sudo nano /etc/dhcp/dhcpd.conf

en gooi ik er deze informatie in:

code:
1
2
3
4
5
subnet 10.0.0.0 netmask 255.255.255.0 {
  range 10.0.0.100 10.0.0.149;
  option domain-name-servers 8.8.8.8, 8.8.4.4;
  option routers 10.0.0.1;
}

(ja, /24 op een 10.x.x.x netwerk is met opzet :Y))
Hiermee deelt mijn DHCP server adressen uit van 10.0.0.100 tot 10.0.0.149, met als DNS servers die van Google, en mijn Ubuntu VM als default gateway. Hiervoor moet ik nog wel even mijn WiFi adapter het goede adres geven:
sudo ifconfig wlan0 10.0.0.1/24

Ook is het nodig om de DHCP server te vertellen welke interface hij moet gebruiken. Dus doe ik:
sudo nano /etc/default/isc-dhcp-server

en verander ik

code:
1
INTERFACES=""


naar

code:
1
INTERFACES="wlan0"


Om ervoor te zorgen dat alles goed gaat, is het nodig om IP forwarding in te schakelen:
sudo sysctl net.ipv4.ip_forward=1

en om wat firewall regels toe te passen
sudo iptables -A FORWARD -s 10.0.0.0/24 -i wlan0 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -d 10.0.0.0/24 -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE

Dan even de DHCP server starten:
sudo service isc-dhcp-server start

en het Access Point de lucht in schoppen
sudo hostapd hostapd.conf

Dat lijkt allemaal prima te werken. Ik kan verbinden en lekker surfen:

https://dl.dropboxusercontent.com/u/7521450/blog/ditm/henk_ap.png

Een grappig iets om te herinneren is dat (zoals ik al eens eerder heb besproken), een WiFi enabled apparaat constant zoekt naar netwerken waar je ooit mee verbonden bent (mits je ze niet handmatig verwijderd hebt, iets wat bij iOS devices alleen kan als ze in de buurt zijn.). Deze "probes" kan je opvangen om te zien waar zoal naar gezocht wordt. Als er bijvoorbeeld in mijn buurt iemand zoekt naar de open hotspot "KPN", en ik noem mijn Access Point geen "Henk" maar "KPN", dan zal die persoon automatisch verbinden met mijn Access Point zonder het door te hebben. Maar wat voor verkeer zie je zoal langskomen?

Om dat wat inzichtelijker te maken gebruik ik Burp. Een zogenaamde intercepting proxy, waarbij je alle HTTP(s) requests kan zien, en aanpassen. Hiervoor moet alleen wel het verkeer op poort 80 (HTTP) en 443 (HTTPS)omgelust worden naar die proxy (Die luistert naar verkeer op poort 8080. Dat is vrij simpel te doen:
sudo iptables -t nat -A PREROUTING -i wlan0 -s 10.0.0.0/24 -p tcp --dport 80 -j REDIRECT --to-port 8080
sudo iptables -t nat -A PREROUTING -i wlan0 -s 10.0.0.0/24 -p tcp --dport 443 -j REDIRECT --to-port 8080
sudo iptables -A INPUT -i wlan0 -s 10.0.0.0/24 -p tcp --dport 8080 -j ACCEPT

En even in stellen dat Burp op alle interfaces gaat luisteren:

https://dl.dropboxusercontent.com/u/7521450/blog/ditm/burp_listen.png

Als je verkeer gaat onderscheppen van devices die niet weten dat ze door een proxy geleid gaan worden, is ook het vinkje "Invisible mode" erg belangrijk:

https://dl.dropboxusercontent.com/u/7521450/blog/ditm/invisible.png

En zo kan je in ieder geval al het HTTP verkeer zien van de client. Zoals bijvoorbeeld een bezoek naar tweakers.net op de telefoon:

https://dl.dropboxusercontent.com/u/7521450/blog/ditm/req_t.net.png

Daarnaast wordt ook al het SSL verkeer door de proxy gestuurd, maar omdat Burp dit ontsleuteld en weer versleuteld met een eigen certificaat zal dit zorgen voor een certificaatwaarschuwing of een niet werkende app (In het goede geval). Bij de tweakers.net app was dit ook het geval. Deze wil (mits er inloggegevens ingevoerd staan in de app) geen content ophalen vanwege een ongeldig SSL certificaat. Kudo's tweakers! Helaas doet het relatief populaire spelletje "Draw Something" daar minder moeilijk over. Bij de eerste run van het spel wordt het device automatisch geregistreerd. Via SSL, dat wel, maar het maakt de app geen klap uit wat voor certificaat daarbij hoort. Resultaat:

https://dl.dropboxusercontent.com/u/7521450/blog/ditm/ds.png

Kassa! Eerste wachtwoord is binnen. Eens kijken wat andere populaire games doen. Kent iemand "4 plaatjes 1 woord"? Zij jou wel:

https://dl.dropboxusercontent.com/u/7521450/blog/ditm/4p1w.png

Nu heb ik op dit toestel eigenlijk alles kwa locatiebepaling uit staan, en zo weinig mogelijk gegevens ingevoerd. Maar zo te zien willen ze best wat van je weten. Positie, geslacht, leeftijd, serienummers, MAC adressen, verbindingsmethode, etc, etc. En dat alleen maar voor een advertentie? Gelukkig versturen ze het versleuteld over het internet, oh, wacht, niet. Even verder kijken..

Coindozer! WIe houdt er niet van een beetje muntje schuiven. Maar, wat de hell dit allemaal moet voorstellen:

https://dl.dropboxusercontent.com/u/7521450/blog/ditm/coindozer.png

Dat nummer daar achter "Type 3" lijkt verdacht veel op het IMEI van de telefoon. En waar is in godsnaam de "ishacked" parameter voor? Root detectie? Not doing a very good job :). Moving on..

We komen aan bij "Stick Stunt Biker 2". En bij de eerste run al gelijk wat interessants:

https://dl.dropboxusercontent.com/u/7521450/blog/ditm/stunt.png

Die grote blob tekst is misschien wat duidelijk, maar hier is ie met enters en ontdaan van URL encoding:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
packages=android
com.andrew.apollo
com.android.backupconfirm
com.android.bluetooth
com.android.browser
com.android.calculator2
com.android.calendar
com.android.cellbroadcastreceiver
com.android.certinstaller
com.android.contacts
com.android.defcontainer
com.android.deskclock
com.android.development
com.android.dreams.basic
com.android.dreams.phototable
com.android.email
com.android.exchange
com.android.galaxy4
com.android.gallery3d
com.android.htmlviewer
com.android.inputdevices
com.android.inputmethod.latin
com.android.keychain
com.android.location.fused
com.android.magicsmoke
com.android.mms
com.android.musicvis
com.android.noisefield
com.android.packageinstaller
com.android.phasebeam
com.android.phone
com.android.providers.applications
com.android.providers.calendar
com.android.providers.contacts
com.android.providers.downloads
com.android.providers.downloads.ui
com.android.providers.drm
com.android.providers.media
com.android.providers.settings
com.android.providers.telephony
com.android.providers.userdictionary
com.android.provision
com.android.settings
com.android.sharedstoragebackup
com.android.smspush
com.android.soundrecorder
com.android.stk
com.android.systemui
com.android.vending
com.android.voicedialer
com.android.vpndialogs
com.android.wallpaper.holospiral
com.android.wallpaper.livepicker
com.bel.android.dspmanager
com.cyanogenmod.lockclock
com.cyanogenmod.trebuchet
com.cyanogenmod.updater
com.djinnworks.StickStuntBiker2.free
com.google.android.apps.uploader
com.google.android.backup
com.google.android.ears
com.google.android.feedback
com.google.android.gm
com.google.android.gms
com.google.android.gsf
com.google.android.gsf.login
com.google.android.location
com.google.android.marvin.talkback
com.google.android.onetimeinitializer
com.google.android.partnersetup
com.google.android.setupwizard
com.google.android.syncadapters.bookmarks
com.google.android.syncadapters.calendar
com.google.android.syncadapters.contacts
com.google.android.talk
com.google.android.voicesearch
com.hyperkani.stuntcarchallenge
com.icemobile.tweakers
com.king.candycrushsaga
com.leftover.CoinDozer
com.omgpop.dstfree
com.supportware.Buienradar
com.svox.pico
com.tmobile.themechooser
com.tmobile.thememanager
com.zynga.draw2.googleplay.free
de.lotum.whatsinthefoto.us
jackpal.androidterm
net.cactii.flash2


Eh? Ik kan me geen geldige reden bedenken waarom een provider van advertenties een lijst moet hebben van ALLE apps die op mijn telefoon staan. En al helemaal niet waarom ze dat onversleuteld versturen (En ja, ook hier staat mijn Device ID in het request). Toen ik echter verder ging testen bleek het echter nog erger. De app draaide niet, en ik installeerde de ING app. Tot mijn grote verbazing zie ik:

https://dl.dropboxusercontent.com/u/7521450/blog/ditm/stunt2.png

Kan iemand mij vertellen waarom een simpel spelletje elke andere app die ik installeer doorbelt?

* Slurpgeit zet tin foil hat op.

One more time for dramatic effect, dit is dus allemaal zonder een nieuw root certificaat op het apparaat te installeren, of tools als SSLStrip. Je maakte je druk om PRISM? Maak je liever druk om je eigen broekzak.

Uiteraard is dit soort onderzoek heel erg goed zelf uit te voeren. Het is best makkelijk om het CA certificaat van Burp op je toestel te installeren, gewoon even het certificaat exporteren met een browser, opslaan als .crt op de root van je SD kaart, en:

https://dl.dropboxusercontent.com/u/7521450/blog/ditm/CA1.png
https://dl.dropboxusercontent.com/u/7521450/blog/ditm/CA2.png
https://dl.dropboxusercontent.com/u/7521450/blog/ditm/CA3.png

Daarnaast is het ook wel handig om op het toestel een proxy in te stellen, zodat Burp de juiste certificaten kan genereren per website:

https://dl.dropboxusercontent.com/u/7521450/blog/ditm/proxy.png

Als laatste heb je ook nog apps die doen aan "Certificate pinning". Oftewel, ze accepteren alleen het certificaat dat ergens in de code gedefiniŽerd staat. Hier zijn echter ook programma's voor, zoals: https://github.com/iSECPartners/android-ssl-bypass en https://code.google.com/p/intrinsec-android-ssl-patch/.

Ik wilde nog een stuk bij dit blog maken over wat apps allemaal versturen als ze gepatched zijn om alle SSL certificaten te accepteren, of als ik het Burp CA certificaat op het toestel had gezet. Bij nader inzien leek het me echter wel leuk om dat aan jouw verbeelding over te laten, en misschien een beetje te triggeren om zelf op onderzoek uit te gaan ;). De resultaten van hierboven zijn overigens niet meer dan een paar uur onderzoek. Ik ga even het huis verven met loodverf, want er verschijnen allemaal busjes met schotels op het dak voor de deur.

robots.txt

Door Slurpgeit op dinsdag 2 juli 2013 00:23 - Reacties (12)
Categorie: -, Views: 7.273

Klein dumppostje tussendoor. Leek me eigenlijk wel een goed idee om een scriptje te maken wat automatisch de robots.txt van een website doorloopt om te kijken of er nog spannende pagina's tussen staan. Wie weet heeft iemand anders er nog wat aan ;). Overigens ben ik absoluut geen coder, dus verwacht een paar schoonheidsfoutjes.

https://dl.dropboxusercontent.com/u/7521450/blog/robots/2-7-2013%200-20-54.png


Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env python

#############################################
# GetRobots - Get titles for all            #
# robots.txt URI's.                         #
# Author: Slurpgeit                         #
# Github: https://github.com/Slurpgeit      #
#############################################

## Imports
import sys
import urllib2
import time
import socket

# Check for BeautifulSoup
try:
    from bs4 import BeautifulSoup
except:
    print 'Please install the BS4 python module.'
    sys.exit()

## Basic stuff
# The helptext
helptext = """\
==========\n\
GetRobots\n\
==========\n\
Usage: """ + sys.argv[0] + """ -u <url> <options>\n\
    -u <url>        The URL to use\n\
    -P <ip>:<port>      Use HTTP proxy\n\
    -t <timeout>        Timeout (Default is 1 second)
    -v          Verbose (Show HTTP errors)
    -h          Display this help\
"""

# See if URL is set
try:
    url = urllib2.unquote(sys.argv[sys.argv.index('-u') + 1])
    if ('http://' not in url) and ('https://' not in url):
        url = 'http://' + url
except:
    print helptext
    sys.exit()

# Check if URL resolves
try:
    rawurl = url.strip('http://')
    rawurl = url.strip('https://')
    socket.gethostbyname(rawurl)
except:
    print '\033[91m[-]\033[0m Could not revolve "' + url + '"'
    sys.exit()

# Parse command line
if ('-h' in sys.argv) or ('--help' in sys.argv):
    print helptext
    sys.exit()

if '-P' in sys.argv:
    proxyaddr = urllib2.unquote(sys.argv[sys.argv.index('-P') + 1])
    proxy = urllib2.ProxyHandler({'http': proxyaddr})
    opener = urllib2.build_opener(proxy)
    urllib2.install_opener(opener)

if '-t' in sys.argv:
    timeout = int(urllib2.unquote(sys.argv[sys.argv.index('-t') + 1]))
else:
    timeout = 1

if '-v' in sys.argv:
    verbose = 1

## Functions
# Get all "Disallow: " lines
def getdisallow(url):
    disallow = []
    try:
        req = urllib2.urlopen(url + '/robots.txt')
        status = req.getcode()
        print '\033[92m[+]\033[0m ' + str(status) + ' | robots.txt'

    except Exception, error:
        try:
            print '\033[91m[-]\033[0m ' + str(error.code) + ' | robots.txt'
        except:
            print '\033[91m[-]\033[0m Error: ' + str(error)
        sys.exit()
    
    robots = req.readlines()
    for line in robots:
        if 'Disallow:' in line:
            if ('Disallow: /\n' not in line) and ('Disallow: /*\n' not in line):
                disallow.append(line)
    return disallow

# Get all URI titles
def getcontent(uri):
    for uri in uris:
        try:
            req = urllib2.urlopen(url + uri)
            status = str(req.getcode())
            html = BeautifulSoup(req)
            try:
                title = html.title.string
                title = title.strip('\n')
                title = title.strip('\t')
            except:
                title = 'No title'

            print '\033[92m[+]\033[0m ' + status + ' | ' + uri.rstrip() + ' | "' + title.rstrip() + '" | ' + url + uri.rstrip()
        except urllib2.URLError, error:
            try:
                if verbose:
                    print '\033[91m[-]\033[0m ' + str(error.code) + ' | ' + uri.rstrip()
            except:
                pass
        time.sleep(timeout)

## Running code
# Fill 'uris' array
uris = []
disallow = getdisallow(url)

if not disallow:
    print 'No "Disallow:" entries in robots.txt.'
else:
    for entry in disallow:
        entry = entry.strip('Disallow: ')
        uris.append(entry)

# Request all URI's
getcontent(uris)



https://github.com/Slurpg...ster/scripts/getrobots.py