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