#
Документация по API
Актуальная документация по API находится по ссылке: https://ВАШ_ЛИЧНЫЙ_КАБИНЕТ.sf-cloud.ru/api/docs
#
Получить Авторизационный токен (срок жизни - 12 часов)
curl --location --request POST 'https://keycloak.sf-cloud.ru/auth/realms/scanfactory/protocol/openid-connect/token' \
--header 'Accept: application/json' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=<Поддомен вашего ЛК без .sf-cloud.ru>' \
--data-urlencode 'username=test@test.com' \
--data-urlencode 'password=password' \
--data-urlencode 'grant_type=password'
import requests
login='test@test.com'
password='password'
auth_token = requests.post(
'https://keycloak.sf-cloud.ru/auth/realms/scanfactory/protocol/openid-connect/token',
data={
"client_id": "<Поддомен вашего ЛК без .sf-cloud.ru>",
"username": login,
"password": password,
"grant_type": "password"
},
headers={
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded"
}
).json().get("access_token", None)
<?php
$login = 'test@test.com';
$password = 'password';
$address_prefix = '<Поддомен вашего ЛК без .sf-cloud.ru>';
$url = 'https://keycloak.sf-cloud.ru/auth/realms/scanfactory/protocol/openid-connect/token';
$data = http_build_query([
'client_id' => $address_prefix,
'username' => $login,
'password' => $password,
'grant_type' => 'password'
]);
$options = [
'http' => [
'header' => "Content-Type: application/x-www-form-urlencoded\r\n" .
"Accept: application/json\r\n",
'method' => 'POST',
'content' => $data
]
];
$response = file_get_contents($url, false, stream_context_create($options));
$auth_token = json_decode($response, true)['access_token'] ?? null;
?>
require 'uri'
require 'net/http'
require 'json'
login = 'test@test.com'
password = 'password'
address_prefix = '<Поддомен вашего ЛК без .sf-cloud.ru>'
url = URI("https://keycloak.sf-cloud.ru/auth/realms/scanfactory/protocol/openid-connect/token")
response = Net::HTTP.start(url.host, url.port, use_ssl: true) do |http|
request = Net::HTTP::Post.new(url)
request.set_form_data({
client_id: address_prefix,
username: login,
password: password,
grant_type: 'password'
})
http.request(request)
end
auth_token = JSON.parse(response.body)['access_token'] || nil
#
Получить Годовой Авторизационный токен (например, для Telegram-бота)
curl https://<CLIENT>.sf-cloud.ru/api/admin/agent-token -H "Accept: application/json" -H "Authorization: Bearer <АВТОРИЗАЦИОННЫЙ_12_ЧАСОВОЙ_ТОКЕН_С_ПРЕДЫДУЩЕГО_ШАГА>"
#
Получить список живых хостов
/api/hosts/?alive=1&hidden=0
curl -X 'GET' \
'https://<CLIENT>.sf-cloud.ru/api/hosts/?alive=1&hidden=0&token=<АВТОРИЗАЦИОННЫЙ_ТОКЕН>' \
-H 'accept: application/json'
import requests
url = 'https://<CLIENT>.sf-cloud.ru/api/hosts/'
params = {'alive': 1, 'token': '<АВТОРИЗАЦИОННЫЙ_ТОКЕН>'}
headers = {'Accept': 'application/json'}
alive_hosts = requests.get(url, params=params, headers=headers).json()
<?php
$url = 'https://<CLIENT>.sf-cloud.ru/api/hosts/?alive=1&hidden=0&token=<АВТОРИЗАЦИОННЫЙ_ТОКЕН>';
$options = array(
'http' => array(
'header' => 'accept: application/json'
)
);
$response = file_get_contents($url, false, stream_context_create($options));
$data = json_decode($response, true);
?>
require 'net/http'
require 'uri'
require 'json'
url = URI('https://<CLIENT>.sf-cloud.ru/api/hosts/')
params = { alive: 1, token: '<АВТОРИЗАЦИОННЫЙ_ТОКЕН>' }
url.query = URI.encode_www_form(params)
headers = { 'Accept': 'application/json' }
response = Net::HTTP.get_response(url, headers)
alive_hosts = JSON.parse(response.body)
Актуальный список параметров находится в Swagger в Вашем Личном Кабинете. Ссылка на Swagger: https://ВАШ_ЛИЧНЫЙ_КАБИНЕТ.sf-cloud.ru/api/docs
Ниже приведён краткий пример, какие параметры возможно передать
Status code: 200
{
"count": 1,
"items": [
{
"ipv4": "51.32.2.0",
"domains": [
{
"domain": "foo.bar.com",
"found_by": [
"altdns-4"
],
"alert_stats": {
"critical": 0,
"high": 0,
"medium": 0
}
}
],
"ports": [
{
"port_number": 0,
"found_by": [
"nmap-5"
],
"open": true,
"protocol": "string",
"info": {
"name": "ssh",
"product": "OpenSSH",
"version": "7.9p1 Debian 10+deb10u2",
"extrainfo": "protocol 2.0",
"ostype": "Linux",
"method": "probed",
"conf": "10",
"cpelist": [
"cpe:/a:openbsd:openssh:7.9p1",
"cpe:/o:linux:linux_kernel"
]
},
"history": [
{
"open": true,
"at": "2022-06-14T17:27:25.024141",
"task_id": "<project_id: uuid | str>"
}
],
"last_seen": "2022-06-14T17:27:25.024141",
"cdate": "2022-06-14T17:27:25.024141",
"mdate": "2022-06-14T17:27:25.024141"
}
],
"project_id": "<project_id: uuid | str>",
"found_by": "altdns",
"pending": true,
"hidden": true,
"ping_ok": true,
"cdate": "2022-06-14T17:27:25.024141",
"mdate": "2022-06-14T17:27:25.024141",
"last_seen": "2022-06-14T17:27:25.024141",
"alert_stats": {
"critical": 0,
"high": 0,
"medium": 0
},
"whois": {}
}
]
}
#
Получить уязвимости за неделю
/api/alerts/?active=1&limit=10000
curl -X 'GET' \
https://<CLIENT>.sf-cloud.ru/api/alerts/\?active\=1\&limit\=10000\>-last_seen\="$(date +%s --date '7 days ago')"\&sort=-last_seen&token=<АВТОРИЗАЦИОННЫЙ_ТОКЕН> \
-H 'accept: application/json'
import requests
import time
url = 'https://<CLIENT>.sf-cloud.ru/api/alerts/?active=1>-last_seen={}&limit=10000&sort=-last_seen&token=<АВТОРИЗАЦИОННЫЙ_ТОКЕН>'.format(int(time.time()) - 7*24*60*60)
headers = {'accept': 'application/json'}
response = requests.get(url, headers=headers)
alerts = response.json()
<?php
$url = 'https://<CLIENT>.sf-cloud.ru/api/alerts/?active=1&limit=10000>-last_seen=' . (time() - 7 * 24 * 60 * 60) . '&sort=-last_seen&token=<АВТОРИЗАЦИОННЫЙ_ТОКЕН>';
$options = array(
'http' => array(
'header' => 'accept: application/json'
)
);
$response = file_get_contents($url, false, stream_context_create($options));
$alerts = json_decode($response, true);
?>
require 'net/http'
require 'json'
require 'time'
url = URI('https://<CLIENT>.sf-cloud.ru/api/alerts/?active=1&limit=10000>-last_seen=' + (Time.now.to_i - 7 * 24 * 60 * 60).to_s + '&sort=-last_seen&token=<АВТОРИЗАЦИОННЫЙ_ТОКЕН>')
headers = {
'accept' => 'application/json'
}
response = Net::HTTP.start(url.host, url.port, :use_ssl => true) do |http|
request = Net::HTTP::Get.new(url)
headers.each do |key, value|
request[key] = value
end
http.request(request)
end
data = JSON.parse(response.body)
Актуальный список параметров находится в Swagger в Вашем Личном Кабинете. Ссылка на Swagger: https://ВАШ_ЛИЧНЫЙ_КАБИНЕТ.sf-cloud.ru/api/docs
Ниже приведён краткий пример, какие параметры возможно передать
Status code: 200
{
"count": 1,
"items": [
{
"ipv4": "51.32.2.0",
"domains": [
{
"domain": "foo.bar.com",
"found_by": [
"altdns-4"
],
"alert_stats": {
"critical": 0,
"high": 0,
"medium": 0
}
}
],
"ports": [
{
"port_number": 0,
"found_by": [
"nmap-5"
],
"open": true,
"protocol": "string",
"info": {
"name": "ssh",
"product": "OpenSSH",
"version": "7.9p1 Debian 10+deb10u2",
"extrainfo": "protocol 2.0",
"ostype": "Linux",
"method": "probed",
"conf": "10",
"cpelist": [
"cpe:/a:openbsd:openssh:7.9p1",
"cpe:/o:linux:linux_kernel"
]
},
"history": [
{
"open": true,
"at": "2022-06-14T17:27:25.024141",
"task_id": "<project_id: uuid | str>"
}
],
"last_seen": "2022-06-14T17:27:25.024141",
"cdate": "2022-06-14T17:27:25.024141",
"mdate": "2022-06-14T17:27:25.024141"
}
],
"project_id": "<project_id: uuid | str>",
"found_by": "altdns",
"pending": true,
"hidden": true,
"ping_ok": true,
"cdate": "2022-06-14T17:27:25.024141",
"mdate": "2022-06-14T17:27:25.024141",
"last_seen": "2022-06-14T17:27:25.024141",
"alert_stats": {
"critical": 0,
"high": 0,
"medium": 0
},
"whois": {}
}
]
}
#
Добавление хостов в проект
Чтобы добавить хосты в проект, необходимо выполнить POST
запрос на https://<CLIENT>.sf-cloud.ru/api/projects/<project_UUID>/scope-extension/
Новые домены будут дописываться в конец уже существующего скоупа.
#
Body запроса
{
"root_domains": ["domain.com", "some.domain.com"]
}
{
"root_ips": ["25.65.9.0", "44.43.1.0"]
}
{
"root_domains": ["domain.com", "some.domain.com"],
"root_ips": ["25.65.9.0", "44.43.1.0"]
}
#
Код
curl -X POST \
https://<CLIENT>.sf-cloud.ru/api/projects/<project_id: uuid | str>/scope-extension/?token=<АВТОРИЗАЦИОННЫЙ_ТОКЕН> \
-H 'Content-Type: application/json' \
-H 'accept: application/json' \
-d 'PAYLOAD FROM "Body запроса" SECTION'
import requests
import json
url = 'https://<CLIENT>.sf-cloud.ru/api/projects/<project_id: uuid | str>/scope-extension/?token=<АВТОРИЗАЦИОННЫЙ_ТОКЕН>'
headers = {'Content-Type': 'application/json', 'accept': 'application/json'}
payload = {'PAYLOAD FROM "Body запроса" SECTION'}
response = requests.post(url, headers=headers, data=json.dumps(payload))
project_config = response.json()
<?php
$url = 'https://<CLIENT>.sf-cloud.ru/api/projects/<project_id: uuid | str>/scope-extension/?token=<АВТОРИЗАЦИОННЫЙ_ТОКЕН>';
$data = ['PAYLOAD FROM "Body запроса" SECTION'];
$options = [
'http' => [
'header' => "Content-type: application/json\r\n" .
"Accept: application/json\r\n",
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result);
?>
require 'net/http'
require 'json'
url = URI('https://<CLIENT>.sf-cloud.ru/api/projects/<project_id: uuid | str>/scope-extension/?token=<АВТОРИЗАЦИОННЫЙ_ТОКЕН>')
headers = {
'Content-Type' => 'application/json',
'accept' => 'application/json'
}
data = {'PAYLOAD FROM "Body запроса" SECTION'}
response = Net::HTTP.start(url.host, url.port, :use_ssl => true) do |http|
request = Net::HTTP::POST.new(url)
headers.each do |key, value|
request[key] = value
end
request.body = data.to_json
http.request(request)
end
data = JSON.parse(response.body)
Status code: 200
{
"scope_settings": {
"root_domains": ["домен.который.уже.был.в.настройках", "domain.com", "some.domain.com"],
"root_ips": ["44.0.1.1" "25.65.9.0", "44.43.1.0"],
"blacklist": {
"domains": [],
"ipv4": [],
"ipv6": [],
"url": ["http://somedomain.com/?\\?path=([^&=?]+)"],
"url_exceptions": [],
"domains_exceptions": [],
"ipv4_exceptions": []
},
"manual_ip_approve": false,
"exclude_private_ips": true,
"hide_unreachable": false
}
}
Status code: 400
{"error":"bad request body","field":"scope_settings.root_ips: 127.0.0.1 is not allowed (private IP)"}
#
Удаление хостов из проекта
Чтобы удалить хост из проекта, необходимо выполнить POST
запрос на https://<CLIENT>.sf-cloud.ru/api/projects/<project_UUID>/scope-deletion
#
Body запроса
{
"root_domains": ["domain.com", "some.domain.com"]
}
{
"root_ips": ["25.65.9.0", "44.43.1.0"]
}
{
"root_domains": ["domain.com", "some.domain.com"],
"root_ips": ["25.65.9.0", "44.43.1.0"]
}
#
Код
curl -X POST \
https://<CLIENT>.sf-cloud.ru/api/projects/<project_id: uuid | str>/scope-deletion/?token=<АВТОРИЗАЦИОННЫЙ_ТОКЕН> \
-H 'Content-Type: application/json' \
-H 'accept: application/json' \
-d 'PAYLOAD FROM "Body запроса" SECTION'
import requests
import json
url = 'https://<CLIENT>.sf-cloud.ru/api/projects/<project_id: uuid | str>/scope-deletion/?token=<АВТОРИЗАЦИОННЫЙ_ТОКЕН>'
headers = {'Content-Type': 'application/json', 'accept': 'application/json'}
payload = {'PAYLOAD FROM "Body запроса" SECTION'}
response = requests.post(url, headers=headers, data=json.dumps(payload))
project_config = response.json()
<?php
$url = 'https://<CLIENT>.sf-cloud.ru/api/projects/<project_id: uuid | str>/scope-deletion/?token=<АВТОРИЗАЦИОННЫЙ_ТОКЕН>';
$data = ['PAYLOAD FROM "Body запроса" SECTION'];
$options = [
'http' => [
'header' => "Content-type: application/json\r\n" .
"Accept: application/json\r\n",
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result);
?>
require 'net/http'
require 'json'
url = URI('https://<CLIENT>.sf-cloud.ru/api/projects/<project_id: uuid | str>/scope-deletion/?token=<АВТОРИЗАЦИОННЫЙ_ТОКЕН>')
headers = {
'Content-Type' => 'application/json',
'accept' => 'application/json'
}
data = {'PAYLOAD FROM "Body запроса" SECTION'}
response = Net::HTTP.start(url.host, url.port, :use_ssl => true) do |http|
request = Net::HTTP::POST.new(url)
headers.each do |key, value|
request[key] = value
end
request.body = data.to_json
http.request(request)
end
data = JSON.parse(response.body)
Status code: 200
{
"scope_settings": {
"root_domains": ["оставшиеся домены", ...],
"root_ips": ["оставшиеся айпи", ...],
"blacklist": {
"domains": [],
"ipv4": [],
"ipv6": [],
"url": ["http://somedomain.com/?\\?path=([^&=?]+)"],
"url_exceptions": [],
"domains_exceptions": [],
"ipv4_exceptions": []
},
"manual_ip_approve": false,
"exclude_private_ips": true,
"hide_unreachable": false
}
}
Status code: 404
{"error": "project <project_id> not found"}