Niedawno trafiłem na ciekawy, krótki wpis na stronce The Den (theden.sh), poświęcony nietuzinkowemu sposobowi na przechowywanie danych.

Nietypową skrytką byłby tutaj DNS. Ta część internetu, którą można porównać do książki telefonicznej lub do precyzyjnego drogowskazu.
Każda osoba mająca własną domenę może modyfikować te informacje, które jej dotyczą. Autor proponuje modyfikację, która jest jak doklejenie na drogowskazie albo na stronie książki karteczki z informacjami.

Wpis z The Den jest całkiem przystępny dla osób, które miały okazję korzystać z programów konsolowych. Ale dla innych będzie wyglądał jak ciąg niezrozumiałych pojęć oraz inkantacji.

Postanowiłem zatem „przetłumaczyć” wpis dla mniej konsolowych hobbystów. Raz: może więcej osob go doceni. Dwa: w ten sposób lepiej ułożę fundamenty we własnej głowie. Tak jak już kiedyś zrobiłem w przypadku artykułu na temat pewnej cyfrowej blokady.

Zapraszam!

Zdjęcie drogowskazu na północy Wielkiej Brytanii, prawie w całości zakrytego różnymi nalepkami. Obrazek jest przerobiony, zamiast jednej z nazw miejscowości widać napis ciemnastrona.com.pl. Karteczki naklejone na znak są podpisane 'Rekordy DNS'.

Źródła: Daily Record, Flaticon, przeróbki moje. Szczegóły pod koniec wpisu.

Spis treści

DNS i rekordy

Wpis kręci się wokół DNS-a, więc na początek napiszę o nim parę słów.

To jeden z filarów współczesnego internetu. Choć mało kto o nim wie, DNS cały czas działa w tle, mówiąc przeglądarkom, dokąd mają iść. Ujawnia na ich prośbę, jaki adres „komputerowy” (IP) odpowiada czytelnemu adresowi „ludzkiemu” (jak ciemnastrona.com.pl).

DNS bierze udział w najprostszych, codziennych wędrówkach po sieci.
Gdy klikniemy w przeglądarce link do jakiejś strony, której nigdy (bądź od jakiegoś czasu) nie odwiedzaliśmy, to przeglądarka nie będzie go znała. I zapyta jakiegoś DNS-a.

Jakiegoś, bo nie ma jednego, centralnego, globalnego systemu. Istnieje wiele różnych, niezależnych od siebie serwerów DNS.
W praktyce przeglądarka często zwraca się do tych sugerowanych przez hotspota, z którym jest połączony komputer. Chyba że ustawi się coś innego w opcjach.

Powiązane wpisy

DNS już parę razy gościł na łamach tego bloga.
Raz wspominałem o jego powiązaniach z internetową prywatnością. Czasem jej szkodzi, bo ukazuje firmom telekomunikacyjnym, jakie ktoś odwiedzał strony. Czasem pomaga – odgrywa kluczową rolę w nowej, raczkującej metodzie szyfrowania (meta-)danych.
Innym razem pisałem o tym, że może być narzędziem cenzury. Na życzenie swoich właścicieli okłamującym internautów, że jakaś strona nie istnieje.

DNS to jednak nie tylko wyrocznia mówiąca, jakie IP odpowiada danej stronie. Może przechowywać więcej rodzajów informacji.

Dig i zaglądanie do rekordów DNS-a

Typowe przeglądarki, jak Firefox, to świetna sprawa dla osób ciekawych świata. Pozwalają łatwo zajrzeć za kulisy odwiedzanych stron internetowych.

Jakiś ciekawy element, niestandardowa animacja? Można kliknąć prawym przyciskiem myszy i wybrać opcję Zbadaj albo Zbadaj element. I wczytać się w kod strony (czasem całkiem czytelny). Eksperymentować, zmieniać wartości. Zobaczyć, jak działa ten świat :relaxed:.

W przypadku DNS-a niestety nie ma tak dobrze.
Przeglądarka ukrywa interakcje z nim przed użytkownikami i nie daje równie łatwego wglądu „pod maskę”. Na plus wyróżnia się tutaj Firefox, bo przynajmniej daje taki wgląd dodatkom przeglądarkowym. Ale to jednak nie do końca to samo.

