|
Хакинг. Хакинг__искусство_эксплоита_2_е_469663841. Книга дает полное представление о программировании, машин ной архитектуре, сетевых соединениях и хакерских приемах
129 } for(i=0; i < 15; i++) { // Цикл поиска совпадений. j = i + 1; while(j < 16) { if(numbers[i] == numbers[j]) match = numbers[i]; j++; } } if(match != -1) { printf(“The dealer matched the number %d!\n”, match); printf(“You lose %d credits.\n”, wager); player.credits -= wager; } else { printf(“There were no matches! You win %d credits!\n”, wager); player.credits += wager; } return 0; } // Это игра Find the Ace. // Она возвращает -1, если у игрока 0 очков. int find_the_ace() { int i, ace, total_wager; int invalid_choice, pick = -1, wager_one = -1, wager_two = -1; char choice_two, cards[3] = {‘X’, ‘X’, ‘X’}; ace = rand()%3; // Выбрать для туза случайную позицию. printf(“******* Find the Ace *******\n”); printf(“In this game, you can wager up to all of your credits.\n”); printf(“Three cards will be dealt out, two queens and one ace.\n”); printf(“If you find the ace, you will win your wager.\n”); printf(“After choosing a card, one of the queens will be revealed.\n”); printf(“At this point, you may either select a different card or\n”); printf(“increase your wager.\n\n”); if(player.credits == 0) { printf(“You don’t have any credits to wager!\n\n”); return -1; } while(wager_one == -1) // Выполнять цикл, пока не будет // сделана допустимая ставка. wager_one = take_wager(player.credits, 0); print_cards(“Dealing cards”, cards, -1); pick = -1; while((pick < 1) || (pick > 3)) { // Выполнять цикл, пока не будет // сделан допустимый выбор. printf(“Select a card: 1, 2, or 3 “);
130 0x200 Программирование scanf(“%d”, &pick); } pick--; // Корректировать выбор, потому что нумерация карт начинается с 0. i=0; while(i == ace || i == pick) // Выполнять цикл, пока i++; // не будет найдена дама для открытия. cards[i] = ‘Q’; print_cards(“Revealing a queen”, cards, pick); invalid_choice = 1; while(invalid_choice) { // Выполнять цикл, пока не будет сделан // допустимый выбор. printf(“Would you like to:\n[c]hange your pick\tor\t[i]ncrease your wager?\n”); printf(“Select c or i: “); choice_two = ‘\n’; while(choice_two == ‘\n’) // Сбросить лишние переводы строки. scanf(“%c”, &choice_two); if(choice_two == ‘i’) { // Увеличить ставку. invalid_choice=0; // Это допустимый выбор. while(wager_two == -1) // Повторять, пока не сделана // вторая допустимая ставка. wager_two = take_wager(player.credits, wager_one); } if(choice_two == ‘c’) { // Изменить выбранную карту. i = invalid_choice = 0; // Допустимый выбор. while(i == pick || cards[i] == ‘Q’) // Повторять в цикле, // пока не найдена i++; // другая карта, pick = i; // а затем изменить выбор. printf(“Your card pick has been changed to card %d\n”, pick+1); } } for(i=0; i < 3; i++) { // Раскрыть все карты. if(ace == i) cards[i] = ‘A’; else cards[i] = ‘Q’; } print_cards(“End result”, cards, pick); if(pick == ace) { // Обработка выигрыша. printf(“You have won %d credits from your first wager\n”, wager_one); player.credits += wager_one; if(wager_two != -1) { printf(“and an additional %d credits from your second wager!\n”, wager_two); player.credits += wager_two; } } else { // Обработка проигрыша. printf(“You have lost %d credits from your first wager\n”, wager_one); player.credits -= wager_one;
0x280 Опираясь на основы 131 if(wager_two != -1) { printf(“and an additional %d credits from your second wager!\n”, wager_two); player.credits -= wager_two; } } return 0; } Поскольку это многопользовательская программа, выполняющая за- пись в файл, находящийся в каталоге /var, у нее должен быть установ- лен бит suid root. reader@hacking:/booksrc $ gcc -o game_of_chance game_of_chance.c reader@hacking:/booksrc $ sudo chown root:root ./game_of_chance reader@hacking:/booksrc $ sudo chmod u+s ./game_of_chance reader@hacking:/booksrc $ ./game_of_chance -=-={ New Player Registration }=-=- Enter your name: Jon Erickson Welcome to the Game of Chance, Jon Erickson. You have been given 100 credits. -=[ Game of Chance Menu ]=- 1 - Play the Pick a Number game 2 - Play the No Match Dealer game 3 - Play the Find the Ace game 4 - View current high score 5 - Change your username 6 - Reset your account at 100 credits 7 - Quit [Name: Jon Erickson] [You have 100 credits] -> 1 [DEBUG] current_game pointer @ 0x08048e6e ####### Pick a Number ###### This game costs 10 credits to play. Simply pick a number between 1 and 20, and if you pick the winning number, you will win the jackpot of 100 credits! 10 credits have been deducted from your account. Pick a number between 1 and 20: 7 The winning number is 14. Sorry, you didn’t win. You now have 90 credits. Would you like to play again? (y/n) n -=[ Game of Chance Menu ]=- 1 - Play the Pick a Number game 2 - Play the No Match Dealer game 3 - Play the Find the Ace game 4 - View current high score 5 - Change your username
132 0x200 Программирование 6 - Reset your account at 100 credits 7 - Quit [Name: Jon Erickson] [You have 90 credits] -> 2 [DEBUG] current_game pointer @ 0x08048f61 ::::::: No Match Dealer ::::::: In this game you can wager up to all of your credits. The dealer will deal out 16 random numbers between 0 and 99. If there are no matches among them, you double your money! How many of your 90 credits would you like to wager? 30 ::: Dealing out 16 random numbers ::: 88 68 82 51 21 73 80 50 11 64 78 85 39 42 40 95 There were no matches! You win 30 credits! You now have 120 credits Would you like to play again? (y/n) n -=[ Game of Chance Menu ]=- 1 - Play the Pick a Number game 2 - Play the No Match Dealer game 3 - Play the Find the Ace game 4 - View current high score 5 - Change your username 6 - Reset your account at 100 credits 7 - Quit [Name: Jon Erickson] [You have 120 credits] -> 3 [DEBUG] current_game pointer @ 0x0804914c ******* Find the Ace ******* In this game you can wager up to all of your credits. Three cards will be dealt: two queens and one ace. If you find the ace, you will win your wager. After choosing a card, one of the queens will be revealed. At this point you may either select a different card or increase your wager. How many of your 120 credits would you like to wager? 50 *** Dealing cards *** ._. ._. ._. Cards: |X| |X| |X| 1 2 3 Select a card: 1, 2, or 3: 2 *** Revealing a queen *** ._. ._. ._. Cards: |X| |X| |Q| ^-- your pick
0x280 Опираясь на основы 133 Would you like to [c]hange your pick or [i]ncrease your wager? Select c or i: c Your card pick has been changed to card 1. *** End result *** ._. ._. ._. Cards: |A| |Q| |Q| ^-- your pick You have won 50 credits from your first wager. You now have 170 credits. Would you like to play again? (y/n) n -=[ Game of Chance Menu ]=- 1 - Play the Pick a Number game 2 - Play the No Match Dealer game 3 - Play the Find the Ace game 4 - View current high score 5 - Change your username 6 - Reset your account at 100 credits 7 – Quit [Name: Jon Erickson] [You have 170 credits] -> 4 ====================| HIGH SCORE |==================== You currently have the high score of 170 credits! ====================================================== -=[ Game of Chance Menu ]=- 1 - Play the Pick a Number game 2 - Play the No Match Dealer game 3 - Play the Find the Ace game 4 - View current high score 5 - Change your username 6 - Reset your account at 100 credits 7 - Quit [Name: Jon Erickson] [You have 170 credits] -> 7 Thanks for playing! Bye. reader@hacking:/booksrc $ sudo su jose jose@hacking:/home/reader/booksrc $ ./game_of_chance -=-={ New Player Registration }=-=- Enter your name: Jose Ronnick Welcome to the Game of Chance Jose Ronnick. You have been given 100 credits. -=[ Game of Chance Menu ]=- 1 - Play the Pick a Number game 2 - Play the No Match Dealer game 3 - Play the Find the Ace game
134 0x200 Программирование 4 - View current high score 5 - Change your username 6 - Reset your account at 100 credits 7 - Quit [Name: Jose Ronnick] [You have 100 credits] -> 4 ====================| HIGH SCORE |==================== Jon Erickson has the high score of 170. ====================================================== -=[ Game of Chance Menu ]=- 1 - Play the Pick a Number game 2 - Play the No Match Dealer game 3 - Play the Find the Ace game 4 - View current high score 5 - Change your username 6 - Reset your account at 100 credits 7 - Quit [Name: Jose Ronnick] [You have 100 credits] -> 7 Thanks for playing! Bye. jose@hacking:/booksrc $ exit exit reader@hacking:/booksrc $ Поработайте немного с этой программой. Игра Find the Ace (найди туз) демонстрирует понятие условной вероятности: вопреки интуитивным представлениям, изменяя свой выбор, вы увеличиваете вероятность найти туз с 33 процентов до 66. Многие никак не могут этого понять, почему я и говорю, что это противоречит интуиции. Секрет хакин- га в том, чтобы разбираться в таких малоизвестных вещах и получать с их помощью результаты, кажущиеся чудом.
0x300 ЭксплойтыПрограммные эксплойты составляют основу хакинга. Как показано в предыдущей главе, программа – это сложный набор правил, определяющих некоторый порядок исполнения и в конечном счете указывающих компьютеру, что он должен делать. Программный эксплойт – это искусный способ заставить компьютер выполнить то, что вам нужно, даже если выполняемая в данный момент программа не предусматривает таких действий. Поскольку программа на самом деле может работать только так, как ей предписано, брешь в защите фактически представляет собой ошибку или недосмотр, допущенные при разработке программы или среды, в которой она выполняется. Для обнаружения таких брешей, или уязвимостей, и написания программ, в которых они устранены, требуется творческий склад ума. Иногда эти бреши – результат относительно очевидных ошибок программиста, но встречаются и менее явные ошибки, на которых основаны более сложные технологии эксплойтов, применяемые в самых разных сферах.Программа может делать лишь то, что в ней будет заложено, в бук- вальном смысле. К сожалению, код программы не всегда соответствует тому, что программа должна была бы делать по замыслу программиста. Проиллюстрируем это положение следующим шутливым рассказом. Некто, гуляя в лесу, находит волшебную лампу. Он не задумываясь подби- рает ее, протирает рукавом, и из нее появляется джинн. В благодарность за свое освобождение джинн предлагает исполнить три желания. Человек в восторге, он точно знает, чего хочет. «Во-первых, – говорит он, – хочу миллион долларов». Джинн щелкает пальцами, и прямо из воздуха появляется чемодан, пол- ный денег. 1360x300 Эксплойты Вытаращив от изумления глаза, человек продолжает: «Во-вторых, хочу „феррари“». Джинн щелкает пальцами, и тут же из ничего возникает «феррари». Человек продолжает: «А в-третьих – хочу стать неотразимым для жен- щин». Джинн щелкает пальцами, и человек превращается в коробку шоколадных конфет. Последнее желание человека было исполнено в соответствии с тем, что он сказал, а не с тем, что подумал. Точно так же программа выполняет свои инструкции буквально, и результат может оказаться не тем, что предполагал программист. Иногда просто катастрофой. Программисты – тоже люди, и порой пишут не совсем то, что имеют в виду. Например, распространенная ошибка программирования – ошибка на единицу ( off-by-one). Как следует из названия, она возни- кает, когда программист при подсчете ошибается на единицу в ту или иную сторону. Это происходит гораздо чаще, чем можно было бы пред- положить, и проще всего проиллюстрировать это таким примером. До- пустим, вы строите изгородь длиной 30 метров и ставите столбы че- рез каждые три метра. Сколько столбов вам понадобится? Первое, что приходит в голову – 10, но это неверно, потому что в действительности потребуется 11 столбов. Такую ошибку на единицу иногда называют ошибкой числа столбов в заборе, и она случается, когда программист считает сами предметы вместо промежутков между ними или наобо- рот. Другой пример: программист выбирает интервал чисел или эле- ментов, которые нужно обработать, например элементы от номера N до номера M. Если N = 5, а M = 17, то сколько элементов надо обработать? Очевидный ответ: M – N, или 17 – 5 = 12 элементов. Но это неправиль- но, потому что на самом деле элементов M – N + 1, то есть всего 13. На первый взгляд это кажется нелогичным, но именно отсюда и получа- ются такие ошибки. Часто эти ошибки остаются незамеченными, потому что при тестиро- вании программ не проверяются все возможные случаи, а на обычном выполнении программы ошибка никак не сказывается. Однако если программе передать такие входные данные, которые заставят ошиб- ку проявиться, это может оказать разрушительное действие на всю остальную логику программы. Правильно построенный на ошибке на единицу эксплойт превращает защищенную, казалось бы, программу в уязвимую. Классическим примером является OpenSSH – комплекс программ за- щищенной связи с терминалом, который должен был заменить небезо- пасные и не использующие шифрование службы, такие как telnet, rsh и rcp. Однако в коде, выделяющем каналы, была допущена ошибка на единицу, которая интенсивно эксплуатировалась. А именно в операто- ре if был такой код: 0x300 Эксплойты 137if (id < 0 || id > channels_alloc) { Правильный код должен выглядеть так: if (id < 0 || id >= channels_alloc) { На обычном языке этот код означает: « Если ID меньше 0 или ID больше количества выделенных каналов, выполнить следующее…», тогда как правильным было бы « Если ID меньше 0 или ID больше или равен коли-честву выделенных каналов, выполнить следующее…». Эта простая ошибка на единицу позволила создать эксплойт, с помо- щью которого обычный зарегистрировавшийся в системе пользователь получал в ней неограниченные права администратора. Разумеется, по- добная функциональность не входила в намерения разработчиков та- кой защищенной программы, как OpenSSH, но компьютер может вы- полнять только те инструкции, которые получает. Другая ситуация, порождающая ошибки, которые впоследствии ста- новятся основой для эксплойтов, связана с поспешной модификаци- ей программы в целях расширения ее функциональности. Расширение функциональности повышает продаваемость программы и ее цену, но при этом растет и сложность программы, а значит и вероятность до- пустить в ней оплошность. Программа веб-сервера Microsoft IIS долж- на предоставлять пользователям статическое и интерактивное содер- жимое. Для этого она должна разрешать пользователям читать, запи- сывать и выполнять программы и файлы из некоторых каталогов. Та- кие возможности, однако, должны предоставляться только в этих вы- деленных каталогах. В противном случае пользователи получат пол- ный контроль над системой, что, очевидно, недопустимо с точки зре- ния безопасности. С этой целью в программу был включен код провер- ки маршрутов, запрещающий пользователям перемещаться вверх по дереву каталогов с помощью символа обратного слэша (косой черты) и входить в другие каталоги. Однако с добавлением в программу поддержки кодировки символов Unicode ее сложность увеличилась. Unicode представляет собой на- бор символов, записываемых двумя байтами, и содержит символы всех языков, включая китайский и арабский. Используя для каждо- го символа два байта вместо одного, Unicode позволяет записывать де- сятки тысяч различных символов, а не всего несколько сотен, как при однобайтных символах. Дополнительная сложность привела к тому, что символ обратного слэша стал представляться несколькими спо- собами. Например, %5c в кодировке Unicode транслируется в символ обратного слэша, но эта трансляция происходит уже после выполне- ния кода, проверяющего допустимость маршрута. Поэтому ввод сим- волов %5c вместо \ делает возможным перемещение по дереву катало- гов, что открывает уязвимость, о которой говорилось выше. Два чер- вя Sadmind и CodeRed использовали просмотр в преобразовании коди- ровки Unicode такого типа для искажения вида (дефейса) веб-страниц. 1380x300 Эксплойты Другой похожий пример такого принципа буквального исполнения, хотя и не относящийся к программированию, известен как «лазей- ка ЛаМаккиа» (LaMacchia Loophole). Подобно правилам компьютер- ных программ, в законодательстве США иногда обнаруживаются пра- вила, говорящие не то, что подразумевалось их авторами, и, подобно программным эксплойтам, эти юридические лазейки можно использо- вать, чтобы обойти смысл закона. В конце 1993 года 21-летний компьютерный хакер и студент МТИ Дэ- вид ЛаМаккиа (David LaMacchia) организовал электронную доску объ- явлений под названием Cynosure (Полярная звезда) для пиратского об- мена программами. Кто-то загружал программу на сервер, а осталь- ные могли скачивать ее с сервера. К концу шестой недели существо- вания эта служба породила такой мощный сетевой трафик по всему свету, что привлекла внимание университетских и федеральных вла- стей. Компании-производители программного обеспечения заявили, что Cynosure нанесла им убытки в размере миллиона долларов, и фе- деральное Большое жюри предъявило ЛаМаккиа обвинение в заговоре с неизвестными лицами и нарушении закона о мошенничестве с при- менением электронных средств. Однако обвинение было снято, по- скольку действия ЛаМаккиа не являлись преступлением согласно за- кону об авторских правах, так как они не имели целью получение ком- мерческих преимуществ или личной финансовой выгоды. Очевидно, законодателям в свое время не пришло в голову, что кто- нибудь станет заниматься такой деятельностью, имея другие цели, не связанные с личным обогащением. Позднее, в 1997 году, Конгресс США закроет эту лазейку законом об электронном воровстве. Хотя в этом примере не участвует эксплойт компьютерной программы, су- дьи и суды могут рассматриваться здесь как компьютеры, выполняю- щие программу юридической системы буквально, как она написана. Абстрактные понятия хакинга выходят за компьютерные рамки и мо- гут применяться к различным жизненным ситуациям, в которых уча- ствуют сложные системы. |
|
|