1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-07 00:58:40 +03:00

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)
This commit is contained in:
Andrew Tridgell 2004-09-03 08:28:24 +00:00 committed by Gerald (Jerry) Carter
parent a560082c60
commit a67ec52fde
3 changed files with 164 additions and 10 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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"),