Na szczęście istnieją inne programy, które pozwalają prosić DNS-a o różne rzeczy. Jednym z najbardziej znanych jest dig (skrót od Domain Information Groper).

W najprostszym przypadku można użyć komendy:

dig DOMENA

Gdzie DOMENA oznacza czytelną nazwę „trzonu” strony. Na przykład google.com – znana wszystkim wyszukiwarka i jeden z głównych szwarccharakterów na tym blogu.

Wyświetli się lista informacji, jakie dig uzyskał od DNS-a na temat podanej domeny. O ile strona funkcjonuje i nie jest przez pytanego DNS-a cenzurowana, to wyświetli się takie coś:

Fragment odpowiedzi otrzymanej od DNS-a. Posiada ona nagłówek 'Sekcja odpowiedzi', a pod spodem widać jedną linijkę tekstu. Na jej końcu znajduje się adres IP, złożony z czterech liczb rozdzielanych kropkami

Liczby i kropki na końcu to adres IP. To właśnie jego otrzymują przeglądarki po zapytaniu DNS-a. Po czym wysyłają pod niego prośbę o stronę, już do samego Google’a.

Nie tylko adresy IP

…Ale to tylko najbardziej podstawowe zastosowanie. Literka A w wyniku wskazuje konkretny rodzaj rekordu – odpowiadający adresom IP, a dokładniej IPv4. To tylko jeden z wielu dostępnych rodzajów!

Można rozszerzyć wcześniejszą komendę, dopisując do niej rodzaj rekordu:

dig DOMENA REKORD

Można spróbować tam wpisać any, żeby zdobyć wszystkie możliwe rekordy, ale nie każdy DNS to wspiera. Można też wpisać jakiś konkretniejszy rodzaj z dostępnej listy.

Poniżej rekordy, jakie DNS pokazuje w odpowiedzi na różne prośby diga związane ze stronką theden.sh:

Tabelka złożona z dwóch najważniejszych kolumn. Pierwsza z nich ma tytuł Komenda i widać nad nią ikonę laptopa. Znajdują się w niej trzy warianty komendy dig theden.sh, dla różnych nazw rekordów. Kolumna druga, nad którą jest ikona serwera, jest zatytułowana Odpowiedź.

Odpowiedź DNS-a na zapytanie ogólne any to nawiązanie do jednego z internetowych standardów, RFC8482. Sprowadza się z grubsza do: „Nie muszę odpowiadać na to zapytanie”.

Omówienie wpisu z The Den

Podstawy DNS-a i rekordów przybliżyłem, więc przejdę teraz do wpisu z The Den. Jego autor wpadł na pomysł, żeby użyć rekordów TXT (przeznaczonych na ogólne informacje w formie tekstu) i chować w nich różne rzeczy.

Ciekawostka

Ikonka theden.sh to gratka dla użytkowników Firefoksa – jest animowana!
Firefox to jedna z bardzo nielicznych przeglądarek wspierających animowane ikony w zakładkach. Większość użytkowników zobaczy tylko statyczny, nieruchomy obrazek. A fanom Lisa będzie mrugało, jak kursor w konsoli.

Dwa zrzuty ekranu pokazujące tę samą ikonkę w zakładce przeglądarki. W pierwszym przypadku zawiera w dolnej części zielony pasek, w drugim go nie ma

Początek

Wstęp omówię bardzo pobieżnie, bo to głównie luźne przemyślenia i eksperymenty autora. Nie mają wpływu na samo mięso wpisu, czyli chowanie informacji w DNS-ie.

Na początku autor zastanawia się, jak dużo danych może tam umieścić. Najpierw cytuje oficjalny standard i na jego podstawie ustala, że może sobie pozwolić na 255 bajtów w pojedynczym rekordzie TXT.

1. TXT "Krótki ciąg znaków 1"
2. TXT "Krótki ciąg znaków 2"
...

