vegeta_ssj@saiyajinz:~/posty/hs_auth/$

hidden service authorization

9 minut czytania opublikowano: 22.01.2021

uwierzytelnienie do ukrytej usługi sieci Tor
Ukryta usługa sieci Tor umożliwia dodatkowe uwierzytelnienie kluczem bez 
którego połączenie z usługą będzie niemożliwe. Jest to ciekawe rozwiązanie. 
By skonfigurować HiddenServiceAuth potrzebna jest para kluczy zgodnych z 
algorytmem x25519 zakodowanych w base32. Klucz publiczny zostaje po stronie 
serwera, klucz prywatny u klienta. Konfiguracja jest prosta.

Oficjalne mądrości: gitweb.torproject.org/torspec.git/tree/rend-spec-v3.txt

The supported are: "descriptor". The supported are: "x25519". The is the 
base32 representation of the raw key bytes only (32 bytes for x25519).

en.wikipedia.org/wiki/Curve25519
en.wikipedia.org/wiki/Base32

Do generowania kluczy można użyć taki spoko skrypcik dla leniwych 
w pajtonie3 który wymaga doinstalowania pynacl # pip3 install pynacl, 
ale niżej pokażę jak to zrobić w bashu. Skrypty są spoko, ale ręczna 
robota ma walor edukacyjny. Łit łit łit :-P

#!/usr/bin/env python3
import base64
try:
    import nacl.public
except ImportError:
    print('PyNaCl is required: "pip install pynacl" or similar')
    exit(1)

def key_str(key):
    # bytes to base 32
    key_bytes = bytes(key)
    key_b32 = base64.b32encode(key_bytes)
    # strip trailing ====
    assert key_b32[-4:] == b'===='
    key_b32 = key_b32[:-4]
    # change from b'ASDF' to ASDF
    s = key_b32.decode('utf-8')
    return s

def main():
    priv_key = nacl.public.PrivateKey.generate()
    pub_key = priv_key.public_key
    print('public:  %s' % key_str(pub_key))
    print('private: %s' % key_str(priv_key))

if __name__ == '__main__':
    exit(main())

Skrypt wypluje gotowe klucze zakodowane w base32.

#przykładowy out
public:  M4A567PD4T3TLZXSHZYEZRVIFFK4PFEQVPFG5LDHLSIGMX2ZAUDQ
private: DWMADSU7FI2NMRYLJLZ3VPLOD3RAJDCNESKQA377BOZB75GZNQSQ

Ręcznie w bashu robi się to tak:

Generuję klucz prywatny:

openssl genpkey -algorithm x25519 -out key.private.pem

vegeta_ssj@saiyajinz:~/klucze$ cat *.pem
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VuBCIEIJCepih/udOZmGBLdW9hfvlX6vUX4sy3ay0jzdvvxfBi
-----END PRIVATE KEY-----

Z pliku wyciągam sobie sam kluczyk do obróbki który jest zakodowany w base64 
i zapisuje jako priv.pem:

cat key.private.pem | grep -v " PRIVATE KEY" > priv.pem

vegeta_ssj@saiyajinz:~/klucze$ cat priv.pem
MC4CAQAwBQYDK2VuBCIEIJCepih/udOZmGBLdW9hfvlX6vUX4sy3ay0jzdvvxfBi

Dekoduje klucz z base64 polecenim base64pem z pakietu basez.
Nie ma go domyślnie w debianie # sudo apt install besez.

cat priv.pem | base64pem -d > decoded.pem

vegeta_ssj@saiyajinz:~/klucze$ cat decoded.pem
0.0+en" ���(�ә�`Kuoa~�W���̷k-#�����

Klucz ma być 32 bajtowy, trzeba wypieprzyć ten nagłówek czy co to tam
jest.

cat decoded.pem | tail --bytes=32 > 32_priv.pem

