Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aces missing from Users.json?? - version 2 (BloodhoundCE) #25

Open
LarsVonZipper opened this issue Jan 4, 2024 · 8 comments
Open

Aces missing from Users.json?? - version 2 (BloodhoundCE) #25

LarsVonZipper opened this issue Jan 4, 2024 · 8 comments
Assignees

Comments

@LarsVonZipper
Copy link

Hi,
It's probably me but ...,

When I use Rusthound from the v2-branch, there seems to be numerous 'missing' Aces in the users.json when I compare the results to those captured using rusthound from the main-branch version??

For example, there is a user account that has “Write all properties” access that applies to “Descendant User objects” set on the domain object.

With data collected using the main-branch Rusthound, all users in that domain have an Ace that referenced the said user account as having “IsInherited: true”, “GenericWrite” (correct). Whereas, data collected using the v2-branch Rusthound failed to record this on any user account?

Then, when I took a random user from data collected using the main-branch version, there were 68 Aces recorded. Data for the same user, collected at the same time using the v2-branch version only recorded 52.

Obviously the specific numbers are relative to the domain but the fact there was a large discrepancy worried me a little

@g0h4n g0h4n self-assigned this Jan 8, 2024
@g0h4n
Copy link
Collaborator

g0h4n commented Jan 8, 2024

Hi @LarsVonZipper,

I'll be analysing this more in detail during the week. Thank you for the information. 👍

@LarsVonZipper
Copy link
Author

Thanks @g0h4n I appreciate it. Let me know if I can help in someway.
Keep up the excellent work!

@LarsVonZipper
Copy link
Author

Hey @g0h4n,
Didn't know if the attached might be of some help??

The .CSV files are a bit redacted but hopefully you get the gist. They are the "Aces" component of the same user collected with the older and newer (v2) version of RustHound.
The screenshot's just show the difference in file sizes of the collected .JSON files comparing the older version of RustHound with the newer (v2)

Regards
Lars

oldRustHound
newRustGound
Old-UserAcesRedacted.csv
New-UserAcesRedacted.csv

@g0h4n
Copy link
Collaborator

g0h4n commented Jan 11, 2024

Thanks for all the additional information, I appreciate it, it should help me! 😄

@g0h4n
Copy link
Collaborator

g0h4n commented Jan 15, 2024

@LarsVonZipper,

I was unable to reproduce the issue
I used v1.1.69 and v2.0.0 to generate the JSON files and passed them to the following python script to retrieve only the ACLs. . However, v1 and v2 files have the same ACEs on the MayFly GOAD lab.

Could you please pass the JSON files into the script and send me the two examples?

#!/usr/bin/python3
import json
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-f', action='store',
                     metavar='<JSON_filename>',
                     help='JSON file',
                     required=True)
parser.add_argument('-V', action='store',
                     metavar='<v1 or v2>',
                     help='Version',
                     required=True)
args = parser.parse_args()
filename = vars(args)['f']
version = vars(args)['V']

print("[?] filename: ",filename)
print("[?] version: ",version)

with open(filename, "r") as f:
	datas = json.load(f)
	for jsonObj in datas["data"]:
		name = jsonObj["Properties"]["name"]
		aces = jsonObj["Aces"]
		print("[+] Name '"+name+"' parsed")
		#print("[?] Aces: ",aces)
		with open(name+"_"+version+".json","w") as f2:
			f2.write(str(aces))
			f2.close
			print("[+] File '"+name+"_"+version+".json"+"' created")

Example:

#v1.1.69
python3 parse_json.py -f v1.1.69/2024xxxxxxxxxx_essos-local_users.json -V v1

#v2.0.0
python3 parse_json.py -f v2.0.0/2024xxxxxxxxxx_essos-local_users.json -V v2

@LarsVonZipper
Copy link
Author

Thanks for the update @g0h4n
On one hand I'm glad you didn't find any discrepancies but on the other.....
I'm more than willing to provide information on the user.json files returned. However, in my scenario I'm dealing with nearly 8000 users; the python script outputs a JSON file for each. Also, I'd need to redact the principalSid information somehow.
Any thoughts?

@g0h4n
Copy link
Collaborator

g0h4n commented Jan 15, 2024

This version allows you to add a limit on the number of users to parse and I've added a reglex to automatically replace the contents of the SID in order to anonymise it.

#!/usr/bin/python3
import json
import argparse
import re

parser = argparse.ArgumentParser()
parser.add_argument('-f', action='store',
                     metavar='<JSON_filename>',
                     help='JSON file',
                     required=True)
parser.add_argument('-V', action='store',
                     metavar='<v1 or v2>',
                     help='Version',
                     required=True)
parser.add_argument('-n', type=int,
                     action='store',
                     metavar='<integer>',
                     help='Number users like -n 10',
                     required=True)

args = parser.parse_args()
filename = vars(args)['f']
version = vars(args)['V']
number = vars(args)['n']

print("[?] filename: ",filename)
print("[?] version: ",version)
print("[?] limit: ",str(number))

with open(filename, "r") as f:
	datas = json.load(f)
	cpt = 0
	for jsonObj in datas["data"]:
		if cpt == number:
			exit()
		try:
			name = re.sub(r'@([a-zA-Z0-9]+.[a-zA-Z0-9]+)', '@ANONYMOUS.LOCAL', str(jsonObj["Properties"]["name"]))
		except:
			name = jsonObj["Properties"]["name"]
		aces = jsonObj["Aces"]
		aces = re.sub(r'S-1-5-21-(\d+-\d+\-\d+)', 'S-1-5-21-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx', str(aces))
		aces = re.sub(r'([a-zA-Z0-9]+.[a-zA-Z0-9]+)-S-', 'ANONYMOUS.LOCAL-S-', str(aces))		
		print("["+str(cpt+1)+"] Name '"+name+"' parsed")
		#print("[?] Aces: ",aces)
		with open(name+"_"+version+".json","w") as f2:
			f2.write(str(aces))
			f2.close
			print("["+str(cpt+1)+"] File '"+name+"_"+version+".json"+"' created")
		cpt += 1

Examples:

#v1.1.69
python3 parse_json.py -f v1.1.69/2024xxxxxxxxxx_essos-local_users.json -V v1 -n 10

#v2.0.0
python3 parse_json.py -f v2.0.0/2024xxxxxxxxxx_essos-local_users.json -V v2 -n 10

Could you please make sure you send me the users where the ACEs are different?

@LarsVonZipper
Copy link
Author

Please see attached.
I have sent 10 user accounts as an initial sample. Please let me know if you require more or any more details.
Many thanks
Rusthound_v1_Results.tar.gz
Rusthound_v2_Results.tar.gz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants