Jaki jest szósty znak skrótu hasła w systemie Linux i dlaczego często jest to ukośnik?


83

W systemie Linux, gdzie jest przechowywany szósty znak skrótu hasła /etc/shadow?

W moim linuksowym pudełku w stylu szczeniaka, jeśli spróbuję wygenerować 100 losowych haseł za pomocą shufi /dev/urandom, wtedy szósta postać będzie /mniej więcej w połowie.

Moje pytanie nie jest przeznaczone do celów produkcyjnych, ponieważ uruchamiam go za każdym razem, gdy jest świeżo z płyty CD. Czy to oznacza, że ​​mój system jest w jakiś sposób źle skonfigurowany lub niepewny?

Uruchomiłem plik, shufaby sprawdzić, czy jest to busyboxlink.

file /usr/bin/shuf

    shuf: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, stripped

Nie sądzę, że shufjest to busyboxlink tutaj.

ls -l /usr/bin/shuf

    -rwxr-xr-x 1 root root 41568 Mar  7  2015 /usr/bin/shuf

podczas

ls -l /bin/wget

    lrwxrwxrwx 1 root root 14 Apr 29 03:49 wget -> ../bin/busybox

Oto przybliżony pomysł na to, co zrobiłem:

# ! / b i n / b a s h
##  don't try this on any real computer
##  this is not a production script, it is just psuedo code
##  with pseudo results to illustrate a point

##  for this run of 100 ?random? passwords,
##  46 of the 6th character of the hash stored in
##  '/ect/shadow' were '/'

function is_this_really_a_random_password () {
PERHAPS_RANDOM=''
for (( Z=0 ; Z<=8 ; Z++ )) do
PERHAPS_RANDOM="$PERHAPS_RANDOM$( shuf --head-count=1 --random-source=/dev/urandom $FILE_OF_SAFE_CHARACTERS )"
done
echo "$USER_NAME:$PERHAPS_RANDOM" | chpasswd
}

