
0dAPI Documentation officielle
Commencez !
pip install zerodai==0.0.0.20
export zerodapi_key="TU_API_KEY"
Obtenez votre clé API https://zerodai.com Chat Conversationnel Simple - Sans mémoire
from zerodai import zerodai
import os
zerodai.api_auth(os.getenv("zerodapi_key"))
messages = []
while True:
prompt = input("> ")
if prompt == "exit":
break
messages.append({"role": "user", "content": prompt})
messages.append({"role": "system", "content": "Eres 0dAI un asistente de ciberseguridad cuya unica función es..."})
zerodai.inference(model="0dai70b", messages=messages, temperature=0.7, stream=True)
Zerodai est une bibliothèque de traitement du langage naturel orientée vers la cybersécurité qui cherche à automatiser partiellement des processus basés sur le traitement humain de l'information, le raisonnement, la planification et l'exécution. Nous cherchons à créer un framework d'agents pour la cybersécurité avec les capacités suivantes :
C'est la méthode de base d'interaction avec le modèle et elle dispose des paramètres suivants. Il est important d'apprendre et de comprendre ces paramètres car ils sont la base de la bibliothèque.
model : Le modèle de langage à utiliser. Les modèles disponibles sont :
0dai7b : Modèle basique avec utilisation illimitée, rapide et parfait pour des conversations simples et de l'aide en programmation. Il défend bien en cybersécurité.
0dai8x7b : Modèle flexible avec une grande fenêtre de contexte, au niveau de GPT-4 en matière de code, bon pour les questions et scripts complexes de cybersécurité.
0daifn : Modèle recommandé pour les appels de fonctions, le meilleur en appels de fonctions, beaucoup de contexte, plus léger que 0dai70b, et en plus, au niveau des appels de fonctions multipas, il est au niveau des meilleurs GPT
0dai70b (Recommandé) : Actuellement SOTA en cybersécurité, capable d'effectuer des raisonnements logiques complexes basés sur beaucoup de contexte et de résoudre des tests de pentesting de manière semi-autonome. Il dispose d'appels de fonctions et peut répondre en messages structurés. C'est le plus lent mais il offre un grand bond en qualité.
messages : Les messages qui seront envoyés au modèle. Ici, nous devons comprendre 3 rôles :
Les messages doivent être dans ce format :
messages = [
{"role": "system", "content": """Eres 0dAI tu función es..."""},
{"role": "user", "content": "0dAI escribe un exploit en C"},
]
functions : Les fonctions qui peuvent être appelées pendant l'interaction. Nous entrerons plus dans les détails dans fn_c. Dans ce cas, cela nous donnera simplement le JSON.
Une fonction se déclare ainsi :
function_shodan = [ {
"name": "shodan_dork",
"description": "This tools is used to generate a shodan query",
"parameter_definitions": {
"dork": {
"type": "string",
"description": "The shodan dork",
"required": True
}
}
}, ]
temperature : Contrôle l'aléatoire des réponses du modèle. Plus la température est élevée, plus il y a d'aléatoire ; plus elle est basse, moins il y en a.
stream (bool) : Si la réponse doit être transmise en temps réel.
from zerodai import zerodai
messages = []
messages.append({"role": "user", "content": prompt})
messages.append({"role": "system", "content": "Eres 0dAI un asistente de ciberseguridad cuya unica función es..."})
zerodai.inference(model="0dai70b", messages=messages, temperature=0.7, stream=True)
En se basant sur une fonction ou une liste de fonctions dans le paramètre function, le modèle sera capable de générer une réponse structurée qui peut nous servir après une inférence : Fonction de base
function_shodan = [ {
"name": "shodan_dork",
"description": "This tools is used to generate a shodan query",
"parameter_definitions": {
"dork": {
"type": "string",
"description": "The shodan dork",
"required": True
}
}
}, ]
Réponse du modèle basée sur cette fonction
[
{
"tool_name": "shodan_dork",
"parameters": {
"dork": "hacked-router-help-sos"
}
}
]
Ces fonctions peuvent être multipas ou non, cela sera défini par le nombre de positions du JSON, une réponse multipas ressemble à ceci :
[
{
"tool_name": "shodan_dork",
"parameters": {
"dork": "hacked-router-help-sos"
}
},
{
"tool_name": "shodan_dork",
"parameters": {
"dork": "\"smb\" \"authentication: disabled\""
}
},
{
"tool_name": "shodan_dork",
"parameters": {
"dork": ".docuword_exploited.txt"
}
}
]
Il peut également exister une logique récursive entre inférence et fonction qui se rétroalimentent, imaginons ce cas :
Fonction sous-domaines
funcion_subdomains = [ {
"name": "subdominios",
"description": "This tools is used to collect domains to extract subdomains",
"parameter_definitions": {
"domain": {
"type": "string",
"description": "The domain",
"required": True
}
}
}, ]
Fonction crawler
crawler_endpoints = [ {
"name": "crawler",
"description": "This tools is used to crawle ndpoints for a host",
"parameter_definitions": {
"host": {
"type": "string",
"description": "The domain",
"required": True
}
}
}, ]
Entrée :
J'ai besoin d'obtenir les sous-domaines de openai.com et omegaai.io
Sortie 1. Fonction :
[
{
"tool_name": "subdomains",
"parameters": {
"domain": "openai.com"
}
},
{
"tool_name": "subdomains",
"parameters": {
"domain": "omegaai.io"
}
},
]
Après avoir extrait les sous-domaines de l'entrée, nous appliquons notre logique d'exécution qui consisterait à obtenir les sous-domaines...
subdomain1.openai.com
subdomain2.openai.com
subdomain3.openai.com
subdomain1.omegaai.io
subdomain2.omegaai.io
subdomain3.omegaai.io
Après avoir passé cela à la fonction du crawler, cela donnerait quelque chose comme :
Sortie 2. Fonction :
[
{
"tool_name": "crawler",
"parameters": {
"domain": "subdominio1.openai.com"
}
},
{
"tool_name": "crawler",
"parameters": {
"domain": "subdominio1.omegaai.io"
}
},
{
"tool_name": "crawler",
"parameters": {
"domain": "subdominio2.openai.com"
}
},
{
"tool_name": "crawler",
"parameters": {
"domain": "subdominio2.omegaai.io"
}
},
{
"tool_name": "crawler",
"parameters": {
"domain": "subdominio3.openai.com"
}
},
{
"tool_name": "crawler",
"parameters": {
"domain": "subdominio3.omegaai.io"
}
},
]
fn_c Ce qu'il nous permet, c'est de collecter les paramètres et le nom de l'outil directement sans avoir à passer par cette logique de filtrage du JSON lui-même.
###Utilisation
from zerodai import zerodai
zerodai.api_auth("TU_API_KEY")
tool_name, parameters = zerodai.fn_c(model_fn=model_fn_call, messages=messages, functions=subdomain_functions, stream=stream, multistep=False)
print(tool_name)
print(parameters)
print(parameters["domain"])
Note : Le standard des fonctions est généralement OpenAI, c'est pourquoi nous avons conçu une fonction qui convertit les fonctions OpenAI vers notre propre format, exemple :
tool_name, parameters = cls.fn_c(model_fn=model_fn_call, messages=messages, functions=OpenAI2CommandR(osint_funcs), stream=stream, multistep=False)
Zerodai inclut un système d'agents qui peut être étendu via des fonctions et un module d'exécution.
def exec_module(tool, arguments, multitool=True):
output = ""
if tool == "Shodan":
process = subprocess.Popen(["nmap", "-Pn", next(iter(arguments.values()))], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in iter(process.stdout.readline, b''):
output += line.decode('utf-8').strip()
print(line.decode('utf-8').strip())
elif tool == "XSS-Scanner" or tool == "nuclei-http":
try:
process = subprocess.Popen(["nuclei", "-t", "dns", next(iter(arguments.values()))], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd="/home/omegaleitatadmin/exllamav2/0dAPI/nuclei-templates/nuclei-templates-9.8.6/")
for line in iter(process.stdout.readline, b''):
output += line.decode('utf-8').strip()
print(line.decode('utf-8').strip())
except:
pass
elif tool == "WAF-tool":
process = subprocess.Popen(["python3", "whatwaf", "-u", "https://" + next(iter(arguments.values()))], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd="/home/omegaleitatadmin/exllamav2/0dAPI/WhatWaf")
for line in iter(process.stdout.readline, b''):
output += line.decode('utf-8').strip()
print(line.decode('utf-8').strip())
elif tool == "Attack":
process = subprocess.Popen(["nmap", "-Pn", next(iter(arguments.values()))], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in iter(process.stdout.readline, b''):
output += line.decode('utf-8').strip()
print(line.decode('utf-8').strip())
elif tool == "OSINT":
ZeroDAI.Osint(next(iter(arguments.values())))
return output
Ce code doit aller de pair avec les fonctions utilisées.
python_functions = [ {
"name": "Shodan",
"description": "tool for shodan",
"parameter_definitions": {
"ip": {
"type": "string",
"description": "The ip",
"required": True
}
}
},
{
"name": "nuclei-http",
"description": "This tools is use for nuclei",
"parameter_definitions": {
"target": {
"type": "string",
"description": "The domain",
"required": True
}
}
},
{
"name": "WAF-tool",
"description": "This tools is used for waf",
"parameter_definitions": {
"webapp": {
"type": "string",
"description": "The webapp",
"required": True
}
}
},
{
"name": "Attack",
"description": "This tools is used to attack a host",
"parameter_definitions": {
"host": {
"type": "string",
"description": "The domain",
"required": True
}
}
}, ]
Cela permet de créer des agents dynamiques multipas et multi-outils.
###Utilisation
zerodai.agent(model="0dai70b",
messages=messages,
model_fn_call="0daifn",
temperature=0.7,
functions=python_functions,
exec_module=exec_module,
exec_module_bool=True,
multistep=True)
exec_module-bool pour indiquer si nous voulons utiliser un module d'exécution (Si on met True et pas de module d'exécution, il en exécutera un par défaut).
exec_module module d'exécution
functions Fonctions en accord avec le module d'exécution
multistep Si nous voulons que plusieurs étapes soient exécutées à chaque itération du modèle d'appels de fonctions
##Preuves de concept
Cette API est livrée avec des intégrations de Shodan, plusieurs services de données, Censys et bien plus encore, ces services ne nécessitent que l'API de 0dAI :
zerodai.Osint(prompt)
prompt - Simple message en langage naturel pour que le LLM effectue une recherche dans nos sources privées de fuites de données et vous donne les fuites d'un utilisateur
zerodai.Osint(prompt)
prompt - Simple message en langage naturel pour que le LLM effectue une recherche dans Shodan et vous donne les résultats directement
zerodai.rubberducky_gen(prompt)
prompt - Simple message en langage naturel pour que le LLM génère un payload valide de Rubber Ducky
Cette API a été entièrement développée par Luijait (Luis Javier Navarrete Lozano) sous 0dAI. Si les connaissances décrites ici sont utilisées dans un autre document, il est nécessaire de créditer l'auteur, en premier nom Luijait et en second 0dAI.