diff options
Diffstat (limited to 'source4/torture/rpc/lsa.c')
-rw-r--r-- | source4/torture/rpc/lsa.c | 152 |
1 files changed, 152 insertions, 0 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; } |