Давно еще, со времен фидо, остался у меня один нерешенный крякми. Суть в том, что даже дан исходный код, необходимо соответственно узнать пароль. Используется crc32. Мне в голову, ничего кроме прямого брута не лезет. Да и брутом тоже не могу, долго перебирается. Может быть у кого-то какие-нибудь мысли есть? Привожу оригинальный пост из фидо доисторических лет: Код (Text): const right_crc32:array [0..7] of longint = ($073EE641, $6E40EADF, $7A8EC36F, $92D0CF8E, $15FCE913, $16A8E48B, $1E01F3B0, $B1A61BFD); var table: array [byte] of longint; i,n,l:longint; crc32:array [0..7] of longint; pwd:string; begin write('enter your password: '); readln(pwd); for i:=0 to 255 do {заполняем массив полиномов} begin l:=i; for n:=0 to 7 do begin if l and 1 = 1 then l:=(l shr 1) xor $EDB88320 else l:=l shr 1; end; table[i]:=l; end; fillchar(crc32, sizeof(crc32), #$ff); {считаем 8 CRC32 от пароля} for i:=0 to 7 do begin for n:=1 to length(pwd) do begin crc32[i]:=table[BYTE(crc32[i] xor longint(ord(pwd[n])))] xor (crc32[i] shr 8); if ord(pwd[n]) and 1 = 0 then {циклически сдвигаем вправо} pwd[n]:=chr(ord(pwd[n]) shr 1) else pwd[n]:=chr(ord(pwd[n]) shr 1 + $80); end; crc32[i]:=not crc32[i]; end; for i:=0 to 7 do {проверяем полученные CRC32 с правильными} if crc32[i]<>right_crc32[i] then begin writeln('invalid password'); exit; end; writeln('valid password') end. Ну и соответственно мой брутфорс этого крякми. Писал в Virtual Pascal, может быть соберется и под Free Pascal. Основной цикл repeat until false практически весь на ассемблере, не смотрите на середину - это закаментированные строки паскалевские, просто чтобы понимать что происходит.... Мог конечно и ошибится при написании где-нибудь и уверен, что можно еще оптимизировать сильно, но моего скила хватило только на это: Код (Text): uses crt; const right_crc32:array [0..7] of longint = ($073EE641, $6E40EADF, $7A8EC36F, $92D0CF8E, $15FCE913, $16A8E48B, $1E01F3B0, $B1A61BFD); Alphabet : String = 'abcdefghijklmnopqrstuvwxyz'; var szAlphabet : Array [0..255] of Char; szPassword : Array [0..255] of Char; // текущий паpоль bAlphabet : Array [0..255] of Char; // таблица k : Byte; table: array [byte] of longint; i,n,l:longint; crc32:array [0..7] of longint; pwd : string; cnt : cardinal; //password length begin For i := 1 to Length(Alphabet) do szAlphabet[i-1] := Alphabet[i]; i := 0; k := 0; repeat bAlphabet[k] := szAlphabet[i]; if szAlphabet[i] = chr(0) then break; k := Ord(szAlphabet[i]); Inc(i); until false; { write('enter your password: '); readln(pwd);} for i:=0 to 255 do {заполняем массив полиномов} begin l:=i; for n:=0 to 7 do begin if l and 1 = 1 then l:=(l shr 1) xor $EDB88320 else l:=l shr 1; end; table[i]:=l; end; cnt := 0; writeln('Bruteforce started. Press any key for info...'); repeat asm push eax push ebx push ecx push edx // generate next password mov edi,offset szPassword mov edx,edi mov ebx,offset bAlphabet @L1: movzx eax,byte ptr [edi] xlat cmp al,0 je @L3 mov [edi],al jmp @L5 @L3: xlat stosb jmp @L1 @L5: // copy szPassword to pwd //mov edi,edx //curent password //mov ecx,255 //xor al,al //repne scasb //find zero chr //sub edi,edx //mov ecx,edi //dec ecx //ecx - str length //mov esi,edx //mov edi,offset pwd //mov byte ptr [edi],cl //inc edi //rep movsb inc cnt // inc counter // fill crc32 with $FF mov edi, offset crc32 mov eax, $FFFFFFFF mov ecx, 8 rep stosd { end; i := 0; pwd := ''; repeat pwd := pwd + szPassword[i]; inc(i); until Ord(szPassword[i]) = 0; writeln(pwd,len); readln;} // fillchar(crc32, sizeof(crc32), #$ff); {считаем 8 CRC32 от пароля} { for i:=0 to 7 do begin for n:=1 to length(pwd) do begin crc32[i]:=table[BYTE(crc32[i] xor longint(ord(pwd[n])))] xor (crc32[i] shr 8); if ord(pwd[n]) and 1 = 0 then pwd[n]:=chr(ord(pwd[n]) shr 1) else pwd[n]:=chr(ord(pwd[n]) shr 1 + $80); end; crc32[i]:=not crc32[i]; end; asm pusha} mov esi,offset crc32 mov ecx,8 mov edi,offset szPassword @i_lup: push ecx push edi @n_lup: mov eax,[esi] mov ecx,eax // save crc32[i] xor edx,edx mov dl,[edi] test dl,dl jz @done_p xor eax,edx //eax = crc32[i] xor pwd[n] mov ebx,offset table and eax, $000000FF //eax = al shl eax,2 // eax= eax*2 mov eax,[ebx+eax] // eax= table[crc32[i] xor pwd[n]] shr ecx,8 //ecx = crc32[i] shr 8 xor eax,ecx mov [esi],eax //crc32[i] = ... mov eax,edx shr eax,1 and edx,1 test edx,edx jz @if1 add al,$80 @if1: mov [edi],al mov i,eax inc edi jmp @n_lup @done_p: not dword ptr [esi] pop edi pop ecx add esi,4 loop @i_lup mov k,0 // check new CRC32 mov esi,offset crc32 mov edi,offset right_crc32 mov ecx,8 repe cmpsd je @done mov k,1 @done: pop edx pop ecx pop ebx pop eax end; // k := 0; // for i:=0 to 7 do {проверяем полученные CRC32 с правильными} // if crc32[i]<>right_crc32[i] then k := 1; If k = 0 then writeln('valid password ',pwd); If keypressed then begin write('cur pwd: '); for i := 1 to 255 do if szPassword[i] <> #0 then Write(szPassword[i]) else break; writeln(' cnt: ',cnt); readkey; end; until false; writeln('pwd: ', pwd); readln; end.
а какие еще могут быть мысли? ищи уязвимости алгоритма црц32. Или делай перебор. Твой (да не важно чей) друг по сути спорил, что нельзя взломать црц32. Кроме перебора или коллизии вариантов не существует (если мне ни с кем не изменяет память)
xlat и stosb уже немодно, новые процессоры слишком долго вспоминают, как исполнять столь архаичные команды.
Для инкриментного перебора паролей я руководствовался статьей с этого сайта: http://www.wasm.ru/print.php?article=cycle_pwd Плюс ко всему, я сомневаюсь, что генерация пароля занимает много времени по сравнению с расчетом новых crc. Вот они то и тормозят весь процесс. А генерация нового пароля - фи, ничто по сравнению с ...
Кстати, хинт: если следующий пароль отличается от предыдущего одной буквой на конце, CRC32 не обязательно пересчитывать полностью, достаточно запомнить CRC32 для предыдущих букв и модифицировать его в зависимости от последней. По идее, можно сделать даже таблицу для двух-, трёх- и даже четырёхсимвольных комбинаций и поиметь на этом ещё большее ускорение перебора - в разы и даже на порядки.
Я тоже думал об этом, но загвозка в том, что там меняется ксорится crc текущая с каждым сиволом, потом еще крутятся сами символы. То-есть все взаимосвязано. Если бы оно просто считало crc32 от строки, то конечно, можно было бы создать таблицы.. А так, даже не знаю. Наверное все-таки задача из разряда не решаемых за приемлемое время.
Внимательно не читал, но совсем не сложно обратить crc32, те по заданному CRC32_E найти такое x что CRC32(x)=CRC32_E всего за два цикла по 32 итерации ... ну или таблицу построить заранее.
PSR1257 Очень интересная мысль... А не поделитесь процедуркой? Или где почитать про обращение crc32? spa Увы, не на чем выполнять (древняя ati x1650 pro), да и полный ноль в паралельном программинге.
Криптостойкость crc32 равна 2^0, ничего перебирать не нужно тоесть. Это известно всем, так как алгос полностью обратим. Можно мгновенно пропатчить четыре байта длинного файла и получить любой нужный crc без малейшего перебора.
persicum Ну так покажите нам строку на крк32 0x073EE641 и вы взломаете крякми. Я не сомневаюсь что так можно, даже где-то читал про такую возможность, просто интересно посмотреть, да и про перебор, тоже интересно)
Здесь 8 параллельных CRC32 над битами строки в разном порядке (с циклическим сдвигом). Следовательно, данный кракми представляет собой линейную систему с 64 неизвестными. Если пароль автора 8 символов или меньше, он будет определен однозначно за миллисекунды. Если пароль был длиннее 8 символов, алгоритм даст какую-то 8-байтную строку за те же миллисекунды, скорее всего бессмысленную, возможно не ASCII, но удовлетворяющую всем 8 CRC. Дальше в силу эффекта сжатия будут существовать множество возможных строк (как и в хешах), определить верную можно только семантическим анализом (ну или полуавтоматически в предположении, что все символы например - латинские буквы). Практического интереса задание не представляет.
Смотря какой алгоритм... Мой не дает. Дошел до 8 символов алфавита a-z, дальше сложно с моим процессором )
Tronix перепишешь на си попробую у себя) ну можешь кинуть и скомпилированную версию имхо лучше перебирай все байты. а потом можно хоть на глаз определить строка или нет. Прост со своими a-z не факт что ты себе и процу облекаешь задачу. Можно подробней почему так? Просто заинтересовало почему-то) ну это само собой.
Скомпилиная версия брута, алфавит 0-9. Там же и исходник. ЗЫ: Только как всякий человек мог где-то ошибиться когда на асм переводил (( Но вроде все правильно должно быть...
Tronix А если пароль AAff5533ff%%**? А вот если верить OLS то существует пароль который состоит из 8 байт, так что сделайте перебор по всем байтам и выводите в % готовность, я думаю это хоть и не быстро, но вполне можно дождаться
И еще надо бы распараллелить. Хотя бы сделайте все байты, и вывод в %-ах, завтра часа на 3-4 запустить могу)