From ba5a421b3e75f4e5962c1f434f6cec301df0080d Mon Sep 17 00:00:00 2001 From: iLightThings Date: Thu, 22 Sep 2022 08:31:02 -0400 Subject: [PATCH 1/7] Added local admins. Made CSV write function. --- cme/cmedb.py | 53 ++++++++++++++++++++++++++++++++--- cme/protocols/smb/database.py | 3 ++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/cme/cmedb.py b/cme/cmedb.py index 76963c8b..2e2d2333 100755 --- a/cme/cmedb.py +++ b/cme/cmedb.py @@ -54,6 +54,8 @@ class DatabaseNavigator(cmd.Cmd): line = line.split() + # Need to use if/elif/else to keep compatibility with py3.8/3.9 + # Users if line[0].lower() == 'creds': if len(line) < 3: print("[-] invalid arguments, export creds ") @@ -74,6 +76,7 @@ class DatabaseNavigator(cmd.Cmd): export_file.write('{}\n'.format(password)) print('[+] creds exported') + #Hosts elif line[0].lower() == 'hosts': if len(line) < 2: print("[-] invalid arguments, export hosts ") @@ -85,6 +88,7 @@ class DatabaseNavigator(cmd.Cmd): export_file.write('{},{},{},{},{},{}\n'.format(hostid,ipaddress,hostname,domain,opsys,dc)) print('[+] hosts exported') + #Shares elif line[0].lower() == 'shares': if len(line) < 3: print("[-] invalid arguments, export shares ") @@ -120,15 +124,56 @@ class DatabaseNavigator(cmd.Cmd): shareCSV.writerow([shareid,prettyhost,prettyuser,sharename,shareremark,bool(read),bool(write)]) print('[+] shares exported') - - else: - print("[-] invalid arguments, export shares ") + + #Local Admin + elif line[0].lower() == 'local_admins': + if len(line) < 3: + print("[-] invalid arguments, export local_admins ") return + # These Values don't change between simple and detailed + local_admins = self.db.get_admin_relations() + csv_header = ["id","userid","computerid"] + filename = line[2] + + if line[1].lower() == 'simple': + self.write_csv(filename,csv_header,local_admins) + + elif line[1].lower() == 'detailed': + formattedLocalAdmins = [] + + for entry in local_admins: + formattedEntry = [] # Can't modify a tuple + + #Entry ID + formattedEntry.append(entry[0]) + + #DOMAIN/Username + user = self.db.get_users(filterTerm=entry[1])[0] + formattedEntry.append(f"{user[1]}/{user[2]}") + + #Hostname + formattedEntry.append(self.db.get_computers(filterTerm=entry[2])[0][2]) + + formattedLocalAdmins.append(formattedEntry) + + self.write_csv(filename,csv_header,formattedLocalAdmins) + + + else: print('[-] invalid argument, specify creds, hosts or shares') - + def write_csv(self,filename,headers,entries): + """ + Writes a CSV file with the provided parameters. + """ + with open(os.path.expanduser(filename), 'w') as export_file: + csvFile = csv.writer(export_file,delimiter=";", quoting=csv.QUOTE_ALL, lineterminator='\n') + csvFile.writerow(headers) + for entry in entries: + csvFile.writerow(entry) + def do_import(self, line): if not line: return diff --git a/cme/protocols/smb/database.py b/cme/protocols/smb/database.py index b0e87ed3..e5420620 100755 --- a/cme/protocols/smb/database.py +++ b/cme/protocols/smb/database.py @@ -320,6 +320,9 @@ class database: elif hostID: cur.execute("SELECT * FROM admin_relations WHERE computerid=?", [hostID]) + + else: + cur.execute("SELECT * FROM admin_relations") results = cur.fetchall() cur.close() From ca48229e323ecbf5ebd1964c7bb2586c16542418 Mon Sep 17 00:00:00 2001 From: iLightThings Date: Thu, 22 Sep 2022 08:45:27 -0400 Subject: [PATCH 2/7] Refactored export shares to use new write_csv func --- cme/cmedb.py | 71 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/cme/cmedb.py b/cme/cmedb.py index 2e2d2333..c9975268 100755 --- a/cme/cmedb.py +++ b/cme/cmedb.py @@ -94,36 +94,54 @@ class DatabaseNavigator(cmd.Cmd): print("[-] invalid arguments, export shares ") return + shares = self.db.get_shares() + csv_header = ["id","computerid","userid","name","remark","read","write"] + filename = line[2] + if line[1].lower() == 'simple': - shares = self.db.get_shares() - with open(os.path.expanduser(line[2]), 'w') as export_file: - shareCSV = csv.writer(export_file, delimiter=";", quoting=csv.QUOTE_ALL, lineterminator='\n') - csv_header = ["id","computerid","userid","name","remark","read","write"] - shareCSV.writerow(csv_header) - #id|computerid|userid|name|remark|read|write - for share in shares: - shareid,hostid,userid,sharename,shareremark,read,write = share - shareCSV.writerow([shareid,hostid,userid,sharename,shareremark,read,write]) - print('[+] shares exported') + self.write_csv(filename,csv_header,shares) + + + print('[+] shares exported') elif line[1].lower() == 'detailed': #Detailed view gets hostsname, and usernames, and true false statement - shares = self.db.get_shares() - #id|computerid|userid|name|remark|read|write - with open(os.path.expanduser(line[2]), 'w') as export_file: - shareCSV = csv.writer(export_file, delimiter=";", quoting=csv.QUOTE_ALL, lineterminator='\n') - csv_header = ["id","computerid","userid","name","remark","read","write"] - shareCSV.writerow(csv_header) - for share in shares: - shareid,hostid,userid,sharename,shareremark,read,write = share + formattedShares = [] + for share in shares: + entry = [] + #shareID + entry.append(share[0]) + + #computerID + entry.append(self.db.get_computers(share[1])[0][2]) + + #userID + user = self.db.get_users(share[2])[0] + entry.append(f"{user[1]}\{user[2]}") + + #name + entry.append(share[3]) + + #remark + entry.append(share[4]) + + #read + entry.append(bool(share[5])) + + #write + entry.append(bool(share[6])) + + formattedShares.append(entry) + + self.write_csv(filename,csv_header,formattedShares) #Format is domain\user - prettyuser = f"{self.db.get_users(userid)[0][1]}\{self.db.get_users(userid)[0][2]}" + #prettyuser = f"{self.db.get_users(userid)[0][1]}\{self.db.get_users(userid)[0][2]}" #Format is hostname - prettyhost = f"{self.db.get_computers(hostid)[0][2]}" + #prettyhost = f"{}" - shareCSV.writerow([shareid,prettyhost,prettyuser,sharename,shareremark,bool(read),bool(write)]) - print('[+] shares exported') + + print('[+] shares exported') #Local Admin elif line[0].lower() == 'local_admins': @@ -140,10 +158,11 @@ class DatabaseNavigator(cmd.Cmd): self.write_csv(filename,csv_header,local_admins) elif line[1].lower() == 'detailed': + formattedLocalAdmins = [] for entry in local_admins: - formattedEntry = [] # Can't modify a tuple + formattedEntry = [] # Can't modify a tuple which is what self.db.get_admin_relations() returns. #Entry ID formattedEntry.append(entry[0]) @@ -155,14 +174,14 @@ class DatabaseNavigator(cmd.Cmd): #Hostname formattedEntry.append(self.db.get_computers(filterTerm=entry[2])[0][2]) + formattedLocalAdmins.append(formattedEntry) self.write_csv(filename,csv_header,formattedLocalAdmins) + print('[+] Local Admins exported') - - else: - print('[-] invalid argument, specify creds, hosts or shares') + print('[-] invalid argument, specify creds, hosts, local_admins or shares') def write_csv(self,filename,headers,entries): """ From fa3e4227b42791754d250663f751283c279809fb Mon Sep 17 00:00:00 2001 From: iLightThings Date: Thu, 22 Sep 2022 09:20:07 -0400 Subject: [PATCH 3/7] Refactored Hosts and Creds --- cme/cmedb.py | 58 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/cme/cmedb.py b/cme/cmedb.py index c9975268..c6a725ec 100755 --- a/cme/cmedb.py +++ b/cme/cmedb.py @@ -58,34 +58,54 @@ class DatabaseNavigator(cmd.Cmd): # Users if line[0].lower() == 'creds': if len(line) < 3: - print("[-] invalid arguments, export creds ") + print("[-] invalid arguments, export creds ") return - if line[1].lower() == 'plaintext': - creds = self.db.get_credentials(credtype="plaintext") - elif line[1].lower() == 'hashes': - creds = self.db.get_credentials(credtype="hash") - else: - creds = self.db.get_credentials() - - with open(os.path.expanduser(line[2]), 'w') as export_file: + + filename = line[2] + creds = self.db.get_credentials() + csv_header = ["id","domain","username","password","credtype","pillaged_from"] + + if line[1].lower() == "simple": + self.write_csv(filename,csv_header,creds) + + elif line[1].lower() == "detailed": + formattedCreds = [] + for cred in creds: - credid, domain, user, password, credtype, fromhost = cred - if line[1].lower() == 'csv': - export_file.write('{},{},{},{},{},{}\n'.format(credid,domain,user,password,credtype,fromhost)) + entry = [] + + entry.append(cred[0]) + entry.append(cred[1]) + entry.append(cred[2]) + entry.append(cred[3]) + entry.append(cred[4]) + + + if cred[5] == "": + entry.append("Manual") else: - export_file.write('{}\n'.format(password)) + entry.append(self.db.get_computers(cred[5])[0][2]) + formattedCreds.append(entry) + self.write_csv(filename,csv_header,formattedCreds) print('[+] creds exported') #Hosts elif line[0].lower() == 'hosts': - if len(line) < 2: - print("[-] invalid arguments, export hosts ") + if len(line) < 3: + print("[-] invalid arguments, export hosts ") return hosts = self.db.get_computers() - with open(os.path.expanduser(line[1]), 'w') as export_file: - for host in hosts: - hostid,ipaddress,hostname,domain,opsys,dc = host - export_file.write('{},{},{},{},{},{}\n'.format(hostid,ipaddress,hostname,domain,opsys,dc)) + csv_header = ["id","ip","hostname","domain","os","dc","smbv1","signing"] + filename = line[2] + + if line[1].lower() == 'simple': + self.write_csv(filename,csv_header,hosts) + + #TODO, maybe add more detail like who is an admin on it, shares discovered, ect + elif line[1].lower() == 'detailed': + self.write_csv(filename,csv_header,hosts) + + print('[+] hosts exported') #Shares From 74810a7165e978138eeb0ee32aedad8eb37f0be7 Mon Sep 17 00:00:00 2001 From: iLightThings Date: Thu, 22 Sep 2022 09:46:17 -0400 Subject: [PATCH 4/7] Added notes --- cme/cmedb.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cme/cmedb.py b/cme/cmedb.py index c6a725ec..d1f29ac8 100755 --- a/cme/cmedb.py +++ b/cme/cmedb.py @@ -74,11 +74,11 @@ class DatabaseNavigator(cmd.Cmd): for cred in creds: entry = [] - entry.append(cred[0]) - entry.append(cred[1]) - entry.append(cred[2]) - entry.append(cred[3]) - entry.append(cred[4]) + entry.append(cred[0]) # ID + entry.append(cred[1]) # Domain + entry.append(cred[2]) # Username + entry.append(cred[3]) # Password/Hash + entry.append(cred[4]) # Cred Type if cred[5] == "": From 7daaed784703faec90b8c9e7e8daa744fc4ef448 Mon Sep 17 00:00:00 2001 From: iLightThings Date: Thu, 22 Sep 2022 10:31:18 -0400 Subject: [PATCH 5/7] Fixed a gltich where creds where manually entired. --- cme/cmedb.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cme/cmedb.py b/cme/cmedb.py index d1f29ac8..8d44a4dd 100755 --- a/cme/cmedb.py +++ b/cme/cmedb.py @@ -55,6 +55,7 @@ class DatabaseNavigator(cmd.Cmd): line = line.split() # Need to use if/elif/else to keep compatibility with py3.8/3.9 + # Reference DB Function cme/protocols/smb/database.py # Users if line[0].lower() == 'creds': if len(line) < 3: @@ -80,12 +81,12 @@ class DatabaseNavigator(cmd.Cmd): entry.append(cred[3]) # Password/Hash entry.append(cred[4]) # Cred Type - - if cred[5] == "": - entry.append("Manual") + print(cred[5]) + if cred[5] == None: + entry.append("") else: entry.append(self.db.get_computers(cred[5])[0][2]) - formattedCreds.append(entry) + formattedCreds.append(entry) self.write_csv(filename,csv_header,formattedCreds) print('[+] creds exported') From 2077deae5aabdd7e28279bc988d7bf04aa230841 Mon Sep 17 00:00:00 2001 From: iLightThings Date: Thu, 22 Sep 2022 10:31:43 -0400 Subject: [PATCH 6/7] Removed Print --- cme/cmedb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cme/cmedb.py b/cme/cmedb.py index 8d44a4dd..39c4cd68 100755 --- a/cme/cmedb.py +++ b/cme/cmedb.py @@ -81,7 +81,7 @@ class DatabaseNavigator(cmd.Cmd): entry.append(cred[3]) # Password/Hash entry.append(cred[4]) # Cred Type - print(cred[5]) + if cred[5] == None: entry.append("") else: From 854becfcd4d520b9caf97de6b6224cd66414ede6 Mon Sep 17 00:00:00 2001 From: iLightThings Date: Fri, 23 Sep 2022 11:28:16 -0400 Subject: [PATCH 7/7] Changed computerID to computer --- cme/cmedb.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cme/cmedb.py b/cme/cmedb.py index 39c4cd68..3d6638cc 100755 --- a/cme/cmedb.py +++ b/cme/cmedb.py @@ -116,7 +116,7 @@ class DatabaseNavigator(cmd.Cmd): return shares = self.db.get_shares() - csv_header = ["id","computerid","userid","name","remark","read","write"] + csv_header = ["id","computer","userid","name","remark","read","write"] filename = line[2] if line[1].lower() == 'simple': @@ -132,7 +132,7 @@ class DatabaseNavigator(cmd.Cmd): #shareID entry.append(share[0]) - #computerID + #computer entry.append(self.db.get_computers(share[1])[0][2]) #userID @@ -172,7 +172,7 @@ class DatabaseNavigator(cmd.Cmd): # These Values don't change between simple and detailed local_admins = self.db.get_admin_relations() - csv_header = ["id","userid","computerid"] + csv_header = ["id","userid","computer"] filename = line[2] if line[1].lower() == 'simple':