Sphinx Relay Chat Hack oder Ich bestimme wohin du dich verbindest
Vor kurzem habe ich angefangen etwas mit dem Sphinx Relay Chat zu experimentieren. Leider ist es aktuell so, dass dieser nicht mit Tor funktioniert. Dies ist insofern ungünstig, da viele insbesondere neue Nodes, standardmäßig Tor nutzen. Tatsächlich gibt es dazu auch ein Ticket auf github.
Im besten Fall, installiert ihr Sphinx z.B. auf eurem Umbrel oder Raspiblitz, dann erhaltet ihr einen Zugangscode und den scant ihr als QR oder gebt diesen innerhalb der Desktop App ein.
“So sieht die erfolgreiche Installation mit z.B. Umbrel aus, QR Code und String wurden obfuskiert aus Sicherheitsgründen”
Alternativ, kann man sich auch das Logfile von dem Sphinx Container ansehen.
$ docker logs -f c4760585abc6
=> env: production
=> [db] starting setup...
=> [db] sync now
=> [db] done syncing
=> [db] setup done
=> 2021-06-22 06:34:05 [lnd] reconnecting... attempt #1
Node listening on 3300.
(node:7) DeprecationWarning: grpc.load: Use the @grpc/proto-loader module with grpc.loadPackageDefinition instead
=> [lnd] connected! 2021-06-22 06:34:05
>> FINISH SETUP
[lightning] [ 'signBuffer' ]
[tribes] try to connect: tls://tribes.sphinx.chat:8883
[db] created node owner contact, id: 1
=> Relay version: , commit:
>> aXA6OmFpc29wZGpzYXAxM2FscGRzcHYyemdiZDRvNW52bXM2ejkzamRtYXNkc2R2ZXlscWQub25pb246MzMwMDo6Njc4MTIzODkxMjM4OTEyZGZhYWJjMzEyMzEK
Scan this QR in Sphinx app
In meinem Fall konnte sich der Client jedoch nicht mit dem Ziel verbinden und es gab auch keine Fehlermeldung. Dies war verwunderlich, da ich sicher war, dass die Daten korrekt waren….so entstand der erste Artikel dieser Serie. Nachdem ich noch weiter gebastelt hatte, viel mir auf, dass der einzugebene String/Code, stark nach base64 aussah. Base64 ist, ähnlich wie das im BTC Bereich gerne gewählte Base58 ein Kodierungsformat, dass für einen nahtlosen Transport von Informationen insbesondere in Netzwerkpacketen oder Daten geeignet ist. Historisch betrachtet, war dies insbesondere bei Textprotokollen wie z.B. SMTP von großem Vorteil. Übrigens falls ihr euch fragt, warum man bei BTC gerne Base58 benutzt, die Antwort ist einfach: Es fehlen Zeichen, die einfach zu verwechseln sind, wie z.B. 0 (null) und O (großes O). Dies ist sehr sinnvoll bei Adressen, die vielleicht mit Hand abgetippt werden. Niemand will seine wertvollen BTCs ins Nirvana schicken. Aber zurück zu dem Encoding. Der String, der euch angezeigt wird, lässt sich problemlos mit einem base64 decoder zurück in eine für den Menschen lesbare Zeile verwandeln. Derartige Decoder gibt es jede Menge im Internet: Online Decoder oder wir machen das mit Linux und dem Tool: base64. Powershell unterstützt das ganze natürlich auch.
In meinem Beispiel nehme ich Linux und der Code sieht wie folgt aus: * aXA6OmFpc29wZGpzYXAxM2FscGRzcHYyemdiZDRvNW52bXM2ejkzamRtYXNkc2R2ZXlscWQub25pb246MzMwMDo6Njc4MTIzODkxMjM4OTEyZGZhYWJjMzEyMzEK
Solltet ihr kein base64 installiert haben:
Debian/Ubuntu:
# apt install base64
ArchLinux:
# pacman -S base64
Alternativ könnt ihr z.B. auch einen python oder perl Interpreter nehmen:
$ python -c 'import base64; s=b"test123";print(base64.b64encode(s))'
b'dGVzdDEyMw=='
$ python -c 'import base64; s=b"dGVzdDEyMw==";print(base64.b64decode(s))'
b'test123'
Die Dekodierung auf der Kommandozeile:
$ echo 'aXA6OmFpc29wZGpzYXAxM2FscGRzcHYyemdiZDRvNW52bXM2ejkzamRtYXNkc2R2ZXlscWQub25pb246MzMwMDo6Njc4MTIzODkxMjM4OTEyZGZhYWJjMzEyMzEK'|base64 -d
ip::aisopdjsap13alpdspv2zgbd4o5nvms6z93jdmasdsdveylqd.onion:3300::678123891238912dfaabc31231
Wir sehen:
* Unsere Onion Adresse
* Einen Port (3300)
* Und etwas was wie eine ID oder ein Passwort aussieht
!ACHTUNG! Die letzte Zeichenkette (678123891238912dfaabc31231) ist euer Passwort! Daher empfehle ich ausdrücklich NICHT den eigenen Base64 String, der von dem Sphinx-Relay angezeigt wird mit anderen Nutzern zu teilen. Dazu ein kurzer Blick in den Source-Code vom Sphinx Relay Chat:
export async function getQR():Promise<string> {
let theIP
const public_url = config.public_url
if (public_url) theIP = public_url
if (!theIP) {
const ip = process.env.NODE_IP
if (!ip) {
try {
theIP = await publicIp.v4()
} catch (e) { }
} else {
// const port = config.node_http_port
// theIP = port ? `${ip}:${port}` : ip
theIP = ip
}
}
return Buffer.from(`ip::${theIP}::${password || ''}`).toString('base64')
}
Die letzte Zeile, zeigt uns, theIP ist eine Kombination aus der IP-Adresse und dem Port, nach dem gewählten Trennzeichen :: kommt die Variable password, also das Passwort. Um den Client mit unserer Node zu verbinden, können wir dies recht simpel machen und müssen dafür nicht mehr die /etc/hosts anpassen. Wir können der Anwendung einfach einen selbstgenerierten String geben. Legen wir also fest: dass wir anstelle der Onion-Adresse eine IP benutzen wollen, z.B. die IP von lightning.codes (162.55.163.147), Standardport und Passwort lassen wir gleich.
$ echo 'ip::162.55.163.147:3300::678123891238912dfaabc31231' | base64
aXA6OjE2Mi41NS4xNjMuMTQ3Lm9uaW9uOjMzMDA6OjY3ODEyMzg5MTIzODkxMmRmYWFiYzMxMjMx
Cg==
Mit dieser Zeichenkette verbindet sich die Client-Anwendung direkt mit dem System auf dem Ihr das Relay installiert habt. Falls ihr lieber eine Host mit dynamischer IP respektive DynDNS angeben wollt oder einen anderen Port, ist dies auch kein Problem. Denn wir bestimmen gerade was der Client machen soll ;-)
Happy Chatting!