[Pkg-samba-maint] [samba] 07/10: backport torture test for CVE-2015-0240

Ivo De Decker ivodd at moszumanska.debian.org
Mon Feb 23 19:40:42 UTC 2015


This is an automated email from the git hooks/post-receive script.

ivodd pushed a commit to annotated tag debian/2%4.1.17+dfsg-1
in repository samba.

commit 1cff678e65e3eed2bc957525aa8f0f31482dd2d2
Author: Ivo De Decker <ivodd at debian.org>
Date:   Mon Feb 23 19:30:50 2015 +0100

    backport torture test for CVE-2015-0240
---
 debian/changelog                                 |   2 +
 debian/patches/samba_bug_11077_torturetest.patch | 259 +++++++++++++++++++++++
 debian/patches/series                            |   1 +
 3 files changed, 262 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 358a57a..fd0228d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,6 +5,8 @@ samba (2:4.1.17+dfsg-1) UNRELEASED; urgency=medium
                    Controller. Closes: #776993
   - CVE-2015-0240: Unexpected code execution in smbd. Closes: #779033
   * Refresh patch add-so-version-to-private-libraries.
+  * Add new smbtorture test rpc.schannel_anon_setpw to detect the conditions
+    leading to CVE-2015-0240.
 
  -- Ivo De Decker <ivodd at debian.org>  Sun, 22 Feb 2015 19:53:54 +0100
 
diff --git a/debian/patches/samba_bug_11077_torturetest.patch b/debian/patches/samba_bug_11077_torturetest.patch
new file mode 100644
index 0000000..c4a0f18
--- /dev/null
+++ b/debian/patches/samba_bug_11077_torturetest.patch
@@ -0,0 +1,259 @@
+From cbb435953365ddc7ceb5364ae6cc45ac80ba11f6 Mon Sep 17 00:00:00 2001
+From: Andreas Schneider <asn at samba.org>
+Date: Mon, 16 Feb 2015 08:56:28 +0100
+Subject: [PATCH] torture: Add netr_setPassword(2) schannel test.
+
+Thanks to Florian Weimer <fweimer at redhat.com> for the help to write
+this torture test.
+
+Pair-Programmed-With: Guenther Deschner <gd at samba.org>
+Signed-off-by: Andreas Schneider <asn at samba.org>
+Signed-off-by: Guenther Deschner <gd at samba.org>
+---
+ selftest/target/Samba.pm       |   1 +
+ selftest/target/Samba3.pm      |  50 +++++++++++++++++++
+ source3/selftest/tests.py      |   6 ++-
+ source4/torture/rpc/rpc.c      |   1 +
+ source4/torture/rpc/schannel.c | 109 +++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 166 insertions(+), 1 deletion(-)
+
+Index: samba/selftest/target/Samba.pm
+===================================================================
+--- samba.orig/selftest/target/Samba.pm
++++ samba/selftest/target/Samba.pm
+@@ -156,6 +156,7 @@ sub get_interface($)
+ 
+     $interfaces{"localktest6"} = 7;
+     $interfaces{"maptoguest"} = 8;
++    $interfaces{"locals3dc9"} = 9;
+ 
+     # 11-16 used by selftest.pl for client interfaces
+ 
+Index: samba/selftest/target/Samba3.pm
+===================================================================
+--- samba.orig/selftest/target/Samba3.pm
++++ samba/selftest/target/Samba3.pm
+@@ -153,6 +153,8 @@ sub setup_env($$$)
+ 
+ 	if ($envname eq "s3dc") {
+ 		return $self->setup_s3dc("$path/s3dc");
++	} elsif ($envname eq "s3dc_schannel") {
++		return $self->setup_s3dc_schannel("$path/s3dc_schannel");
+ 	} elsif ($envname eq "simpleserver") {
+ 		return $self->setup_simpleserver("$path/simpleserver");
+ 	} elsif ($envname eq "maptoguest") {
+@@ -216,6 +218,54 @@ sub setup_s3dc($$)
+ 
+ 	return $vars;
+ }
++
++sub setup_s3dc_schannel($$)
++{
++	my ($self, $path) = @_;
++
++	print "PROVISIONING S3DC WITH SERVER SCHANNEL ...";
++
++	my $pdc_options = "
++	domain master = yes
++	domain logons = yes
++	lanman auth = yes
++
++	rpc_server:epmapper = external
++	rpc_server:spoolss = external
++	rpc_server:lsarpc = external
++	rpc_server:samr = external
++	rpc_server:netlogon = external
++	rpc_server:register_embedded_np = yes
++
++	rpc_daemon:epmd = fork
++	rpc_daemon:spoolssd = fork
++	rpc_daemon:lsasd = fork
++
++	server schannel = yes
++";
++
++	my $vars = $self->provision($path,
++				    "LOCALS3DC9",
++				    "locals3dc9pass",
++				    $pdc_options);
++
++	$vars or return undef;
++
++	if (not $self->check_or_start($vars, "yes", "yes", "yes")) {
++	       return undef;
++	}
++
++	$vars->{DC_SERVER} = $vars->{SERVER};
++	$vars->{DC_SERVER_IP} = $vars->{SERVER_IP};
++	$vars->{DC_SERVER_IPV6} = $vars->{SERVER_IPV6};
++	$vars->{DC_NETBIOSNAME} = $vars->{NETBIOSNAME};
++	$vars->{DC_USERNAME} = $vars->{USERNAME};
++	$vars->{DC_PASSWORD} = $vars->{PASSWORD};
++
++	$self->{vars}->{s3dc_schannel} = $vars;
++
++	return $vars;
++}
+ 
+ sub setup_member($$$)
+ {
+Index: samba/source3/selftest/tests.py
+===================================================================
+--- samba.orig/source3/selftest/tests.py
++++ samba/source3/selftest/tests.py
+@@ -274,7 +274,7 @@ rpc = ["rpc.authcontext", "rpc.samba3.bi
+        "rpc.samr.passwords.pwdlastset", "rpc.samr.large-dc", "rpc.samr.machine.auth",
+        "rpc.samr.priv", "rpc.samr.passwords.validate",
+        "rpc.netlogon.admin",
+-       "rpc.schannel", "rpc.schannel2", "rpc.bench-schannel1", "rpc.join", "rpc.bind"]
++       "rpc.schannel", "rpc.schannel2", "rpc.bench-schannel1", "rpc.schannel_anon_setpw", "rpc.join", "rpc.bind"]
+ 
+ local = ["local.nss-wrapper", "local.ndr"]
+ 
+@@ -358,6 +358,10 @@ for t in tests:
+ # test the dirsort module.
+         plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/tmpsort -U$USERNAME%$PASSWORD')
+         plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
++    elif t == "rpc.schannel_anon_setpw":
++        plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/tmp -U$%', description="anonymous password set")
++        plansmbtorture4testsuite(t, "s3dc_schannel", '//$SERVER_IP/tmp -U$%', description="anonymous password set (schannel enforced server-side)")
++        plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER/tmp -U$%', description="anonymous password set")
+     else:
+         plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
+         plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
+Index: samba/source4/torture/rpc/rpc.c
+===================================================================
+--- samba.orig/source4/torture/rpc/rpc.c
++++ samba/source4/torture/rpc/rpc.c
+@@ -496,6 +496,7 @@ NTSTATUS torture_rpc_init(void)
+ 	torture_suite_add_simple_test(suite, "schannel", torture_rpc_schannel);
+ 	torture_suite_add_simple_test(suite, "schannel2", torture_rpc_schannel2);
+ 	torture_suite_add_simple_test(suite, "bench-schannel1", torture_rpc_schannel_bench1);
++	torture_suite_add_simple_test(suite, "schannel_anon_setpw", torture_rpc_schannel_anon_setpw);
+ 	torture_suite_add_suite(suite, torture_rpc_srvsvc(suite));
+ 	torture_suite_add_suite(suite, torture_rpc_svcctl(suite));
+ 	torture_suite_add_suite(suite, torture_rpc_samr_accessmask(suite));
+Index: samba/source4/torture/rpc/schannel.c
+===================================================================
+--- samba.orig/source4/torture/rpc/schannel.c
++++ samba/source4/torture/rpc/schannel.c
+@@ -543,6 +543,83 @@ static bool test_schannel(struct torture
+ 	return true;
+ }
+ 
++/*
++ * Purpose of this test is to demonstrate that a netlogon server carefully deals
++ * with anonymous attempts to set passwords, in particular when the server
++ * enforces the use of schannel. This test makes most sense to be run in an
++ * environment where the netlogon server enforces use of schannel.
++ */
++
++static bool test_schannel_anonymous_setPassword(struct torture_context *tctx,
++						uint32_t dcerpc_flags,
++						bool use2)
++{
++	struct test_join *join_ctx;
++	NTSTATUS status, result;
++	const char *binding = torture_setting_string(tctx, "binding", NULL);
++	struct dcerpc_binding *b;
++	struct dcerpc_pipe *p = NULL;
++	struct cli_credentials *credentials;
++	bool ok = true;
++
++	credentials = cli_credentials_init(NULL);
++	torture_assert(tctx, credentials != NULL, "Bad credentials");
++	cli_credentials_set_anonymous(credentials);
++
++	status = dcerpc_parse_binding(tctx, binding, &b);
++	torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
++
++	status = dcerpc_pipe_connect_b(tctx,
++				       &p,
++				       b,
++				       &ndr_table_netlogon,
++				       credentials,
++				       tctx->ev,
++				       tctx->lp_ctx);
++	torture_assert_ntstatus_ok(tctx, status, "Failed to connect without schannel");
++
++	if (use2) {
++		struct netr_ServerPasswordSet2 r = {};
++		struct netr_Authenticator credential = {};
++		struct netr_Authenticator return_authenticator = {};
++		struct netr_CryptPassword new_password = {};
++
++		r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
++		r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
++		r.in.secure_channel_type = 0;
++		r.in.computer_name = TEST_MACHINE_NAME;
++		r.in.credential = &credential;
++		r.in.new_password = &new_password;
++		r.out.return_authenticator = &return_authenticator;
++
++		status = dcerpc_netr_ServerPasswordSet2_r(p->binding_handle, tctx, &r);
++		result = r.out.result;
++	} else {
++		struct netr_ServerPasswordSet r = {};
++		struct netr_Authenticator credential = {};
++		struct netr_Authenticator return_authenticator = {};
++		struct samr_Password new_password = {};
++
++		r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
++		r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
++		r.in.secure_channel_type = 0;
++		r.in.computer_name = TEST_MACHINE_NAME;
++		r.in.credential = &credential;
++		r.in.new_password = &new_password;
++		r.out.return_authenticator = &return_authenticator;
++
++		status = dcerpc_netr_ServerPasswordSet_r(p->binding_handle, tctx, &r);
++		result = r.out.result;
++	}
++
++	torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet failed");
++
++	if (NT_STATUS_IS_OK(result)) {
++		torture_fail(tctx, "unexpectedly received NT_STATUS_OK");
++	}
++
++	return ok;
++}
+ 
+ 
+ /*
+@@ -584,6 +661,35 @@ bool torture_rpc_schannel(struct torture
+ 	}
+ 
+ 	return ret;
++}
++
++bool torture_rpc_schannel_anon_setpw(struct torture_context *torture)
++{
++	bool ret = true;
++	bool ok;
++	uint32_t dcerpc_flags = DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_AUTO;
++
++	ok = test_schannel_anonymous_setPassword(torture,
++						 dcerpc_flags,
++						 true);
++	if (!ok) {
++		torture_comment(torture,
++				"Failed with dcerpc_flags=0x%x\n",
++				dcerpc_flags);
++		ret = false;
++	}
++
++	ok = test_schannel_anonymous_setPassword(torture,
++						 dcerpc_flags,
++						 false);
++	if (!ok) {
++		torture_comment(torture,
++				"Failed with dcerpc_flags=0x%x\n",
++				dcerpc_flags);
++		ret = false;
++	}
++
++	return ret;
+ }
+ 
+ /*
diff --git a/debian/patches/series b/debian/patches/series
index 79134da..42249d9 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -14,3 +14,4 @@ waf_smbpasswd_location
 add-so-version-to-private-libraries
 do-not-install-smbclient4-and-nmbclient4
 xsltproc_dont_build_smb.conf.5.patch
+samba_bug_11077_torturetest.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-samba/samba.git




More information about the Pkg-samba-maint mailing list