Package org.zaproxy.zap.extension.ascanrules

Source Code of org.zaproxy.zap.extension.ascanrules.TestCrossSiteScriptV2

/*
* 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.ascanrules;

import java.util.List;

import org.apache.commons.httpclient.InvalidRedirectLocationException;
import org.apache.log4j.Logger;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.core.scanner.AbstractAppParamPlugin;
import org.parosproxy.paros.core.scanner.Alert;
import org.parosproxy.paros.core.scanner.Category;
import org.parosproxy.paros.core.scanner.Plugin;
import org.parosproxy.paros.network.HttpMessage;
import org.zaproxy.zap.httputils.HtmlContext;
import org.zaproxy.zap.httputils.HtmlContextAnalyser;
import org.zaproxy.zap.model.Vulnerabilities;
import org.zaproxy.zap.model.Vulnerability;

public class TestCrossSiteScriptV2 extends AbstractAppParamPlugin {

    private static Vulnerability vuln = Vulnerabilities.getVulnerability("wasc_8");
    private static Logger log = Logger.getLogger(TestCrossSiteScriptV2.class);

    @Override
    public int getId() {
        return 40012;
    }

    @Override
    public String getName() {
      return Constant.messages.getString("ascanrules.rxss.name");
    }

    @Override
    public String[] getDependency() {
        return null;
    }

    @Override
    public String getDescription() {
      if (vuln != null) {
        return vuln.getDescription();
      }
      return "Failed to load vulnerability description from file";
    }

    @Override
    public int getCategory() {
        return Category.INJECTION;
    }

    @Override
    public String getSolution() {
      if (vuln != null) {
        return vuln.getSolution();
      }
      return "Failed to load vulnerability solution from file";
    }

    @Override
    public String getReference() {
      if (vuln != null) {
        StringBuilder sb = new StringBuilder();
        for (String ref : vuln.getReferences()) {
          if (sb.length() > 0) {
            sb.append('\n');
          }
          sb.append(ref);
        }
        return sb.toString();
      }
      return "Failed to load vulnerability reference from file";
    }

    @Override
    public void init() {
    }
   
    private List<HtmlContext> performAttack (HttpMessage msg, String param, String attack,
        HtmlContext targetContext, int ignoreFlags) {
    HttpMessage msg2 = msg.cloneRequest();
    setParameter(msg2, param, attack);
        try {
      sendAndReceive(msg2);
      } catch (InvalidRedirectLocationException e) {
        // Not an error, just means we probably attacked the redirect location
    } catch (Exception e) {
      log.error(e.getMessage(), e);
    }

        HtmlContextAnalyser hca = new HtmlContextAnalyser(msg2);
        if (Plugin.AlertThreshold.HIGH.equals(this.getAlertThreshold())) {
          // High level, so check all results are in the expected context
          return hca.getHtmlContexts(attack, targetContext, ignoreFlags);
        }
        return hca.getHtmlContexts(attack);
    }
     
    @Override
    public void scan(HttpMessage msg, String param, String value) {
     
    try {
        // Inject the 'safe' eyecatcher and see where it appears
      boolean attackWorked = false;
      setParameter(msg, param, Constant.getEyeCatcher());
            sendAndReceive(msg);
           
            HtmlContextAnalyser hca = new HtmlContextAnalyser(msg);
            List<HtmlContext> contexts = hca.getHtmlContexts(Constant.getEyeCatcher(), null, 0);
            if (contexts.size() == 0) {
              // Lower case?
                contexts = hca.getHtmlContexts(Constant.getEyeCatcher().toLowerCase(), null, 0);
            }
            if (contexts.size() == 0) {
              // Upper case?
                contexts = hca.getHtmlContexts(Constant.getEyeCatcher().toUpperCase(), null, 0);
            }
            if (contexts.size() == 0) {
              // No luck - try again, appending the eyecatcher to the original value
          setParameter(msg, param, param + Constant.getEyeCatcher());
                sendAndReceive(msg);
                hca = new HtmlContextAnalyser(msg);
              contexts = hca.getHtmlContexts(value + Constant.getEyeCatcher(), null, 0);
            }
            if (contexts.size() == 0) {
              // No luck - lets just try a direct attack
              List<HtmlContext> contexts2 = performAttack (msg, param,
                  "'\"<script>alert(1);</script>", null, 0);
              if (contexts2.size() > 0) {
                // Yep, its vulnerable
          bingo(Alert.RISK_HIGH, Alert.SUSPICIOUS, null, param, contexts2.get(0).getTarget(),
              "", contexts2.get(0).getTarget(), contexts2.get(0).getMsg());
          attackWorked = true;
              }
            }
           
            for (HtmlContext context : contexts) {
              // Loop through the returned contexts and lauch targetted attacks
              if (attackWorked) {
                break;
              }
              if (context.getTagAttribute() != null) {
                // its in a tag attribute - lots of attack vectors possible
        
              if (context.isInScriptAttribute()) {
                  // Good chance this will be vulnerable
                // Try a simple alert attack
                      List<HtmlContext> contexts2 = performAttack (msg, param, ";alert(1)", context, 0);
                     
                      for (HtmlContext context2 : contexts2) {
                        if (context2.getTagAttribute() != null &&
                            context2.isInScriptAttribute()) {
                          // Yep, its vulnerable
                    bingo(Alert.RISK_HIGH, Alert.WARNING, null, param, context2.getTarget(),
                        "", contexts2.get(0).getTarget(), context2.getMsg());
                    attackWorked = true;
                    break;
                        }
                      }
                      if (!attackWorked) {
                        log.debug("Failed to find vuln in script attribute on " + msg.getRequestHeader().getURI());
                      }

              } else if (context.isInUrlAttribute()) {
                // Its a url attribute
                      List<HtmlContext> contexts2 = performAttack (msg, param, "javascript:alert(1);", context, 0);

                      for (HtmlContext ctx : contexts2) {
                        if (ctx.isInUrlAttribute()) {
                          // Yep, its vulnerable
                    bingo(Alert.RISK_HIGH, Alert.WARNING, null, param, ctx.getTarget(),
                      "", ctx.getTarget(), ctx.getMsg());
                    attackWorked = true;
                          break;
                        }
                      }
                      if (!attackWorked) {
                        log.debug("Failed to find vuln in url attribute on " + msg.getRequestHeader().getURI());
                      }

              }
                if (! attackWorked && context.isInTagWithSrc()) {
                  // Its in an attribute in a tag which supports src attributes
                      List<HtmlContext> contexts2 = performAttack (msg, param,
                          context.getSurroundingQuote() + " src=http://badsite.com", context, HtmlContext.IGNORE_TAG);

                      if (contexts2.size() > 0) {
                bingo(Alert.RISK_HIGH, Alert.WARNING, null, param, contexts2.get(0).getTarget(),
                  "", contexts2.get(0).getTarget(), contexts2.get(0).getMsg());
                attackWorked = true;
                      }
                      if (!attackWorked) {
                        log.debug("Failed to find vuln in tag with src attribute on " + msg.getRequestHeader().getURI());
                      }
                }
             
              if (! attackWorked) {
                // Try a simple alert attack
                      List<HtmlContext> contexts2 = performAttack (msg, param,
                          context.getSurroundingQuote() + "><script>alert(1);</script>", context, HtmlContext.IGNORE_TAG);
                      if (contexts2.size() > 0) {
                      // Yep, its vulnerable
                bingo(Alert.RISK_HIGH, Alert.WARNING, null, param, contexts2.get(0).getTarget(),
                    "", contexts2.get(0).getTarget(), contexts2.get(0).getMsg());
                attackWorked = true;
                      }
                      if (!attackWorked) {
                        log.debug("Failed to find vuln with simple script attack " + msg.getRequestHeader().getURI());
                      }
              }
              if (! attackWorked) {
                  // Try adding an onMouseOver
                      List<HtmlContext> contexts2 = performAttack (msg, param,
                          context.getSurroundingQuote() + " onMouseOver=" + context.getSurroundingQuote() + "alert(1);",
                          context, HtmlContext.IGNORE_TAG);
                      if (contexts2.size() > 0) {
                      // Yep, its vulnerable
                bingo(Alert.RISK_HIGH, Alert.WARNING, null, param, contexts2.get(0).getTarget(),
                    "", contexts2.get(0).getTarget(), contexts2.get(0).getMsg());
                attackWorked = true;
                    }
                      if (!attackWorked) {
                        log.debug("Failed to find vuln in with simple onmounseover " + msg.getRequestHeader().getURI());
                      }
              }
              } else if (context.isHtmlComment()) {
                // Try breaking out of the comment
                  List<HtmlContext> contexts2 = performAttack (msg, param,
                      "--><script>alert(1);</script><!--", context, HtmlContext.IGNORE_HTML_COMMENT);
                  if (contexts2.size() > 0) {
                  // Yep, its vulnerable
            bingo(Alert.RISK_HIGH, Alert.WARNING, null, param, contexts2.get(0).getTarget(),
                "", contexts2.get(0).getTarget(), contexts2.get(0).getMsg());
            attackWorked = true;
                  } else {
                    // Maybe they're blocking script tags
                      contexts2 = performAttack (msg, param,
                      "--><b onMouseOver=alert(1);>test</b><!--", context, HtmlContext.IGNORE_HTML_COMMENT);
                      if (contexts2.size() > 0) {
                    // Yep, its vulnerable
              bingo(Alert.RISK_HIGH, Alert.WARNING, null, param, contexts2.get(0).getTarget(),
                  "", contexts2.get(0).getTarget(), contexts2.get(0).getMsg());
              attackWorked = true;
                  }
                  }
              } else {
                // its not in a tag attribute
                if ("body".equalsIgnoreCase(context.getParentTag())) {
                  // Immediately under a body tag
                // Try a simple alert attack
                      List<HtmlContext> contexts2 = performAttack (msg, param,
                          "<script>alert(1);</script>", null, HtmlContext.IGNORE_PARENT);
                      if (contexts2.size() > 0) {
                          // Yep, its vulnerable
                    bingo(Alert.RISK_HIGH, Alert.WARNING, null, param, contexts2.get(0).getTarget(),
                        "", contexts2.get(0).getTarget(), contexts2.get(0).getMsg());
                    attackWorked = true;
                      } else {
                        // Maybe they're blocking script tags
                          contexts2 = performAttack (msg, param,
                          "<b onMouseOver=alert(1);>test</b>", context, HtmlContext.IGNORE_PARENT);
                      for (HtmlContext context2 : contexts2) {
                        if ("body".equalsIgnoreCase(context2.getParentTag()) ||
                            "script".equalsIgnoreCase(context2.getParentTag())) {
                          // Yep, its vulnerable
                    bingo(Alert.RISK_HIGH, Alert.WARNING, null, param, contexts2.get(0).getTarget(),
                        "TBI Body tag", contexts2.get(0).getTarget(), contexts2.get(0).getMsg());
                    attackWorked = true;
                    break;
                        }
                      }
                      }
                } else if (context.getParentTag() != null){
                  // Its not immediately under a body tag, try to close the tag
                      List<HtmlContext> contexts2 = performAttack (msg, param,
                          "</" + context.getParentTag() + "><script>alert(1);</script><" + context.getParentTag() + ">",
                          context, HtmlContext.IGNORE_IN_SCRIPT);
                      if (contexts2.size() > 0) {
                         // Yep, its vulnerable
                   bingo(Alert.RISK_HIGH, Alert.WARNING, null, param, contexts2.get(0).getTarget(),
                       "", contexts2.get(0).getTarget(), contexts2.get(0).getMsg());
                attackWorked = true;
                      } else if ("script".equalsIgnoreCase(context.getParentTag())){
                        // its in a script tag...
                          contexts2 = performAttack (msg, param,
                              context.getSurroundingQuote() + ";alert(1);" + context.getSurroundingQuote(), context, 0);
                          if (contexts2.size() > 0) {
                             // Yep, its vulnerable
                       bingo(Alert.RISK_HIGH, Alert.WARNING, null, param, contexts2.get(0).getTarget(),
                           "", contexts2.get(0).getTarget(), contexts2.get(0).getMsg());
                    attackWorked = true;
                          }
                      }
                }
              }
            }
      } catch (InvalidRedirectLocationException e) {
        // Not an error, just means we probably attacked the redirect location
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
   
  @Override
  public int getRisk() {
    return Alert.RISK_HIGH;
  }

  @Override
  public int getCweId() {
    return 79;
  }

  @Override
  public int getWascId() {
    return 8;
  }

}
TOP

Related Classes of org.zaproxy.zap.extension.ascanrules.TestCrossSiteScriptV2

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.