dsniff  2.4b2
About: A collection of tools for network auditing
  Fossies Dox: dsniff-2.4b2.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

decode_pptp.c
Go to the documentation of this file.
1 /*
2  * decode_pptp.c
3  *
4  * Microsoft PPTP MS-CHAP. Derived from Aleph One's anger.c.
5  *
6  * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
7  * Copyright (c) 2000 Aleph One <aleph1@securityfocus.com>
8  *
9  * $Id: decode_pptp.c,v 1.4 2001/03/15 08:33:02 dugsong Exp $
10  */
11 
12 #include "config.h"
13 
14 #include <sys/types.h>
15 #include <openssl/sha.h>
16 
17 #include <stdio.h>
18 #include <string.h>
19 
20 #include "buf.h"
21 #include "decode.h"
22 
24  u_char flags; /* bitfield */
25  u_char ver; /* should be PPTP_GRE_VER (enhanced GRE) */
26  u_short protocol; /* should be PPTP_GRE_PROTO (ppp-encaps) */
27  u_short payload_len; /* size of ppp payload, not inc. gre header */
28  u_short call_id; /* peer's call_id for this session */
29  u_int32_t seq; /* sequence number. Present if S==1 */
30  u_int32_t ack; /* seq number of highest packet recieved by */
31  /* sender in this session */
32 };
33 
34 #define PPTP_GRE_PROTO 0x880B
35 #define PPTP_GRE_VER 0x1
36 
37 #define PPTP_GRE_IS_C(f) ((f) & 0x80)
38 #define PPTP_GRE_IS_R(f) ((f) & 0x40)
39 #define PPTP_GRE_IS_K(f) ((f) & 0x20)
40 #define PPTP_GRE_IS_S(f) ((f) & 0x10)
41 #define PPTP_GRE_IS_A(f) ((f) & 0x80)
42 
43 struct ppp_header {
44  u_char address;
45  u_char control;
46  u_short proto;
47 };
48 
49 #define PPP_PROTO_CHAP 0xc223
50 
52  u_char code;
53  u_char ident;
54  u_short length;
55 };
56 
57 #define PPP_CHAP_CODE_CHALLENGE 1
58 #define PPP_CHAP_CODE_RESPONSE 2
59 
61  u_char size;
62  union {
63  u_char challenge_v1[8];
64  u_char challenge_v2[16];
65  struct {
66  u_char lanman[24];
67  u_char nt[24];
68  u_char flag;
69  } response_v1;
70  struct {
71  u_char peer_challenge[16];
72  u_char reserved[8];
73  u_char nt[24];
74  u_char flag;
75  } response_v2;
76  } value;
77  /* name */
78 };
79 
80 struct challenge {
81  u_char version;
82  u_char challenge[16];
83 };
84 
85 int
86 decode_pptp(u_char *buf, int len, u_char *obuf, int olen)
87 {
88  static struct challenge save_challenge;
89  struct buf outbuf;
90  struct pptp_gre_header *pgh;
91  struct ppp_header *ppp;
92  struct ppp_lcp_chap_header *chap;
93  struct ppp_chap_challenge *chapch;
94  u_short proto;
95  u_char *p, name[64], digest[SHA_DIGEST_LENGTH];
96  SHA_CTX ctx;
97  int i, pghlen;
98 
99  buf_init(&outbuf, obuf, olen);
100 
101  if (len < (pghlen = sizeof(*pgh)))
102  return (0);
103 
104  pgh = (struct pptp_gre_header *)buf;
105 
106  if ((pgh->ver & 0x7f) != PPTP_GRE_VER ||
107  ntohs(pgh->protocol) != PPTP_GRE_PROTO ||
108  PPTP_GRE_IS_C(pgh->flags) || PPTP_GRE_IS_R(pgh->flags) ||
109  PPTP_GRE_IS_K(pgh->flags) == 0 || (pgh->flags & 0xf) != 0) {
110  return (0);
111  }
112  if (PPTP_GRE_IS_S(pgh->flags) == 0)
113  return (0);
114 
115  if (PPTP_GRE_IS_A(pgh->ver) == 0)
116  pghlen -= sizeof(pgh->ack);
117 
118  if (len - pghlen < ntohs(pgh->payload_len))
119  return (0);
120 
121  ppp = (struct ppp_header *)(pgh + 1);
122 
123  if (ppp->address != 0xff && ppp->control != 0x3) {
124  proto = pntohs(ppp);
125  chap = (struct ppp_lcp_chap_header *)
126  ((u_char *)ppp + sizeof(proto));
127  }
128  else {
129  proto = ntohs(ppp->proto);
130  chap = (struct ppp_lcp_chap_header *)(ppp + 1);
131  }
132  if (proto != PPP_PROTO_CHAP)
133  return (0);
134 
135  switch (chap->code) {
136 
138  chapch = (struct ppp_chap_challenge *)(chap + 1);
139 
140  if (chapch->size == 8) {
141  save_challenge.version = 1;
142  memcpy(save_challenge.challenge,
143  chapch->value.challenge_v1, 8);
144  }
145  else if (chapch->size == 16) {
146  save_challenge.version = 2;
147  memcpy(save_challenge.challenge,
148  chapch->value.challenge_v2, 16);
149  }
150  else save_challenge.version = 0;
151  break;
152 
154  if (save_challenge.version == 0)
155  break;
156 
157  chapch = (struct ppp_chap_challenge *)(chap + 1);
158  i = ntohs(chap->length) - 54;
159  if (i > 63) i = 63;
160  memcpy(name, (u_char *)chap + 54, i);
161  name[i] = '\0';
162 
163  buf_putf(&outbuf, "%s:0:", name);
164 
165  if (save_challenge.version == 1) {
166  for (i = 0; i < 8; i++) {
167  buf_putf(&outbuf, "%02X",
168  save_challenge.challenge[i]);
169  }
170  buf_put(&outbuf, ":", 1);
171 
172  for (i = 0; i < 24; i++) {
173  buf_putf(&outbuf, "%02X",
174  chapch->value.response_v1.lanman[i]);
175  }
176  buf_put(&outbuf, ":", 1);
177 
178  for (i = 0; i < 24; i++) {
179  buf_putf(&outbuf, "%02X",
180  chapch->value.response_v1.nt[i]);
181  }
182  buf_put(&outbuf, "\n", 1);
183  }
184  else if (save_challenge.version == 2) {
185  chapch = (struct ppp_chap_challenge *)(chap + 1);
186  if ((p = strchr(name, '\\')) == NULL)
187  p = name;
188 
189  SHA1_Init(&ctx);
190  SHA1_Update(&ctx, chapch->value.response_v2.peer_challenge, 16);
191  SHA1_Update(&ctx, save_challenge.challenge, 16);
192  SHA1_Update(&ctx, p, strlen(p));
193  SHA1_Final(digest, &ctx);
194 
195  for (i = 0; i < 8; i++) {
196  buf_putf(&outbuf, "%02X", digest[i]);
197  }
198  buf_putf(&outbuf, ":000000000000000000000000000000000000000000000000:");
199  for (i = 0; i < 24; i++) {
200  buf_putf(&outbuf, "%02X",
201  chapch->value.response_v2.nt[i]);
202  }
203  buf_put(&outbuf, "\n", 1);
204 
205  save_challenge.version = 0;
206  }
207  break;
208  }
209  buf_end(&outbuf);
210 
211  return (buf_len(&outbuf));
212 }
213 
buf_putf
int buf_putf(buf_t buf, const char *fmt,...)
Definition: buf.c:106
ppp_chap_challenge::response_v1
struct ppp_chap_challenge::@0::@1 response_v1
ppp_lcp_chap_header
Definition: decode_pptp.c:51
ppp_chap_challenge::nt
u_char nt[24]
Definition: decode_pptp.c:67
ppp_header::proto
u_short proto
Definition: decode_pptp.c:46
challenge::challenge
u_char challenge[16]
Definition: decode_pptp.c:82
PPTP_GRE_VER
#define PPTP_GRE_VER
Definition: decode_pptp.c:35
ppp_lcp_chap_header::length
u_short length
Definition: decode_pptp.c:54
ppp_lcp_chap_header::code
u_char code
Definition: decode_pptp.c:52
buf_init
void buf_init(buf_t buf, u_char *data, int len)
Definition: buf.c:24
ppp_chap_challenge::challenge_v1
u_char challenge_v1[8]
Definition: decode_pptp.c:63
challenge::version
u_char version
Definition: decode_pptp.c:81
decode_pptp
int decode_pptp(u_char *buf, int len, u_char *obuf, int olen)
Definition: decode_pptp.c:86
PPTP_GRE_PROTO
#define PPTP_GRE_PROTO
Definition: decode_pptp.c:34
buf_end
void buf_end(buf_t buf)
Definition: buf.c:121
ppp_chap_challenge::flag
u_char flag
Definition: decode_pptp.c:68
PPTP_GRE_IS_R
#define PPTP_GRE_IS_R(f)
Definition: decode_pptp.c:38
pptp_gre_header::seq
u_int32_t seq
Definition: decode_pptp.c:29
pptp_gre_header::payload_len
u_short payload_len
Definition: decode_pptp.c:27
buf_put
int buf_put(buf_t buf, void *src, int len)
Definition: buf.c:93
PPTP_GRE_IS_S
#define PPTP_GRE_IS_S(f)
Definition: decode_pptp.c:40
pntohs
#define pntohs(p)
Definition: decode.h:33
pptp_gre_header::ver
u_char ver
Definition: decode_pptp.c:25
decode.h
buf.h
ppp_header
Definition: decode_pptp.c:43
pptp_gre_header::protocol
u_short protocol
Definition: decode_pptp.c:26
ppp_chap_challenge::size
u_char size
Definition: decode_pptp.c:61
buf
Definition: buf.h:14
pptp_gre_header::ack
u_int32_t ack
Definition: decode_pptp.c:30
ppp_lcp_chap_header::ident
u_char ident
Definition: decode_pptp.c:53
ppp_header::address
u_char address
Definition: decode_pptp.c:44
pptp_gre_header::flags
u_char flags
Definition: decode_pptp.c:24
ppp_chap_challenge
Definition: decode_pptp.c:60
PPP_PROTO_CHAP
#define PPP_PROTO_CHAP
Definition: decode_pptp.c:49
PPTP_GRE_IS_C
#define PPTP_GRE_IS_C(f)
Definition: decode_pptp.c:37
pptp_gre_header
Definition: decode_pptp.c:23
ppp_chap_challenge::value
union ppp_chap_challenge::@0 value
challenge
Definition: decode_pptp.c:80
ppp_chap_challenge::response_v2
struct ppp_chap_challenge::@0::@2 response_v2
ppp_chap_challenge::reserved
u_char reserved[8]
Definition: decode_pptp.c:72
ppp_chap_challenge::challenge_v2
u_char challenge_v2[16]
Definition: decode_pptp.c:64
config.h
obuf
static char obuf[4096]
Definition: trigger.c:43
PPP_CHAP_CODE_RESPONSE
#define PPP_CHAP_CODE_RESPONSE
Definition: decode_pptp.c:58
PPP_CHAP_CODE_CHALLENGE
#define PPP_CHAP_CODE_CHALLENGE
Definition: decode_pptp.c:57
PPTP_GRE_IS_A
#define PPTP_GRE_IS_A(f)
Definition: decode_pptp.c:41
buf_len
#define buf_len(b)
Definition: buf.h:34
PPTP_GRE_IS_K
#define PPTP_GRE_IS_K(f)
Definition: decode_pptp.c:39
ppp_header::control
u_char control
Definition: decode_pptp.c:45
ppp_chap_challenge::lanman
u_char lanman[24]
Definition: decode_pptp.c:66
ppp_chap_challenge::peer_challenge
u_char peer_challenge[16]
Definition: decode_pptp.c:71
pptp_gre_header::call_id
u_short call_id
Definition: decode_pptp.c:28