W komentarzach z HN znalazłem informację, że w rzeczywistości maksimum jest znacznie większe. Bo liczba 255 nie odnosi się do całego rekordu TXT, tylko do ciągu znaków, a rekord może zawierać ich więcej.
Nie weryfikowałem, kto ma rację, ale przedstawiam tu obie wersje.

Potem autor trochę eksperymentuje ze skryptami w języku Python, żeby zobaczyć, ile mógłby zyskać dzięki kompresji.
Używa do niej modułu zlib. Rozmiar danych znacznie maleje, ale bardzo możliwe, że DNS by ich nie przyjął. Przez kompresję przestał to być „grzeczny” format tekstowy. Mogłyby wystąpić błędy podczas przetwarzania.

Dlatego autor w drugiej kolejności używa modułu base64, który (kosztem pewnego zwiększenia rozmiaru) potrafi każdy ciąg zer i jedynek przedstawić jako ciąg znaków „grzecznych”, które już nie powinny nigdzie sprawiać problemu.

Wniosek autora? W pojedynczym rekordzie dałoby się całkiem sporo zmieścić.
Ale to taka obserwacja poboczna. Sednem wpisu było zaszyfrowanie jakiegoś tekstu, umieszczenie go na DNS-ie, a potem odczytanie. Prawie wszystko z użyciem zwięzłych poleceń konsolowych.

Etap szyfrowania

Najpierw autor zapewne uruchomił swoją zaufaną konsolę, w którą można wpisywać polecenia tekstowe. Zapewne na Linuksie – więc przykro mi, ale użytkownicy Windowsa mogą nie być w stanie powtórzyć u siebie komend. Chyba że zainstalują dodatkowe rzeczy.

Następnie zaszyfrował dane, używając do tego takiej komendy:

echo -n 'mySuperSecretPassword1!!1!!' | openssl enc -e -aes-256-cbc -a -salt -pbkdf2

Dla osób, które nie mają styczności z konsolą, może to brzmieć jak czarna magia. Dlatego na spokojnie to objaśnię.

  1. Pionowe kreski |, czyli „rury” (ang. pipes), służą do łączenia programów w efektowne combosy.
    Jeśli między programami stoi rura, to wynik programu po lewej stronie trafi do tego po prawej. Wynik ostatniego programu w tym łańcuszku trafi do wyjścia standardowego. Czyli w praktyce: wyświetli się w konsoli.

  2. Każdy z programów składa się ze swojej nazwy (najbardziej po lewej) oraz argumentów rozdzielanych spacjami. Argumenty to dodatkowe informacje mówiące programowi, jak ma działać. Odpowiednik klikania pstryczków w ustawieniach jakiejś apki.

Te dwie podstawy tu wystarczą. Są dwa programy połączone rurą, reszta to argumenty określające ich działanie. A że obrazek wyraża więcej niż tysiąc słów, to służę schematem:

Schemat pokazujący szyfrowanie tekstu jako dwie maszynki do mięsa. Pierwsza jest podpisana echo, a druga openssl. Strzałki pokazują kierunek przepływu danych, a obok nich są dopisane argumenty. Na samym dole widać zaszyfrowany tekst wewnątrz miniaturki konsoli

W roli programów: maszynki do mięsa.

Argumenty dla każdego programu są inne, bo każdy ma własną konwencję. Aby poznać możliwe argumenty, można wpisać w konsolę nazwę programu, a po niej -h albo --help. Często (nie zawsze) coś podpowie.
W tym konkretnym przykładzie mamy:

  • echo z dwoma argumentami: -n i tekstem do zaszyfrowania.

    Konsola nie jest miejscem, w którym można wpisywać wszystko, co się tylko chce. Muszą to być nazwy programów, argumenty do nich albo inne, specjalne operatory (jak rury).
    Jeśli zatem chce się wprowadzić do konsoli tekst, to trzeba to zrobić przez jakiś program. I tylko od tego jest tutaj echo.
    Z kolei argument -n mówi „echu”, żeby nie dodawało na końcu oznaczenia końca linii, jak to domyślnie robi.

  • openssl otrzymuje tekst do zaszyfrowania. Poza tym ma aż sześć dodatkowych parametrów.

    Pierwszy argument to enc, mówiący żeby użyć konkretnego podprogramiku (bo openssl to cały pakiet). Z kolei -e mówi, żeby działać w trybie szyfrowania.
    -a mówi, żeby zastosować kodowanie Base64 (wspomniane wyżej; sprowadza tekst do postaci 64 najprostszych, „bezpiecznych” znaków).
    Pozostałe parametry – -aes-256-cbc, -pbkdf2 i -salt – precyzują metody szyfrowania. Niestety mało wiem o kryptografii i trudno mi ocenić, czemu autor wybrał akurat ten zestaw. Na HN ktoś napisał, że to niezbyt bezpieczna kombinacja.