rm sixth-character-often-forward-slash.txt
for (( I=1; I<=100; I++ )) do
is_this_really_a_random_password
grep --regexp=root /etc/shadow | cut --characters=-40 >> sixth-character-often-forward-slash.txt
done
    root:$5$56YsS//DE$HasM6O8y2mnXbtgeE64zK
    root:$5$ho8pk/4/A6e/m0eW$XmjA5Up.0Xig1e
    root:$5$jBQ4f.t1$vY/T/1kX8nzAEK8vQD3Bho
    root:$5$BJ44S/Hn$CsnG00z6FB5daFteS5QCYE
    root:$5$Jerqgx/96/HlV$9Wms5n1FEiM3K93A8
    root:$5$qBbPLe4zYW$/zXRDqgjbllbsjkleCTB
    root:$5$37MrD/r0AlIC40n6$8hplf2c3DgtbM1
    root:$5$.4Tt5S6F.3K7l7E$dAIZzFvvWmw2uyC
    root:$5$A4dX4ZlOoE$6axanr4GLPyhDstWsQ9B
    root:$5$HXAGhryJ/5$40tgmo7q30yW6OF7RUOE
    root:$5$EzNb9t5d$/nQEbEAQyug7Dk9X3YXCEv
    root:$5$HHS5yDeSP$LPtbJeTr0/5Z33vvw87bU
    root:$5$sDgxZwTX5Sm$6Pzcizq4NcKsWEKEL15
    root:$5$FK1du/Paf/$hAy8Xe3UQv9HIpOAtLZ2
    root:$5$xTkuy/BLUDh/N$/30sESA.5nVr1zFwI
    root:$5$PV4AX/OjZ$VU8vX651q4eUqjFWbE2b/
    root:$5$iDuK0IUGijv4l$cdGh8BlHKJLYxPB8/
    root:$5$0DEUp/jz$JBpqllXswNc0bMJA5IFgem
    root:$5$Wz3og/W3Jra/WKA.$6D7Wd4M1xxRDEp
    root:$5$ntHWB.mC3x$Kt4DNTjRZZzpbFvxpMxP
    root:$5$g/uEc/cq$Ptlgu8CXV.vrjrmuok9RRT
    root:$5$/XAHs/5x$Z9J4Zt4k6NxdjJ27PpLmTt
    root:$5$mgfbZeWD0h/$UDGz8YX.D85PzeXnd2K
    root:$5$f4Oh3/bF2Ox/eN$xt/Jkn0LxPnfKP8.
    root:$5$J0mZZXGJG7/v$e16VxghNvZZKRONown
    root:$5$SNza9XFl9i$Qq7r/N6Knt2j74no8H0x
    root:$5$aFCu//xiL$Ocn9mcT2izcnm3rUlBOJg
    root:$5$kMkyos/SLZ/Mm6$wNYxZ9QeuJ8c8T.o
    root:$5$ujXKC/Xnj0h/nQ$PUmePvJZr.UXmTGK
    root:$5$wtEhA/YKaTKH$6VCSXUiIdsfelkCYWV
    root:$5$I1taRlq59YZUGe$4OyIfByuvJeuwsjM
    root:$5$N54oH//j4nbiB$K4i6QOiS9iaaX.RiD
    root:$5$ps8bo/VjPGMP0y4$NTFkI6OeaMAQL7w
    root:$5$IRUXnXO8tSykA8$NatM5X/kKHHgtDLt
    root:$5$VaOgL/8V$m45M9glUYnlTKk8uCI7b5P
    root:$5$/lPDb/kUX73/F3$jJL.QLH5o9Ue9pVa
    root:$5$/sHNL/tVzuu//cr$QasvQxa02sXAHOl
    root:$5$hGI.SMi/7I$fYm0rZP0F5B2D1YezqtX
    root:$5$WsW2iENKA$4HhotPoLRc8ZbBVg4Z5QW
    root:$5$cN6mwqEl$q5S3U85cRuNHrlxS9Tl/PC
    root:$5$wwzLR/YMvk5/7ldQ$s3BJhq5LyrtZww
    root:$5$GUNvr/d15n8/K$CiNHwOkAtxuWJeNy1
    root:$5$nGE75/8mEjM/A$pD/84iLunN/ZNI/JK
    root:$5$77Dn2dHLS$d5bUQhTz.OU4UA.67IGMB
    root:$5$EWrI//1u$uubkPk3YhAnwYXOYsvwbah
    root:$5$Hzfw1UCudP/N/U$Rjcdzdbov1YgozSJ
    root:$5$2y8CKTj.2eTq$7BEIgMWIzAJLl1SWBv
    root:$5$lcWsD/42g8zEEABA$r/vGxqqUZTkJ0V
    root:$5$LPJLc/Xz$tnfDgJh7BsAT1ikpn21l76
    root:$5$ucvPeKw9eq8a$vTneH.4XasgBIeyGSA
    root:$5$Fwm2eUR7$ByjuLJRHoIFWnHtvayragS
    root:$5$yBl7BtMb$KlWGwBL6/WjgHVwXQh9fJS
    root:$5$1lnnh2kOG$rdTLjJsSpC3Iw4Y6nkPhq
    root:$5$WfvmP6cSfb066Z$1WvaC9iL11bPCAxa
    root:$5$qmf/hHvalWa4GE25$m3O2pdu25QBCwU
    root:$5$4P.oT/9HQ$Ygid4WXi0QCEObLVNsqFZ
    root:$5$FNr4Bkj56Y$38mG7mKV0mdb1PMCxrVd
    root:$5$hoNcyURtV$aTidBWHjngc1I0vUTi5bB
    root:$5$rzHmykYT$ATiXdUDUvUnB2fNMUQgwvE
    root:$5$o11Yb/ZQv2/k3wg9$5yShpVejDBk6HB
    root:$5$REPGN//y9H$awpPmUvCqvi6Bd/6bQxF
    root:$5$HbAEY/djXJx$y56GhMwavd7xTQ.jPg6
    root:$5$3T1k5.LZUcy$Cup.LM5AnaBTIaJtBnF
    root:$5$wXaSC/P8bJ$y/0DoYJVjaP09O6GWiki
    root:$5$YuFfY8QPqm/dD$IIh0/tyn.18xEBl5Y
    root:$5$uTTBpjsKG//3Et8$9ibN9mVwSeVyOI4
    root:$5$dASlMLzbVbFMnZ$N4uGBwGHhdg93z/V
    root:$5$03.FA/LnRBb.k7Zl$XOHU2ZlHkV9oz9
    root:$5$2zL1p/VDCi$/QRT7Bo3cZ3Rxb8Y7ddo
    root:$5$0NpZqZs/qt/jIv.$8W/TTM3Gy2UMOWy
    root:$5$a4SXynoro7ucT$qFM2C79QJ15jQ0ZlL
    root:$5$RL0Eg/jroH8/ONP$EzceXz.pz74k104
    root:$5$O3R5V/n1$U.mmCTbpID8xMXbvtzd4ch
    root:$5$0T2nVrv/P/xaRwUD$YVm17XF8kTsL0f
    root:$5$2bRwMNIXobZwn$Q228FJqg6/iRCe9GQ
    root:$5$PyYgL/axfgj/$uaL5y/kdzU4Kzi.JlB
    root:$5$A6QtfJdJ4Gwvx4$d4PA5AJ0806NzRnm
    root:$5$H8Mta5LDgGXp$QGdOJh.bFWgR3L719Z
    root:$5$H06URjv4BtOAbA$EJs1mZYhdKIVgCmn
    root:$5$OeB.O/GrmFB/az$SoE759KE9WIE17Uf
    root:$5$huiB9/sk$el3XMf7SGX81LnD3.SaF8J
    root:$5$fO7tfM.fjdSHA8G6$s.QIjfNniCzFdU
    root:$5$32at3SQJAD/xlw$HbXmBLVXTTyZfxQv
    root:$5$FHBFL/QdFl$FMipxpW0HlEFUIAr7IxF
    root:$5$sHvKf/M5OPdBuZZ$dz4qLOkTLGeCINX
    root:$5$hw4Vu/e34$/82lXu7ISrse.Ihk.qbqT
    root:$5$k1JOy/jRWZ$30YSk7kbhdKOjfDaiWVf
    root:$5$MnX.LUzqrB/B2$JuwqC.SmKFnMUWkEf
    root:$5$arRYf/PG$Xw6PpZNFO656p.Eb636iLt
    root:$5$5op/p8Hqs5$Nj2jA0Qxm80aG4fHW3oz
    root:$5$VHIT9/8yzZ$CpIK4ODps78GcqcsgiMT
    root:$5$.AlH7jBJoh/8$sjuVt.PcRH.vyvB3og
    root:$5$f7Ewinqm$nrJ2p/hKTuiEK//IfCTjth
    root:$5$N.dv/VCvrCADg$peSXfo35KN1dmbw/n
    root:$5$PSc4W./54l/SroH$CFFVOHRYK.Jj8Sp
    root:$5$8UBP3f4IcnAd/N1/$P.ud49qTStQ7Lw
    root:$5$qnXsZ/NlLZh/$nlaQVTS3FCJg1Jb2QG
    root:$5$xOpbbBqENR/7$boYJQzkCkZhRf7Uicf
    root:$5$V93tjZhzT$LrsIZWZmYo4ocRUvCixO6
    root:$5$1MVz8/lf5oC/$rUKpnX23MhFx4.y2ZS

Mniej więcej połowa szóstych znaków skrótu to /:

cat sixth-character-often-forward-slash.txt | cut --character=14 | sort


    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    /
    .
    .
    .
    .
    2
    5
    6
    8
    8
    B
    d
    D
    e
    e
    E
    f
    H
    I
    j
    j
    j
    J
    k
    k
    K
    l
    L
    M
    M
    n
    n
    N
    q
    r
    r
    r
    s
    S
    S
    t
    t
    T
    U
    U
    U
    U
    V
    w
    x
    X
    X
    X
    Z
    Z
    Z

3
man 3 crypti przeczytaj sekcję UWAGI, aby uzyskać pełny opis tego pola.
Stephen Harris,

(Pozostawiono jako wskazówkę dla osoby, która chce w pełni zbadać sprawę): W polu hasła użyto 64 znaków; więc prawdopodobnie używany jest jakiś wariant base64. Więc zgaduję , że to, co widzisz, to wypełnienie base64, ale to dziwne, że nie jest to koniec soli ...
derobert

1
Z badań Debian & mkpasswd, tak się nie stanie, ciekawy, czy to się dzieje z mkpasswd dla ciebie (jak to byłoby łatwiejsze do zbadania niż faktycznie ustawiania hasła root):for ((i=0; i<50; ++i)); do pwgen -1 -s 16 | mkpasswd -m sha-256 --stdin ; done | cut -c9 | sort | uniq -c
derobert

Nie mogę tego odtworzyć na obecnym Ubuntu 14.04 lub 16.04. Ukośnik znajduje się pośrodku listy częstotliwości (użyty powyżej fragment @derobert z 5000 pętlami zamiast 50), ale nadal wygląda trochę nierównomiernie, Najczęstsze char (q) @ 2,00% całości jest 1,63 częstsze niż najmniej często jeden (r) @ 1,22% całości.
arielf

