Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

книги хакеры / Защита_от_взлома_сокеты,_эксплойты,_shell_код_Фостер_Дж_

.pdf
Скачиваний:
14
Добавлен:
19.04.2024
Размер:
3.68 Mб
Скачать

 

 

 

 

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

 

 

 

 

 

 

 

 

 

 

e

 

 

 

 

 

df-xchan62

 

 

}

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

Сканирование сети с помощью UDP сокетов 171

 

to

 

 

 

 

 

 

 

 

 

 

 

 

w Click

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

63

64 for(y=(x % 16); y < 16 ; ++y)

65{

66printf(" ");

67}

68

69for(y=0; y < (x % 16); ++y)

70{

71printf("%c", isprint(tmp[y]) ? tmp[y] : '.');

72}

73}

74

75printf("\n");

76}

77

78/*

79* makegetreq()

80*

81*

82*/

83

84#define SNMP1_PDU_HEAD "\x30\x00\x02\x01\x00\x04"

85#define SNMP1_PDU_TAIL "\xa0\x1c\x02\x04\x7e\x16\xa2\x5e" \

86

"\x02\x01\x00\x02\x01\x00\x30\x0e" \

87

"\x30\x0c\x06\x08\x2b\x06\x01\x02" \

88

"\x01\x01\x05\x00\x05\x00"

89

 

90

int makegetreq (char *buf, int blen, int *olen, char *comn)

91{

92int hlen = sizeof(SNMP1_PDU_HEAD) – 1;

93int tlen = sizeof(SNMP1_PDU_TAIL) – 1;

94int clen = strlen(comn);

95int len = 0;

96

97len = hlen + 1 + clen + tlen;

98if(len > blen)

99{

100printf("недостаточно места в буфере (%d,%d).\n",

101blen, len);

102return(-1);

103}

104

105memset(buf, 0x00, blen);

106memcpy(buf, SNMP1_PDU_HEAD, hlen);

107memcpy(buf + hlen + 1, comn, clen);

108memcpy(buf + hlen + 1 + clen, SNMP1_PDU_TAIL, tlen);

110 buf[0x01] = 0x23 + clen;

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

-

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

to

 

 

172

Глава 3. BSD сокеты

w Click

 

 

 

 

 

 

 

 

 

 

 

 

 

m

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

 

 

 

 

e

 

buf[hlen] = (char) clen;

 

 

 

df-xchan

111

 

 

 

 

 

 

 

 

112

 

 

 

 

 

 

 

 

 

113

*olen = len;

 

 

 

 

 

 

 

 

114

 

 

 

 

 

 

 

 

 

115

return(0);

 

 

 

 

 

 

 

 

116}

 

 

 

 

 

 

 

 

 

117

 

118/*

119* dores()

120*

121*

122*/

123int dores (int sock)

124{

125char buf[SNMP1_BUF_SIZE];

126int ret = 0;

127

128ret = recvfrom(sock, buf, SNMP1_BUF_SIZE, 0, NULL, NULL);

129if(ret < 0)

130{

131printf("ошибка recv().\n");

132return(-1);

133}

134

135 hexdisp(buf, ret);

136

137return(0);

138}

139

140/*

141* doreq()

142*

143*

144*/

145int doreq (int sock, char *comn)

146{

147char buf[SNMP1_BUF_SIZE];

148int len = 0;

149int ret = 0;

150

151ret = makegetreq(buf, SNMP1_BUF_SIZE, &len, comn);

152if(ret < 0)

153{

154printf("ошибка makegetreq().\n");

155return(-1);

156}

157

158 hexdisp(buf, len);

159

 

 

 

 

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

 

 

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

 

E

 

 

 

 

 

 

 

 

C

 

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

-

 

 

 

 

 

 

 

d

 

 

 

 

-

 

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

 

 

t

 

 

 

F

 

 

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

 

 

i

r

 

 

D

 

 

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

 

 

NOW!

o

 

P

 

 

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

to

 

 

 

 

 

 

 

Сканирование сети с помощью UDP сокетов 173

 

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

m

 

w Click

 

 

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

o

 

 

 

w

 

 

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

 

 

 

.c

 

 

 

.

 

 

 

 

 

 

 

 

.c

 

 

 

p

d

 

 

 

 

 

 

e

 

 

ret = send(sock, buf, len, 0);

 

 

p

d

 

 

 

 

 

 

e

 

 

 

 

 

 

 

 

 

g

 

 

 

 

 

 

 

 

 

x cha

g

 

 

 

 

 

 

 

f-

xch160

 

 

 

 

 

 

f-

 

 

 

 

 

 

 

 

 

 

an

 

 

 

 

 

 

 

 

 

 

 

 

n

 

 

 

 

 

 

 

 

 

 

 

161

 

 

if(ret != len)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

162

 

 

{

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

163

 

 

printf("ошибка send().\n");

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

164

 

 

return(-1);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

165

 

 

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

166

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

167return(0);

168}

169

170/*

171* makeudpsock()

172*

173*

174*/

175int makeudpsock (char *targ, unsigned short port)

176{

177struct sockaddr_in sin;

178unsigned int taddr = 0;

179int sock = 0;

180int ret = 0;

181

182taddr = inet_addr(targ);

183if(taddr == INADDR_NONE)

184{

185printf("ошибка inet_addr().\n");

186return(-1);

187}

188

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

190if(sock < 0)

191{

192printf("ошибка socket().\n");

193return(-1);

194}

195

196

memset(&sin, 0x0, sizeof(sin));

197

 

 

 

198

sin.sin_family

=

AF_INET;

199

sin.sin_port

=

htons(port);

200

sin.sin_addr.s_addr =

taddr;

201

 

 

 

202ret = connect(sock, (struct sockaddr *) &sin, sizeof(sin));

203if(ret < 0)

204{

205printf("ошибка connect().\n");

206return(-1);

207}

208

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

-

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

to

 

 

174

Глава 3. BSD сокеты

w Click

 

 

 

 

 

 

 

 

 

 

 

 

 

m

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

 

 

 

 

e

 

return(sock);

 

 

 

df-xchan

209

 

 

 

 

 

 

 

 

210 }

 

 

 

 

 

 

 

 

211

 

212/*

213* scan()

214*

215*

216*/

217int scan (char *targ, unsigned short port, char *cname)

218{

219int sock = 0;

220int ret = 0;

221

222sock = makeudpsock(targ, port);

223if(sock < 0)

224{

225printf("makeudpsocket() failed.\n");

226return(-1);

227}

228

229ret = doreq(sock, cname);

230if(ret < 0)

231{

232printf("ошибка doreq().\n");

233return(-1);

234}

235

236ret = dores(sock);

237if(ret < 0)

238{

239printf("ошибка dores().\n");

240return(-1);

241}

242

243return(0);

244}

245

246/*

247* usage()

248*

249*

250*/

251void usage(char *prog)

252{

253printf("snmp1 00.00.01\r\n");

254printf("usage : %s -t target_ip <-p target_port> " \

255

" <-c community_name>\n", prog);

256printf("пример: %s -t 127.0.0.1 -p 161 -c public\n\n",

257prog);

 

 

 

 

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

 

 

xch258

 

 

 

 

 

 

f-

 

an

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

Сканирование сети с помощью UDP сокетов 175

 

to

 

 

 

 

 

 

 

 

 

 

 

 

w Click

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

259

260int

261main(int argc, char *argv[])

262{

263unsigned short port = SNMP1_DEF_PORT;

264char *targ = NULL;

265char *comn = SNMP1_DEF_COMN;

266char ch = 0;

267int ret = 0;

268

269opterr = 0;

270while((ch = getopt(argc, argv, "t:p:c:")) != -1)

271{

272switch(ch)

273{

274case 't':

275

276targ = optarg;

277break;

278

279 case 'p':

280

281port = atoi(optarg);

282break;

283

284 case 'c':

285

286comn = optarg;

287break;

288

289case '?':

290default:

292usage(argv[0]);

293return(1);

294}

295}

296

297if(targ == NULL)

298{

299usage(argv[0]);

300return(1);

301}

302

303printf("заданы: цель: %s; порт: %d; " \

304имя сообщества: \"%s\"\n", targ, port, comn);

306 ret = scan(targ, port, comn);

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

-

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

to

 

 

176

Глава 3. BSD сокеты

w Click

 

 

 

 

 

 

 

 

 

 

 

 

 

m

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

g

 

 

if(ret < 0)

 

 

 

 

 

 

 

e

 

 

 

 

df-xchan

307

 

 

 

 

 

 

 

 

308

{

 

 

 

 

 

 

 

 

309

printf("ошибка scan().\n");

 

 

 

 

 

 

 

 

310

return(1);

311 }

312

313 printf("сканирование завершено.\n");

314

315return(0);

316}

 

 

 

 

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

 

 

 

 

Компиляция

obsd32# gcc -o snmp1 snmp1.c

Пример исполнения

obsd32# ./snmp1 -t 192.168.100

заданы: цель: 192.168.100; порт: 161; имя сообщества: "public"

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..

08

2B

06

01

02

01 01 05 00 04

06

68

70

31

37

30

.+.........

hp170

30

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0

 

сканирование завершено

obsd32# ./snmp1 -t 192.168.100 -c internal

заданы: цель: 192.168.100; порт: 161; имя сообщества: "internal"

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

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

22

02

04

7E

16

A2

5E

02

01

00 02 01

00

30

14

30

"..~.C^

......0.0

12

06

08

2B

06

01

02

01

01

05 00 04

06

68

70

31

...+.........

hp1

37

30

30

 

 

 

 

 

 

 

 

 

 

 

 

 

700

 

сканирование завершено

Программе snmð1.c передаются в командной строке IP-адрес и порт цели, а также имя сообщества. Эти значения помещаются в протокольную единицу обмена (Protocol Data Unit – PDU) GetRequest в формате SNMPv1, которая далее инкапсулируется в UDP-датаграмму и отправляется целевому IP-адресу. Затем программа ждет ответа GetResponse. Если ответ получен, он форматируется и печатается на стандартный вывод.

 

 

 

 

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

 

 

 

 

 

 

 

 

 

 

e

 

 

 

 

df

 

Анализ

 

 

 

 

 

n

 

 

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

Сканирование сети с помощью UDP сокетов 177

 

to

 

 

 

 

 

 

 

 

 

 

 

 

w Click

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

В строках 8–16 включаются необходимые заголовочные файлы;

В строках 18 и 19 задаются номер UDP-порта по умолчанию (161) и стандартное имя SNMP-сообщества(public);

В строках 23–75 определяется функция hexdisp(), которая принимает два параметра: указатель на массив символов и длину этого массива в байтах. Эта функция форматирует находящиеся в указанном массиве символы, представляя их в читаемом виде, и выводит результат на печать. Формат аналогичен принятому в программе tcpdump, когда она вызывается с флагом –X;

В строках 83–87 определяются фрагменты SNMP-запроса GetRequest. Впоследствии значение SNMP1_PDU_HEAD будет помещено в нача- ло буфера сообщения, за ним – имя сообщества и в конце – значение SNMP1_PDU_TAIL. В совокупности эти три части составляют полный SNMP-запрос GetRequest;

В строках 89–115 определена функция makegetreq(). Она отвечает за конструирование запроса GetRequest и размещение его в предоставленном буфере. Первый ее параметр – указатель на буфер, представляющий со-

бой массив символов, второй – целое число, равное длине буфера

âбайтах, третий – указатель на целое число, в которое будет помещена длина сформированного запроса. Четвертый параметр – это имя SNMPсообщества. Созданный запрос требует от удаленного хоста, чтобы тот вернул значение параметра system.sys.Name.0 из базы управляющей информации MIB-II, являющейся частью протокола SNMP. В этом параметре хранится имя целевого хоста;

В строке 105 функция makegetreq() копирует значение SNMP1_PDU_HEAD

âначало буфера;

В строке 106 в буфере после SNMP1_PDU_HEAD дописывается указанное имя сообщества;

В строке 107 вслед за именем сообщества дописывается значение

SNMP1_PDU_TAIL;

В строке 109 функция makegetreq() записывает во второй байт буфера значение длины имени SNMP-сообщества плюс 35. Это диктуется правилами форматирования запроса GetRequest;

В строке 110 длина имени SNMP-сообщества записывается в байт, следующий за SNMP1_PDU_HEAD, но предшествующий самому имени;

В строке 112 полная длина всего созданного запроса сохраняется в параметре olen;

В строке 114 функция возвращает код успешного завершения. В этот момент запрос GetRequest построен в предоставленном буфере;

178 Глава 3. BSD сокеты

 

 

 

 

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

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

 

m

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

g

.c

 

 

 

p

 

 

 

 

 

 

 

В строках 122–127 определена функция dores(). Она принимает SNMP--x cha

 

e

 

 

 

 

df

 

 

n

 

 

 

 

 

 

 

 

 

 

ответ GetResponse от удаленного хоста, которому был отправлен запрос. Для этой цели вызывается функция recvfrom(). Если ответ получен, то данные передаются функции hexdump() для форматирования и печати;В строках 144–167 определена функция doreq(). Она принимает построенный SNMP-запрос GetRequest и передает его функции hexdump() для форматирования и печати, а затем посылает запрос по указанному IP-

адресу в указанный порт. Для этого вызывается функция send();

В строках 174–209 определена функция makeudpsock(). Она преобразует заданный IP-адрес из точечно-десятичной нотации в беззнаковое целое число. Затем с помощью функции socket() создается сокет, пригодный для отправки и приема UDP-датаграмм. Полученный дескриптор ассоциируется с целевым IP-адресом и портом с помощью функции connect(). Если все операции завершились успешно, то makeudpsock() возвращает корректный дескриптор сокета, в противном случае – отрицательное число;

В строках 216–243 определена функция scan(). Она сначала вызывает makeudpsock() для создания сокета. Затем дескриптор созданного сокета передается функции doreq(), которая создает запрос GetRequest и отправляет его целевому хосту. После этого для приема ответа вызывается dores(). Если не произошло никаких ошибок, то scan() возвращает 0, в противном случае – отрицательное число;

В строках 250–257 определена функция usage(), которая печатает информацию о порядке запуска программы snmp1;

В строках 260–316 определена функция main(). Это главная точка входа в программу. Она обрабатывает аргументы, заданные в командной строке и вызывает scan() для выполнения сканирования.

Сканирование сети

с помощью TCP сокетов

В этом разделе мы рассмотрим полную программу, которая использует протокол TCP и API сокетов для идентификации номеров программ, реализующих удаленные вызовы процедур (RPC – Remote Procedure Call). В ней применяется метод, известный под названием «сканирование с помощью попытки соединения по протоколу TCP», смысл которого в обнаружении открытых TCP-портов на удаленном хосте. Обнаружив порт, программа пытается определить, какая RPC-программа его использует. С помощью подобной утилиты можно выяснить, на каком TCP-порту работает служба RPC, если прямой дос-

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

r

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

 

 

Сканирование сети с помощью ТСР сокетов 179

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

m

w Click

 

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

g

.c

 

 

.

 

 

 

 

g

.c

 

 

 

p

 

 

 

 

 

 

 

 

 

 

p

 

-x cha

 

 

 

 

 

 

 

-xchòóïa

 

к порту 111, зарезервированному для службы отображения портов (RPC

 

 

e

 

 

 

 

df

 

 

n

e

 

 

 

 

 

df

 

 

n

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

portmapper), закрыт.

Протокол RPC позволяет разделить функциональность программы на части, исполняемые на различных компьютерах. Клиентская программа обращается к RPC, для того чтобы передать параметры функции, работающей на удаленной машине. Удаленная машина получает эти параметры, вызывает запрошенную функцию и возвращает полученные от нее данные по сети машине-отправителю, а та передает результаты вызова удаленной функции клиентской программе.

Части программы, использующей RPC, работают на разных машинах. Во время запуска она регистрирует свой номер в службе отображения портов на удаленном хосте. Эта служба прослушивает TCP и UDP-порт с номером 111. Удаленный хост может сообщить службе отображения портов на другом хосте номер конкретной программы и получить в ответ номер TCP и UDP-порта, на котором эта программа ожидает поступления запросов. Это стандартный способ обнаружения RPC-программ.

Иногда служба отображения портов недоступна или доступ к ней закрыт межсетевым экраном, поэтому с ее помощью узнать, где искать нужную RPC-программу, невозможно. Тут-то и приходят на помощь утилиты типа нашей программы rpc1, которые позволяют выяснить номер RPC-програм- мы путем исследования открытых TCP-портов без обращения к службе отображения портов.

Для этого мы посылаем последовательность RPC-запросов в произвольный TCP-порт. В каждом запросе должен быть указан номер программы. Если этот номер не соответствует номеру программы, прослушивающей данный порт, то будет возвращен код ошибки, говорящий о том, что номер программы задан неверно. Если же номера совпадают, то мы не получим кода ошибки, и, значит, номер программы можно считать установленным. В примере 3.10 показано, как с помощью сокетов реализовать такой тип сканирования и идентифицировать номера RPC-программ.

Пример 3.10. Сканер RPC*программ (rpc1.c)

1 /*

2 * rpc1.c

3*

4 * Сканер RPC-программ на основе TCP. Пример #1.

5 *

6*

7 * foster <jamescfoster@gmail.com>

8 */

9

10 #include <stdio.h>

11 #include <unistd.h>

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

-

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

to

 

 

180 Глава 3. BSD сокеты

 

w Click

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

m

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

 

 

 

 

e

 

 

 

 

 

df-xchan

12 #include <signal.h>

 

 

 

 

 

 

 

 

 

13

 

 

 

 

 

 

 

 

 

14 #include <sys/socket.h>

 

 

 

 

 

 

 

 

 

15 #include <netinet/in.h>

 

 

 

 

 

 

 

 

 

16 #include <arpa/inet.h>

 

 

 

 

 

 

 

 

 

17

 

 

 

 

 

 

 

 

 

18 #define RPC1_BUF_SIZE

0x0400

19#define RPC1_DEF_CTO_SEC 0x0005

20#define RPC1_DEF_RTO_SEC 0x0005

22/*

23* номера программ

24*/

25unsigned int progid[] =

26{

270x000186A0, 0x000186A1, 0x000186A2, 0x000186A3,

280x000186A4, 0x000186A5, 0x000186A6, 0x000186A7,

290x000186A8, 0x000186A9, 0x000186AA, 0x000186AB,

300x000186AC, 0x000186AD, 0x000186AE, 0x000186AF,

310x000186B1, 0x000186B2, 0x000186B3, 0x000186B4,

320x000186B5, 0x000186B6, 0x000186B7, 0x000186B8,

330x000186B9, 0x000186BA, 0x000186BB, 0x000186BC,

340x000186BD, 0x000186C5, 0x000186C6, 0x000186E4,

350x000186F3, 0x0001877D, 0x00018788, 0x0001878A,

360x0001878B, 0x00018799, 0x000249F1, 0x000493F3,

370x00049636, 0x30000000, 0x00000000

38};

39

40/*

41* hexdisp()

42*

43*

44*/

45void hexdisp (char *buf, int len)

46{

47char tmp[16];

48int x = 0;

49int y = 0;

50

51for(x=0; x < len; ++x)

52{

53tmp[x % 16] = buf[x];

55if((x + 1) % 16 == 0)

56{

57for(y=0; y < 16; ++y)

58{

59printf("%02X ", tmp[y] & 0xFF);

60}

 

 

 

 

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