Seit 2015 bietet WordPress auch ein REST API an, diese ist in jeder Version standardmäßig aktiv und benötigt zur Nutzung keine weitere Authentifizierung. Diesen Umstand habe ich mir zunutze gemacht und ein Programm verfasst, welches sämtliche Benutzernamen einer WordPress-Webseite ausliest. Etwas weiter gedacht könnte man die auf diese Weise erhaltenen Benutzernamen sicherlich für einen Brute-Force-Angriff auf WordPress Webseiten nutzen.
Generell ist das Programm aber auch ein schönes Beispiel für den Zugriff auf eine solche REST API.
Das Programm ist objektorientiert aufgebaut und besteht aus einer Main.py, welche das eigentliche Programm enthält, sowie einer Datei mit Klassen und Methoden (classes.py). Alle Einstellungen werden innerhalb der Datei program_settings.py vorgenommen.
Main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #!/usr/bin/python # -*- coding: utf-8 -*- import json # For Parsing import sys # For clean Program Exit import requests # HTTP_Request to API import logging # Error Logging import classes as myclasses # Classes of this Program import program_settings as config #My Settings_file #Enable Errorlogging with Settings from program_settings.py config.set_logdir() logger = logging.getLogger('') # Load the Target-URL from program_settings.py url = config.target # # Query the API response = requests.get(url + '//wp-json/wp/v2/users', allow_redirects = False) data = response.text # The request body # load the json to a string resp = json.loads(data) # Handover HTTP Status Code to Class in config CallClass = myclasses.OutputTTY(response.status_code) #Formatted Output if response.status_code == 200: CallClass.OnSuccess() #Begin Logging logger.info('---BOF---') logger.info('Usernames retrieved:') logger.debug(resp) logger.debug ('Available Keys in JSON-Dictionary:') logger.debug (resp[0].keys()) # Give out all Usernames to TTY and LogFile for i in resp: print (i['slug']) logger.debug('Got Username:') logger.info(i['slug']) logger.info('---EOF---') sys.exit() else: if resp['code'] =='rest_no_route': CallClass.OnError() else: CallClass.OnError() logger.info(data) sys.exit() |
program_settings.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #!/usr/bin/python # -*- coding: utf-8 -*- import logging # error logging import os # fancy paths # Change the Target-URL here target = 'http://192.168.2.173' def set_logdir(): # Define the Path for logging relative to the current Workingdirectory (current Workindirectory\\logs\[LOGFILE}]) log_dir = os.path.join(os.path.normpath(os.getcwd() + os.sep), 'logs') log_fname = os.path.join(log_dir, 'wp_api.log') # Set Loglevel and specify logging to file logging.basicConfig(format='%(asctime)s %(levelname)-8s %(message)s', level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S', filename=log_fname) |
classes.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #!/usr/bin/python # -*- coding: utf-8 -*- from colorama import Fore, Style #Terminal_Colours # Defining a class class OutputTTY: #Retrieve Values from main.py def __init__(self, HTTP_STATUS_CODE): #self.course = course self.HTTP_STATUS_CODE = HTTP_STATUS_CODE #create output for main.py def OnError(self): print ('-------------------------') print (Fore.RED +"Failure ! -- Couldn't reach API.") print (Fore.WHITE +'Errorcode:', Fore.YELLOW +'HTTP', self.HTTP_STATUS_CODE) print(Style.RESET_ALL) print ('-------------------------') def OnSuccess(self): print (Fore.WHITE +'-------------------------') print (Fore.GREEN +'Success!', Fore.WHITE +'The API is reachable --', Fore.GREEN +'Recieved: HTTP', self.HTTP_STATUS_CODE) print (Fore.WHITE +'-------------------------') print (Fore.WHITE +'Retrieving Usernames...') print (Fore.WHITE +'-------------------------') print (Fore.GREEN +'Usernames retrieved:') print ('') print(Style.RESET_ALL) |
Das gesamte Programm kann hier heruntergeladen werden.