@ Arielf Wątpię, aby było to istotne statystycznie. Trzeba by zrobić coś w rodzaju testu χ2, aby się upewnić, ale to znacznie poza terytorium Uniksa i Linuksa i dostanie się na terytorium Cross Validated .
derobert

Odpowiedzi:


86

Format skrótu i ​​źródło

Format skrótu hasła to $<type>$<salt>$<hash>, gdzie <type> 5jest skrót skrótu oparty na SHA-256. Sól ma zwykle co najmniej 8 znaków (i jest w przykładach w pytaniu), więc szósty znak jest częścią soli.

Te skróty są prawdopodobnie generowane przez wersję pakietu narzędzi Shadow (pakiet src shadoww Debianie, shadow-utilsw CentOS)

Próbowałem dowiedzieć się, dlaczego dokładnie kod stronniczy na slash. (dzięki @thrig za pierwotne wykopanie kodu).

TLDR: To trochę interesujące, ale nie ma znaczenia.


Kod generujący sól

W libmisc/salt.cznajdujemy gensaltfunkcję, która wywołuje l64aw pętli:

strcat (salt, l64a (random()));
do {
       strcat (salt, l64a (random()));
} while (strlen (salt) < salt_size);

Pętla pobiera losową liczbę random(), zamienia ją w kawałek struny i łączy ją z ciągiem tworzącym sól. Powtarzaj, aż zgromadzi się wystarczająca liczba znaków.

To, co się dzieje, l64ajest jednak bardziej interesujące. Wewnętrzna pętla generuje jeden znak na raz z wartości wejściowej (która pochodzi random()):

for (i = 0; value != 0 && i < 6; i++) {
    digit = value & 0x3f;

    if (digit < 2) {
        *s = digit + '.';
    } else if (digit < 12) {
        *s = digit + '0' - 2;
    } else if (digit < 38) {
        *s = digit + 'A' - 12;
    } else {
        *s = digit + 'a' - 38;
    }

    value >>= 6;
    s++;
}

Pierwszy wiersz loop ( digit = value & 0x3f) wybiera sześć bitów z wartości wejściowej, a ifklauzule zamieniają wartość utworzoną przez te znaki w znak. ( .dla zera, /dla jednego, 0dla dwóch itd.)

l64abierze longale wartości wyjściowe random()są ograniczone do RAND_MAX, który wydaje się być 2147483647 lub 2 ^ 31 - 1 na glibc. Tak więc wartość, która idzie do l64ajest losową liczbą 31 bitów. Biorąc 6 bitów na raz lub wartość 31 bitów, otrzymujemy pięć rozsądnie równomiernie rozmieszczonych znaków, a także szósty, który pochodzi tylko z jednego bitu!

Ostatni znak wygenerowany przez l64anie może być .jednak, ponieważ pętla ma również warunek value != 0i zamiast .szóstego znaku l64azwraca tylko pięć znaków. Dlatego połowa czasu, szósta postać to a /, a połowa czasu l64azwraca pięć lub mniej znaków. W tym drugim przypadku następujący element l64amoże również generować ukośnik na pierwszych pozycjach, więc w pełnej soli szósty znak powinien być ukośnikiem nieco ponad połowę czasu.

Kod ma również funkcję losowego wybierania długości soli, ma od 8 do 16 bajtów. To samo nastawienie dla postaci z ukośnikiem występuje również w przypadku kolejnych wywołań, w l64aktórych 11. i 12. postać również będzie miała ukośnik częściej niż cokolwiek innego. 100 soli przedstawionych w pytaniu ma 46 ukośników odpowiednio na szóstej pozycji, a 13 i 15 odpowiednio na 11. i 12. pozycji. (nieco mniej niż połowa soli ma mniej niż 11 znaków).

Na Debianie

Na Debianie nie mogłem tego odtworzyć za pomocą prostej, chpasswdjak pokazano w pytaniu. Ale chpasswd -c SHA256wykazuje to samo zachowanie. Zgodnie z instrukcją domyślną akcją bez -cjest umożliwienie PAM obsługi mieszania, więc najwyraźniej PAM na Debianie przynajmniej używa innego kodu do wygenerowania soli. Jednak nie patrzyłem na kod PAM w żadnej dystrybucji.

(Poprzednia wersja tej odpowiedzi stwierdzała, że ​​efekt nie pojawił się na Debianie. To nie było poprawne).

Znaczenie i wymagania dotyczące soli

Czy to ma jednak znaczenie? Jak skomentował @RemcoGerlich, jest to tylko kwestia kodowania. Będzie to skutecznie naprawić niektóre kawałki soli do zera, ale jest prawdopodobne, że będzie to miało żadnego znaczącego wpływu w tym przypadku, ponieważ pochodzenie tych bitów jest to wywołanie srandomw seedRNG:

srandom (tv.tv_sec ^ tv.tv_usec ^ getpid ());

Jest to wariant dawnego zwyczaju wysiewu RNG z bieżącym czasem. ( tv_seci tv_usecsą sekundami i mikrosekundami bieżącego czasu, getpid()podają identyfikator procesu, jeśli jest uruchomiony). Ponieważ czas i PID nie są bardzo nieprzewidywalne, ilość losowości tutaj prawdopodobnie nie będzie większa niż to, co może utrzymać kodowanie.

Czas i PID nie są czymś, za pomocą którego chcesz tworzyć klucze , ale mogą być nieprzewidywalne dla soli. Sole muszą być wyraźne, aby zapobiec testowaniu wielokrotnych skrótów haseł za pomocą jednego obliczenia, ale powinny być również nieprzewidywalne, aby zapobiec lub spowolnić celowane obliczenia wstępne, które mogłyby zostać wykorzystane do skrócenia czasu od uzyskania skrótów haseł do uzyskania rzeczywistych haseł .

Nawet z drobnymi problemami, o ile algorytm nie generuje tej samej soli dla różnych haseł, powinno być w porządku. I wydaje się, że tak nie jest, nawet jeśli generuje kilkadziesiąt w pętli, jak pokazuje lista w pytaniu.

Ponadto kod, o którym mowa, nie jest używany do niczego poza generowaniem soli do haseł, więc nie ma to wpływu na problemy gdzie indziej.

W przypadku soli zobacz także np. Ten na Stack Overflow i ten na security.SE .

Wniosek

Podsumowując, nie ma nic złego w twoim systemie. Sprawdzenie, czy hasła są dobre i nieużywane w niepowiązanych systemach, jest bardziej przydatne do przemyślenia.


2
Więc rzeczywiste sole nie są stronnicze, to tylko artefakt, w jaki sposób są kodowane i nie ma to żadnego wpływu na bezpieczeństwo, prawda?
RemcoGerlich,

8
@RemcoGerlich To jest podręcznikowa definicja błędu. Ponieważ nie wszystkie bity są rozliczane jednolicie. Ma to również wpływ na inne projekty, w których ten kod jest używany w kontekście innym niż sól. Jako sole w hasłach do / etc / shadow, nie jest to showstopper, ale jest niepokojący.
Aaron Toponce,

@RemcoGerlich, Prawie tak. Okej, to nie jest silny RNG, więc moglibyśmy porozmawiać o tym z uprzedzeniami. Ale ze względów bezpieczeństwa nie ma to znaczenia dla soli.
ilkkachu

3
Błędnie zinterpretowałeś post z Security.SE, do którego linkowałeś, a zaakceptowana odpowiedź na post z SO, do którego linkujesz, jest błędna, dlatego jest inna odpowiedź z ponad 10-krotnością głosów przeciwnych. Stwierdzenie, że „sole muszą być odrębne” nie jest prawdą; entropia tematyce sprawach soli, ponieważ to, co kontroluje o ile zwiększa trudność precomputation. Sole te mają mniejszą entropię, niż mogłyby ze względu na swoją długość, ze względu na odchylenie. Nie krytycznie mniej, ale mniej więcej 5 bitów. To jest wada.
hobbs

Być może ktoś powinien zadać pytanie security.SE odnoszące się konkretnie do tej funkcji, aby uzyskać kwalifikowaną opinię.
hobbs

26

Ta postać jest częścią soli zgodnie z crypt(3)instrukcją. Biorąc pod uwagę, że długość soli (ciąg między $5$identyfikatorem a kolejnymi $) różni się dla wyświetlanych skrótów, nie jestem do końca pewien, co ilustruje wybranie losowego znaku z tej konkretnej kolumny dla kilku haseł.

