1 /*
2 ettercap -- PPP decoder module
3
4 Copyright (C) ALoR & NaGA
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 */
21
22 #include <ec.h>
23 #include <ec_decode.h>
24 #include <ec_capture.h>
25 #include <ec_dissect.h>
26
27 #include <openssl/sha.h>
28
29 /* globals */
30 struct ppp_header {
31 u_char address;
32 u_char control;
33 u_int16 proto;
34 };
35
36 struct ppp_lcp_header {
37 u_char code;
38 u_char ident;
39 u_int16 length;
40 };
41
42 struct ppp_chap_challenge {
43 u_char size;
44 union {
45 u_char challenge_v1[8];
46 u_char challenge_v2[16];
47 struct {
48 u_char lanman[24];
49 u_char nt[24];
50 u_char flag;
51 } response_v1;
52 struct {
53 u_char peer_challenge[16];
54 u_char reserved[8];
55 u_char nt[24];
56 u_char flag;
57 } response_v2;
58 } value;
59 };
60
61 #define PPP_PROTO_IP 0x0021
62 #define PPP_PROTO_CHAP 0xc223
63 #define PPP_PROTO_PAP 0xc023
64 #define PPP_PROTO_LCP 0xc021
65 #define PPP_PROTO_ECP 0x8053
66 #define PPP_PROTO_CCP 0x80fd
67 #define PPP_PROTO_IPCP 0x8021
68
69 #define PPP_CHAP_CODE_CHALLENGE 1
70 #define PPP_CHAP_CODE_RESPONSE 2
71
72 /* protos */
73
74 FUNC_DECODER(decode_ppp);
75 FUNC_ALIGNER(align_ppp);
76 void ppp_init(void);
77
78 /*******************************************/
79
80 /*
81 * this function is the initializer.
82 * it adds the entry in the table of registered decoder
83 */
84
ppp_init(void)85 void __init ppp_init(void)
86 {
87 add_decoder(LINK_LAYER, IL_TYPE_PPP, decode_ppp);
88 add_aligner(IL_TYPE_PPP, align_ppp);
89 dissect_add("ppp", NET_LAYER, LL_TYPE_PPP, decode_ppp);
90 }
91
FUNC_DECODER(decode_ppp)92 FUNC_DECODER(decode_ppp)
93 {
94 FUNC_DECODER_PTR(next_decoder);
95 struct ppp_header *ppph;
96 struct ppp_lcp_header *lcph;
97 struct ppp_chap_challenge *chapch;
98 u_int16 proto;
99 u_int32 i;
100 u_char auth_len;
101 char user[128], dummy[3], temp[128], *pap_auth;
102 static char version=0, schallenge[512];
103 u_char digest[SHA_DIGEST_LENGTH];
104 SHA_CTX ctx;
105
106
107 ppph = (struct ppp_header *)DECODE_DATA;
108
109 /* Set the L4 header for the hook */
110 PACKET->L4.header = (u_char *)DECODE_DATA;
111
112 /* HOOK POINT: HOOK_PACKET_PPP */
113 hook_point(HOOK_PACKET_PPP, PACKET);
114
115 /* We have to guess if header compression was negotiated */
116 /* XXX - && or || ??? */
117 if (ppph->address != 0xff && ppph->control != 0x3) {
118 proto = *((u_char *)ppph);
119
120 if (proto != PPP_PROTO_IP) {
121 proto = ntohs(*((u_int16 *)ppph));
122 DECODED_LEN = 2;
123 } else
124 DECODED_LEN = 1;
125
126 } else {
127 proto = ntohs(ppph->proto);
128 DECODED_LEN = sizeof(ppph);
129
130 if (proto != PPP_PROTO_IP && proto != PPP_PROTO_CHAP &&
131 proto != PPP_PROTO_PAP && proto != PPP_PROTO_LCP &&
132 proto != PPP_PROTO_ECP && proto != PPP_PROTO_CCP &&
133 proto != PPP_PROTO_IPCP) {
134 proto = *((u_char *)ppph + 2);
135 DECODED_LEN = 3;
136 }
137 }
138
139 /* Set the L4 header to LCP for subsequent hooks */
140 PACKET->L4.header = (u_char *)(DECODE_DATA + DECODED_LEN);
141
142 /* XXX - Add standard CHAP parsing */
143
144 /* XXX - IPv6 over PPP? */
145 if (proto == PPP_PROTO_IP) {
146 /* If the payload is an IP packet... */
147 /* ...get the next decoder */
148 next_decoder = get_decoder(NET_LAYER, LL_TYPE_IP);
149 EXECUTE_DECODER(next_decoder);
150
151 } else if (proto == PPP_PROTO_CHAP) {
152 /* Parse MSCHAP auth schemes */
153 lcph = (struct ppp_lcp_header *)(DECODE_DATA + DECODED_LEN);
154 chapch = (struct ppp_chap_challenge *)(lcph + 1);
155
156 switch (lcph->code) {
157 case PPP_CHAP_CODE_CHALLENGE:
158
159 if (chapch->size == 8) {
160 schallenge[0]=0;
161 version = 1;
162 for (i=0; i<8; i++) {
163 snprintf(dummy, 3, "%02X", chapch->value.challenge_v1[i]);
164 strcat(schallenge, dummy);
165 }
166 } else if (chapch->size == 16) {
167 version = 2;
168 memcpy (schallenge, chapch->value.challenge_v2, chapch->size);
169 }
170 else version = 0;
171 break;
172
173 case PPP_CHAP_CODE_RESPONSE:
174
175 if (version != 1 && version !=2)
176 break;
177
178 i = ntohs(lcph->length) - 5 - chapch->size;
179 if (i > sizeof(user)-2)
180 i = sizeof(user)-2;
181
182 memcpy(user, (u_char *)lcph + 5 + chapch->size, i);
183 user[i] = '\0';
184
185 /* Check if it's from PPP or PPTP */
186 if (!ip_addr_null(&PACKET->L3.dst) && !ip_addr_null(&PACKET->L3.src)) {
187 DISSECT_MSG("\n\nTunnel PPTP: %s -> ", ip_addr_ntoa(&PACKET->L3.src, temp));
188 DISSECT_MSG("%s\n", ip_addr_ntoa(&PACKET->L3.dst, temp));
189 }
190
191 DISSECT_MSG("PPP*MS-CHAP Password*%s:$MSCHAPv2$", user);
192
193 if (version == 1) {
194 for (i = 0; i < 24; i++)
195 DISSECT_MSG("%02X", chapch->value.response_v1.lanman[i]);
196 DISSECT_MSG(":");
197 for (i = 0; i < 24; i++)
198 DISSECT_MSG("%02X", chapch->value.response_v1.nt[i]);
199 DISSECT_MSG(":%s\n\n",schallenge);
200
201 } else if (version == 2) {
202 /*#ifdef HAVE_OPENSSL */
203 char *p;
204
205 if ((p = strchr(user, '\\')) == NULL)
206 p = user;
207 else
208 p++;
209
210 SHA1_Init(&ctx);
211 SHA1_Update(&ctx, chapch->value.response_v2.peer_challenge, 16);
212 SHA1_Update(&ctx, schallenge, 16);
213 SHA1_Update(&ctx, p, strlen(p));
214 SHA1_Final(digest, &ctx);
215
216 for (i = 0; i < 8; i++)
217 DISSECT_MSG("%02X", digest[i]);
218 DISSECT_MSG("$");
219
220 for (i = 0; i < 24; i++)
221 DISSECT_MSG("%02X",chapch->value.response_v2.nt[i]);
222 DISSECT_MSG("$%s\n\n", user);
223 /*#else
224 for (i = 0; i < 16; i++)
225 DISSECT_MSG("%02X", schallenge[i]);
226 DISSECT_MSG("$");
227 for (i = 0; i < 24; i++)
228 DISSECT_MSG("%02X",chapch->value.response_v2.nt[i]);
229 DISSECT_MSG("$");
230 for (i = 0; i < 16; i++)
231 DISSECT_MSG("%02X",chapch->value.response_v2.peer_challenge[i]);
232 DISSECT_MSG("$%s\n\n", user);
233 #endif*/
234 }
235 version = 0;
236 break;
237 }
238 } else if (proto == PPP_PROTO_PAP) {
239
240 /* Parse PAP auth scheme */
241 lcph = (struct ppp_lcp_header *)(DECODE_DATA + DECODED_LEN);
242 pap_auth = (char *)(lcph + 1);
243
244 if (lcph->code == 1) {
245
246 /* Check if it's from PPP or PPTP */
247 if (!ip_addr_null(&PACKET->L3.dst) && !ip_addr_null(&PACKET->L3.src)) {
248 DISSECT_MSG("\n\nTunnel PPTP: %s -> ", ip_addr_ntoa(&PACKET->L3.src, temp));
249 DISSECT_MSG("%s\n", ip_addr_ntoa(&PACKET->L3.dst, temp));
250 }
251
252 DISSECT_MSG("PPP : PAP User: ");
253
254 auth_len = *pap_auth;
255 if (auth_len > sizeof(temp)-2)
256 auth_len = sizeof(temp)-2;
257 pap_auth++;
258 memcpy(temp, pap_auth, auth_len);
259 temp[auth_len] = 0;
260 DISSECT_MSG("%s\n",temp);
261
262 pap_auth += auth_len;
263 auth_len = *pap_auth;
264 pap_auth++;
265 if (auth_len > sizeof(temp)-2)
266 auth_len = sizeof(temp)-2;
267 memcpy(temp, pap_auth, auth_len);
268 temp[auth_len] = 0;
269 DISSECT_MSG("PPP : PAP Pass: %s\n\n", temp);
270 }
271 } else if (proto == PPP_PROTO_LCP) {
272 /* HOOK POINT: HOOK_PACKET_LCP */
273 hook_point(HOOK_PACKET_LCP, PACKET);
274 } else if (proto == PPP_PROTO_ECP || proto == PPP_PROTO_CCP) {
275 /* HOOK POINT: HOOK_PACKET_ECP */
276 hook_point(HOOK_PACKET_ECP, PACKET);
277 } else if (proto == PPP_PROTO_IPCP) {
278 /* HOOK POINT: HOOK_PACKET_IPCP */
279 hook_point(HOOK_PACKET_IPCP, PACKET);
280 }
281
282 return NULL;
283 }
284
FUNC_ALIGNER(align_ppp)285 FUNC_ALIGNER(align_ppp)
286 {
287 // should be file only. nothing to align
288 return 0;
289 }
290
291 /* EOF */
292
293 // vim:ts=3:expandtab
294
295