Posumowując: poprzez echo autor wprowadza do konsoli swój tekst. Następnie rura podaje go do openssl-a, żeby go zaszyfrować. Wyświetla się pytanie o hasło, autor wpisuje hackerman. Potem jeszcze raz. Pod spodem wyświetla się jego tekst, już w zaszyfrowanej postaci.

Umieszczanie danych w DNS-ie

Po zaszyfrowaniu danych autor pisze:

I stored the encrypted secret on the TXT record under pass.theden.sh

Ma na myśli, że skopiował zaszyfrowany tekst z poprzedniego punktu. Potem zapewne zalogował się na swoje konto u rejestratora domen (firmy, od której nabył theden.sh). Kliknął opcję dodania nowego rekordu typu TXT, wkleił do niego swój szyfr. I to wszystko.

Ciekawostka

Wnikliwi zauważą, że strona bloga to thoughts.theden.sh, zaś tekst umieścił na pass.theden.sh. Dlaczego?
To dlatego, że autor jest właścicielem domeny głównej, theden.sh. Z tego tytułu może również wydzielać jej subdomeny. A każda z nich może mieć własne rekordy DNS, inne niż ta główna.
Co więcej, odkrycie wszystkich subdomen cudzej domeny nie jest wcale taką prostą sprawą. Osoby analizujące powiązania korzystają w tym celu z różnych trików.

Od teraz każdy Smith, Kowalski czy inny obywatel świata może zwrócić się do swojego DNS-a z prośbą o rekordy tekstowe dla (sub-)domeny pass.theden.sh. O ile jego DNS nie ma strony The Den na cenzurowanym, to je odeśle.
A wśród nich ten nowy, świeżo dodany, z zaszyfrowanym tekstem.

Odszyfrowywanie danych

Po umieszczeniu tekstu wewnątrz DNS-a autor demonstruje, w jaki sposób mógłby do niego sięgnąć z dowolnego miejsca, używając jednolinijkowej komendy. Jeszcze bardziej zakręconej niż poprzednia:

dig pass.theden.sh TXT +short | sed 's/^"\(.*\)"$/\1/' | openssl aes-256-cbc -a -d -salt -pbkdf2

Ta sprawia niestety, że polecenie może być trudniejsze do zrozumienia. Zatem ponownie rozbiję je na części! Są tu trzy programy, jeden po drugim, połączone „rurami” – dig, sed i openssl. Cała reszta to rzeczy, jakie autor do nich wrzuca.

Schemat pokazujący pobieranie rekordu tekstowego z DNS-a i odszyfrowanie go jednym konsolowym poleceniem. Widać na nim trzy programy, stylizowane na rysunkowe maszynki do mięsa, oraz strzałki pokazujące przepływ informacji.

A jeśli chodzi o same programy, mamy tutaj:

  • omawiany już dig

    Pobiera rekordy odpowiadające subdomenie pass.theden.sh, należącej do theden.sh.
    Argumenty to TXT (żeby pobrać tylko rekordy tekstowe) oraz +short, żeby wyświetlić same wartości.
    Autor ma u siebie tylko jeden rekord, więc program zwróci jeden tekst, otoczony podwójnymi cudzysłowami.

  • sed

    Dostaje tekst i argument 's/^"\(.*\)"$/\1/'.
    Brzmi groźnie, zwłaszcza jeśli ktoś nie poznał wyrażeń regularnych!
    Ale sens jest prosty: „weź cały tekst, wraz z cudzysłowami po brzegach, i zastąp go samym wnętrzem bez cudzysłowów”. To potrzebne, żeby kolejny program z łańcuszka mógł ten tekst przyjąć.

    Dokładniejsze omówienie komendy sed (dla zainteresowanych)

    Pierwsza litera, s, wskazuje tryb (substition, czyli znajdź+zamień). Ma składnię s/znajdź/zamień_na/ (plus ew. parametry dodatkowe, których w tym przypadku nie ma).

    W polu Znajdź jest ciąg ^"\(.*\)"$.
    Znak ^ oznacza początek tekstu, zaś $ jego koniec. Czyli ^" oraz "$ odpowiadają za złapanie cudzysłowów na brzegach.
    .* oznacza „weź wszystko od tego miejsca do kolejnej pasującej rzeczy” (czyli tutaj: do cudzysłowu zamykającego).

    Nawiasy sprawiają z kolei, że to wszystko, co się między nimi złapie, zostanie przypisane do grupy numerowanej. W polu Zamień na… autor się do tej grupy odnosi, właśnie poprzez \1 (gdyby grup było więcej, to dałoby się wyjść poza jedynkę).

  • openssl

    Komenda bardzo podobna jak przy szyfrowaniu, bo ma być jego odwrotnością.
    Jest tu jednak parę różnic. Zamiast podprogramiku enc zostaje użyty aes-256-cbc (nazwa odnosi się do użytego szyfru; wcześniej była identyczna, ale jako parametr).
    Parametr -d, od decrypt, włącza tryb odszyfrowywania.

Na ostatnim etapie wyświetli się prośba o wpisanie hasła. Po wpisaniu hackerman, ustawionego wcześniej przez autora, ukaże się pierwotny, odszyfrowany tekst.

Wniosek: można użyć DNS-a jako swojej małej skrytki, a nawet zintegrować go z różnymi konsolowymi skryptami. Jedynie etap umieszczania tam danych może wymagać ręcznego działania.

Podsumowanie

Bardzo lubię takie eksperymenty myślowe jak wpis z The Den. Od razu nabieram wtedy inspiracji do wymyślania własnych rzeczy!

I tak na przykład – wyobrażam sobie coś, co mogłoby nosić nazwę DNSitter. Jak Twitter (świętej pamięci, bo to już X), tylko że wewnątrz DNS-a. Co pewien czas można dodawać nowy, krótki rekord TXT z jakimś swoim przemyśleniem.
Nawet gdyby niczego nie kompresować i trzymać się limitu 255 bajtów na rekord, to i tak będzie hojniejszy niż dawne 140 znaki Twittera!

Uwaga

Warto przy tym pamiętać, że podobno DNS może mieszać kolejność wysyłanych rekordów. Dlatego, żeby ułożyć jakąś spójną opowieść z rekordów TXT, należałoby je jakoś numerować.

DNS-a można również użyć w roli tablicy ogłoszeń – choćby na czarną godzinę.
Co by było, gdybym stracił swój hosting od Githuba/Microsoftu? Na przykład za regularne nabijanie się z perły korpoświata, Doliny Krzemowej?

Nadal pozostałaby mi domena. W końcu kupiłem ją całkiem niezależnie, od dostawcy europejskiego. A wraz z nią – swoją małą skrytkę na rekordy.
Do czasu znalezienia nowego nosiciela mógłbym opisać całą historię w rekordach TXT. A zaciekawione osoby mogłyby wtedy użyć komendy dig, żeby zobaczyć, w czym rzecz.

Póki co jest stabilnie, więc i status pozytywny:

Zrzut ekranu z konsoli, pokazujący wpisane w nią polecenie 'dig txt ciemnastrona.com.pl +short'. Pod spodem widać treść dwóch rekordów tekstowych, z których jeden to nazwa strony, a drugi mówi 'U mnie wszystko OK! Udanego dnia i smacznej kawusi'.

Tak jak pan DNS powiedział – smacznej kawusi i do zobaczenia! :smile:

Źródła obrazków

Ikony z serwisu Flaticon użyte na schematach: