[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