Z drugiej strony, / występuje częściej (102 wystąpienia) w całej soli w porównaniu z innymi możliwymi postaciami (około 18), więc chpasswdwydaje się, że coś w niej faworyzuje tę postać w soli;

for x in `seq 1 100000`; do
  echo testacct:asdfasdfasdf | chpasswd -c SHA256
  awk -F: '/testacct/{print $2}' /etc/shadow | awk -F\$ '{print $3}' >> salts
done
perl -nle 'print for m/(.)/g' salts | sort | uniq -c | sort -nr | head -5

w systemie RedHat EL 6 pojawia się:

   1006 /
    195 X
    193 U
    193 q
    193 e

I tak, kod wewnątrz shadow-utils-4.1.5.1-5.el6wykazuje tendencyjność, /która może ułatwić ataki słownikowe:

#include <sys/time.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

// these next two borrowed from libmisc/salt.c of shadow-4.1.5.1 from
// Centos 6.8 RPM at http://vault.centos.org/6.8/os/Source/SPackages/shadow-utils-4.1.5.1-5.el6.src.rpm
char *l64a(long value)
{
    static char buf[8];
    char *s = buf;
    int digit;
    int i;

    if (value < 0) {
        abort();
    }

    for (i = 0; value != 0 && i < 6; i++) {
        digit = value & 0x3f;

        if (digit < 2) {
            *s = digit + '.';
        } else if (digit < 12) {
            *s = digit + '0' - 2;
        } else if (digit < 38) {
            *s = digit + 'A' - 12;
        } else {
            *s = digit + 'a' - 38;
        }

        value >>= 6;
        s++;
    }

    *s = '\0';

    return (buf);
}

static void seedRNG(void)
{
    struct timeval tv;
    static int seeded = 0;

    if (0 == seeded) {
        (void) gettimeofday(&tv, NULL);
        srandom(tv.tv_sec ^ tv.tv_usec ^ getpid());
        seeded = 1;
    }
}

int main(void)
{
    seedRNG();
    for (int x = 0; x < 1000; x++) {
        printf("%s\n", l64a(random()));
    }

    exit(0);
}

Co skutkuje w:

% ./salttest | perl -nle 'print for m/(.)/g' | sort | uniq -c | sort -nr | head -3
 593 /
  96 8
  93 3

A następnie korzystając z tych samych procedur z najnowszego https://github.com/shadow-maint/shadow/blob/master/libmisc/salt.c , stwierdzamy, że nadal istnieje uprzedzenie /. Więc, tak, to jest błąd, który powinien zostać załatany, więc /nie jest tak bardzo faworyzowany, ponieważ idealnie postacie z soli powinny mieć jednakową wagę.


14
Białka w soli same w sobie nie są szkodliwe (w przeciwieństwie do stronniczości w, powiedzmy, kluczu). Sól musi być wyjątkowa, nie musi być nieprzewidywalna. Sól składająca się z adresu MAC (lub czegoś jednoznacznie identyfikującego maszynę) i czasu (zakładając, że zegar nie cofa się) byłaby w porządku. Stwierdzenie, że „najlepiej jest, aby znaki soli miały taką samą wagę” jest błędne.
Gilles

7
@ thrig Nie, przewidywalna sól nie pomaga w atakach słownikowych, ponieważ sól nie pomaga w atakach słownikowych jako takich. Sól pomaga w atakach ukierunkowanych na wiele kont (a dokładniej: wiele skrótów - także kolejne skróty na tym samym koncie), a do tego ważne jest tylko to, że sól jest odrębna dla różnych kont. Nieprzewidywalność soli jest nieistotna, jedynie ich wyjątkowość (w rzeczywistości wystarczająca jest nawet niska liczba powtórzeń).
Gilles

3
Kluczowym punktem tego, co mówi Gilles, jest to, że jest dużo miejsca na generator soli, który może być słaby, ale nie tak zły, że w tym samym pliku cienia (lub w wielu systemach, które atakujący może atakować jednocześnie) występują rzeczywiste kolizje. ). To wszystko ma znaczenie dla działania soli. Pokonanie stołów Rainbow zajmuje tylko trochę losowości .
Peter Cordes,

7
Jeśli jednak sól jest źle generowana, nie budzi zaufania do reszty kodu kryptograficznego.
immibis

3
W przypadku soli muszą być unikalne na całym świecie. Nie muszą być przypadkowe i nie muszą być tajne. Ale muszą być wyjątkowe na całym świecie. Okazuje się, że jest to trudniejsze, jeśli próbujesz zwiększyć licznik lub stworzyć jakiś fantazyjny algorytm deterministyczny, niż tylko wyrywając losowe bity z OS RNG. Jeśli wygenerujesz 16 znaków base64 losowo, masz szansę na kolizję / 64 ^ 16. Oczywiście sedno soli polega na tym, aby ataki na tęczowy stół były bezowocne. W tym przypadku 16-znakowa przestrzeń base64 soli będzie wynosić 64 ^ 15 <n <64 ^ 16. Nie showstopper, ale łatwo naprawić.
Aaron Toponce,

4

mkpasswd(1)może być nakładką na crypt(3), ale to nie to samo, co uruchamianie chpasswd(1), które jest częścią pakietu „shadow-utils” w CentOS i „passwd” w Debianie. Zamiast tego powinieneś porównać jabłka z jabłkami. Rozważ następujący skrypt:

#!/bin/bash

# This repeatedly changes a `saltuser' password
# and grabs the salt out of /etc/shadow.
# Requires root and the existence of `saltuser' user.

if [ $EUID -ne 0 ]; then
    echo "This script requires root access to read /etc/shadow."
    exit 1
fi

grep -q saltuser /etc/passwd

if [ $? -ne 0 ]; then
    echo "This script requires the 'saltuser' to be present."
    exit 2
fi

: > /tmp/salts.txt

for i in {1..1000}; do
    PW=$(tr -cd '[[:print:]]' < /dev/urandom | head -c 64)
    echo "saltuser:${PW}" | chpasswd -c SHA256 -s 0 2> /dev/urandom
    awk -F '$' '/^saltuser/ {print $3}' /etc/shadow >> /tmp/salts.txt
done

while read LINE; do
    # 6th character in the salt
    echo ${LINE:5:1}
done < /tmp/salts.txt | sort | uniq -c | sort -rn

Dane wyjściowe z Debian Sid:

512 /
 14 T
 13 W
 13 v
 13 t
 12 x
 12 m
 12 d
 11 p
 11 L
 11 F
 11 4
 10 s
 10 l
 10 g
 10 f
 10 7
 10 6
  9 Z
  9 w
  9 N
  9 H
  9 G
  9 E
  9 A
  8 Y
  8 X
  8 r
  8 O
  8 j
  8 c
  8 B
  8 b
  8 9
  7 u
  7 R
  7 q
  7 P
  7 M
  7 k
  7 D
  6 z
  6 y
  6 U
  6 S
  6 K
  6 5
  5 V
  5 Q
  5 o
  5 J
  5 I
  5 i
  5 C
  5 a
  5 3
  4 n
  4 h
  4 e
  4 2
  4 0
  4 .
  3 8
  3 1

Dane wyjściowe z CentOS 7:

504 /
 13 P
 13 B
 12 s
 12 Z
 11 e
 11 Y
 11 O
 11 L
 11 G
 10 w
 10 u
 10 q
 10 i
 10 h
 10 X
 10 I
 10 E
  9 x
  9 g
  9 f
  9 W
  9 F
  9 C
  9 9
  9 8
  8 v
  8 t
  8 c
  8 b
  8 S
  8 H
  8 D
  8 0
  7 z
  7 y
  7 o
  7 k
  7 U
  7 T
  7 R
  7 M
  7 A
  7 6
  7 4
  7 1
  6 p
  6 d
  6 a
  6 Q
  6 J
  6 5
  6 .
  5 r
  5 m
  5 j
  5 V
  5 3
  5 2
  4 n
  4 l
  4 N
  4 K
  3 7

Tak więc problem nie jest unikalny dla CentOS, ale prawdopodobnie pochodzi z góry, z którego czerpią oba projekty.


Czy to : > /tmp/salts.txtto samo co touch /tmp/salts.txt? :jest NOP, prawda?
someonewithpc

1
@someonewithpc Jest to POSIX-y sposób na opróżnianie pliku. touch(1)tworzy plik, jeśli nie istnieje, ale po prostu aktualizuje zmodyfikowany znacznik czasu, jeśli istnieje. To nie jest właściwy sposób na opróżnienie pliku. : > filezagwarantuje, że istnieje i że jest pusty.
Aaron Toponce,

@Aaron, tak, masz absolutną rację. Nie jest całkowicie specyficzny dla jednej dystrybucji.
ilkkachu
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.