diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-09-03 08:28:24 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:58:30 -0500 |
commit | a67ec52fdecf07c6685e986c9a10cca526094da1 (patch) | |
tree | 9c8d47aebe0ad9f88ba1fc8c2aad0ddb6db85ac2 | |
parent | a560082c60e618de327170dbcb8107ab988913fb (diff) | |
download | samba-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.c | 152 | ||||
-rw-r--r-- | source4/torture/rpc/testjoin.c | 9 | ||||
-rw-r--r-- | source4/torture/torture.c | 13 |
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"), |