diff options
Diffstat (limited to 'source4/torture')
-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"), |