sqlmap peut être considéré comme un artefact de détection d'injection SQL, mais l'efficacité de l'utilisation de sqlmap pour tester l'injection SQL est très faible et chaque URL doit être testée manuellement. Les développeurs de sqlmap ont ajouté sqlmapapi.py, qui peut être utilisé directement via des appels d'interface, simplifiant ainsi l'exécution des commandes sqlmap.
sqlmap api est divisé en serveur et client. sqlmap api a deux modes, l'un est le mode d'interface basé sur le protocole HTTP et l'autre est le mode d'interface basé sur la ligne de commande.
adresse de téléchargement du code source sqlmap : https://github.com/sqlmapproject/sqlmap/
python sqlmapapi.py. - h
Avant d'utiliser le service API, vous devez d'abord démarrer le serveur API, qu'il soit basé sur le protocole HTTP. ou un modèle d'interface basé sur une ligne de commande. Pour démarrer le serveur API, exécutez simplement la commande suivante : python sqlmapapi.py -s
Une fois la commande réussie, certaines informations seront renvoyées dans la ligne de commande. La commande suivante signifie à peu près que le serveur API s'exécute sur le port local 8775 et que le jeton d'administrateur est c6bbb0c1f86b7d7bc2ed6ce3e3bbdcb5, etc.
Cependant, il y a un inconvénient à ouvrir le serveur API dans de la manière ci-dessus. Lorsque le service Si le client et le client ne sont pas sur le même hôte, ils ne pourront pas se connecter. Par conséquent, si vous souhaitez résoudre ce problème, vous pouvez ouvrir le serveur API en entrant la commande suivante : python. sqlmapapi.py -s -H "0.0.0.0" -p 8775#🎜🎜 #
Une fois la commande réussie, le client distant peut se connecter au serveur API en spécifiant l'adresse IP et le port de l'hôte distant. 3. Mode d'interface basé sur la ligne de commande3.1 Ouvrez le client et lancez la commande d'injectionpython sqlmapapi.py. - cSi le client et le serveur ne sont pas le même ordinateur, saisissez la commande suivante :
python sqlmapapi.py -c -H " 192.168.1.101" -p 87753.2, commande d'aide, obtenir toutes les commandes
help 显示帮助信息 new ARGS 开启一个新的扫描任务 use TASKID 切换 taskid data 获取当前任务返回的数据 log 获取当前任务的扫描日志 status 获取当前任务的扫描状态 option OPTION 获取当前任务的选项 options 获取当前任务的所有配置信息 stop 停止当前任务 kill 杀死当前任务 list 显示所有任务列表 flush 清空所有任务 exit 退出客户端
3.3.1.new command
new -u "url" Exemple : new -u "http://www.baidu.com"Bien que nous ayons uniquement spécifié le paramètre -u, il ressort des informations renvoyées que la saisie de new Après l'émission la commande /task/new est d'abord demandée pour créer un nouvel ID de tâche, puis une demande est émise pour démarrer la tâche. Par conséquent, on peut constater que l'essence de ce mode est également basée sur le protocole HTTP.
3.3.2. Commande d'état
Obtenir l'état d'analyse de la tâche, if Si le champ d'état dans le contenu renvoyé est terminé, cela signifie que l'analyse est terminée. Si le champ d'état dans le contenu renvoyé est exécuté, cela signifie que l'analyse est toujours en cours. L'image suivante est une capture d'écran de l'analyse terminée :3.3.3 commande de données
Si le champ de données est dans les données renvoyées ne le sont pas. Si elles sont vides, on peut conclure que l'injection a réussi. Cet exemple montre un contenu de retour contenant une injection SQL, qui contient des informations telles que le type de base de données, la charge utile et les paramètres d'injection. 4. Mode d'interface basé sur le protocole HTTP Présentez brièvement le h de sqlmapapi.py basé sur l'appel de l'interface http mode La fonction principale, entrant dans la classe serveur de lib/utils/api.py, peut interagir avec le service en soumettant des données au serveur. Il existe 3 types au total.Méthodes des utilisateurs Méthode utilisateurFonction d'administration Fonction de gestionfonctions d'interaction de base de SQLmap Fonction d'interaction de baseLes types de données qui peuvent être soumis sont les suivants :#🎜 🎜#
4.1, méthode utilisateur
@get("/task/new") def task_new(): """ Create a new task """ taskid = encodeHex(os.urandom(8), binary=False) remote_addr = request.remote_addr DataStore.tasks[taskid] = Task(taskid, remote_addr) logger.debug("Created new task: '%s'" % taskid) return jsonize({"success": True, "taskid": taskid})
@get("/task/delete")
@get("/task/<taskid>/delete") def task_delete(taskid): """ Delete an existing task """ if taskid in DataStore.tasks: DataStore.tasks.pop(taskid) logger.debug("(%s) Deleted task" % taskid) return jsonize({"success": True}) else: response.status = 404 logger.warning("[%s] Non-existing task ID provided to task_delete()" % taskid) return jsonize({"success": False, "message": "Non-existing task ID"})</taskid>
4.2, fonction interactive de base#🎜🎜 #
@post("/option/get")@post("/ option/set")@get("/scan/stop")#🎜🎜 #@post("/option/<taskid>/set") def option_set(taskid): """ Set value of option(s) for a certain task ID """ if taskid not in DataStore.tasks: logger.warning("[%s] Invalid task ID provided to option_set()" % taskid) return jsonize({"success": False, "message": "Invalid task ID"}) if request.json is None: logger.warning("[%s] Invalid JSON options provided to option_set()" % taskid) return jsonize({"success": False, "message": "Invalid JSON options"}) for option, value in request.json.items(): DataStore.tasks[taskid].set_option(option, value) logger.debug("(%s) Requested to set options" % taskid) return jsonize({"success": True})</taskid>Copier après la connexion@post("/scan/start")
@post("/scan/<taskid>/start") def scan_start(taskid): """ Launch a scan """ if taskid not in DataStore.tasks: logger.warning("[%s] Invalid task ID provided to scan_start()" % taskid) return jsonize({"success": False, "message": "Invalid task ID"}) if request.json is None: logger.warning("[%s] Invalid JSON options provided to scan_start()" % taskid) return jsonize({"success": False, "message": "Invalid JSON options"}) # Initialize sqlmap engine's options with user's provided options, if any for option, value in request.json.items(): DataStore.tasks[taskid].set_option(option, value) # Launch sqlmap engine in a separate process DataStore.tasks[taskid].engine_start() logger.debug("(%s) Started scan" % taskid) return jsonize({"success": True, "engineid": DataStore.tasks[taskid].engine_get_id()})</taskid>Copier après la connexion
@get("/scan/<taskid>/stop") def scan_stop(taskid): """ Stop a scan """ if (taskid not in DataStore.tasks or DataStore.tasks[taskid].engine_process() is None or DataStore.tasks[taskid].engine_has_terminated()): logger.warning("[%s] Invalid task ID provided to scan_stop()" % taskid) return jsonize({"success": False, "message": "Invalid task ID"}) DataStore.tasks[taskid].engine_stop() logger.debug("(%s) Stopped scan" % taskid) return jsonize({"success": True})</taskid>
@get("/scan/<taskid>/kill") def scan_kill(taskid): """ Kill a scan """ if (taskid not in DataStore.tasks or DataStore.tasks[taskid].engine_process() is None or DataStore.tasks[taskid].engine_has_terminated()): logger.warning("[%s] Invalid task ID provided to scan_kill()" % taskid) return jsonize({"success": False, "message": "Invalid task ID"}) DataStore.tasks[taskid].engine_kill() logger.debug("(%s) Killed scan" % taskid) return jsonize({"success": True})</taskid>
@get("/scan/<taskid>/status") def scan_status(taskid): """ Returns status of a scan """ if taskid not in DataStore.tasks: logger.warning("[%s] Invalid task ID provided to scan_status()" % taskid) return jsonize({"success": False, "message": "Invalid task ID"}) if DataStore.tasks[taskid].engine_process() is None: status = "not running" else: status = "terminated" if DataStore.tasks[taskid].engine_has_terminated() is True else "running" logger.debug("(%s) Retrieved scan status" % taskid) return jsonize({ "success": True, "status": status, "returncode": DataStore.tasks[taskid].engine_get_returncode() })</taskid>
@get("/scan/<taskid>/data") def scan_data(taskid): """ Retrieve the data of a scan """ json_data_message = list() json_errors_message = list() if taskid not in DataStore.tasks: logger.warning("[%s] Invalid task ID provided to scan_data()" % taskid) return jsonize({"success": False, "message": "Invalid task ID"}) # Read all data from the IPC database for the taskid for status, content_type, value in DataStore.current_db.execute("SELECT status, content_type, value FROM data WHERE taskid = ? ORDER BY id ASC", (taskid,)): json_data_message.append({"status": status, "type": content_type, "value": dejsonize(value)}) # Read all error messages from the IPC database for error in DataStore.current_db.execute("SELECT error FROM errors WHERE taskid = ? ORDER BY id ASC", (taskid,)): json_errors_message.append(error) logger.debug("(%s) Retrieved scan data and error messages" % taskid) return jsonize({"success": True, "data": json_data_message, "error": json_errors_message})</taskid>
@get("/scan/log")
@get("/download/")
4.3, fonction de gestion#🎜🎜 #
@get("/admin/list")@get("/admin/list") @get("/admin/<token>/list") def task_list(token=None): """ Pull task list """ tasks = {} for key in DataStore.tasks: if is_admin(token) or DataStore.tasks[key].remote_addr == request.remote_addr: tasks[key] = dejsonize(scan_status(key))["status"] logger.debug("(%s) Listed task pool (%s)" % (token, "admin" if is_admin(token) else request.remote_addr)) return jsonize({"success": True, "tasks": tasks, "tasks_num": len(tasks)})</token>
@get("/admin/flush") @get("/admin/<token>/flush") def task_flush(token=None): """ Flush task spool (delete all tasks) """ for key in list(DataStore.tasks): if is_admin(token) or DataStore.tasks[key].remote_addr == request.remote_addr: DataStore.tasks[key].engine_kill() del DataStore.tasks[key] logger.debug("(%s) Flushed task pool (%s)" % (token, "admin" if is_admin(token) else request.remote_addr)) return jsonize({"success": True})</token>
sqlmapapi.py fournit commodément une entrée de requête http, mais lorsqu'il est utilisé, vous ne pouvez obtenir que le résultat final, savoir s'il faut injecter ou non chaque interface. est spécifique lors de l'exécution d'une analyse par injection. Il est difficile de savoir quel type de requête est lancé et combien de requêtes sont effectuées. Permettez-moi de partager l'organigramme enregistré après avoir personnellement trié le code source de sqlmap. À partir de la figure, vous pouvez localiser l'emplacement spécifique de la requête au niveau de la charge utile. Si vous souhaitez savoir quel type de requête a été lancé et combien de requêtes, il vous suffit d'ajouter du code personnalisé ici.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!