книги хакеры / Защита_от_взлома_сокеты,_эксплойты,_shell_код_Фостер_Дж_
.pdf
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|
||
|
|
X |
|
|
|
|
|
|
|
||
|
- |
|
|
|
|
d |
|
|
|||
|
F |
|
|
|
|
|
|
t |
|
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
|
||
P |
|
|
|
|
|
NOW! |
o |
|
|||
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|
|||
|
|
|
|
to |
|
|
|
|
|
Язык C# |
|
w Click |
|
|
|
|
|
|
|||||
|
|
|
|
|
|
m |
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
|
. |
|
|
|
|
|
.c |
|
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
e |
|
|
||
|
|
|
df-xchan8 |
|
|
|
|
9 #include "ipv4_parse.h"
10
11/*
12* ipv4_parse_sv()
13*
14*
15*/
16static
17int ipv4_parse_sv(ipv4_parse_ctx *ctx,
18 |
int |
idx, |
19 |
char |
*sv) |
20{
21int wc = 0;
22int x = 0;
24// проверить, есть ли в значении метасимволы (весь диапазон 0-255)
25wc = (strchr(sv, '*') == NULL ? 0 : 1);
26if(wc)
27{
28if(strlen(sv) != 0x1)
29{
30return(-1);
31}
32
33for(x=0; x <= 0xFF; ++x)
34{
35ctx->m_state[idx][x] = 1;
36}
37}
38// одиночное значение (например, "1", "2", "192", "10")
39else
40{
41ctx->m_state[idx][(unsigned char) atoi(sv)] = 1;
42}
43
44return(0);
45}
46
47/*
48* ipv4_parse_r()
49*
50*
51*/
52static
53int ipv4_parse_r(ipv4_parse_ctx *ctx,
54 |
int |
idx, |
|
55 |
char |
*r |
) |
56 |
{ |
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
71 |
|
to |
|
|
|
|
|
|||
|
|
|
|
|
|
|
||||
w Click |
|
|
|
|
|
|
m |
|||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|
|
|
|||
|
|
X |
|
|
|
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
|
|
|
|||
|
F |
|
|
|
|
|
|
|
t |
|
|
|
||
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r |
|
|
||
P |
|
|
|
|
|
NOW! |
|
o |
|
|
||||
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
BUY |
|
|
|
|
|
||||
|
|
|
|
to |
|
|
|
72 Глава 1. Написание безопасных программ |
||||||
w Click |
|
|
|
|
||||||||||
|
|
|
|
|
||||||||||
|
|
|
|
|
|
|
|
m |
|
|
||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
o |
|
|
|
|
. |
|
|
|
|
|
|
.c |
|
|
|
|||
|
|
p |
|
|
|
|
g |
|
57 |
|
|
|||
|
|
|
df-xchan |
e |
unsigned char hi = 0; |
|||||||||
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
58 unsigned char lo = 0; |
|||
|
|
|
|
|
|
|
|
|
|
|
59 |
char |
*p1 = NULL; |
|
|
|
|
|
|
|
|
|
|
|
|
60 |
int |
x = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
61 |
|
|
62// разобрать левую и правую границу диапазона
63p1 = strchr(r, '-');
64*p1 = '\0';
65++p1;
66
67lo = (unsigned char) atoi(r );
68hi = (unsigned char) atoi(p1);
70// если левая граница больше правой,
71// вернуть ошибку (например, "200-100").
72if(lo >= hi)
73{
74return(-1);
75}
76
77// считать диапазон допустимым
78for(x=lo; x <= hi; ++x)
79{
80ctx->m_state[idx][x] = 1;
81}
82
83return(0);
84}
85
86/*
87* ipv4_parse_tok()
88*
89*
90*/
91static
92int ipv4_parse_tok(ipv4_parse_ctx *ctx,
93 |
int |
idx, |
94 |
char |
*tok) |
95{
96int ret = 0;
97
98// есть ли внутри значения "-", означающий, что диапазон
99// (например, "1-5"); если нет, считать одиночным значением ("1",
100// "2", "*"), иначе диапазоном ("1-5")
101ret = (strchr(tok, '-') == NULL) ?
102ipv4_parse_sv(ctx, idx, tok) :
103ipv4_parse_r (ctx, idx, tok);
104return(ret);
105}
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
||
|
|
|
C |
|
|
E |
|
|
|
|
|
||||
|
|
X |
|
|
|
|
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
|
|
d |
|
|
|
|||
|
F |
|
|
|
|
|
|
|
|
|
t |
|
|
||
|
D |
|
|
|
|
|
|
|
|
|
|
i |
r |
|
|
P |
|
|
|
|
|
|
|
NOW! |
o |
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
BUY |
|
|
|
|
||||
|
|
|
|
|
to |
|
|
|
|
|
|
|
Язык C# |
||
w Click |
|
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
m |
||||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
|
o |
|
|
|
. |
|
|
|
|
|
|
|
|
.c |
|
|
|||
|
|
p |
|
|
|
|
|
|
|
e |
|
|
|
||
|
|
|
d |
|
|
xch106 |
|
|
|
||||||
|
|
|
|
f- |
|
an |
|
|
|
|
|
|
107/*
108* ipv4_parse_octet()
109*
110*
111*/
112static
113int ipv4_parse_octet(ipv4_parse_ctx *ctx,
114 |
int |
idx, |
115 |
char |
*octet) |
116{
117char *tok = NULL;
118int ret = 0;
120// разобрать октеты, разделенные запятыми, если
121// запятая присутствует
122 tok |
= strtok(octet, ","); |
123if(tok != NULL)
124{
125while(tok != NULL)
126{
127// считать, что каждое отделенное запятой значение – это
128// диапазон или одиночное значение ("2-100", "7" è ò.ä.)
129 |
ret |
= ipv4_parse_tok(ctx, idx, tok); |
130if(ret < 0)
131{
132return(-1);
133}
134
135 tok = strtok(NULL, ",");
136}
137}
138// если запятой нет, считать диапазоном или
139// одиночным значением ("2-100", "7" è ò.ä.)
140else
141{
142ret = ipv4_parse_tok(ctx, idx, octet);
143if(ret < 0)
144{
145return(-1);
146}
147}
148
149return(0);
150}
151
152/*
153* ipv4_parse_ctx_init()
154*
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
73 |
|
to |
|
|
|
|
|
|||
|
|
|
|
|
|
|
||||
w Click |
|
|
|
|
|
|
m |
|||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|
|
|
||
|
|
X |
|
|
|
|
|
|
|
|
|
||
|
- |
|
|
|
|
d |
|
|
|
|
|||
|
F |
|
|
|
|
|
|
t |
|
|
|
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
|
r |
|
|
|
||
P |
|
|
|
|
|
NOW! |
o |
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|
|
|
|||
|
|
|
|
to |
|
|
74 Глава 1. Написание безопасных программ |
|
|||||
w Click |
|
|
|
|
|||||||||
|
|
|
|
|
|||||||||
|
|
|
|
|
|
m |
|
|
|
||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
|
|
|
. |
|
|
|
|
|
.c |
|
|
|
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
|
|
e |
|
* |
диапазон IP-адресов трактуется как 4 массива из 256 значений |
|||
|
|
|
df-xchan |
155 |
|||||||||
|
|
|
|
|
|
|
|
156 |
* |
типа unsigned char. Каждый массив представляет один из четырех |
|||
|
|
|
|
|
|
|
|
157 |
* |
октетов IP-адреса. Элементы массива равны 1 или 0 в зависимости |
|||
|
|
|
|
|
|
|
|
158 |
* |
от того представлен данный адрес в диапазоне или нет. |
|||
|
|
|
|
|
|
|
|
159 |
* |
Например, пусть задан такой адрес: |
|
||
|
|
|
|
|
|
|
|
160 |
* |
|
|
||
|
|
|
|
|
|
|
|
161 |
* |
|
|
||
|
|
|
|
|
|
|
|
162 |
* |
char *range = "10.1.1.1"; |
|
||
|
|
|
|
|
|
|
|
163 |
* |
|
|
||
|
|
|
|
|
|
|
|
164 |
* |
Тогда в первом массиве 10-ый байт будет равен 1, а во втором, |
|||
|
|
|
|
|
|
|
|
165 |
* |
третьем и четвертом массивах 1 будет равен первый байт. |
|||
|
|
|
|
|
|
|
|
166 |
* |
|
|
||
|
|
|
|
|
|
|
|
167 |
* |
|
|
||
|
|
|
|
|
|
|
|
168 |
* |
|
|
||
|
|
|
|
|
|
|
|
169 |
* |
После того как диапазон полностью разобран и |
|||
|
|
|
|
|
|
|
|
170 |
* |
все значения сохранены в массивах (состояния), |
|||
|
|
|
|
|
|
|
|
171 |
* |
можно выполнить несколько циклов для обхода |
|||
|
|
|
|
|
|
|
|
172 |
* |
диапазона. |
|
||
|
|
|
|
|
|
|
|
173 |
* |
|
|
||
|
|
|
|
|
|
|
|
174 |
* |
Ниже приведен пример синтаксиса задания IP-адресов |
|||
|
|
|
|
|
|
|
|
175 |
* |
в командной строке в стиле программы nmap: |
|||
|
|
|
|
|
|
|
|
176 |
* |
|
|
||
|
|
|
|
|
|
|
|
177 |
* |
Пример: |
|
||
|
|
|
|
|
|
|
|
178 |
* |
|
|
||
|
|
|
|
|
|
|
|
179 |
* |
"192.168.1,2,3,4-12,70.*" |
|
||
|
|
|
|
|
|
|
|
180 |
* |
|
|
||
|
|
|
|
|
|
|
|
181 |
* |
|
|
||
|
|
|
|
|
|
|
|
182 |
* |
|
|
||
|
|
|
|
|
|
|
|
183 |
*/ |
|
|
||
|
|
|
|
|
|
|
|
184 |
int ipv4_parse_ctx_init(ipv4_parse_ctx *ctx, |
||||
|
|
|
|
|
|
|
|
185 |
|
char |
*range) |
186{
187char *oc[4];
188int x = 0;
190 if(ctx == NULL ||
191range == NULL)
192{
193return(-1);
194}
195
196 memset(ctx, 0x00, sizeof(ipv4_parse_ctx));
197
198// разобрать диапазон IP-адресов на 4 октета
199if((oc[0] = strtok(range, ".")) == NULL ||
200(oc[1] = strtok(NULL , ".")) == NULL ||
201(oc[2] = strtok(NULL , ".")) == NULL ||
202(oc[3] = strtok(NULL, ".")) == NULL)
203{
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
||
|
|
|
C |
|
|
E |
|
|
|
|
||||
|
|
X |
|
|
|
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
|
|
d |
|
|
|||
|
F |
|
|
|
|
|
|
|
|
|
t |
|
||
|
D |
|
|
|
|
|
|
|
|
|
|
i |
r |
|
P |
|
|
|
|
|
|
|
NOW! |
o |
|||||
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
BUY |
|
|
|
||||
|
|
|
|
|
to |
|
|
|
|
|
|
|
||
w Click |
|
|
|
|
|
|
|
m |
||||||
|
|
|
|
|
|
|
|
|
||||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
|
|
|
.c |
|
|||
|
|
p |
|
|
|
|
|
|
|
e |
|
|
||
|
|
|
d |
|
|
xch204 |
|
|
||||||
|
|
|
|
f- |
|
an |
|
|
|
|
|
Язык C#
return(-1);
205 }
206
207// разобрать каждый октет
208if(ipv4_parse_octet(ctx, 0, oc[0]) < 0 ||
209ipv4_parse_octet(ctx, 1, oc[1]) < 0 ||
210ipv4_parse_octet(ctx, 2, oc[2]) < 0 ||
211ipv4_parse_octet(ctx, 3, oc[3]) < 0)
212{
213return(-1);
214}
215
216return(0);
217}
218
219/*
220* ipv4_parse_next_addr()
221*
222* Эта функция служит для обхода уже разобранного
223* диапазона IP-адресов.
224*
225*
226*
227*
228*
229*
230*/
231int ipv4_parse_next(ipv4_parse_ctx *ctx,
232 |
unsigned int *addr) |
233{
234if(ctx == NULL ||
235addr == NULL)
236{
237return(-1);
238}
239
240for( ; ctx->m_index[0] <= 0xFF; ++ctx->m_index[0])
241{
242if(ctx->m_state[0][ctx->m_index[0]] != 0)
243{
244for( ; ctx->m_index[1] <= 0xFF; ++ctx->m_index[1])
245{
246if(ctx->m_state[1][ctx->m_index[1]] != 0)
247{
248for( ; ctx->m_index[2] <= 0xFF; ++ctx->m_index[2])
249{
250if(ctx->m_state[2][ctx->m_index[2]] != 0)
251{
252for( ; ctx->m_index[3] <= 0xFF; ++ctx->m_index[3])
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
75 |
|
to |
|
|
|
|
|
|||
|
|
|
|
|
|
|
||||
w Click |
|
|
|
|
|
|
m |
|||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|
|
||
|
|
X |
|
|
|
|
|
|
|
|
||
|
- |
|
|
|
|
d |
|
|
|
|||
|
F |
|
|
|
|
|
|
t |
|
|
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
r |
|
|
||
P |
|
|
|
|
|
NOW! |
o |
|
|
|||
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|
|
|||
|
|
|
|
to |
|
|
76 Глава 1. Написание безопасных программ |
|
||||
w Click |
|
|
|
|
||||||||
|
|
|
|
|
||||||||
|
|
|
|
|
|
m |
|
|
||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
|
|
. |
|
|
|
|
|
.c |
|
|
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
|
e |
|
{ |
|
||
|
|
|
df-xchan |
253 |
|
|||||||
|
|
|
|
|
|
|
|
254 |
if(ctx->m_state[3][ctx->m_index[3]] != 0) |
|||
|
|
|
|
|
|
|
|
255 |
{ |
|
||
|
|
|
|
|
|
|
|
256 |
*addr = |
|
||
|
|
|
|
|
|
|
|
257 |
((ctx->m_index[0] << |
0) & 0x000000FF) ^ |
||
|
|
|
|
|
|
|
|
258 |
((ctx->m_index[1] << |
8) & 0x0000FF00) ^ |
||
|
|
|
|
|
|
|
|
259 |
((ctx->m_index[2] << 16) & 0x00FF0000) ^ |
|||
|
|
|
|
|
|
|
|
260 |
((ctx->m_index[3] << 24) & 0xFF000000); |
|||
|
|
|
|
|
|
|
|
261 |
++ctx->m_index[3]; |
|
||
|
|
|
|
|
|
|
|
263 |
|
|
||
|
|
|
|
|
|
|
|
264 |
return(0); |
|
265}
266}
267ctx->m_index[3] = 0;
268}
269}
270ctx->m_index[2] = 0;
271}
272}
273ctx->m_index[1] = 0;
274}
275}
276
277return(-1);
278}
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
Ôàéëipv4_parse.c – это сердце программы. Он содержит несколько функций для выполнения низкоуровневого разбора адреса, которые вызываются из управляющего файла main.c. Функция i pv4_parse_sv разбирает отдельные числовые значения (sv означает «single value» – одиночное значение). Сначала она проверяет, не является ли одиночное значение метасимволом (звездочкой) и допустима ли его длина. Затем в цикле for результирующие значения заносятся в массив m_state. Функция i pv4_parse_r разбирает диапазон IP-адресов, определяя его нижнюю и верхнюю границу. Функция i pv4_parse_tok выясняет, нет ли в исследуемом значении символа «минус»
(–). Это важно для того, чтобы знать, представляет ли значение диапазон адресов либо один или несколько отдельных адресов. Функция ipv4_parse_octet разбирает числа, разделенные запятыми; так бывает, когда в командной строке задан список адресов, а не целый диапазон. IP-адреса обычно представляются в точечно-десятичной нотации, то есть состоят из четырех однобайтовых чисел в десятичной записи, отделенных друг от друга точками. Функция ipv4_ctx_init создает четыре массива, в которых хранятся разобранные IP-адреса. Функция ipv4_parse_next облегчает процесс разбора, переходя к следующей десятичной компоненте адреса, афункция ipv4_next_addr обходит уже разобранные данные.
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|
||
|
|
X |
|
|
|
|
|
|
|
||
|
- |
|
|
|
|
d |
|
|
|||
|
F |
|
|
|
|
|
|
t |
|
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
|
||
P |
|
|
|
|
|
NOW! |
o |
|
|||
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|
|||
|
|
|
|
to |
|
|
|
|
|
Язык C# |
|
w Click |
|
|
|
|
|
|
|||||
|
|
|
|
|
|
m |
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
|
. |
|
|
|
|
|
.c |
|
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
e |
|
|
||
|
|
|
df-xchan1 |
|
/* |
|
|||||
|
|
|
|
|
|
2 |
|
|
* main.c |
|
|
|
|
|
|
|
|
3 |
|
|
* |
|
|
|
|
|
|
|
|
4 |
|
|
*/ |
|
|
|
|
|
|
|
|
5 |
|
|
|
|
|
|
|
|
|
|
|
6 |
|
#include <stdio.h> |
|
||
|
|
|
|
|
|
7 |
|
#include "ipv4_parse.h" |
|
||
|
|
|
|
|
|
8 |
|
|
|
|
|
|
|
|
|
|
|
9 int |
|
||||
|
|
|
|
|
10 main(int argc, char *argv[]) |
|
|||||
|
|
|
|
|
11 |
|
{ |
|
|
||
|
|
|
|
|
12 |
|
|
ipv4_parse_ctx ctx; |
// context to hold state of ip range |
||
|
|
|
|
|
13 |
|
|
unsigned int addr = 0; |
|
||
|
|
|
|
|
14 |
|
|
int ret = 0; |
|
||
|
|
|
|
|
15 |
|
|
|
|
16if(argc != 2)
17{
18printf("usage: %s ip_range\r\n", argv[0]);
19return(1);
20}
21
22 |
// вначале произвести разбор диапазона IP-адресов |
|
23 |
ret |
= ipv4_parse_ctx_init(&ctx, argv[1]); |
24if(ret < 0)
25{
26printf("*** ошибка ipv4_parse_ctx_init().\r\n");
27return(1);
28}
29
30// распечатать все IP-адреса из диапазона
31while(1)
32{
33// получить следующий IP-адрес из диапазона
34ret = ipv4_parse_next(&ctx, &addr);
35if(ret < 0)
36{
37printf("*** конец диапазона.\r\n");
38break;
39}
40
41// напечатать его
42printf("ADDR: %d.%d.%d.%d\r\n",
43(addr >> 0) & 0xFF,
44(addr >> 8) & 0xFF,
45(addr >> 16) & 0xFF,
46(addr >> 24) & 0xFF);
47}
48
49return(0);
50}
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
77 |
|
to |
|
|
|
|
|
|||
|
|
|
|
|
|
|
||||
w Click |
|
|
|
|
|
|
m |
|||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
||
|
|
|
C |
|
E |
|
|
|
|
|
|
|
C |
|
E |
|
|
|
||||||
|
|
X |
|
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
||||||
|
- |
|
|
|
|
|
d |
|
|
|
- |
|
|
|
|
|
d |
|
||||||
|
F |
|
|
|
|
|
|
|
i |
|
|
|
F |
|
|
|
|
|
|
|
i |
|
||
|
|
|
|
|
|
|
|
t |
|
|
|
|
|
|
|
|
|
|
t |
|
||||
P |
D |
|
|
|
|
|
|
|
|
o |
|
P |
D |
|
|
|
|
|
|
|
|
o |
||
|
|
|
|
NOW! |
r |
|
|
|
|
|
NOW! |
r |
||||||||||||
|
|
|
|
|
BUY |
|
|
|
|
|
|
|
|
BUY |
|
|
||||||||
|
|
|
|
to |
|
|
|
78 Глава 1. Написание безопасных программ |
|
|
|
|
to |
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
w |
|
|
|
|
|
|
|
|
|
m |
|
w |
|
|
|
|
|
|
|
|
|
m |
||
w Click |
|
|
|
|
|
|
o |
|
w Click |
|
|
|
|
|
|
o |
||||||||
|
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
||
|
. |
|
|
|
|
|
|
.c |
|
|
|
. |
|
|
|
|
|
|
.c |
|
||||
|
|
p |
df |
|
|
|
|
e |
|
|
|
|
p |
df |
|
|
|
|
e |
|
||||
|
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
g |
|
|
|
||||||
|
|
|
|
|
n |
|
|
|
|
|
|
|
|
|
|
n |
|
|
|
|
||||
|
|
|
|
-xcha |
|
|
|
|
|
Можно сказать, что функция main в файле main.c управляет разбором. Она-x cha |
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
получает из командной строки подлежащие разбору IP-адреса (строка 10). |
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
В строках 16–20 объясняется, как запускать программу, причем эта информа- |
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
ция отправляется на стандартный вывод. Строки 30–46 составляют основную |
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
часть программы. В цикле while вызывает функция ipv4_parse_next, которая |
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
разбирает очередной адрес, после чего он выводится на печать. |
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
1 /* |
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
2 |
* ipv4_parse.h |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
* |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
6 #ifndef __IPV4_PARSE_H__
7 #define __IPV4_PARSE_H__
8
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12
13typedef struct ipv4_parse_ctx
14{
15unsigned char m_state[4][256];
16unsigned short m_index[4];
17
18 } ipv4_parse_ctx;
19
20/*
21* ipv4_parse_ctx_init()
22*
23*
24*/
25int ipv4_parse_ctx_init(ipv4_parse_ctx *ctx,
26 |
char *range); |
27 |
|
28/*
29* ipv4_parse_next_addr()
30*
31*
32*/
33int ipv4_parse_next(ipv4_parse_ctx *ctx,
34 |
unsigned int *addr); |
35 |
|
36#ifdef __cplusplus
37}
38#endif
39
40 #endif /* __IPV4_PARSE_H__ */
41
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
||
|
|
|
C |
|
E |
|
|
|
|
|
|
C |
|
E |
|
|
|
||||||
|
|
X |
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
||||||
|
- |
|
|
|
|
|
d |
|
|
- |
|
|
|
|
|
d |
|
||||||
|
F |
|
|
|
|
|
|
|
t |
|
|
F |
|
|
|
|
|
|
|
t |
|
||
|
D |
|
|
|
|
|
|
|
|
i |
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
|
|
|
|
|
|
|
|
|
r |
||||
P |
|
|
|
|
|
NOW! |
o |
P |
|
|
|
|
|
NOW! |
o |
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
|
BUY |
|
|
|
|
|
|
|
BUY |
|
|
||||||||
|
|
|
|
to |
|
|
|
|
|
|
Язык Perl 79 |
|
to |
|
|
|
|
|
|
||||
w Click |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
m |
w Click |
|
|
|
|
|
|
|
m |
|||||||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
||
|
w |
|
|
|
|
|
|
|
|
o |
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|
. |
|
|
|
|
g |
.c |
|
||||||
|
|
p |
|
-xcha |
|
|
|
|
|
p |
|
-x cha |
|
|
|
||||||||
|
|
|
|
|
|
ipv4_parse.h – это заголовочный файлдля программ наC/C++. В нем объяв- |
|
|
e |
|
|||||||||||||
|
|
|
df |
|
|
n |
e |
|
|
|
|
df |
|
|
n |
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
лены прототипы функций, определенных в файле |
ipv4_parse.c. Предвари- |
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
тельное объявление прототипов позволяет избежать предупреждений, гене- |
|
|
|
|
|
|
|
|
|
рируемых компилятором с языка C. Для компиляторов же с языка C++ объявление прототипов обязательно, это связано со строгой типизацией языка. Предложение extern «C» необходимо для того, чтобы компилятор C++ не преобразовывал имена функций.
Язык Perl
В 1987 году Ларри Уолл (Larry Wall) создал и разослал по многочисленным конференциям Usenet язык Perl. Первоначально он задумывался как язык сценариев, интегрирующий в себе многие функциональные возможности различных интерпретируемых языков, уже имевшихся к тому времени в системе UNIX. Эмуляция функций из таких языков, как sh, sed è awk в сочетании с наличием регулярных выражений способствовало тому, что Perl стал популярен очень быстро, а широкое распространение Интернет, последовавшее за рождением Всемирной паутины (WWW), сделало Perl языком номер один в мире сценариев.
Популярность Perl росла по мере расширения WWW, так как очень скоро он превратился в один из самых простых методов написания CGI-прило- жений (Common Gateway Interface – общий шлюзовой интерфейс). Такие приложения применяются для отправки динамического контента пользователям Web и обеспечения доступа к базам данных. Интерфейс CGI определяет общий формат данных и механизмы взаимодействия различных приложений. К числу общепризнанных достоинств Perl относятся гибкость и реализация регулярных выражений (regex). Нередко приходится слышать мнение, что мощь аппарата регулярных выражений в Perl превосходит все прочие реализации. Этот механизм позволяет записывать алгоритмы сопоставления с образцом и строковых подстановок одной строкой кода в случа- ях, где на C пришлось бы написать сотни строк. Например, следующее выражение ищет в указанной строке все вхождения слова «cat» и заменяет их на «dog»:
$mystring =~ s/cat/dog/g;
В программе на C пришлось бы написать цикл, который считывает данные из строки, обрабатывает отдельные символы, а затем производит замену одной подстроки на другую. Конечно, это гораздо труднее и утомительнее.
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
||
|
|
|
C |
|
E |
|
|
|
|
|
|
C |
|
E |
|
|
|
||||||
|
|
X |
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
||||||
|
- |
|
|
|
|
|
d |
|
|
- |
|
|
|
|
|
d |
|
||||||
|
F |
|
|
|
|
|
|
|
i |
|
|
F |
|
|
|
|
|
|
|
i |
|
||
|
|
|
|
|
|
|
|
t |
|
|
|
|
|
|
|
|
|
t |
|
||||
P |
D |
|
|
|
|
|
|
|
|
o |
P |
D |
|
|
|
|
|
|
|
|
o |
||
|
|
|
|
NOW! |
r |
|
|
|
|
NOW! |
r |
||||||||||||
|
|
|
|
|
BUY |
|
|
|
|
|
|
|
BUY |
|
|
||||||||
|
|
|
|
to |
|
|
|
80 Глава 1. Написание безопасных программ |
|
|
|
|
to |
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
w |
|
|
|
|
|
|
|
|
|
m |
w |
|
|
|
|
|
|
|
|
|
m |
||
w Click |
|
|
|
|
|
|
o |
w Click |
|
|
|
|
|
|
o |
||||||||
|
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
||
|
. |
|
|
|
|
|
|
.c |
|
|
. |
|
|
|
|
|
|
.c |
|
||||
|
|
p |
df |
|
|
|
|
e |
|
|
|
p |
df |
|
|
|
|
e |
|
||||
|
|
|
|
|
g |
|
|
|
|
|
|
|
|
g |
|
|
|
||||||
|
|
|
|
|
n |
|
|
|
|
|
|
|
|
|
n |
|
|
|
|
||||
|
|
|
|
-xcha |
|
|
Программисты, работающие в области безопасности, системные админист--x cha |
|
|
|
|
|
раторы, студенты и хакеры используют Perl по разным причинам: для написания коммерческих приложений для Web, создания инструментария для управления заданиями, разработки сложных объектов и классов для биоинженерии, простых счетчиков для Web-страниц и разного рода утилит. Среди популярных инструментов, относящихся к безопасности и написанных на Perl, можно назвать Whisker, Narrow Security Scanner и Wellenreiter, не говоря уже о множестве «эксплойтов», атакующих имеющиеся уязвимости как локально, так и удаленно.
Многие специалисты по безопасности выбирают в качестве языка сценариев Perl, потому что он работает на всех платформах, обеспечивает простой доступ к сокетам, позволяет подключать бинарный код, да и вообще является общепринятым. Благодаря дистрибутивам GNU Perl и ActiveState Win32 Perl, имеются бесплатные версии интерпретатора для операционных систем Microsoft 95/98/ME/NT/2000/XP/.NET, Solaris, NetBSD/OpenBSD/FreeBSD, Irix, HPUX, Red Hat и других дистрибутивов Linux.
Типы данных
Объявление переменных в Perl делается очень просто. Существует три основных типа данных: скаляры, массивы è õýøè. В отличие от языков с более жесткой структурой, Perl обрабатывает символы, строки и числа единообразно, автоматически определяя тип данных. Имена всех скаляров начинаются с символа $. Например, чтобы присвоить значение 5 переменной Gabe, надо написать $Gabe = 5;. Важно отметить, что в отличие от большинства типизированных языков, объявлять переменную до ее инициализации необязательно, можно сразу присвоить ей значение. Массивы или списки в Perl динамические, их имена начинаются с символа @. Массив может содержать символы, числа или строки. Кроме того, в Perl есть возможность использовать массивы массивов. В примере 1.25 создается многомерный массив, содержащий в совокупности восемь элементов.
Пример 1.25. Создание в Perl многомерного массива из восьми элементов
Определение
@ArrayOfArray = (
[ "foster", "price" ],
[ "anthony", "marshall", "chad" ], [ "tom", "eric", "gabe" ]
);
print $ArrayOfArray[2][2];
Напечатано
gabe