Определение Captcha

В прошлый раз мы остановились на таблице соответствия “код в URL картинки –> пяти-значный код Captcha”. В общем виде таблица выглядела следующим образом:

7 9 5 0
1101112 1110012 1101012 1100002
8 6 7 5
1110002 1101102 1101012 1101012
2 4 5 6
1100102 1101002 1101012 1101102
Процедура, определяющая код Captcha была построена вот так:


function Captcha(URL: string):string;  
var aURL: TURLComponents;  
 ParamStr: string; //строка, содержащая код каптчи  
 code: string; //7-ми значнй код из каптчи  
 i,j:integer;  
 begin  
    //разбиваем УРЛ на составляющие  
    Result:=URL;  
    fillchar(aurl, sizeof(turlcomponents), 0);  
    with aurl do  
    begin  
        lpszscheme := nil;  
        dwschemelength := internet_max_scheme_length;  
        lpszhostname := nil;  
        dwhostnamelength := internet_max_host_name_length;  
        lpszusername := nil;  
        dwusernamelength := internet_max_user_name_length;  
        lpszpassword := nil;  
        dwpasswordlength := internet_max_password_length;  
        lpszurlpath := nil;  
        dwurlpathlength := internet_max_path_length;  
        lpszextrainfo := nil;  
        dwextrainfolength := internet_max_path_length;  
        dwstructsize := sizeof(aurl);  
     end;  
     if internetcrackurl(pchar(Result), length(Result), 0, aurl) then  
     begin  
         ParamStr:=copy(aurl.lpszExtraInfo,5, length(aurl.lpszExtraInfo)-4);  
         //выдираем 7-ми значный код и подбираем ему число  
         Result:='';  
         for I:=1 to 5 do //всего 35 цифр по 7 цифр на знак  
         begin  
            code:=copy(ParamStr,i+7*(i-1)-(i-1),7);  
            for j := 0 to High(MCat_Captcha) do  
            if code=Cat_Captcha[j] then  
            Result:=Result+IntToStr(j);  
         end;  
      end;  
    ShowMessage('Код Captcha '+Result)  
end;  

И первое, что хочется сказать по поводу этой процедуры – она просто так не заработает. Для того, чтобы разобрать любой URL на составляющие его компоненты необходимо подключать в uses модуль WinInet в котором и содержится процедура internetcrackurl.

Теперь пройдем немного дальше. Взгляните ещё раз на таблицу соответствия. Как Вы можете заметить – она содержит расшифровку не всех цифр. Так, в таблице отсутствуют цифры: 1 и 3. Я не буду повторяться и дописывать недостающие элементы, а предложу Вам более красивый с точки зрения программистов вариант расшифровки.

Берем любое число и соответствующий ему код Captchaб например:


7 –> 1101112  

Те, кто знаком с двоичной формой счисления, могут с первого взгляда определить, что в коде Captcha содержится число 7. Смотрите:


7 –> 11+0111+2

Открываем калькулятор, жмем кнопочку Bin, забиваем 0111, жмем кнопочку Dec и, о чудо, на табло высвечивается цифра 7!

Можете проверить всю таблицу таким образом – результат попадания в цель будет 100%. Теперь можно смело сократить код для расшифровки с семи до 4-х символов, т.е. отсечь первые 2 цифры – они всегда 11 и последнюю – она всегда 2. Теперь, ради спортивного интереса, можно получить семизначный код для недостающих элементов таблицы:


1 –> 1100012  
3 –> 1100112  

Теперь осталось написать функцию по переводу двоичного представления числа в десятеричную.


function BIN2DEC(BIN: string): LONGINT;  
var  
  J: LONGINT;  
  Error: BOOLEAN;  
  DEC: LONGINT;  
begin  
  DEC := 0;  
  Error := False;  
  for J := 1 to Length(BIN) do  
    begin  
      if (BIN[J] < > '0') and (BIN[J] < > '1') then  
        Error := True;  
      if BIN[J] = '1' then  
        DEC := DEC + (1 shl (Length(BIN) - J));  
{ (1 SHL (Length(BIN) - J)) = 2^(Length(BIN)- J) }  
    end;  
  if Error then  
    BIN2DEC := 0  
  else  
    BIN2DEC := DEC;  
end;  

Весь секрет работы с двоичной системой заключается в теории, которую я, кстати почерпнул из книги “Нестандартные приемы программирования на Delphi”.

Теперь переписываем основную процедуру распознавания Captcha,используя полученные знания (в листинге представлена часть измененной процедуры):


function Captcha(URL: string):string;  
var aURL: TURLComponents;  
 ParamStr: string; //строка, содержащая код каптчи  
 code: string; //7-ми значнй код из каптчи  
 i,j:integer;  
begin  
...  
 for I:=1 to 5 do //всего 35 цифр по 7 цифр на знак  
   begin  
    {получили 4-х значный код - двоичное представление числа}  
    code:=copy(copy(ParamStr,i+7*(i-1)-(i-1),7), 3, 4);  
    Result:=Result+BIN2DEC(Code); //вычислили число Captcha  
 end  
...  
end;  

Вот и весь секрет слабой Captcha. И последнее, что хотелось бы сказать – это то, что врядли Вы когда-то встретите теперь в Интернете подобную систему защиты. Судя по тому, что из 50 каталогов сайтов, использующих эту систему защиты 50 мёртвых или переделанных, можно сделать однозначный вывод – время халявы кончилось :) Теперь Captcha стала на порядок сложнее для взлома.
Теги:
Captcha
Добавлено: 04 Августа 2018 08:07:16 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...