Skip to content

Commit

Permalink
DNS plugin: currently reviews if there is SPF entry
Browse files Browse the repository at this point in the history
Signed-off-by: Miguel Angel Garcia <[email protected]>
  • Loading branch information
magmax committed Oct 30, 2023
1 parent c16fa91 commit c631c11
Show file tree
Hide file tree
Showing 14 changed files with 364 additions and 0 deletions.
10 changes: 10 additions & 0 deletions addOns/dns/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Changelog
All notable changes to this add-on will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## Unreleased

- First version.
- Detection of no-SPF record
- Detection of more than one SPF record
17 changes: 17 additions & 0 deletions addOns/dns/dns.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
description = "Recon via DNS entries"

zapAddOn {
addOnName.set("DNS")

manifest {
author.set("ZAP Dev Team")
}
}

crowdin {
configuration {
val resourcesPath = "org/zaproxy/addon/${zapAddOn.addOnId.get()}/resources/"
tokens.put("%messagesPath%", resourcesPath)
tokens.put("%helpPath%", resourcesPath)
}
}
2 changes: 2 additions & 0 deletions addOns/dns/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
version=0.0.1
release=false
135 changes: 135 additions & 0 deletions addOns/dns/src/main/java/org/zaproxy/addon/dns/DnsPassiveScanner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2023 The ZAP Development Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.zaproxy.addon.dns;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.URIException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.core.scanner.Alert;
import org.parosproxy.paros.network.HttpMessage;
import org.zaproxy.zap.extension.pscan.PluginPassiveScanner;

public class DnsPassiveScanner extends PluginPassiveScanner {
private static final Logger LOGGER = LogManager.getLogger(DnsPassiveScanner.class);
private volatile boolean enabled = true;
private static List<String> reviewedDomains = new ArrayList<String>();

@Override
public void scanHttpRequestSend(HttpMessage msg, int id) {
super.scanHttpRequestSend(msg, id);

URI uri = msg.getRequestHeader().getURI();

try {
String host = uri.getHost();
if (reviewedDomains.contains(host)) {
return;
}
reviewedDomains.add(host);
LOGGER.debug("HOST: " + host);
List<String> txtRecord = getTxtRecord(host);
checkSpfRecord(txtRecord);
} catch (URIException e) {
LOGGER.debug("There was a problem getting the TXT records", e);
}
}

private void checkSpfRecord(List<String> txtRecord) {
int entries = 0;
for (String entry : txtRecord) {
if (!entry.startsWith("v=spf1 ")) {
continue;
}
LOGGER.debug("SPF record: " + entry);
entries++;
}

if (entries == 0) {
newAlert()
.setRisk(Alert.RISK_INFO)
.setConfidence(Alert.CONFIDENCE_MEDIUM)
.setDescription(
Constant.messages.getString("dns.nospfrecord.desc")
+ "\n"
+ Constant.messages.getString("dns.nospfrecord.desclong"))
.raise();
} else if (entries > 1) {
newAlert()
.setRisk(Alert.RISK_INFO)
.setConfidence(Alert.CONFIDENCE_MEDIUM)
.setDescription(
Constant.messages.getString("dns.toomanyspfrecords.desc")
+ "\n"
+ Constant.messages.getString("dns.toomanyspfrecords.desclong"))
.raise();
}
}

private ArrayList<String> getTxtRecord(String hostName) {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
ArrayList<String> result = new ArrayList<String>();

try {
DirContext dirContext = new InitialDirContext(env);
Attributes attrs = dirContext.getAttributes(hostName, new String[] {"TXT"});
Attribute attr = attrs.get("TXT");

NamingEnumeration<?> attrenum = attr.getAll();
while (attrenum.hasMore()) {
result.add(attrenum.next().toString());
}

} catch (javax.naming.NamingException e) {
LOGGER.debug("There was a problem getting the TXT record", e);
}
return result;
}

@Override
public String getName() {
return Constant.messages.getString("dns.scanner");
}

@Override
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

@Override
public boolean isEnabled() {
return enabled;
}

@Override
public boolean appliesToHistoryType(int historyType) {
return PluginPassiveScanner.getDefaultHistoryTypes().contains(historyType);
}
}
69 changes: 69 additions & 0 deletions addOns/dns/src/main/java/org/zaproxy/addon/dns/ExtensionDns.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2023 The ZAP Development Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.zaproxy.addon.dns;

import org.parosproxy.paros.Constant;
import org.parosproxy.paros.control.Control;
import org.parosproxy.paros.extension.ExtensionAdaptor;
import org.parosproxy.paros.extension.ExtensionHook;
import org.zaproxy.zap.extension.pscan.ExtensionPassiveScan;

