Skip to content
Snippets Groups Projects
Commit 17bd857b authored by Joël Krähemann's avatar Joël Krähemann
Browse files

OO-653: added some XSS snippeds.

parent 70e733f3
No related branches found
No related tags found
No related merge requests found
......@@ -20,10 +20,23 @@
package org.olat.util.xss.client;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
/**
*
* @author jkraehemann, joel.kraehemann@frentix.com, frentix.com
*/
public class CharsetUtil {
public static byte[] encode(String str, String charsetName){
Charset charset = Charset.forName(charsetName);
return(charset.encode(str).array());
}
public static String decode(byte[] str, String charsetName){
Charset charset = Charset.forName(charsetName);
return(charset.decode(ByteBuffer.wrap(str)).toString());
}
}
/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.util.xss.client;
import java.io.IOException;
/**
*
* @author jkraehemann, joel.kraehemann@frentix.com, frentix.com
*/
public interface HttpClient {
public void connect(String host, int port);
public void setHttpHeader(byte[] buffer);
public void httpGet(byte[] data);
public void httpPut(byte[] data);
public void httpDelete(byte[] data);
public void httpPost(byte[] data);
}
......@@ -20,13 +20,35 @@
package org.olat.util.xss.client;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.olat.util.FunctionalEPortfolioUtil;
/**
*
* @author jkraehemann, joel.kraehemann@frentix.com, frentix.com
*/
public class HttpUtil {
public final static String DEFAULT_HIJACKED_USER_AGENT = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)";
private String hijackedUserAgent;
public HttpUtil() {
this.hijackedUserAgent = DEFAULT_HIJACKED_USER_AGENT;
}
enum HttpMethod {
HTTP_PUT,
HTTP_DELETE,
......@@ -34,11 +56,103 @@ public class HttpUtil {
HTTP_POST,
};
public static byte[] createHttpHeader(HttpMethod method, HashSet<String> parameter, String headerEncoding, String bodyEncoding){
byte[] header = null;
public byte[] createHttpGetHeader(String path, String host,
String jsessionId, String headerEncoding){
VelocityContext context = new VelocityContext();
context.put("path", path);
context.put("host", host);
context.put("userAgent", hijackedUserAgent);
context.put("jsessionId", jsessionId);
VelocityEngine engine = null;
engine = new VelocityEngine();
StringWriter sw = new StringWriter();
try {
engine.evaluate(context, sw, "xssClient_HTTP_GET-Header", HttpUtil.class.getResourceAsStream("xssClient_HTTP_GET-Header.vm"));
} catch (ParseErrorException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MethodInvocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ResourceNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] header = CharsetUtil.encode(sw.toString(), headerEncoding);
return(header);
}
public byte[] createHttpPostHeader(String path, String host,
String jsessionId, String headerEncoding, String bodyEncoding, HashMap<String,String> parameters){
StringBuffer stringBuffer = new StringBuffer();
Set<Entry<String,String>> keys = parameters.entrySet();
Iterator<Entry<String,String>> iter = keys.iterator();
while(iter.hasNext()){
Entry<String,String> entry = iter.next();
stringBuffer.append(entry.getKey())
.append("=")
.append(CharsetUtil.encode(entry.getValue(), bodyEncoding))
.append('\n');
}
VelocityContext context = new VelocityContext();
context.put("path", path);
context.put("host", host);
context.put("userAgent", hijackedUserAgent);
context.put("contentLength", Integer.toString(stringBuffer.length()));
context.put("jsessionId", jsessionId);
context.put("parameters", stringBuffer.toString());
VelocityEngine engine = null;
engine = new VelocityEngine();
StringWriter sw = new StringWriter();
try {
engine.evaluate(context, sw, "xssClient_HTTP_POST-Header", HttpUtil.class.getResourceAsStream("xssClient_HTTP_POST-Header.vm"));
} catch (ParseErrorException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MethodInvocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ResourceNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//TODO:JK: implement me
byte[] header = CharsetUtil.encode(sw.toString(), headerEncoding);
return(header);
}
public String getHijackedUserAgent() {
return hijackedUserAgent;
}
public void setHijackedUserAgent(String hijackedUserAgent) {
this.hijackedUserAgent = hijackedUserAgent;
}
}
......@@ -20,11 +20,15 @@
package org.olat.util.xss.client;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.net.InetSocketAddress;
import org.apache.xmlrpc.webserver.XmlRpcServlet;
......@@ -39,7 +43,7 @@ import org.olat.util.xss.client.HttpUtil.HttpMethod;
*
* @author jkraehemann, joel.kraehemann@frentix.com, frentix.com
*/
public class XssClient extends XmlRpcServlet implements HttpClient {
public class XssClient extends XmlRpcServlet {
final static String DEFAULT_ENCODING = "UTF-8";
......@@ -48,13 +52,33 @@ public class XssClient extends XmlRpcServlet implements HttpClient {
final static String DEFAULT_BODY_ENCODING = "UTF-16";
final static String DEFAULT_SCRIPT_ENCODING = "UTF-7";
final static int DEFAULT_FIELD_LENGTH_LIMITATION = 255;
final static int DEFAULT_THREAD_COUNT = 100;
final static int DEFAULT_FAKE_USER_COUNT = 100;
final static int DEFAULT_CONCURRENT_USER_COUNT = 100;
final static int DEFAULT_DISTRIBUTED_CHUNK_SIZE = 65535;
final static String DEFAULT_ESCAPING_PATTERN = "\\\\\\//";
final static String DEFAULT_CLOSING_TAGS_PATTERN = "</body></html>${\"xssCommonInjectionCode\"}";
final static String DEFAULT_CLOSING_JSON_PATTERN = "',xssAlert: ${\"xssJSonInjectionCode\"};{";
final static String DEFAULT_COMMENT_OUT_PATTERN = "${\"xssInlineInjectionCode\"}<!--";
final static String DEFAULT_SCRIPTIFY_PATTERN = "${\"xssInlineInjectionCode\"}<javascript>";
final static String DEFAULT_FRAMEIFY_PATTERN = "${\"xssInlineInjectionCode\"}<frame src=\"javascript:void(){window.document.body}\" />";
final static String DEFAULT_IFRAMEIFY_PATTERN = "${\"xssInlineInjectionCode\"}<iframe src=\"javascript:void(){window.document.body}\" />";
final static String DEFAULT_TOPLEVEL_FRAME = "<iframe style=\"z-index: -1;\" src=\"javascript:void(){${\"xssSnippedInjectionCode\"}}\">";
final static String DEFAULT_B_MAIN_ONLY_PATTERN = "<div id=\"b_main\" class=\"javascript:void(){${\"xssSnippedInjectionCode\"}}\"/>";
enum XssStrategy{
TRICK_ESCAPING,
CLOSE_TAGS,
COMMENT_OUT,
SCRIPTIFY,
FRAMEIFY,
IFRAMIFY,
TOPLEVEL_FRAME,
B_MAIN_ONLY,
CLOSE_JSON,
MASQUERADE_ENCODING,
FAKE_USERS,
CONCURRENT_USERS,
......@@ -77,12 +101,20 @@ public class XssClient extends XmlRpcServlet implements HttpClient {
private Socket connection;
private OutputStream out;
private int fieldLengthLimitation;
private int threadCount;
private int fakeUserCount;
private int concurrentUserCount;
private int distributedChunkSize;
private String escapingPattern;
private String closingTagsPattern;
private List<Script> scripts;
private HttpUtil httpUtil;
public XssClient(){
this.defaultEncoding = DEFAULT_ENCODING;
......@@ -94,12 +126,20 @@ public class XssClient extends XmlRpcServlet implements HttpClient {
this.connection = new Socket();
this.out = null;
this.fieldLengthLimitation = DEFAULT_FIELD_LENGTH_LIMITATION;
this.threadCount = DEFAULT_THREAD_COUNT;
this.fakeUserCount = DEFAULT_FAKE_USER_COUNT;
this.concurrentUserCount = DEFAULT_CONCURRENT_USER_COUNT;
this.distributedChunkSize = DEFAULT_DISTRIBUTED_CHUNK_SIZE;
this.escapingPattern = DEFAULT_ESCAPING_PATTERN;
this.closingTagsPattern = DEFAULT_CLOSING_TAGS_PATTERN;
this.scripts = new ArrayList<Script>();
this.httpUtil = new HttpUtil();
reloadScripts();
}
......@@ -117,51 +157,155 @@ public class XssClient extends XmlRpcServlet implements HttpClient {
scripts.add(script);
}
@Override
public void connect(String host, int port) {
// TODO Auto-generated method stub
public void connect(String host, int port) throws IOException {
connection.connect(new InetSocketAddress(host, port));
out = connection.getOutputStream();
}
@Override
public void setHttpHeader(byte[] buffer) {
this.header = buffer;
}
@Override
public void httpGet(byte[] data) {
// TODO Auto-generated method stub
private HashMap<String,String> trickEscaping(HashMap<String,String> parameter, int space){
if(parameter == null){
return(null);
}
HashMap<String,String> injectionCode = new HashMap<String,String>();
Iterator<String> iter = parameter.keySet().iterator();
int iNext = escapingPattern.length();
while(iter.hasNext()){
String key = iter.next();
StringBuffer stringBuffer = new StringBuffer();
for(int i = 0;
iNext < fieldLengthLimitation &&
iNext < distributedChunkSize &&
iNext < space;
i = iNext){
stringBuffer.append(escapingPattern);
iNext = i + escapingPattern.length();
}
injectionCode.put(key, stringBuffer.toString());
}
return(injectionCode);
}
@Override
public void httpPut(byte[] data) {
// TODO Auto-generated method stub
private HashMap<String,String> closeTags(HashMap<String,String> parameter, int space){
if(parameter == null){
return(null);
}
HashMap<String,String> injectionCode = new HashMap<String,String>();
Iterator<String> iter = parameter.keySet().iterator();
int iNext = escapingPattern.length();
while(iter.hasNext()){
String key = iter.next();
StringBuffer stringBuffer = new StringBuffer();
for(int i = 0;
iNext < fieldLengthLimitation &&
iNext < distributedChunkSize &&
iNext < space;
i = iNext){
stringBuffer.append(closingTagsPattern);
iNext = i + closingTagsPattern.length();
}
injectionCode.put(key, stringBuffer.toString());
}
return(injectionCode);
}
@Override
public void httpDelete(byte[] data) {
// TODO Auto-generated method stub
private HashMap<String,String> commentOut(HashMap<String,String> parameter){
HashMap<String,String> injectionCode = new HashMap<String,String>();
//TODO:JK: implement me
return(injectionCode);
}
@Override
public void httpPost(byte[] data) {
// TODO Auto-generated method stub
private HashMap<String,String> scriptify(HashMap<String,String> parameter){
HashMap<String,String> injectionCode = new HashMap<String,String>();
//TODO:JK: implement me
return(injectionCode);
}
public void attack(String path, HttpMethod method, HashSet<String> parameter, XssStrategy strategy, String snipped){
this.attack("localhost", 8080, path, method, parameter, strategy, snipped);
private HashMap<String,String> frameify(HashMap<String,String> parameter){
HashMap<String,String> injectionCode = new HashMap<String,String>();
//TODO:JK: implement me
return(injectionCode);
}
private void attack(String host, int port, String path, HttpMethod method, HashSet<String> parameter, XssStrategy strategy, String snipped){
private HashMap<String,String> b_main_only(HashMap<String,String> parameter){
HashMap<String,String> injectionCode = new HashMap<String,String>();
//TODO:JK: implement me
return(injectionCode);
}
private HashMap<String,String> applyStrategy(XssStrategy[] strategy, HashMap<String,String> parameter){
HashMap<String,String> injectionCode = new HashMap<String,String>();
//TODO:JK: implement me
return(injectionCode);
}
public void attack(String path,
HttpMethod method, HashMap<String,String> parameter, String jsessionId,
XssStrategy[] strategy, String snipped, boolean distributed) throws IOException{
this.attack("localhost", 8080, path,
method, parameter, jsessionId,
strategy, snipped, distributed);
}
private void attack(String host, int port, String path,
HttpMethod method, HashMap<String,String> parameter, String jsessionId,
XssStrategy[] strategy, String snipped, boolean distributed) throws IOException {
connect(host, port);
byte[] header = HttpUtil.createHttpHeader(method, parameter, getClientEncoding(), getBodyEncoding());
//TODO:JK: implement other methods
byte[] header = null;
switch(method){
case HTTP_GET:
{
header = httpUtil.createHttpGetHeader(path, host + ":" + port,
jsessionId, getClientEncoding());
}
break;
case HTTP_POST:
{
HashMap<String,String> injectionCode = applyStrategy(strategy, parameter);
header = httpUtil.createHttpPostHeader(path, host + ":" + port,
jsessionId, getClientEncoding(), getBodyEncoding(), injectionCode);
}
break;
default:
break;
}
out.write(header);
}
public String getDefaultEncoding() {
......@@ -236,6 +380,14 @@ public class XssClient extends XmlRpcServlet implements HttpClient {
this.out = out;
}
public int getFieldLengthLimitation() {
return fieldLengthLimitation;
}
public void setFieldLengthLimitation(int fieldLengthLimitation) {
this.fieldLengthLimitation = fieldLengthLimitation;
}
public int getThreadCount() {
return threadCount;
}
......@@ -260,6 +412,30 @@ public class XssClient extends XmlRpcServlet implements HttpClient {
this.concurrentUserCount = concurrentUserCount;
}
public int getDistributedChunkSize() {
return distributedChunkSize;
}
public void setDistributedChunkSize(int distributedChunkSize) {
this.distributedChunkSize = distributedChunkSize;
}
public String getEscapingPattern() {
return escapingPattern;
}
public void setEscapingPattern(String escapingPattern) {
this.escapingPattern = escapingPattern;
}
public String getClosingTagsPattern() {
return closingTagsPattern;
}
public void setClosingTagsPattern(String closingTagsPattern) {
this.closingTagsPattern = closingTagsPattern;
}
public List<Script> getScripts() {
return scripts;
}
......
GET ${"path"} HTTP/1.1
Host: ${"host"}
User-Agent: ${"userAgent"}
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: JSESSIONID=${"jsessionId"}
Pragma: no-cache
Cache-Control: no-cache
POST ${"path"} HTTP/1.1
Host: ${"host"}
User-Agent: ${"userAgent"}
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: ${"contentLength"}
Cookie: JSESSIONID=${"jsessionId"}
Pragma: no-cache
Cache-Control: no-cache
${"parameters"}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment