[Openswan dev] [LONG] standalone pluto + VPN client Aggressive mode + PSK + XAUTH

Philippe Sultan philippe.sultan at inria.fr
Tue Jul 20 10:40:44 CEST 2004


Thank you Ken and Michael for your advices,

I applied Tsukasa's patch (thanx Tsukasa :)), and modified some little
parts of pluto's code.
As Michael stated in a previous message, the Cisco client is locked to
work with a Cisco server. So I did not manage to have an entire Phase 1
exchange but some of these locks are detailed in the description of the
small modifications I made to the original code, and some of these don't
match the requirements of RFCs.

Using a tool like ikecrack (without prior knowledge of the pre-shared 
key, http://ikecrack.sourceforge.net) with this IKE stack + arp-sk + 
libnet (for example), one could attempt to set up a fake VPN server in a 
LAN environmenet in order to build up a username/password base for Cisco 
VPN clients. Later on and after some more development, a full Man In The 
Middle Attack could be tried.

Here's what I got now when using the Cisco VPN client on a windows
platform (v 4.0.4 + Aggressive + PSK + XAUTH) on one hand and a slightly
modified pluto (v 1.0.6 + Aggressive + PSK + XAUTH) on a Debian dist +
kernel 2.4.25 on the other hand:
- Aggressive mode + PSK + MD5 hash and AES encryption : OK
- Server asks for XAUTH username / password
- client sends info in CLEAR TEXT, the password is not even hashed

Let me detail this test, starting with the configuration information :
Once comfortably sat down (following Michael's advice :)) I launched
pluto with the following parameters :
#./pluto --debug-all --noklips --stderrlog --nofork

And whack...
#./whack --name silly --host %any  --to --host <isakmp server ip>
--nexthop <isakmp server ip> --psk --aggrmode --xauth
#./whack --listen

Here is the modified Makefile I used (with 'make all'):
---------------------------------
!FILE : Makefile
!include des.h functions, + no KLIPS, + XAUTH server

--- Makefile.orig       2004-04-01 16:13:33.000000000 +0200
+++ Makefile    2004-07-01 15:05:27.000000000 +0200
@@ -37,7 +37,7 @@
         -Wstrict-prototypes # -Wundef

  # where to find klips headers and Openswan headers
-HDRDIRS = -I.. -I$(KLIPSD) $(OPENSWANINCLS)
+HDRDIRS = -I.. -I$(KLIPSD) $(OPENSWANINCLS) -Icrypto

  # On non-LINUX systems, these one of these may be needed (see endian.h)
  # BYTE_ORDER = -DBIG_ENDIAN=4321 -DLITTLE_ENDIAN=1234
-DBYTE_ORDER=BIG_ENDIAN
@@ -74,16 +74,15 @@

  DEFINES = $(BYTE_ORDER) \
         -DPLUTO \
-       -DKLIPS \
         -DDEBUG \
         -DGCC_LINT \
         -DNAT_TRAVERSAL -DVIRTUAL_IP \
         -DI_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT \
         -DAPPLY_CRISCO \
         -DDPD \
-       # -DMODECFG \
+       -DMODECFG \
         # -DLEAK_DETECTIVE
-
+       # -DKLIPS

  # libefence is a free memory allocation debugger
  LIBSPLUTO = -lgmp -lresolv -lpthread # -lefence
@@ -98,7 +97,7 @@
  #LDAP_VERSION=2

  # Uncomment this line to enable support for XAUTH Server
-#XAUTH_SERVER=1
+XAUTH_SERVER=1


Here are the modifications I applied to pluto's code, the following 
files have been modified :
- connections.c
- constants.h
- demux.c
- id.c
- ipsec_doi.c

---------------------------------
!FILE : connections.c
!just a small correction as I don't use KLIPS

--- connections.c.orig  2004-03-12 20:09:00.000000000 +0100
+++ connections.c       2004-07-16 17:36:49.000000000 +0200
@@ -1539,7 +1539,7 @@
  #ifdef KLIPS
             has_bare_hold(our_client, peer_client, cr->transport_proto);
  #else
-           bool is_held =  was_held;
+           was_held;
  #endif
      int whackfd = cr->whackfd;

---------------------------------
!FILE : constants.h
!Cisco client asks for a 2147483 sec for ISAKMP SA lifetime.
!Cisco_Unity_Vendor_ID constant is also written here

--- constants.h.orig    2003-11-17 01:11:00.000000000 +0100
+++ constants.h 2004-07-13 16:15:57.000000000 +0200
@@ -918,7 +918,7 @@
  #define OAKLEY_LIFE_KILOBYTES 2

  #define OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT 3600    /* one hour */
-#define OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM 86400   /* 24 hours */
+#define OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM 2147483

  /* Oakley PRF attribute (none defined)
   * draft-ietf-ipsec-ike-01.txt appendix A
@@ -1003,6 +1003,9 @@
  #define XAUTH_Vendor_ID                "\x09\x00\x26\x89\xDF\xD6\xB7\x12"
  #define XAUTH_Vendor_ID_len    (sizeof(XAUTH_Vendor_ID)-1)

+#define Cisco_Unity_Vendor_ID
"\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00"
+#define Cisco_Unity_Vendor_ID_len      (sizeof(Cisco_Unity_Vendor_ID)-1)
+
  #define SAFENET_VID            1
  #define SAFENET_Vendor_ID      (const unsigned char
*)"\x47\xBB\xE7\xC9\x93\xF1\xFC\x13\xB4\xE6\xD0\xDB\x56\x5C\x68\xE5"
  #define SAFENET_Vendor_ID_len  (sizeof(SAFENET_Vendor_ID)-1)

---------------------------------
!FILE : demux.c
!actual packet size and packet size specified in header
!don't match...but let's ignore that for our test

--- demux.c.orig        2003-11-26 16:43:49.000000000 +0100
+++ demux.c     2004-07-16 17:50:43.000000000 +0200
@@ -1309,10 +1309,12 @@

      if (md->packet_pbs.roof != md->message_pbs.roof)
      {
+       /* Trying to make pluto work with the Cisco VPN client v4.0.4.
+        * So just inform the user without returning.
+        * Testing purpose as RFC 2408 5.1 prohibits this behavior
+        */
         plog("size (%u) differs from size specified in ISAKMP HDR (%u)"
             , (unsigned) pbs_room(&md->packet_pbs), md->hdr.isa_length);
-       SEND_NOTIFICATION(PAYLOAD_MALFORMED);
-       return;
      }

---------------------------------
!FILE id.c
!I needed to force the ID Payload parameters 'proto id' and
!port (known as  'DOI specific A' and 'DOI specific B') to
!values 17 and 500 respectively, so that a matching hash
!is used to authenticate the third ISAKMP message sent by the
!client.
!This is a quiete bad modif, and it should probably be written
!elsewhere in the code

--- id.c.orig   2003-11-17 00:32:11.000000000 +0100
+++ id.c        2004-07-16 13:24:33.000000000 +0200
@@ -375,6 +375,8 @@
      case ID_DER_ASN1_DN:
      case ID_KEY_ID:
         *tl = end->id.name;
+       hd->isaiid_protoid = 17;
+       hd->isaiid_port = 500;
         break;
      case ID_IPV4_ADDR:
      case ID_IPV6_ADDR:

---------------------------------
!FILE ipsec_doi.c
!A Cisco Vendor ID payload MUST be sent out in the first reply
!by the server, otherwise the Client stops

--- ipsec_doi.c.orig    2004-04-03 18:48:10.000000000 +0200
+++ ipsec_doi.c 2004-07-19 11:32:39.000000000 +0200
@@ -2057,13 +2057,13 @@
      union hash_ctx ctx;

      DBG_cond_dump(DBG_CRYPT, "last Phase 1 IV:"
-       , st->st_ph1_iv, st->st_ph1_iv_len);
+       , st->st_iv, st->st_iv_len);

      st->st_new_iv_len = h->hash_digest_size;
      passert(st->st_new_iv_len <= sizeof(st->st_new_iv));

      h->hash_init(&ctx);
-    h->hash_update(&ctx, st->st_ph1_iv, st->st_ph1_iv_len);
+    h->hash_update(&ctx, st->st_iv, st->st_iv_len);
      passert(*msgid != 0);
      h->hash_update(&ctx, (const u_char *)msgid, sizeof(*msgid));
      h->hash_final(st->st_new_iv, &ctx);
@@ -2455,6 +2455,15 @@
         return FALSE;
      }

+    else {
+      loglog(RC_LOG_SERIOUS, "protocol/port in Phase 1 ID Payload must
be 0/0, %d/0"
+            " or %d/%d and are %d/%d"
+            , IPPROTO_UDP, IPPROTO_UDP, IKE_UDP_PORT
+            , id->isaid_doi_specific_a, id->isaid_doi_specific_b);
+
+    }
+
+
      peer.kind = id->isaid_idtype;

      switch (peer.kind)
@@ -4149,15 +4158,28 @@
      if(c->policy & POLICY_XAUTH)
      {
         struct isakmp_generic r_vid;
+       struct isakmp_generic r_vid_cisco;
         pb_stream       r_vid_pbs;
+       pb_stream       r_vid_pbs_cisco;

         /* as per ike-xauth, Sec 4.0 */
-       r_vid.isag_np = ISAKMP_NEXT_NONE;
+       r_vid.isag_np = ISAKMP_NEXT_VID;
+       r_vid_cisco.isag_np = ISAKMP_NEXT_NONE;
+
         if (!out_struct(&r_vid, &isakmp_vendor_id_desc, &md->rbody,
&r_vid_pbs))
                 return STF_INTERNAL_ERROR;
+
                 if (!out_raw(XAUTH_Vendor_ID, XAUTH_Vendor_ID_len,
&r_vid_pbs, "XAUTH ViD"))
                         return STF_INTERNAL_ERROR;
                 close_output_pbs(&r_vid_pbs);
+
+
+       if (!out_struct(&r_vid_cisco, &isakmp_vendor_id_desc,
&md->rbody, &r_vid_pbs_cisco))
+               return STF_INTERNAL_ERROR;
+
+               if
(!out_raw(Cisco_Unity_Vendor_ID,Cisco_Unity_Vendor_ID_len,
&r_vid_pbs_cisco, "Cisco-Unity ViD
+                       return STF_INTERNAL_ERROR;
+               close_output_pbs(&r_vid_pbs_cisco);
      }

      /* finish message */

Philippe Sultan
INRIA



Ken Bantoft wrote:
> Check users lists for a patch for Aggressive Mode - might help you get 
> further along.
> 
> http://lists.openswan.org/pipermail/users/2004-July/001652.html
> 
> On Wed, 7 Jul 2004, Philippe Sultan wrote:
> 
> 
>>Hello everybody,
>>
>>I have compiled pluto (openswan v1.0.6) without klips in order to get a 
>>standalone ISAKMP stack and make it work with a Cisco VPN client.
>>
>>The client works as a roadwarrior in IKE Aggressive mode + preshared 
>>keys + XAUTH. My /etc/ipsec.secrets file :
>>%any: PSK "*********"
>>:PSK "*********"
>>
>>The first message from the client is processed through the 
>>'aggr_inI1_outR1()' function (Cisco client specifies a wrong value for 
>>the packet size in the ISAKMP HDR, but I think pluto should ignore this 
>>in my case), and after that by find_host_connections() -> 
>>find_host_pair_connections() -> find_host_pair().
>>
>>These functions (found in connections.c) always returns NULL which makes 
>>pluto discard the ISAKMP message.
>>
>>In fact, the 'for' loop in the find_host_pair() is never entered, 
>>because the static struct 'host_pairs' is set to NULL (and p = 
>>host_pairs at loop initialization).
>>
>>I would like to know when and how the host_pairs struct if filled. 
>>Shouldn't it be initialized before we enter find_host_pair()?
>>
>>Thanks in advance for any help.
>>
>>Philippe
>>
>>_______________________________________________
>>Dev mailing list
>>Dev at lists.openswan.org
>>http://lists.openswan.org/mailman/listinfo/dev
>>
> 
> 





More information about the Dev mailing list