Acties:
  • +6 Henk 'm!

  • StapelPanda
  • Registratie: Februari 2005
  • Laatst online: 10-06 09:23
Wat is de Gramofon?
Met de Gramofon tover je elke luidspreker om tot draadloze speaker. Sluit deze wifi ontvanger aan op je audio systeem en stream muziek van een mobiel apparaat naar je speakers. Op deze manier luister je draadloos naar internet radio, streamingdiensten of je opgeslagen nummers. Als je meerdere Gramafons hebt, maak je eenvoudig een multiroom systeem. Met 1 app neem je de controle over elke speaker. Je streamt muziek naar een willekeurige speaker of laat elke speaker tegelijkertijd hetzelfde nummer afspelen. Doordat de ontvanger via wifi muziek streamt, luister je naar een helder geluid zonder storingen.
TLDR: Kastje welke je kan gebruiken om een versterker zonder Spotify Connect te voorzien van Spotify Connect.

Wat is jouw doel?
Het leek mij weer een keer leuk om iets te onderzoeken op embedded gebied, persoonlijk ben ik heel erg benieuwd hoe de Spotify Connect geregeld is.
Gramofon is gemaakt door FON welke eerder ook al openWRT heeft gebruikt, met een beetje geluk kan dit dus ook op routers met een USB poort draaien, of op een ander bordje zoals een Raspberry PI Zero of een CHIP.

Ook hoop ik dat het doorlezen van dit topic mensen op weg kan helpen om een apparaat met Linux te onderzoeken.

Welke stappen heb je al genomen?
Eerst het apparaat open geschroefd en gekeken wat voor processor erin zit, een AR9341. Met behulp van de datasheet de slow UART poort opgezocht en de baantjes gevolgd. Hier was al een net groepje van 4 pinnen aanwezig. Dus een mooi kabeltje aan vast gesoldeerd om deze aan de PC te koppelen.
Nadat de terminal is ingesteld op de relatief standaard baudrate van 115200 kwam meteen een terminal tevoorschijn. Helaas geen standaard wachtwoord voor root, tijd om de bootloader te bezoeken. Na de reboot kwamen er in het begin rare tekens tevoorschijn, een andere baudrate voor de bootloader dus. De buspirate eraan gehangen en tijdens het bootproces een paar keer de macro "(4) automatic baudrate detection" gedraaid, de nieuwe baudrate is: 128000. "Press any key to abort boot", alweer rare tekens 8)7, dus hetzelfde proces nog een keer, het winnende getal is: 121212.
code:
1
2
3
4
5
6
7
8
9
10
11
## Booting image at 9f020000 ...
   Image Name:   MIPS OpenWrt Linux-3.3.8
   Created:      2015-11-13  19:47:03 UTC
   Image Type:   MIPS Linux Multi-File Image (lzma compressed)
   Data Size:    1022268 Bytes = 998.3 kB
   Load Address: 80060000
   Entry Point:  80060000
   Contents:
   Image 0:  1022260 Bytes = 998.3 kB
   Verifying Checksum at 0x9f020040 ...OK
   Uncompressing Multi-File Image ... OK

Relevant U-Boot stukje

Ze willen het blijkbaar niet eenvoudig maken om het apparaat te clonen, het TFTP commando heeft alleen een get en geen put. De enige overgebleven optie is dan via de seriële terminal de hele flash uit te lezen, voor proef eerst even de kernel gedownload aan de hand van de u-boot log. Het commando hiervoor is md.b [address] [bytes] waarbij alle getallen hexadecimaal zijn. De regels bevatten het adres, 16 bytes in hex en in ASCII (zie hieronder). Met dit Python scriptje kan dit worden omgezet naar een echte binary dump. Helaas miste er af en toe een stukje en moesten een aantal regels gerepareerd worden (cheap ass usb serieël converter). Voor 1Mb is dit te doen, de 16Mb programmeer ik liever een script voor.
code:
1
a0000000: 19 d5 80 ee b7 7d b3 e4 50 fe d0 b6 80 85 99 08    .....}..P.......

Bytedump

Dus over naar het scripten, mijn Python is net zo als mijn mening over python: smerig en voor snelle oplossingen.
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
# Python util for getting a hex dump from an u-boot prompt, device needs to be in u-boot before starting this script
# Designed for the Gramofon by Michiel Vonk
# Used https://github.com/gmbnomis/uboot-mdb-dump as reference for output processing