/** An ZAP extension which performs DNS operations to get information or vulnerabilities. */
public class ExtensionDns extends ExtensionAdaptor {

// The name is public so that other extensions can access it
public static final String NAME = "ExtensionDns";

protected static final String PREFIX = "dns";

private DnsPassiveScanner passiveScanner;

public ExtensionDns() {
super(NAME);
setI18nPrefix(PREFIX);
}

@Override
public void init() {
super.init();

passiveScanner = new DnsPassiveScanner();
}

@Override
public void hook(ExtensionHook extensionHook) {
super.hook(extensionHook);

Control.getSingleton()
.getExtensionLoader()
.getExtension(ExtensionPassiveScan.class)
.addPassiveScanner(passiveScanner);
}

@Override
public boolean canUnload() {
return true;
}

@Override
public String getDescription() {
return Constant.messages.getString(PREFIX + ".desc");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<title>
DNS - About
</title>
</head>
<body>
<h1>DNS - About</h1>

<h2>Source Code</h2>
<a href="https://github.com/zaproxy/zap-extensions/tree/main/addOns/dns">https://github.com/zaproxy/zap-extensions/tree/main/addOns/dns</a>

<h2>Authors</h2>
ZAP Dev Team

<h2>History</h2>

<h3>Version 0.0.1</h3>
First Version
<ul>
<li>Detection of no-SPF record</li>
<li>Detection of more than one SPF record</li>
</ul>

</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<title>DNS</title>
</head>
<body>
<h1>DNS</h1>

<p>
Add-on to perform automatic DNS scans on every accessed domain.
</p>

<h2>Current detections</h2>

<ul>
<li>SPF record presence</li>
<li>SPF record duplication</li>
</ul>

<h2>About the icon</h2>

<a href="https://www.flaticon.com/free-icons/dns" title="dns icons">Dns icons created by Freepik - Flaticon</a>
</body>
</html>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE helpset
PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp HelpSet Version 2.0//EN"
"http://java.sun.com/products/javahelp/helpset_2_0.dtd">
<helpset version="2.0" xml:lang="en-GB">
<title>DNS Reconnaissance Add-On</title>

<maps>
<homeID>top</homeID>
<mapref location="map.jhm"/>
</maps>

<view>
<name>TOC</name>
<label>Contents</label>
<type>org.zaproxy.zap.extension.help.ZapTocView</type>
<data>toc.xml</data>
</view>

<view>
<name>Index</name>
<label>Index</label>
<type>javax.help.IndexView</type>
<data>index.xml</data>
</view>

<view>
<name>Search</name>
<label>Search</label>
<type>javax.help.SearchView</type>
<data engine="com.sun.java.help.search.DefaultSearchEngine">
JavaHelpSearch
</data>
</view>

<view>
<name>Favorites</name>
<label>Favorites</label>
<type>javax.help.FavoritesView</type>
</view>
</helpset>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE index
PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp Index Version 1.0//EN"
"http://java.sun.com/products/javahelp/index_2_0.dtd">

<index version="2.0">
<!-- index entries are merged (sorted) into core index -->
<indexitem text="dns" target="dns" />
</index>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE map
PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp Map Version 1.0//EN"
"http://java.sun.com/products/javahelp/map_1_0.dtd">

<map version="1.0">
<mapID target="simple-icon" url="contents/images/dns.png" />
<mapID target="dns" url="contents/dns.html" />
<mapID target="dns.about" url="contents/dns.html" />
</map>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE toc
PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp TOC Version 2.0//EN"
"http://java.sun.com/products/javahelp/toc_2_0.dtd">

<toc version="2.0">
<tocitem text="ZAP User Guide" tocid="toplevelitem">
<tocitem text="Add Ons" tocid="addons">
<tocitem text="DNS" image="dns-icon" target="dns">
<tocitem text="About" target="dns.about"/>
</tocitem>
</tocitem>
</tocitem>
</toc>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
dns.desc = A DNS Add-on
dns.nospfrecord.desc = No SPF record found
dns.nospfrecord.desclong = No SPF record found...
dns.toomanyspfrecords.desc = More than one SPF record found
dns.toomanyspfrecords.desclong = More than one SPF record found...
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ var addOns = listOf(
"directorylistv1",
"directorylistv2_3",
"directorylistv2_3_lc",
"dns",
"domxss",
"encoder",
"evalvillain",
Expand Down

0 comments on commit c631c11

Please sign in to comment.