summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-09-03 08:28:24 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:58:30 -0500
commita67ec52fdecf07c6685e986c9a10cca526094da1 (patch)
tree9c8d47aebe0ad9f88ba1fc8c2aad0ddb6db85ac2
parenta560082c60e618de327170dbcb8107ab988913fb (diff)
downloadsamba-a67ec52fdecf07c6685e986c9a10cca526094da1.tar.gz
samba-a67ec52fdecf07c6685e986c9a10cca526094da1.tar.bz2
samba-a67ec52fdecf07c6685e986c9a10cca526094da1.zip
r2200: solved another piece of the lsakey puzzle - the session key for lsa
encryption on ncacn_ip_tcp is a fixed buffer! I don't yet know what the buffer is, but this code proves its the same buffer for different w2k3 servers and different user passwords, plus it is independent of the negotiated NTLMSSP session key. (This used to be commit 05fd38f3cfd9476bc1cf7fed838a942a75569c0a)
-rw-r--r--source4/torture/rpc/lsa.c152
-rw-r--r--source4/torture/rpc/testjoin.c9
-rw-r--r--source4/torture/torture.c13
3 files changed, 164 insertions, 10 deletions
diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c
index 135e50fb5a..d30e6a535f 100644
--- a/source4/torture/rpc/lsa.c
+++ b/source4/torture/rpc/lsa.c
@@ -496,6 +496,153 @@ static BOOL test_CreateSecret(struct dcerpc_pipe *p,
return ret;
}
+
+static BOOL test_lsakey_puzzle(struct dcerpc_pipe *p_smb,
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle_smb)
+{
+ NTSTATUS status;
+ struct dcerpc_pipe *p_tcp;
+ struct policy_handle handle_tcp, sec_handle, sec_handle2;
+ struct lsa_CreateSecret cr;
+ struct lsa_OpenSecret or;
+ struct lsa_SetSecret sr;
+ struct lsa_QuerySecret qr;
+ char *secname;
+ const char *secret1 = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+ DATA_BLOB session_key, blob1, blob2;
+ DATA_BLOB enc_key;
+ NTTIME old_mtime, new_mtime;
+ struct lsa_DATA_BUF buf1;
+ struct lsa_DATA_BUF_PTR bufp1;
+
+ status = torture_rpc_connection_transport(&p_tcp,
+ DCERPC_LSARPC_NAME,
+ DCERPC_LSARPC_UUID,
+ DCERPC_LSARPC_VERSION,
+ NCACN_IP_TCP);
+ if (!NT_STATUS_IS_OK(status)) {
+ return False;
+ }
+
+ if (!test_OpenPolicy2(p_tcp, mem_ctx, &handle_tcp)) {
+ return False;
+ }
+
+ asprintf(&secname, "torturesecret-%u", (uint_t)random());
+
+ printf("calling CreateSecret on %s\n", secname);
+
+ init_lsa_Name(&cr.in.name, secname);
+
+ cr.in.handle = handle_smb;
+ cr.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
+ cr.out.sec_handle = &sec_handle;
+
+ status = dcerpc_lsa_CreateSecret(p_smb, mem_ctx, &cr);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("CreateSecret failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ status = dcerpc_fetch_session_key(p_smb, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ printf("SMB session key:\n");
+ dump_data(0, session_key.data, session_key.length);
+
+ enc_key = sess_encrypt_string(secret1, &session_key);
+
+ blob1 = data_blob_talloc(mem_ctx, enc_key.data, enc_key.length);
+ sess_crypt_blob(&blob1, &enc_key, &session_key, False);
+
+ printf("Plain-text:\n");
+ dump_data(0, blob1.data, blob1.length);
+
+ printf("SMB encrypted:\n");
+ dump_data(0, enc_key.data, enc_key.length);
+
+ sr.in.handle = &sec_handle;
+ sr.in.new_val = &buf1;
+ sr.in.old_val = NULL;
+ sr.in.new_val->data = enc_key.data;
+ sr.in.new_val->length = enc_key.length;
+ sr.in.new_val->size = enc_key.length;
+
+ printf("calling SetSecret\n");
+
+ status = dcerpc_lsa_SetSecret(p_smb, mem_ctx, &sr);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("SetSecret failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ or.in.handle = &handle_tcp;
+ or.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
+ or.in.name = cr.in.name;
+ or.out.sec_handle = &sec_handle2;
+
+ printf("Calling OpenSecret\n");
+
+ status = dcerpc_lsa_OpenSecret(p_tcp, mem_ctx, &or);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("OpenSecret failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ ZERO_STRUCT(new_mtime);
+ ZERO_STRUCT(old_mtime);
+
+ /* fetch the secret back again */
+ qr.in.handle = &sec_handle2;
+ qr.in.new_val = &bufp1;
+ qr.in.new_mtime = &new_mtime;
+ qr.in.old_val = NULL;
+ qr.in.old_mtime = NULL;
+
+ bufp1.buf = NULL;
+
+ status = dcerpc_lsa_QuerySecret(p_tcp, mem_ctx, &qr);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("QuerySecret failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ status = dcerpc_fetch_session_key(p_tcp, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ printf("TCP session key:\n");
+ dump_data(0, session_key.data, session_key.length);
+
+ blob1.data = qr.out.new_val->buf->data;
+ blob1.length = qr.out.new_val->buf->length;
+
+ printf("Encrypted blob:\n");
+ dump_data(0, blob1.data, blob1.length);
+
+ session_key.length = 16;
+ blob2 = data_blob_talloc(mem_ctx, blob1.data, blob1.length);
+
+ /* try a zero session key to decrypt. */
+ data_blob_clear(&session_key);
+ sess_crypt_blob(&blob2, &blob1, &session_key, False);
+ printf("Test-text:\n");
+ dump_data(0, blob2.data, blob2.length);
+
+ talloc_destroy(mem_ctx);
+ torture_rpc_close(p_smb);
+ torture_rpc_close(p_tcp);
+
+ return True;
+}
+
+
static BOOL test_EnumAccountRights(struct dcerpc_pipe *p,
TALLOC_CTX *mem_ctx,
struct policy_handle *acct_handle,
@@ -893,6 +1040,11 @@ BOOL torture_rpc_lsa(int dummy)
ret = False;
}
+ if (!test_lsakey_puzzle(p, mem_ctx, &handle)) {
+ ret = False;
+ }
+ exit(1);
+
if (!test_many_LookupSids(p, mem_ctx, &handle)) {
ret = False;
}
diff --git a/source4/torture/rpc/testjoin.c b/source4/torture/rpc/testjoin.c
index a4a4979895..5ee17b092a 100644
--- a/source4/torture/rpc/testjoin.c
+++ b/source4/torture/rpc/testjoin.c
@@ -125,10 +125,11 @@ void *torture_join_domain(const char *machine_name,
printf("Connecting to SAMR (forced ncacn_np)\n");
- status = torture_rpc_connection_smb(&join->p,
- DCERPC_SAMR_NAME,
- DCERPC_SAMR_UUID,
- DCERPC_SAMR_VERSION);
+ status = torture_rpc_connection_transport(&join->p,
+ DCERPC_SAMR_NAME,
+ DCERPC_SAMR_UUID,
+ DCERPC_SAMR_VERSION,
+ NCACN_NP);
if (!NT_STATUS_IS_OK(status)) {
goto failed;
}
diff --git a/source4/torture/torture.c b/source4/torture/torture.c
index b1e6695e9e..863fe9d4f5 100644
--- a/source4/torture/torture.c
+++ b/source4/torture/torture.c
@@ -158,11 +158,12 @@ NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p,
return status;
}
-/* open a rpc connection to a named pipe */
-NTSTATUS torture_rpc_connection_smb(struct dcerpc_pipe **p,
- const char *pipe_name,
- const char *pipe_uuid,
- uint32_t pipe_version)
+/* open a rpc connection to a specific transport */
+NTSTATUS torture_rpc_connection_transport(struct dcerpc_pipe **p,
+ const char *pipe_name,
+ const char *pipe_uuid,
+ uint32_t pipe_version,
+ enum dcerpc_transport_t transport)
{
NTSTATUS status;
const char *binding = lp_parm_string(-1, "torture", "binding");
@@ -181,7 +182,7 @@ NTSTATUS torture_rpc_connection_smb(struct dcerpc_pipe **p,
return status;
}
- b.transport = NCACN_NP;
+ b.transport = transport;
status = dcerpc_pipe_connect_b(p, &b, pipe_uuid, pipe_version,
lp_parm_string(-1, "torture", "userdomain"),