import time
import serial
import sys

BYTES_IN_LINE =   0x10
BYTES_PER_BATCH = 0x1000

s_addr = c_addr = 0x9f020000
e_addr =          0x9fffffff

print("Downloading image from {:x} to {:x}".format(c_addr, e_addr))

def getline(ser):
    line = ser.readline()
    if line == b'':
        return ''
    sline = line[:-2].decode('ascii')
    if sline.startswith('fonera'):
        return ''
    return sline

def empty_ser_buffer(ser):
    while getline(ser) != '':
        pass

fOut = open('rawtxt', 'w')
fOutB = open('rawbytes', 'wb')

with serial.Serial('COM3', 121212, timeout=1) as ser:
    while(True):
        #endcondition
        if c_addr > e_addr:
            break
        #get some bytes
        iProgress = (c_addr - s_addr) * 100 / (e_addr - s_addr)
        print (" - Getting {:x} to {:x}, {:.2f}".format(c_addr, c_addr + BYTES_PER_BATCH, iProgress))
        ser.write(("md.b {:x} {:x}\n".format(c_addr, BYTES_PER_BATCH)).encode('ascii'))
        while True:
            sline = getline(ser)
            if sline.startswith('md.b'):
                continue
            if sline == '':
                break
            
            # ADDR: B1 B2 B3 B4 ... B6    C1C2...C16
            data, ascii_data = sline.split("    ", maxsplit = 1)
            straddr, strdata = data.split(maxsplit = 1)
            straddr = straddr[:-1]
            
            # Address
            addr = int.from_bytes(bytes.fromhex(straddr), byteorder = 'big')
            # Data
            data = bytes.fromhex(strdata)
            
            # Check address, if not right break out of loop, will continue on current_address
            if addr != c_addr:
                print("Address mismatch, empty buffer and retry")
                empty_ser_buffer(ser)
                break
            if len(data) != BYTES_IN_LINE:
                print("StrData mismatch {:d}, empty buffer and retry".format(len(strdata)))
                empty_ser_buffer(ser)
                break
            if len(ascii_data) != BYTES_IN_LINE:
                print("AsciiData mismatch {:d}, empty buffer and retry".format(len(ascii_data)))
                empty_ser_buffer(ser)
                break
            
            # Verify that the mapping from hex data to ASCII is consistent (sanity check for transmission errors)
            good = 1
            hex_to_ch = {}
            for b, c in zip(data, ascii_data):
                try:
                    if hex_to_ch[b] != c:
                        print("Data mismatch, empty buffer and retry")
                        empty_ser_buffer(ser)
                        good = 0
                        break
                except KeyError:
                    hex_to_ch[b] = c
            if good == 1:
                c_addr += BYTES_IN_LINE
                fOut.write(sline + '\n')
                fOutB.write(data)
            else:
                break
    print("Done!")
    ser.close()
fOut.close()
fOutB.close()

Jep, geen commandline variabelen, alles lekker hardcoded 8). Maar wel met resultaat, door deze binary in binwalk te gooien krijgen we het volgende resultaat:
code:
1
2
3
4
5
6
DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             uImage header, header size: 64 bytes, header CRC: 0x7B5184B9, created: 2015-11-13 19:47:03, image size: 1022268 bytes, Data Address: 0x80060000, Entry Point: 0x80060000, data CRC: 0x8867A038, OS: Linux, CPU: MIPS, image type: Multi-File Image, compression type: lzma, image name: "MIPS OpenWrt Linux-3.3.8"
72            0x48            LZMA compressed data, properties: 0x6D, dictionary size: 8388608 bytes, uncompressed size: 3067464 bytes
1022332       0xF997C         Squashfs filesystem, little endian, version 4.0, compression:xz, size: 8625546 bytes, 1351 inodes, blocksize: 262144 bytes, created: 2015-11-13 19:47:00
9699328       0x940000        JFFS2 filesystem, big endian

Dus 4 stukjes geheugen met herkenbare punten, het Squashfs kan netjes geopend worden met 7zip en bevat het gehele filesystem.

In het filesystem zit ook een passwd en shadow file, na 5 uur "John the ripper" kwam hier niets uit. Gezien ik in andere bestanden wachtwoorden heb gezien van 20 karakters heb ik deze hoop opgegeven.

09-11-2016
Tijd om de firmware image te voorzien van een nieuw wachtwoord om zo de seriele console te kunnen bereiken.

14-11-2016
Gieltjev in "[Hacking] Gramofon"

Status
  • Toegang tot bootloader
  • Complete binary dump van flash
  • Filesysteem doorzoekbaar op PC
  • Nieuw wachtwoord in squashfs plaatsen en flashen op device
  • TODOSysteem onderzoeken via terminal
Handige info
Datasheet: Linkje
Baudrate: 115200 (Terminal), 128000 (U-Boot), 121212 (U-Boot terminal)
Firmware: OpenWRT 12.09, Kernel 3.3.8

[ Voor 0% gewijzigd door StapelPanda op 16-11-2016 08:44 . Reden: update ]


Acties:
  • 0 Henk 'm!

  • Schlumpie
  • Registratie: Oktober 2013
  • Laatst online: 10-12-2023

Schlumpie

Professioneel prutser

Pas wel op dat ze niet opeens achter je aan gaan rennen met een rechtzaak he :P

Verstuurd vanaf mijn magnetron


Acties:
  • 0 Henk 'm!

  • StapelPanda
  • Registratie: Februari 2005
  • Laatst online: 10-06 09:23
Schlumpie schreef op maandag 14 november 2016 @ 10:30:
Pas wel op dat ze niet opeens achter je aan gaan rennen met een rechtzaak he :P
Ik heb mijzelf ook al wel afgevraagd waar de grens ligt, het gebruiken van 3 baudrates voor de seriële console is natuurlijk al een teken dat de fabrikant dit liever niet heeft. Vervolgens zijn ook bijna alle binary dump mogelijkheden uit uBoot gehaald.

Natuurlijk staat in de titel een algemenere term Hacking ipv Reverse engineering. IANAL, maar ik denk zelf dat ik op dit moment nog aan de veilig kant zit. Op het moment dat ik de binary hier plaats ga ik denk wel over een grens heen, hun Spotify Application Key staat hier bijvoorbeeld in alsmede hun software. Ook als ik mijn doelstelling haal om de software op een ander apparaat te draaien begint het tricky te worden.

Nog even geen tijd gehad om de squashfs te unpacken en repacken met een nieuw Root wachtwoord. De gramofon draait na een reboot nogsteeds vrolijk.

Acties:
  • 0 Henk 'm!

  • Puch-Maxi
  • Registratie: December 2003
  • Laatst online: 11-06 22:00
Mooie topicstart! Ik ga je vorderingen volgen :).
Psst, code=Python3

My favorite programming language is solder.


Acties:
  • 0 Henk 'm!

  • m3gA
  • Registratie: Juni 2002
  • Laatst online: 12-06 08:53
Het prototype van de Gramofon heeft op een raspberry pi (met Mopidy) gewerkt. De fon functionaliteit zal wel niet werken aangezien die voor een deel authenticeert met het mac adres.

heb je hier nog wat aan?

The Gramofon GPL Source Code Based On OpenWrt Is Available To Download At Http://Download.Fon.Com/F...n-Fon2415prod-Gpl.Tar.Bz2

Acties:
  • +2 Henk 'm!

  • StapelPanda
  • Registratie: Februari 2005
  • Laatst online: 10-06 09:23
m3gA schreef op maandag 14 november 2016 @ 14:45:
Het prototype van de Gramofon heeft op een raspberry pi (met Mopidy) gewerkt. De fon functionaliteit zal wel niet werken aangezien die voor een deel authenticeert met het mac adres.

heb je hier nog wat aan?

The Gramofon GPL Source Code Based On OpenWrt Is Available To Download At Http://Download.Fon.Com/F...n-Fon2415prod-Gpl.Tar.Bz2
Thanks! de URL is hoofdlettergevoelig: http://download.fon.com/firmware/gramofon/latest/20140915-1.2.26-gramofon-fon2415prod-gpl.tar.bz2
Snel even doorgekeken, maar het is puur het oninteressante deel, namelijk het OpenWRT gedeelte.

Update 14-11-2016
De actie was redelijk simpel: Eerst met unsquashfs de image uitpakken, password aanpassen en met mksquashfs inpakken. Erna erachter komen dat je 100Kb te veel hebt is een ander verhaal.
Gelukkig zit er een flashy website in welke 2 achtergrondplaatjes heeft van 300Kb, dat is er nu eentje minder O-)

Erna via U-Boot en TFTP de image ingeladen en 1000en jjfs2 errors naar je hoofd geslingerd krijgen, doordat de squashfs image niet op een mooie grens begint moet of het begin of eind gewist worden. Mijn motto was gewoon overschrijven, OpenWRT was het daar minder mee eens.

Dus met wat terminal skills (dd,cat) de orginele raw image en de nieuwe image een image gemaakt welke wel op 16 byte blokken begint en eindigt en het mogelijk wordt om het flash te wissen voordat de nieuwe image erin gaat.

Resultaat:
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
banana login: root
Password:


BusyBox v1.19.4 (2015-11-13 18:31:49 CET) built-in shell (ash)
Enter 'help' for a list of built-in commands.

                      .--.         .--.
                          \       /
                   |\      `\___/'       /|
                   \\    .-'@ @`-.     //
                   ||  .'_________`.  ||
                    \\.'^ _  Y  _ ^`.//
                    .'   (_) | (_)   `.
                   :  _      |      _  :
                  :  (_)     |     (_)  :
                  :          |          :
                  :     _    |    _     :
                  :.   (_)   |   (_)    :
                __::.        |          :__
               /.--::.    _  |  _      :--.\
            __//'   `::. (_) | (_)    .'   `\\___
           `--'     //`::.   |     .'\\     `--'
                    ||  `-.__|__.-'   ||
           jgs      ||                ||
                    //                \\
                   |/                  \|

 ---------------------------------------------------------------
   Coccinellidae (3.1.9, 23f3d22)
 ---------------------------------------------------------------
root@banana:~#

Acties:
  • 0 Henk 'm!

  • Damic
  • Registratie: September 2003
  • Nu online

Damic

Tijd voor Jasmijn thee

Nice

Al wat ik aanraak werk niet meer zoals het hoort. Damic houd niet van zijn verjaardag


Acties:
  • 0 Henk 'm!

  • StapelPanda
  • Registratie: Februari 2005
  • Laatst online: 10-06 09:23
Update 16-11-2016
Ok, mijn doelstelling is wel een beetje uit het raam gevlogen. De oplettende lezer had dit al kunnen zien doordat in de openingspost "MIPS Linux" stond, alle apparaten die ik had genoemd zijn allemaal ARM based.

De mensen van FON zijn begonnen met een AP123, een ontwikkelbord van Atheros. Veel meer is niet bekend over dit bord aangezien je dan 10000 stuks moet afnemen en waarschijnlijk een NDA mag tekenen. Hier hebben zij een AKM dac aangehangen en een driver voor geschreven, het totaalpakket heet dan de gramafon AKA FON2415.

Mopidy, welke in de Kickstart demo gebruikt werd is afgeschreven. Atheros/Quallcom had tegen die tijd orb Networks overgenomen, dit tezamen met hun open llJoyn platform levert een AllPlay device. Tenminste dat vermoed ik, de audioplayer heet "orbPlayer" en hangt aan een AllJoyn daemon vast.

Tot nu toe heb ik dus de interessante binaries weten te bemachtigen, helaas is het totale pakket (AllJoyn + orbPlayer + libraries) rond de 7Mb, hier komt dan nog OpenWRT + Alsa en USB drivers bij. Meeste goedkope apparaten (6/7 euro tot 20 euro) hebben maar 8Mb flash. Dit gaat dus nooit passen.

Heb al een tijdje op wat websites rondgeneusd voor alternatieve apparaten, deze zal ik in de loop van de dag in deze post erbij zetten.

3/4G Wifi Router: 6 Dollar
Mediatek Router: 19 Dollar

De eerste heeft waarschijnlijk maar 4Mb ROM, de tweede is best cool met 16Mb en SD kaart :9~

[ Voor 10% gewijzigd door StapelPanda op 16-11-2016 16:08 . Reden: Routers toegevoegd ]


Acties:
  • 0 Henk 'm!

  • TopdRob
  • Registratie: Oktober 2005
  • Laatst online: 02-03 08:32
Nog vooruitgang geboekt. Is het bijvoorbeeld mogelijk om de (opensource) alljoyn/allplay software te dumpen?
Pagina: 1