1
0

023-CVE-2016-2110-v3-6.patch 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. From 202d69267c8550b850438877fb51c3d2c992949d Mon Sep 17 00:00:00 2001
  2. From: Stefan Metzmacher <metze@samba.org>
  3. Date: Tue, 1 Dec 2015 08:46:45 +0100
  4. Subject: [PATCH 01/10] CVE-2016-2110: s3:ntlmssp: set and use
  5. ntlmssp_state->allow_lm_key
  6. MIME-Version: 1.0
  7. Content-Type: text/plain; charset=UTF-8
  8. Content-Transfer-Encoding: 8bit
  9. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644
  10. Signed-off-by: Stefan Metzmacher <metze@samba.org>
  11. Reviewed-by: Günther Deschner <gd@samba.org>
  12. ---
  13. source3/libsmb/ntlmssp.c | 4 +++-
  14. 1 file changed, 3 insertions(+), 1 deletion(-)
  15. --- a/source3/libsmb/ntlmssp.c
  16. +++ b/source3/libsmb/ntlmssp.c
  17. @@ -176,17 +176,19 @@ void ntlmssp_want_feature_list(struct nt
  18. * also add NTLMSSP_NEGOTIATE_SEAL here. JRA.
  19. */
  20. if (in_list("NTLMSSP_FEATURE_SESSION_KEY", feature_list, True)) {
  21. - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
  22. + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
  23. }
  24. if (in_list("NTLMSSP_FEATURE_SIGN", feature_list, True)) {
  25. - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
  26. + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
  27. }
  28. if(in_list("NTLMSSP_FEATURE_SEAL", feature_list, True)) {
  29. - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
  30. + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
  31. }
  32. if (in_list("NTLMSSP_FEATURE_CCACHE", feature_list, true)) {
  33. ntlmssp_state->use_ccache = true;
  34. }
  35. +
  36. + ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
  37. }
  38. /**
  39. @@ -199,17 +201,20 @@ void ntlmssp_want_feature(struct ntlmssp
  40. {
  41. /* As per JRA's comment above */
  42. if (feature & NTLMSSP_FEATURE_SESSION_KEY) {
  43. - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
  44. + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
  45. }
  46. if (feature & NTLMSSP_FEATURE_SIGN) {
  47. - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
  48. + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
  49. }
  50. if (feature & NTLMSSP_FEATURE_SEAL) {
  51. - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
  52. + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
  53. + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
  54. }
  55. if (feature & NTLMSSP_FEATURE_CCACHE) {
  56. ntlmssp_state->use_ccache = true;
  57. }
  58. +
  59. + ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
  60. }
  61. /**
  62. @@ -387,7 +392,12 @@ static NTSTATUS ntlmssp_client_initial(s
  63. }
  64. if (ntlmssp_state->use_ntlmv2) {
  65. - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
  66. + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_NTLM2;
  67. + ntlmssp_state->allow_lm_key = false;
  68. + }
  69. +
  70. + if (ntlmssp_state->allow_lm_key) {
  71. + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
  72. }
  73. /* generate the ntlmssp negotiate packet */
  74. @@ -422,6 +432,86 @@ static NTSTATUS ntlmssp_client_initial(s
  75. return NT_STATUS_MORE_PROCESSING_REQUIRED;
  76. }
  77. +static NTSTATUS ntlmssp3_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
  78. + uint32_t flags)
  79. +{
  80. + uint32_t missing_flags = ntlmssp_state->required_flags;
  81. +
  82. + if (flags & NTLMSSP_NEGOTIATE_UNICODE) {
  83. + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
  84. + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
  85. + ntlmssp_state->unicode = true;
  86. + } else {
  87. + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
  88. + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
  89. + ntlmssp_state->unicode = false;
  90. + }
  91. +
  92. + /*
  93. + * NTLMSSP_NEGOTIATE_NTLM2 (NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY)
  94. + * has priority over NTLMSSP_NEGOTIATE_LM_KEY
  95. + */
  96. + if (!(flags & NTLMSSP_NEGOTIATE_NTLM2)) {
  97. + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
  98. + }
  99. +
  100. + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
  101. + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
  102. + }
  103. +
  104. + if (!(flags & NTLMSSP_NEGOTIATE_LM_KEY)) {
  105. + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
  106. + }
  107. +
  108. + if (!(flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {
  109. + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
  110. + }
  111. +
  112. + if (!(flags & NTLMSSP_NEGOTIATE_128)) {
  113. + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
  114. + }
  115. +
  116. + if (!(flags & NTLMSSP_NEGOTIATE_56)) {
  117. + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
  118. + }
  119. +
  120. + if (!(flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
  121. + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
  122. + }
  123. +
  124. + if (!(flags & NTLMSSP_NEGOTIATE_SIGN)) {
  125. + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
  126. + }
  127. +
  128. + if (!(flags & NTLMSSP_NEGOTIATE_SEAL)) {
  129. + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
  130. + }
  131. +
  132. + if ((flags & NTLMSSP_REQUEST_TARGET)) {
  133. + ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
  134. + }
  135. +
  136. + missing_flags &= ~ntlmssp_state->neg_flags;
  137. + if (missing_flags != 0) {
  138. + NTSTATUS status = NT_STATUS_RPC_SEC_PKG_ERROR;
  139. + DEBUG(1, ("%s: Got challenge flags[0x%08x] "
  140. + "- possible downgrade detected! "
  141. + "missing_flags[0x%08x] - %s\n",
  142. + __func__,
  143. + (unsigned)flags,
  144. + (unsigned)missing_flags,
  145. + nt_errstr(status)));
  146. + debug_ntlmssp_flags(missing_flags);
  147. + DEBUGADD(4, ("neg_flags[0x%08x]\n",
  148. + (unsigned)ntlmssp_state->neg_flags));
  149. + debug_ntlmssp_flags(ntlmssp_state->neg_flags);
  150. +
  151. + return status;
  152. + }
  153. +
  154. + return NT_STATUS_OK;
  155. +}
  156. +
  157. /**
  158. * Next state function for the Challenge Packet. Generate an auth packet.
  159. *
  160. @@ -448,6 +538,26 @@ static NTSTATUS ntlmssp_client_challenge
  161. DATA_BLOB encrypted_session_key = data_blob_null;
  162. NTSTATUS nt_status = NT_STATUS_OK;
  163. + if (!msrpc_parse(ntlmssp_state, &reply, "CdBd",
  164. + "NTLMSSP",
  165. + &ntlmssp_command,
  166. + &server_domain_blob,
  167. + &chal_flags)) {
  168. + DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
  169. + dump_data(2, reply.data, reply.length);
  170. +
  171. + return NT_STATUS_INVALID_PARAMETER;
  172. + }
  173. + data_blob_free(&server_domain_blob);
  174. +
  175. + DEBUG(3, ("Got challenge flags:\n"));
  176. + debug_ntlmssp_flags(chal_flags);
  177. +
  178. + nt_status = ntlmssp3_handle_neg_flags(ntlmssp_state, chal_flags);
  179. + if (!NT_STATUS_IS_OK(nt_status)) {
  180. + return nt_status;
  181. + }
  182. +
  183. if (ntlmssp_state->use_ccache) {
  184. struct wbcCredentialCacheParams params;
  185. struct wbcCredentialCacheInfo *info = NULL;
  186. @@ -498,17 +608,6 @@ static NTSTATUS ntlmssp_client_challenge
  187. noccache:
  188. - if (!msrpc_parse(ntlmssp_state, &reply, "CdBd",
  189. - "NTLMSSP",
  190. - &ntlmssp_command,
  191. - &server_domain_blob,
  192. - &chal_flags)) {
  193. - DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
  194. - dump_data(2, reply.data, reply.length);
  195. -
  196. - return NT_STATUS_INVALID_PARAMETER;
  197. - }
  198. -
  199. if (DEBUGLEVEL >= 10) {
  200. struct CHALLENGE_MESSAGE *challenge = talloc(
  201. talloc_tos(), struct CHALLENGE_MESSAGE);
  202. @@ -525,13 +624,6 @@ noccache:
  203. }
  204. }
  205. - data_blob_free(&server_domain_blob);
  206. -
  207. - DEBUG(3, ("Got challenge flags:\n"));
  208. - debug_ntlmssp_flags(chal_flags);
  209. -
  210. - ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
  211. -
  212. if (ntlmssp_state->unicode) {
  213. if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
  214. chal_parse_string = "CdUdbddB";
  215. @@ -769,6 +861,7 @@ NTSTATUS ntlmssp_client_start(TALLOC_CTX
  216. ntlmssp_state->unicode = True;
  217. ntlmssp_state->use_ntlmv2 = use_ntlmv2;
  218. + ntlmssp_state->allow_lm_key = lp_client_lanman_auth();
  219. ntlmssp_state->expected_state = NTLMSSP_INITIAL;
  220. @@ -780,6 +873,10 @@ NTSTATUS ntlmssp_client_start(TALLOC_CTX
  221. NTLMSSP_NEGOTIATE_KEY_EXCH |
  222. NTLMSSP_REQUEST_TARGET;
  223. + if (ntlmssp_state->use_ntlmv2) {
  224. + ntlmssp_state->allow_lm_key = false;
  225. + }
  226. +
  227. ntlmssp_state->client.netbios_name = talloc_strdup(ntlmssp_state, netbios_name);
  228. if (!ntlmssp_state->client.netbios_name) {
  229. talloc_free(ntlmssp_state);
  230. --- a/libcli/auth/ntlmssp.h
  231. +++ b/libcli/auth/ntlmssp.h
  232. @@ -83,6 +83,7 @@ struct ntlmssp_state
  233. DATA_BLOB nt_resp;
  234. DATA_BLOB session_key;
  235. + uint32_t required_flags;
  236. uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */
  237. /**