impacket
impacket copied to clipboard
Adds the creation of a new machine account through SMB via ntlmrelayx
I have taken the essential part of the script addComputer.py and adapted it to the smbattack.py script logic for usage with ntlmrelayx.py.
However, I have used the hSamrChangePasswordUser() function to setup the new machine account password. I don't really know why for the moment, but setting up the password with hSamrSetPasswordInternal4New() with an authentication via NTLM relay doesn't seem to work, even with the USER_FORCE_PASSWORD_CHANGE access mask in the user handle. However, by specifying the old hashNT (which is basically the 'blank' NT hash just after the creation) it looks good.
Additionally, for the moment, specifying the target Domain Controller with its FQDN and not its IP address is required. Must be improved to drop this restriction.
The ability to create a machine account through SMB can be useful when the LDAPS service doesn't have any certificate, which blocks the binding...or if the SMB signature is really permissive.
I don't really know why for the moment, but setting up the password with
hSamrSetPasswordInternal4New()with an authentication via NTLM relay doesn't seem to work
The reason is probably here: https://github.com/SecureAuthCorp/impacket/blob/ff32269707df18ef672d6e1036ba647331e91c13/impacket/dcerpc/v5/samr.py#L2944 The buffer gets encrypted with the SMB session key which as far as I know can't be calculated for a relayed connection.
Hum, effectively it makes sense. It is the first time I script something with the Impacket's libraries, so I don't know all the specifies :smile: Thanks for the explain on this part.
Just tested, it's working like a charm 👍

Great PR! For the password generation, imho it would be nice to implement what was done in https://github.com/SecureAuthCorp/impacket/pull/1063 where the password can be defined by the user, or randomly generated in a list of chars that exclude inconvenient ones.
Just tested, it's working like a charm +1
Thanks for the feedback and the test !
Great PR! For the password generation, imho it would be nice to implement what was done in #1063 where the password can be defined by the user, or randomly generated in a list of chars that exclude inconvenient ones.
Ah yes, for the random computer name and password generation I have reused the code snippet from the addComputer() function in the ldapattack.py script in order to be as consistent as possible with what already exists and keep the same "editorial line", but indeed if there is better it can be interesting. I'll look at it as soon as I have time.
Thanks for the feedback !
Two updates:
- It is now possible to specify a computer name and its password, or just the computer name, or nothing and everything will be randomly generated. Also, the password generation is now based on #1063 )
- The Domain Controller FQDN is no more needed, targeting it with its IP address works (however, if there are multiple domains on the DC, it will be necessary to specify the FQDN)
Can we check this one before the next release of impacket @0xdeaddood ? this is really really valuable during internal pentest ! :)
Can we check this one before the next release of impacket @0xdeaddood ? this is really really valuable during internal pentest ! :)
Only if the DC has SMB signing not required though, which doesn't happen so much ^^

Literally just ran into this on a gig, domain controllers without signing required! Awesome work @BlWasp
Literally just ran into this on a gig, domain controllers without signing required! Awesome work @BlWasp
Thanks for the feedback !
Hi @BlWasp! Thanks for the PR. I left you a comment/change request we need to address before merging.
Hi @0xdeaddood ! Thanks for the review. It is my first PR on Impacket and I don't know all the functions that already exist. Effectively your change request seems to work perfectly, I have committed it. :)
@0xdeaddood don't forget this one :)
Hi everyone. I have made some changes on this PR :) First I have resolved the different conflicts. Then I have remove the created function connectSamr2() from secretsdump.py and now I'm using connectSamr(remoteOps.getMachineNameAndDomain()[1]) as suggested by @0xdeaddood .
Additionally, I have moved the exception handles in the samr function hSamrCreateUser2InDomain() in order to limit code duplication as suggested by @martingalloar .
So normally, now the PR is ready to be merged 😃
Anything new about this ?
Anything new about this ?
@anadrianmanrique maybe ?
It would be awesome to merge this, please :pray: Tested, it works. And it doesn't impact other existing features, so I see no problem in merging this PR
ok, I'm currently reviewing these changes. I think adding --smb-add-computer parameter is not necessary as the current --add-computer, it is actually valid in the context of smb relaying (with these changes). So lets reuse it
Hum ok why not. --add-computer is a LDAP option provided through ldapoptions. Do you want that I rename my parameter to --add-computer and there will be the same parameter twice in the help, or that I move the actual --add-computer LDAP parameter to the main options to make it available for both LDAP and SMB ?
Hum ok why not.
--add-computeris a LDAP option provided throughldapoptions. Do you want that I rename my parameter to--add-computerand there will be the same parameter twice in the help, or that I move the actual--add-computerLDAP parameter to the main options to make it available for both LDAP and SMB ?
imo, best would be one option in the LDAP section, one in the SMB section
Hum ok why not.
--add-computeris a LDAP option provided throughldapoptions. Do you want that I rename my parameter to--add-computerand there will be the same parameter twice in the help, or that I move the actual--add-computerLDAP parameter to the main options to make it available for both LDAP and SMB ?
I think for now the best would be to have them duplicated in the LDAP and SMB section
Are you sure this is possible ? Because normally, the same argument name declared twice will raise an argparse error like this:
ldapoptions.add_argument('--add-computer', action='store', metavar=('COMPUTERNAME', 'PASSWORD'), required=False, nargs='*', help='Attempt to add a new computer account')
File "/usr/lib/python3.11/argparse.py", line 1480, in add_argument
return self._add_action(action)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/argparse.py", line 1682, in _add_action
action = super(_ArgumentGroup, self)._add_action(action)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/argparse.py", line 1494, in _add_action
self._check_conflict(action)
File "/usr/lib/python3.11/argparse.py", line 1631, in _check_conflict
conflict_handler(action, confl_optionals)
File "/usr/lib/python3.11/argparse.py", line 1640, in _handle_conflict_error
raise ArgumentError(action, message % conflict_string)
argparse.ArgumentError: argument --add-computer: conflicting option string: --add-computer
Is the error raised when you add the option in the smboptions subparser? In your example it's showing ldapoptions, which already has the add computer option
Yes when I add it in smboptions. I think the error triggers in ldapoptions because it is the second declaration in the list.
hmm ok, if that's not possible, lets just move --add-computer to the general options, but clarifying that it will only apply for SMB and LDAP
Indeed, it won't work, tested now
Hi all,
I have attempted something by creating a new "common" section in the argument parser. I think it is more clear than putting the --add-computer parameter in the main options, and this section could be used in the future for new attacks common to both protocols.
I've just finished testing it. It works as expeceted. Thanks for the PR! everyone involved in the review process also
Hi! Great to hear that! Thanks for the review and the merge.