Skip to content

@odata.nextLink issue #2

Open
Open

Description

@SeiV-K

Hi!
First of all, i got so say that's a great tool !
I tried to dump the users from a domain with multiple users that normally causes the paging in responses. Though, I figured out that the get-user command doesn't handle @odata.nextLink so it only returns the users form the first page. Any plan to fix this ? :)
P.S1 : netLinks are n ot handled for any enum command :/ So, enumerating in large domains with multiple users / groups / applications etc will cause missing a lot

Activity

  1. SeiV-K commented on Mar 30, 2025

    @SeiV-K
    Author

    Ah, i just noticed it's on your TODO list :)

  2. mlcsec commented on Apr 2, 2025

    @mlcsec
    Owner

    This works I've just not had a chance to push everything yet:

    def get_user(args):
        print_yellow("[*] Get-User")
        print("=" * 80)
        
        api_url = "https://graph.microsoft.com/v1.0/users"
        
        if args.id:
            api_url = f"https://graph.microsoft.com/v1.0/users/{args.id}"
        if args.select:
            api_url += "?$select=" + args.select
        
        user_agent = get_user_agent(args)
        access_token = get_access_token(args.token)
        headers = {
            'Authorization': f'Bearer {access_token}',
            'User-Agent': user_agent
        }
        
        while api_url:
            response = requests.get(api_url, headers=headers)
            
            if response.status_code == 200:
                response_json = response.json()
                
                # If an ID is provided, print details for that user
                if args.id:
                    for key, value in response_json.items():
                        if key != "@odata.context":
                            print(f"{key}: {value}")
                else:
                    if 'value' in response_json:
                        for user in response_json['value']:
                            for key, value in user.items():
                                print(f"{key}: {value}")
                            print()
                    else:
                        print_red("[-] No users found or unexpected response format")
                
                # Check if there is a nextLink for the next page of results
                api_url = response_json.get('@odata.nextLink', None)
            else:
                print_red(f"[-] Failed to retrieve user(s): {response.status_code}")
                print_red(response.text)
                break  # Stop if there's an error
        
        print("=" * 80)
    	
    	
    ### ...
    
    def get_group(args):
        print_yellow("[*] Get-Group")
        print("=" * 80)
        
        api_url = "https://graph.microsoft.com/v1.0/groups"
        
        if args.id:
            api_url = f"https://graph.microsoft.com/v1.0/groups/{args.id}"
        if args.select:
            api_url += "?$select=" + args.select
        
        user_agent = get_user_agent(args)
        headers = {
            'Authorization': f'Bearer {get_access_token(args.token)}',
            'User-Agent': user_agent
        }
        
        while api_url:
            response = requests.get(api_url, headers=headers)
            
            if response.status_code == 200:
                response_json = response.json()
                
                # Print details for a specific group if an ID is provided
                if args.id:
                    for key, value in response_json.items():
                        if key != "@odata.context":
                            print(f"{key}: {value}")
                else:
                    if 'value' in response_json:
                        for group in response_json['value']:
                            for key, value in group.items():
                                print(f"{key}: {value}")
                            print()
                    else:
                        print_red("[-] No groups found or unexpected response format")
                
                # Check if there is a next link to fetch more results
                api_url = response_json.get('@odata.nextLink', None)
            else:
                print_red(f"[-] Failed to retrieve group(s): {response.status_code}")
                print_red(response.text)
                break  # Stop if there's an error
                
        print("=" * 80)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions