Сканирование с помощью OWASP Zap Api
Я пытаюсь использовать сценарий для сканирования цели и выполнения активного сканирования в качестве доказательства концепции. Я работал над реализацией ниже, и я не могу заставить ее работать, я не уверен, почему она не будет работать? У меня работает Zap2Docker, и я могу получить к нему доступ через api, я также могу получить доступ через графический интерфейс, сканирование цели из графического интерфейса работает нормально, однако мой скрипт не будет работать через api, см. Ниже:
import org.zaproxy.clientapi.core.ApiResponse;
import org.zaproxy.clientapi.core.ApiResponseElement;
import org.zaproxy.clientapi.core.ApiResponseList;
import org.zaproxy.clientapi.core.ClientApi;
import java.util.List;
public class Spider {
private static String ZAP_ADDRESS;// = "ZAPContainerIp";
private static int ZAP_PORT;// = 8090;
// Change to match the API key set in ZAP, or use NULL if the API key is disabled
private static String ZAP_API_KEY;// = "change me";
// The URL of the application to be tested
private static String TARGET;// = "https://targetip.com";
private static boolean scanComplete;
public static void main(String[] args) {
ZAP_ADDRESS = args[0];
ZAP_PORT = Integer.parseInt(args[1]);
ZAP_API_KEY = args[2];
TARGET = args[3];
ClientApi api = new ClientApi(ZAP_ADDRESS, ZAP_PORT, ZAP_API_KEY);
try {
// Start spidering
System.out.println("Spidering target : " + TARGET);
ApiResponse resp = api.spider.scan(TARGET, null, null, null, null);
String scanID;
int progress;
// The scan returns a scan id to support concurrent scanning
scanID = ((ApiResponseElement) resp).getValue();
// Poll the status until it completes
while (true) {
Thread.sleep(1000);
progress = Integer.parseInt(((ApiResponseElement) api.spider.status(scanID)).getValue());
System.out.println("Spider progress : " + progress + "%");
if (progress >= 100) {
scanComplete = true;
break;
}
}
System.out.println("Spider completed");
// If required post process the spider results
List<ApiResponse> spiderResults = ((ApiResponseList) api.spider.results(scanID)).getItems();
if (scanComplete) {
ActiveScan activeScan = new ActiveScan();
activeScan.attack(ZAP_ADDRESS, ZAP_PORT, ZAP_API_KEY, TARGET);
}
} catch (Exception e) {
System.out.println("Exception : " + e.getMessage());
e.printStackTrace();
}
}
}
Сканирование:
import org.zaproxy.clientapi.core.ApiResponse;
import org.zaproxy.clientapi.core.ApiResponseElement;
import org.zaproxy.clientapi.core.ClientApi;
import java.lang.annotation.Target;
import java.nio.charset.StandardCharsets;
public class ActiveScan {
private int zapPort;// = 8090;
private String zapApiKey;// = null;
private String zapAddress;// = "localhost";
private String target;// = "https://targetip.com";
public ActiveScan(int zapPort, String zapApiKey, String zapAddress, String target) {
this.zapPort = zapPort;
this.zapApiKey = zapApiKey;
this.zapAddress = zapAddress;
this.target = target;
}
public ActiveScan() {
}
public void attack(String zapAddress, int zapPort, String zapApiKey, String target){
ClientApi api = new ClientApi(zapAddress, zapPort, zapApiKey);
try {
System.out.println("Active Scanning target : " + target);
ApiResponse resp = api.ascan.scan(target, "True", "False", null, null, null);
String scanid;
int progress;
// Scan returns a scan id to support concurrent scanning
scanid = ((ApiResponseElement) resp).getValue();
// Poll status until it completes
while (true) {
Thread.sleep(5000);
progress =
Integer.parseInt(
((ApiResponseElement) api.ascan.status(scanid)).getValue());
System.out.println("Active Scan progress : " + progress + "%");
if (progress >= 100) {
break;
}
}
System.out.println("Active Scan complete");
// Print vulnerabilities found by the scanning
System.out.println("Alerts:");
System.out.println(new String(api.core.xmlreport(), StandardCharsets.UTF_8));
} catch (Exception e) {
System.out.println("Exception : " + e.getMessage());
e.printStackTrace();
}
}
}
При запуске я получаю сообщение об ошибке:
java -jar WafTestSuite.jar "zapurl" "8090" "change-me-9203935709" "10.10.10.254:3000"; Spidering target : 10.10.8.254:3000
Exception : java.net.SocketException: Unexpected end of file from server
org.zaproxy.clientapi.core.ClientApiException: java.net.SocketException: Unexpected end of file from server
at org.zaproxy.clientapi.core.ClientApi.callApiDom(ClientApi.http://java:366)
at org.zaproxy.clientapi.core.ClientApi.callApi(ClientApi.http://java:350)
at org.zaproxy.clientapi.gen.Spider.scan(Spider.http://java:242)
at Spider.main(Spider.java:28)
Caused by: java.net.SocketException: Unexpected end of file from server
at sun.net.http://www.http.HttpClient.parseHTTPHeader(Unknown Source)
at sun.net.http://www.http.HttpClient.parseHTTP(Unknown Source)
at sun.net.http://www.http.HttpClient.parseHTTPHeader(Unknown Source)
at sun.net.http://www.http.HttpClient.parseHTTP(Unknown Source)
at sun.net.http://www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
at sun.net.http://www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at org.zaproxy.clientapi.core.ClientApi.getConnectionInputStream(ClientApi.http://java:399)
at org.zaproxy.clientapi.core.ClientApi.callApiDom(ClientApi.http://java:364)
Буду признателен за любую помощь, спасибо.
2 ответа
По умолчанию ZAP не принимает удаленные подключения к API. Вам необходимо включить их и установить подходящий ключ API (или отключить его). Подробности в этом FAQ: https://www.zaproxy.org/faq/how-can-i-connect-to-zap-remotely/
Это сообщение об ошибке...
java -jar WafTestSuite.jar "zapurl" "8090" "change-me-9203935709" "10.10.10.254:3000"; Spidering target : 10.10.8.254:3000
Exception : java.net.SocketException: Unexpected end of file from server
org.zaproxy.clientapi.core.ClientApiException: java.net.SocketException: Unexpected end of file from server
at org.zaproxy.clientapi.core.ClientApi.callApiDom(ClientApi.http://java:366)
... означает, что удаленный сервер принял и закрыл соединение без отправки ответа.
У этой ошибки может быть много причин, и некоторые из них следующие:
- Возможно, удаленная система слишком занята для обработки запроса, поэтому соединение разрывается.
- В запросе могут быть отсутствующие / недопустимые значения заголовка, что вызывает внутреннюю ошибку, и сервер закрывает соединение вместо того, чтобы нормально отправлять ответ об ошибке HTTP.
- Возможна сетевая задержка, из-за которой приложение случайным образом разрывает соединения.
Однако, согласно конфигурации zap- прокси в блоке кода, довольно очевидно, что, хотя вы инициализировалиZAP_API_KEY
как String вы не присвоили никакого значения. отсюда и ошибка.
Таким образом, блок кода для настройки ZAP будет следующим:
private static final String ZAP_ADDRESS = "localhost";
private static final int ZAP_PORT = 8080;
// Change to match the API key set in ZAP, or use NULL if the API key is disabled
private static final String ZAP_API_KEY = "abcdefghijklmnop123456789";
// The URL of the application to be tested
private static final String TARGET = "http://localhost:3000";
Почему по умолчанию требуется ключ API?
Согласно документации с момента появления ZAP версии 2.4.1 ключ API по умолчанию должен быть настроен для вызова операций API, которые вносят изменения в ZAP. Кроме того, при наличии ZAP версии 2.6.0 ключ API требуется по умолчанию для вызова любых операций API. Эта функция безопасности была реализована, чтобы предотвратить вызов ZAP API вредоносными сайтами. Параметры безопасности API, включая ключ API, можно найти на экране параметров API (Интерфейс прокси ZAP -> Инструменты -> Параметры -> API):
Изменение ключа API
Вы можете изменить ключ API следующими способами:
- Создание нового ключа API путем нажатия на Generate Random key кнопку.
Установив ключ API из командной строки, используя:
-config api.key=change-me-9203935709
Отключите ключ API из командной строки, используя:
-config api.disablekey=true