vegeta_ssj@saiyajinz:~/klucze$ cat 32*
���(�ә�`Kuoa~�W���̷k-#�����

Klucz ma 32 bajty. Trzeba go zakodować w base32. Algorytm kodowania 
base32 każde 5 bitów koduje jako literkę czyli jeden bajt więc output 
będzie zawsze uzupełniony zerami by dać liczbę podzielną przez 5. 

vegeta_ssj@saiyajinz:~/klucze$ cat 32_key.pem | base32
YDHNTU67CNF4KBU2VXDSLISRK3IP47GSWFLKKO2O5BCBG7DY55DA====

Wypuszczę się odrobinę w przyszłość. Jak dodałem do konfiguracji Tor 
klucz uwierzytelniający który po zakodowaniu miał 56 bajtów przy 
próbie odpalenia Tora spotkała mnie niemiła niespodziewanka :)

05:49:35.000 [warn] Client authorization encoded base32 public key length 
is invalid: YDHNTU67CNF4KBU2VXDSLISRK3IP47GSWFLKKO2O5BCBG7DY55DA====

Okazało się, że zakodowany klucz musi mieć 52 bajty :)

Wynik kodowania ma 56 bajtów 56*5/8 = 35 czyli te 32 bajty klucza
zostaną przy kodowaniu do base32 uzupełnione zerami do liczby podzielnej 
przez 5. Jeden bit któremu trzeba dodać cztery zera odpowiada ====. Trzeba
kluczyk odrobinę spreparować zgodnie z wymaganiami specyfikacji.

cat 32_priv.pem | base32 | sed 's/=//g' > private.pem

Klucz prywatny jest gotowy :) 

vegeta_ssj@saiyajinz:~/klucze$ cat private.pem
SCPKMKD7XHJZTGDAJN2W6YL67FL6V5IX4LGLO2ZNEPG5X36F6BRA #teraz ma 52 bajty

Pamiętaj, że w tej formie już klucza nie zdekodujesz ;) 

vegeta_ssj@saiyajinz:~/klucze$ echo "SCPKMKD7XHJZTGDAJ(****)" | base32 -d
(�P�l�,�����p[7�>���β�Qٍbase32: invalid input

Czas przygotować klucz publiczny :) Zaczynam od eksportu klucza publicznego 
z klucza prywatnego.

openssl pkey -in key.private.pem -pubout > key.public.pem

Można by to ładnie onelinerem zapisać, ale wtedy się na ekranie nie mieści
i mi brzydko na blogu wygląda xDDDDDDDD

pub=$(openssl pkey -in key.private.pem -pubout | grep -v " PUBLIC KEY")
echo $pub | base64pem -d | tail --bytes=32 | base32 | sed 's/=//g' > pub.key

Klucz publiczny gotowy :)

vegeta_ssj@saiyajinz:~/klucze$ cat pub.key
SPEPIBJPGASN2JU3MEE5HAKPVCXJQO3QKPWH7YC5WSDFQWUXUNZQ

Czas podać klucz serwerowi i spróbować uwierzytelnić się jako klient. W 
konfiguracji Tora jako hidden service jest taka linijka:

HiddenServiceDir /home/exploit/saiyajinz.onion

Definiuje ona gdzie mają się znaleźć wszystkie gadżety od danej usługi. Po 
pierwszym starcie Tora tworzy się też katalog authorized_clients i to on
nas interesuje.

vegeta_ssj@saiyajinz:~$ ls ~/saiyajinz.onion
authorized_clients  hostname  hs_ed25519_public_key  hs_ed25519_secret_key

W katalogu trzeba utworzyć plik o nazwie user.auth i wrzucić doń linijkę 
według schematu:

(auth-type):(key-type):(base32-encoded-public-key)

Czyli:

pub=$(cat ~/klucze/public.key) #klucz publiczny który wcześniej utworzyłem
path=~/saiyajinz.onion/authorized_clients/vegeta.auth
echo "descriptor:x25519:$pub" > $path

Plik powinien wyglądać tak:

vegeta_ssj@saiyajinz:~$ cat $path
descriptor:x25519:SPEPIBJPGASN2JU3MEE5HAKPVCXJQO3QKPWH7YC5WSDFQWUXUNZQ

Czas testów nastał. Moja domena to:

saiyajinz7325zoya7kupyph6lhrwvtp6h45tpyi5pffgxhaa3h4wfqd.onion

Kiedyś jak były złe czasy to klucz prywatny trzeba było manualnie dodać 
do pliku konfiguracyjnego klienta. Teraz są dobre czasy i po wysłaniu 
żądania pokaże się okienko z prośbą o klucz prywatny.



Wklej zawartość pliku z kluczem prywatnym. Jeżeli wszystko jest cacy to
połączysz się z ukrytą usługą. 

vegeta_ssj@saiyajinz:~/klucze$ cat private.pem
SCPKMKD7XHJZTGDAJN2W6YL67FL6V5IX4LGLO2ZNEPG5X36F6BRA #klucz prywatny :)

Jeżeli zrobiłeś coś źle lub po prostu nie masz klucza zobaczysz:



Kto z forum cebulka7millweap.onion ten z cicha pęknięty xD

Jeżeli zdecydowałbyś się dodać ręcznie klucz prywatny do konfiguracji klienta
to dodaj do torrc'a linijkę w której określisz ściężkę do katalogu w którym
będzie plik z kluczem prywatnym. Np:

ClientOnionAuthDir /home/exploit/saiyajin.onion/onion_auth

Następnie stwórz w nim plik o nazwie user.auth_private z zawartością wg. 
schematu:

(56-char-addr-without-.onion):(descriptor:x25519):(x25519 priv key in base32)

To by było na tyle. Smacznego. Mam nadzieję, że pomogłem :)