📄 smb_lsa.inc
字号:
names = NULL; # for each names for (i=0; i<count; i++) { if (strlen(rep) < pos + 20) return NULL; sid_type = get_word (blob:rep, pos:pos); names[i] = raw_dword (d:sid_type); length = get_word (blob:rep, pos:pos+4); size = get_word (blob:rep, pos:pos+6); ref_id = get_dword (blob:rep, pos:pos+8); index = get_dword (blob:rep, pos:pos+12); if (ref_id != 0) { name = domain_names[index]; names[i] += raw_dword (d:strlen(name)) + name; } else names[i] = NULL; pos = pos+16; } # we get names now for (i=0; i<count; i++) { if (names[i] == NULL) continue; if (strlen(rep) < pos + 12) return NULL; max_count = get_dword (blob:rep, pos:pos); offset = get_dword (blob:rep, pos:pos+4); actual_count = get_dword (blob:rep, pos:pos+8); if (strlen(rep) < pos + 12 + actual_count*2) return NULL; name = get_string2 (blob:rep, pos:pos+12, len:actual_count*2, _type:UNICODE_STRING); names[i] += raw_dword (d:strlen(name)) + name; if ((actual_count*2)%4) pos +=2; pos = pos+12+actual_count*2; } return names;}#---------------------------------------------------------## Function : LsaLookupNames ## Description : Translate UserNames to SID ## array of usernames ## ## Return : array of sid_type + rid ## sid_type = rid = raw_dword ##---------------------------------------------------------#function LsaLookupNames (handle, name_array){ local_var data, resp, rep, name, ret, len, ref_id, level, pad, length, size; local_var max_count, offset, actual_count, hostname, pos, count, sid, sid_ref_id; local_var names, ref_idm, name_length, name_size, name_ref_id, sid_type, index, unknown; local_var sid_count, uname, i, rid, sid_tab, tmp_sid; ref_id = 0x00020000; data = handle[0] + # Handle # Account array raw_dword (d:max_index (name_array)) + # number of sid in PSID Array raw_dword (d:max_index (name_array)) ; # max_count ref_id++; # ref_id foreach name (name_array) { if (session_is_unicode() == 0) { session_set_unicode (unicode:1); uname = cstring (string:name,_null:1); session_set_unicode (unicode:0); } else { uname = cstring (string:name, _null:1); } data += raw_word (w:strlen(uname)) + raw_word (w:strlen(uname)) + raw_dword (d:ref_id); ref_id++; } foreach name (name_array) { if (session_is_unicode() == 0) { session_set_unicode (unicode:1); uname = cstring (string:name,_null:1); session_set_unicode (unicode:0); } else { uname = cstring (string:name,_null:1); } data += raw_dword (d:strlen(uname)/2) + raw_dword (d:0) + # offset raw_dword (d:strlen(uname)/2); while ((strlen(uname)%4) != 0) uname += raw_byte (b:0); data += uname; } data += raw_dword (d:0) + # count = 0 raw_dword (d:0) + # NULL pointer (LSA_TRANSLATED_NAMES) raw_dword (d:1) + # Level (nothing else seems to work) raw_dword (d:0) ; # Num mapped ? data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_LSALOOKUPNAMES, data:data); if (!data) return NULL; rep = dce_rpc_parse_response (fid:handle[1], data:data); if (!rep || (strlen (rep) < 20)) return NULL; resp = get_dword (blob:rep, pos:strlen(rep)-4); if ((resp != STATUS_SUCCESS) && (resp != STATUS_NONE_MAPPED)) return NULL; # LSA REF DOMAIN LIST Pointer ref_id = get_dword (blob:rep, pos:0); count = get_dword (blob:rep, pos:4); # Trust information array ref_id = get_dword (blob:rep, pos:8); max_count = get_dword (blob:rep, pos:12); count = get_dword (blob:rep, pos:16); pos = 20; sid_tab = NULL; # for each domain info for (i=0; i < count; i++) { if (strlen(rep) < pos + 24) return NULL; name_length = get_word (blob:rep, pos:pos); name_size = get_word (blob:rep, pos:pos+2); # max size of name buffer (we are happy to know that) name_ref_id = get_dword (blob:rep, pos:pos+4); sid_ref_id = get_dword (blob:rep, pos:pos+8); # name array max_count = get_dword (blob:rep, pos:pos+12); offset = get_dword (blob:rep, pos:pos+16); actual_count = get_dword (blob:rep, pos:pos+20); if (strlen(rep) < pos + 28 + name_length) return NULL; name = substr (rep, pos+24, pos+24+name_length-1); pos = pos+24+name_length; while (name_length%4) { pos++; name_length++; } # SID sid_count = get_dword (blob:rep, pos:pos); if (strlen(rep) < pos + 4+8+sid_count*4) return NULL; sid_tab[i] = substr (rep, pos+4, pos+4+8+sid_count*4-1); pos = pos+4+8+sid_count*4; } # LSA_TRANSLATED_SID count = get_dword (blob:rep, pos:pos); ref_id = get_dword (blob:rep, pos:pos+4); max_count = get_dword (blob:rep, pos:pos+8); pos = pos + 12; sid = NULL; # for each names for (i=0; i<count; i++) { if (strlen(rep) < pos + 12) return NULL; sid_type = get_dword (blob:rep, pos:pos); rid = get_dword (blob:rep, pos:pos+4); index = get_dword (blob:rep, pos:pos+8); tmp_sid = sid_tab[i]; sid[i] = tmp_sid[0] + raw_byte (b: ord(tmp_sid[1])+1) + substr(tmp_sid,2,strlen(tmp_sid)-1) + raw_dword (d:rid); pos = pos+12; } return sid;}#---------------------------------------------------------## Function : LsaEnumerateAccountsWithUserRight ## Description : Get SID of User with Right 'right' ## (string) ## Return : array of sid ##---------------------------------------------------------#function LsaEnumerateAccountsWithUserRight (handle, right){ local_var data, rep, code, ret, resp, ref_id, size, pt, sid_count, count, max_count, sid_tab, i, total_len, pos; pt = raw_dword (d:0x20000) + # pointer ref id class_parameter (ref_id:0x00020000, name:right, size:TRUE, _null:FALSE); data = handle[0] + # Handle pt ; # right pointer data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_LSAENUMERATEACCOUNTWITHUSERRIGHT, data:data); if (!data) return NULL; rep = dce_rpc_parse_response (fid:handle[1], data:data); if (!rep || (strlen (rep) < 16)) return NULL; total_len = strlen(rep); resp = get_dword (blob:rep, pos:total_len); if (resp != STATUS_SUCCESS) return NULL; count = get_dword (blob:rep, pos:0); ref_id = get_dword (blob:rep, pos:4); max_count = get_dword (blob:rep, pos:8); pos= 12; for (i=0; i<count; i++) { if ((pos+4) > total_len) return NULL; ref_id = get_dword (blob:rep, pos:pos); pos += 4; } sid_tab = NULL; for (i=0; i<count; i++) { if ((pos+4) > total_len) return NULL; sid_count = get_dword (blob:rep, pos:pos); pos += 4; if ((pos+8+sid_count*4-1) > total_len) return NULL; sid_tab[i] = substr (rep, pos, pos+8+sid_count*4-1); pos = pos+8+sid_count*4; } return sid_tab;}#---------------------------------------------------------## Function : LsaQuerySecurityObject ## Description : Return security ACLs of the object ## Return : security descriptor ##---------------------------------------------------------#function LsaQuerySecurityObject (handle, type){ local_var data, rep, code, ret, resp, ref_id, size; data = handle[0] + # Handle raw_dword (d:type) ; # Info level data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_LSASECURITYOBJECT, data:data); if (!data) return NULL; rep = dce_rpc_parse_response (fid:handle[1], data:data); if (!rep || (strlen (rep) < 16)) return NULL; resp = get_dword (blob:rep, pos:strlen(rep)-4); if (resp != STATUS_SUCCESS) return NULL; ref_id = get_dword (blob:rep, pos:0); if (isnull(ref_id)) return NULL; size = get_dword (blob:rep, pos:4); ref_id = get_dword (blob:rep, pos:8); if (isnull(ref_id)) return NULL; size = get_dword (blob:rep, pos:12); if (strlen(rep) < (size+16)) return NULL; return parse_security_descriptor (blob:substr(rep, 16, strlen(rep)-5));}#---------------------------------------------------------## Function : LsaClose ## Description : Close lsa handle ## Return : 1 on success ##---------------------------------------------------------#function LsaClose (handle){ local_var data, rep, code, ret; code = NULL; data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_LSACLOSE, data:handle[0]); if (data) { rep = dce_rpc_parse_response (fid:handle[1], data:data); if (rep && (strlen (rep) == 24)) { # NULL handle (useless) + code # Return code code = get_dword (blob:rep, pos:20); } } if (handle[2] == 1) ret = smb_close (fid:handle[1]); if (isnull (code) || (code != STATUS_SUCCESS) || (ret != 1)) return NULL; return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -