diff --git a/build/build.xml b/build/build.xml new file mode 100644 index 0000000..182a1bd --- /dev/null +++ b/build/build.xml @@ -0,0 +1,163 @@ + + Build ZAP extensions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/commons-configuration-1.9.jar b/lib/commons-configuration-1.9.jar new file mode 100644 index 0000000..fa8fac1 Binary files /dev/null and b/lib/commons-configuration-1.9.jar differ diff --git a/lib/zap-2.7.0.jar b/lib/zap-2.7.0.jar new file mode 100644 index 0000000..b840e69 Binary files /dev/null and b/lib/zap-2.7.0.jar differ diff --git a/src/org/zaproxy/zap/extension/endpointfinder/ExtensionEndpointFinder.java b/src/org/zaproxy/zap/extension/endpointfinder/ExtensionEndpointFinder.java new file mode 100644 index 0000000..52a639c --- /dev/null +++ b/src/org/zaproxy/zap/extension/endpointfinder/ExtensionEndpointFinder.java @@ -0,0 +1,135 @@ +/* + * Zed Attack Proxy (ZAP) and its related class files. + * + * ZAP is an HTTP/HTTPS proxy for assessing web application security. + * + * 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.zap.extension.endpointfinder; + +import org.parosproxy.paros.extension.ExtensionAdaptor; +import org.parosproxy.paros.extension.ExtensionHook; +import org.zaproxy.zap.extension.httppanel.Message; +import org.zaproxy.zap.extension.httppanel.component.split.response.ResponseSplitComponent; +import org.zaproxy.zap.extension.httppanel.view.HttpPanelDefaultViewSelector; +import org.zaproxy.zap.extension.httppanel.view.HttpPanelView; +import org.zaproxy.zap.extension.httppanel.view.impl.models.http.response.ResponseBodyByteHttpPanelViewModel; +import org.zaproxy.zap.view.HttpPanelManager; +import org.zaproxy.zap.view.HttpPanelManager.HttpPanelDefaultViewSelectorFactory; +import org.zaproxy.zap.view.HttpPanelManager.HttpPanelViewFactory; + +public class ExtensionEndpointFinder extends ExtensionAdaptor { + public static final String NAME = "ExtensionEndpointFinder"; + + public ExtensionEndpointFinder() { + super(NAME); + } + + public void hook(ExtensionHook extensionHook) { + super.hook(extensionHook); + + if (getView() != null) { + HttpPanelManager panelManager = HttpPanelManager.getInstance(); + + panelManager.addResponseViewFactory(ResponseSplitComponent.NAME, new ResponseEndpointFinderTextViewFactory()); + panelManager.addResponseDefaultViewSelectorFactory(ResponseSplitComponent.NAME, new ResponseEndpointFinderTextViewDefaultViewSelectorFactory()); + } + } + + public boolean canUnload() { + return true; + } + + public void unload() { + if (getView() != null) { + HttpPanelManager panelManager = HttpPanelManager.getInstance(); + + panelManager.removeResponseViewFactory(ResponseSplitComponent.NAME, ResponseEndpointFinderTextViewFactory.NAME); + panelManager.removeResponseViews(ResponseSplitComponent.NAME, ResponseEndpointFinderTextView.NAME, ResponseSplitComponent.ViewComponent.BODY); + + panelManager.removeResponseDefaultViewSelectorFactory(ResponseSplitComponent.NAME, ResponseEndpointFinderTextViewDefaultViewSelectorFactory.NAME); + panelManager.removeResponseDefaultViewSelectors(ResponseSplitComponent.NAME, ResponseEndpointFinderTextViewDefaultViewSelector.NAME, ResponseSplitComponent.ViewComponent.BODY); + } + } + + private static final class ResponseEndpointFinderTextViewFactory implements HttpPanelViewFactory { + public static final String NAME = "ResponseEndpointFinderTextViewFactory"; + + public String getName() { + return NAME; + } + + public HttpPanelView getNewView() { + return new ResponseEndpointFinderTextView(new ResponseBodyByteHttpPanelViewModel()); + } + + public Object getOptions() { + return ResponseSplitComponent.ViewComponent.BODY; + } + } + + private static final class ResponseEndpointFinderTextViewDefaultViewSelector implements HttpPanelDefaultViewSelector { + public static final String NAME = "ResponseEndpointFinderTextViewDefaultViewSelector"; + + public String getName() { + return NAME; + } + + public boolean matchToDefaultView(Message message) { + return ResponseEndpointFinderTextView.isJavaScriptContent(message); + } + + public String getViewName() { + return ResponseEndpointFinderTextView.NAME; + } + + public int getOrder() { + return 20; + } + } + + private static final class ResponseEndpointFinderTextViewDefaultViewSelectorFactory implements HttpPanelDefaultViewSelectorFactory { + private static HttpPanelDefaultViewSelector defaultViewSelector = null; + public static final String NAME = "ResponseEndpointFinderTextViewDefaultViewSelectorFactory"; + + private HttpPanelDefaultViewSelector getDefaultViewSelector() { + if (defaultViewSelector == null) { + createViewSelector(); + } + return defaultViewSelector; + } + + private synchronized void createViewSelector() { + if (defaultViewSelector == null) { + defaultViewSelector = new ResponseEndpointFinderTextViewDefaultViewSelector(); + } + } + + public String getName() { + return NAME; + } + + public HttpPanelDefaultViewSelector getNewDefaultViewSelector() { + return getDefaultViewSelector(); + } + + public Object getOptions() { + System.out.println("Get Options ..."); + return ResponseSplitComponent.ViewComponent.BODY; + } + } + + public String getAuthor() { + return "Olivier Arteau"; + } +} diff --git a/src/org/zaproxy/zap/extension/endpointfinder/ResponseEndpointFinderTextView.java b/src/org/zaproxy/zap/extension/endpointfinder/ResponseEndpointFinderTextView.java new file mode 100644 index 0000000..e9308e9 --- /dev/null +++ b/src/org/zaproxy/zap/extension/endpointfinder/ResponseEndpointFinderTextView.java @@ -0,0 +1,176 @@ +/* + * Zed Attack Proxy (ZAP) and its related class files. + * + * ZAP is an HTTP/HTTPS proxy for assessing web application security. + * + * Copyright 2016 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.zap.extension.endpointfinder; + +import java.awt.BorderLayout; +import java.util.List; + +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +import org.apache.commons.configuration.FileConfiguration; +import org.parosproxy.paros.network.HttpHeaderField; +import org.parosproxy.paros.network.HttpMessage; +import org.zaproxy.zap.extension.httppanel.Message; +import org.zaproxy.zap.extension.httppanel.view.HttpPanelView; +import org.zaproxy.zap.extension.httppanel.view.HttpPanelViewModel; +import org.zaproxy.zap.extension.httppanel.view.HttpPanelViewModelEvent; +import org.zaproxy.zap.extension.httppanel.view.HttpPanelViewModelListener; +import org.zaproxy.zap.extension.httppanel.view.impl.models.http.AbstractHttpByteHttpPanelViewModel; +import org.zaproxy.zap.extension.httppanel.view.impl.models.http.response.ResponseBodyByteHttpPanelViewModel; + +import ca.zhack.endpointfinder.EndpointEntry; +import ca.zhack.endpointfinder.EndpointFinder; +import ca.zhack.endpointfinder.EndpointResult; +import ca.zhack.endpointfinder.Position; + +/** + * @author Olivier Arteau + */ +public class ResponseEndpointFinderTextView implements HttpPanelView, HttpPanelViewModelListener { + public static final String NAME = "ResponseEndpointFinderTextView"; + + private JPanel mainPanel; + private JLabel resultLabel; + + private AbstractHttpByteHttpPanelViewModel model; + + public ResponseEndpointFinderTextView(ResponseBodyByteHttpPanelViewModel model) { + this.model = model; + + resultLabel = new JLabel(); + resultLabel.setVerticalAlignment(JLabel.TOP); + + mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(new JScrollPane(resultLabel)); + + this.model.addHttpPanelViewModelListener(this); + } + + public void setSelected(boolean selected) { + if (selected) { + resultLabel.requestFocusInWindow(); + } + } + + public String getCaptionName() { + return "EndpointFinder"; + } + + public String getTargetViewName() { + return ""; + } + + public int getPosition() { + return 1; + } + + public boolean isEnabled(Message message) { + return isJavaScriptContent(message); + } + + public boolean hasChanged() { + return false; + } + + public JComponent getPane() { + return mainPanel; + } + + public boolean isEditable() { + return false; + } + + public String getName() { + return NAME; + } + + public HttpPanelViewModel getModel() { + return model; + } + + public void dataChanged(HttpPanelViewModelEvent e) { + if (!isEnabled(model.getMessage())) { + resultLabel.setText(""); + return; + } + + try { + HttpMessage msg = (HttpMessage) model.getMessage(); + String stringToParse = new String(msg.getResponseBody().getBytes()); + StringBuilder display = new StringBuilder(); + EndpointResult result = EndpointFinder.getEndpoints(stringToParse); + List entries = result.getEntries(); + + display.append(""); + display.append("Results (" + entries.size() + ")

"); + + for (EndpointEntry entry : entries) { + display.append("--------------------
"); + display.append("Path : " + entry.getPath() + "
"); + + + if (entry.getUnknownPosition().size() > 0) { + int positionNumber = 1; + for (Position pos : entry.getUnknownPosition()) { + String formatUnknowInfo = "Variable #%d : %s (start: %d, end: %d)
"; + display.append(String.format( + formatUnknowInfo, + positionNumber, + stringToParse.substring(pos.getStart(), pos.getEnd()), + pos.getStart(), + pos.getEnd() + )); + } + } + } + + display.append("--------------------

"); + display.append(""); + resultLabel.setText(display.toString()); + } catch (Exception err) { + String errMessage = "An error occured during the parsing of the content.\n\n"; + errMessage += err.getMessage(); + resultLabel.setText(errMessage); + } + } + + public static boolean isJavaScriptContent(Message message) { + if (!(message instanceof HttpMessage)) { + return false; + } + + for (HttpHeaderField field : ((HttpMessage) message).getResponseHeader().getHeaders()) { + if (field.getName().toLowerCase().equals("content-type")) { + return field.getValue().contains("javascript"); + } + } + + return false; + } + + public void setEditable(boolean editable) { } + public void setParentConfigurationKey(String configurationKey) { } + public void loadConfiguration(FileConfiguration fileConfiguration) { } + public void saveConfiguration(FileConfiguration fileConfiguration) { } + public void save() { } +} diff --git a/src/org/zaproxy/zap/extension/endpointfinder/ZapAddOn.xml b/src/org/zaproxy/zap/extension/endpointfinder/ZapAddOn.xml new file mode 100644 index 0000000..0056368 --- /dev/null +++ b/src/org/zaproxy/zap/extension/endpointfinder/ZapAddOn.xml @@ -0,0 +1,19 @@ + + EndpointFinder + 12 + beta + Zap plugin for EndpointFinder + Olivier Arteau + + + + + org.zaproxy.zap.extension.endpointfinder.ExtensionEndpointFinder + + + + + + 2.7.0 + + diff --git a/src/org/zaproxy/zap/extension/endpointfinder/lib/endpointfinder-java-0.0.1-SNAPSHOT.jar b/src/org/zaproxy/zap/extension/endpointfinder/lib/endpointfinder-java-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000..4e1a4db Binary files /dev/null and b/src/org/zaproxy/zap/extension/endpointfinder/lib/endpointfinder-java-0.0.1-SNAPSHOT.jar differ