eapol-fuzzer.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. * wpa_supplicant - EAPOL fuzzer
  3. * Copyright (c) 2015, Jouni Malinen <j@w1.fi>
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "utils/includes.h"
  9. #include "utils/common.h"
  10. #include "utils/eloop.h"
  11. #include "eapol_supp/eapol_supp_sm.h"
  12. #include "rsn_supp/wpa.h"
  13. #include "rsn_supp/wpa_i.h"
  14. struct arg_ctx {
  15. const char *fname;
  16. struct wpa_sm *wpa;
  17. struct eapol_sm *eapol;
  18. };
  19. static void test_send_eapol(void *eloop_data, void *user_ctx)
  20. {
  21. struct arg_ctx *ctx = eloop_data;
  22. char *data;
  23. size_t len;
  24. u8 src[ETH_ALEN] = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x01 };
  25. u8 wpa_ie[200];
  26. size_t wpa_ie_len;
  27. wpa_printf(MSG_INFO, "eapol-fuzzer: Send '%s'", ctx->fname);
  28. data = os_readfile(ctx->fname, &len);
  29. if (!data) {
  30. wpa_printf(MSG_ERROR, "Could not read '%s'", ctx->fname);
  31. goto out;
  32. }
  33. wpa_hexdump(MSG_MSGDUMP, "fuzzer - EAPOL", data, len);
  34. eapol_sm_notify_portEnabled(ctx->eapol, TRUE);
  35. wpa_sm_set_param(ctx->wpa, WPA_PARAM_PROTO, WPA_PROTO_RSN);
  36. wpa_sm_set_param(ctx->wpa, WPA_PARAM_RSN_ENABLED, 1);
  37. wpa_sm_set_param(ctx->wpa, WPA_PARAM_KEY_MGMT, WPA_KEY_MGMT_PSK);
  38. wpa_sm_set_param(ctx->wpa, WPA_PARAM_PAIRWISE, WPA_CIPHER_CCMP);
  39. wpa_sm_set_param(ctx->wpa, WPA_PARAM_GROUP, WPA_CIPHER_CCMP);
  40. wpa_ie_len = sizeof(wpa_ie);
  41. wpa_sm_set_assoc_wpa_ie_default(ctx->wpa, wpa_ie, &wpa_ie_len);
  42. if (eapol_sm_rx_eapol(ctx->eapol, src, (u8 *) data, len) <= 0)
  43. wpa_sm_rx_eapol(ctx->wpa, src, (u8 *) data, len);
  44. out:
  45. os_free(data);
  46. eloop_terminate();
  47. }
  48. static void * get_network_ctx(void *arg)
  49. {
  50. return (void *) 1;
  51. }
  52. static void set_state(void *arg, enum wpa_states state)
  53. {
  54. }
  55. static void deauthenticate(void *arg, int reason_code)
  56. {
  57. }
  58. static u8 * alloc_eapol(void *arg, u8 type,
  59. const void *data, u16 data_len,
  60. size_t *msg_len, void **data_pos)
  61. {
  62. struct ieee802_1x_hdr *hdr;
  63. *msg_len = sizeof(*hdr) + data_len;
  64. hdr = os_malloc(*msg_len);
  65. if (hdr == NULL)
  66. return NULL;
  67. hdr->version = 2;
  68. hdr->type = type;
  69. hdr->length = host_to_be16(data_len);
  70. if (data)
  71. os_memcpy(hdr + 1, data, data_len);
  72. else
  73. os_memset(hdr + 1, 0, data_len);
  74. if (data_pos)
  75. *data_pos = hdr + 1;
  76. return (u8 *) hdr;
  77. }
  78. static int ether_send(void *arg, const u8 *dest, u16 proto,
  79. const u8 *buf, size_t len)
  80. {
  81. return 0;
  82. }
  83. static int get_bssid(void *ctx, u8 *bssid)
  84. {
  85. return -1;
  86. }
  87. static int eapol_send(void *ctx, int type, const u8 *buf, size_t len)
  88. {
  89. return 0;
  90. }
  91. static int init_wpa(struct arg_ctx *arg)
  92. {
  93. struct wpa_sm_ctx *ctx;
  94. ctx = os_zalloc(sizeof(*ctx));
  95. if (ctx == NULL) {
  96. wpa_printf(MSG_ERROR, "Failed to allocate WPA context.");
  97. return -1;
  98. }
  99. ctx->ctx = arg;
  100. ctx->msg_ctx = arg;
  101. ctx->get_network_ctx = get_network_ctx;
  102. ctx->set_state = set_state;
  103. ctx->deauthenticate = deauthenticate;
  104. ctx->alloc_eapol = alloc_eapol;
  105. ctx->ether_send = ether_send;
  106. ctx->get_bssid = get_bssid;
  107. arg->wpa = wpa_sm_init(ctx);
  108. if (!arg->wpa)
  109. return -1;
  110. arg->wpa->pmk_len = PMK_LEN;
  111. return 0;
  112. }
  113. static int init_eapol(struct arg_ctx *arg)
  114. {
  115. struct eapol_ctx *ctx;
  116. ctx = os_zalloc(sizeof(*ctx));
  117. if (ctx == NULL) {
  118. wpa_printf(MSG_ERROR, "Failed to allocate EAPOL context.");
  119. return -1;
  120. }
  121. ctx->ctx = arg;
  122. ctx->msg_ctx = arg;
  123. ctx->eapol_send = eapol_send;
  124. arg->eapol = eapol_sm_init(ctx);
  125. return arg->eapol ? 0 : -1;
  126. }
  127. int main(int argc, char *argv[])
  128. {
  129. struct arg_ctx ctx;
  130. int ret = -1;
  131. if (argc < 2) {
  132. printf("usage: %s <file>\n", argv[0]);
  133. return -1;
  134. }
  135. if (os_program_init())
  136. return -1;
  137. wpa_debug_level = 0;
  138. wpa_debug_show_keys = 1;
  139. if (eloop_init()) {
  140. wpa_printf(MSG_ERROR, "Failed to initialize event loop");
  141. return -1;
  142. }
  143. os_memset(&ctx, 0, sizeof(ctx));
  144. ctx.fname = argv[1];
  145. if (init_wpa(&ctx) || init_eapol(&ctx))
  146. goto fail;
  147. eloop_register_timeout(0, 0, test_send_eapol, &ctx, NULL);
  148. wpa_printf(MSG_DEBUG, "Starting eloop");
  149. eloop_run();
  150. wpa_printf(MSG_DEBUG, "eloop done");
  151. ret = 0;
  152. fail:
  153. if (ctx.wpa)
  154. wpa_sm_deinit(ctx.wpa);
  155. if (ctx.eapol)
  156. eapol_sm_deinit(ctx.eapol);
  157. eloop_destroy();
  158. os_program_deinit();
  159. return ret;
  160. }