Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
vah13 authored Jan 11, 2017
1 parent 039b267 commit 43b39e8
Show file tree
Hide file tree
Showing 42 changed files with 3,696 additions and 0 deletions.
172 changes: 172 additions & 0 deletions burp/BurpExtender.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package burp;

import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class BurpExtender implements IBurpExtender, IScannerCheck, IHttpListener {
private IBurpExtenderCallbacks callbacks;
private IExtensionHelpers helpers;
private OutputStream output;

//CRLF variables
private static final String CRLFHeader = "Burp-Verification-Header: ";
private static final Pattern CRLFPattern = Pattern.compile("\\n\\s*" + CRLFHeader);
private static final List<String> CRLFSplitters = new ArrayList<String>();
private static String CRLFDescription = "";


public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) {
this.callbacks = callbacks;

this.helpers = callbacks.getHelpers();
this.output = callbacks.getStdout();


callbacks.setExtensionName("Burp CRLF plugin");
callbacks.registerScannerCheck(BurpExtender.this);
callbacks.registerHttpListener(BurpExtender.this);
println("Burp CRLF plugin");

initCRLFSplitters();

CRLFDescription = "HTTP response splitting occurs when:<br/><ul>" +
"<li>Data enters a web application through an untrusted source, most frequently an HTTP request.</li>\n" +
"<li>The data is included in an HTTP response header sent to a web user without being validated for malicious characters.</li></ul>\n" +
"HTTP response splitting is a means to an end, not an end in itself. At its root, the attack is straightforward: \n" +
"an attacker passes malicious data to a vulnerable application, and the application includes the data in an HTTP response header.<br/><br/>\n" +
"To mount a successful exploit, the application must allow input that contains CR (carriage return, also given by %0d or \\r) \n" +
"and LF (line feed, also given by %0a or \\n)characters into the header AND the underlying platform must be vulnerable to the injection\n" +
"of such characters. These characters not only give attackers control of the remaining headers and body of the response the application intends"+
"to send, but also allow them to create additional responses entirely under their control.<br/><br/>\n" +
"The example below uses a Java example, but this issue has been fixed in virtually all modern Java EE application servers." +
"If you are concerned about this risk, you should test on the platform of concern to see if the underlying platform allows for CR or LF characters"+
"to be injected into headers. We suspect that, in general, this vulnerability has been fixed in most modern application servers, regardless of what language the code has been written in.";

}

public List<IScanIssue> doActiveScan(IHttpRequestResponse baseRequestResponse, IScannerInsertionPoint insertionPoint) {
baseRequestResponse.getHttpService().getHost();
List<IScanIssue> results = new ArrayList<IScanIssue>();
checkResult res = doCRLF(baseRequestResponse, insertionPoint);
if (res!=null)
{
IHttpRequestResponse attack = res.getAttack();
results.add(new CustomScanIssue(attack.getHttpService(),
this.helpers.analyzeRequest(attack).getUrl(),
new IHttpRequestResponse[]{attack},
"HTTP Response Splitting",
"Vulnerability detected by <b>BurpCRLFPlugin</b> <br/><br/>" + res.getAttackDetails(),
CRLFDescription, res.getPriority(), "Firm"));
}


return results;
}

public List<IScanIssue> doPassiveScan(IHttpRequestResponse baseRequestResponse){
return null;
}


public int consolidateDuplicateIssues(IScanIssue existingIssue, IScanIssue newIssue)
{
return 0;
}


public checkResult doCRLF(IHttpRequestResponse baseRequestResponse, IScannerInsertionPoint insertionPoint){

String uuid = UUID.randomUUID().toString().replaceAll("-", "");

IHttpService httpService = baseRequestResponse.getHttpService();
IHttpRequestResponse checkUUID = this.callbacks.makeHttpRequest(httpService,
insertionPoint.buildRequest(this.helpers.stringToBytes(uuid)));

String respHeaders = String.join("\n", this.helpers.analyzeResponse(checkUUID.getResponse()).getHeaders());


if (respHeaders.contains(uuid)) {
for (String payload: CRLFSplitters) {
String finalPayload = new StringBuffer().append(uuid.substring(0,5))
.append(payload)
.append(CRLFHeader)
.append(uuid.substring(6))
.toString();

IHttpRequestResponse attack = this.callbacks.makeHttpRequest(httpService,
insertionPoint.buildRequest(this.helpers.stringToBytes(finalPayload)));

String respAttackHeaders = String.join("\n",this.helpers.analyzeResponse(attack.getResponse()).getHeaders());

Matcher m = CRLFPattern.matcher(respAttackHeaders);

if (m.find() ){
String body = this.helpers.bytesToString(attack.getResponse());

List requestMarkers = new ArrayList(1);
requestMarkers.add(insertionPoint.getPayloadOffsets(this.helpers.stringToBytes(finalPayload)));
List responseMarkers = new ArrayList(1);
//println(Integer.toString(body.indexOf(CRLFHeader)));
//println(Integer.toString(body.indexOf(CRLFHeader)+CRLFHeader.length()));
responseMarkers.add(new int[]{body.indexOf(CRLFHeader), body.indexOf(CRLFHeader)+CRLFHeader.length() });


String attackDetails = "Vulnerability detected at <b>" + insertionPoint.getInsertionPointName() + "</b>, " +
"payload was set to <b>" + this.helpers.urlEncode(finalPayload) + "</b><br/>" +
"Found response: " + m.group();
return new checkResult(true,
finalPayload,
this.callbacks.applyMarkers(attack,requestMarkers,responseMarkers),
"High",
attackDetails);
}
}
}
return null;
}


public void initCRLFSplitters()
{
byte[] CDRIVES = new byte[] {(byte)0xE5, (byte)0x98, (byte)0x8A, (byte)0xE5, (byte)0x98, (byte)0x8D, };
CRLFSplitters.add(this.helpers.bytesToString(CDRIVES));
CRLFSplitters.add("\r\n");
CRLFSplitters.add("\r ");
CRLFSplitters.add("\r\t");
CRLFSplitters.add("\r\n ");
CRLFSplitters.add("\r\n\t");
CRLFSplitters.add("\r\n\t");

CRLFSplitters.add("%0d");
CRLFSplitters.add("%0a");
CRLFSplitters.add("%0d%0a");
CRLFSplitters.add("%0d%0a%09");
CRLFSplitters.add("%0d+");
CRLFSplitters.add("%0d%20");
CRLFSplitters.add("%0d%0a+");
CRLFSplitters.add("%E5%98%8A%E5%98%8D");
CRLFSplitters.add("%E5%98%8A%E5%98%8D%E5%98%8A%E5%98%8D");
}


private void println(String toPrint) {
try {
this.output.write(toPrint.getBytes());
this.output.write("\n".getBytes());
this.output.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}

@Override
public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) {
// TODO Auto-generated method stub

}
}
82 changes: 82 additions & 0 deletions burp/CustomScanIssue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package burp;

import java.net.URL;

class CustomScanIssue implements IScanIssue {
private IHttpService httpService;
private URL url;
private IHttpRequestResponse[] httpMessages;
private String name;
private String detail;
private String severity;
private String confidence;
private String background;

public CustomScanIssue(IHttpService httpService, URL url, IHttpRequestResponse[] httpMessages, String name,
String detail, String background, String severity, String confidence)
{
this.httpService = httpService;
this.url = url;
this.httpMessages = httpMessages;
this.name = name;
this.detail = detail;
this.severity = severity;
this.confidence = confidence;
this.background = background;
}

public URL getUrl()
{
return this.url;
}

public String getIssueName()
{
return this.name;
}

public int getIssueType()
{
return 0;
}

public String getSeverity()
{
return this.severity;
}

public String getConfidence()
{
return this.confidence;
}

public String getIssueBackground()
{
return this.background;
}

public String getRemediationBackground()
{
return null;
}

public String getIssueDetail()
{
return this.detail;
}

public String getRemediationDetail()
{
return null;
}

public IHttpRequestResponse[] getHttpMessages()
{
return this.httpMessages;
}

public IHttpService getHttpService()
{
return this.httpService;
}
}
31 changes: 31 additions & 0 deletions burp/IBurpExtender.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package burp;

/*
* @(#)IBurpExtender.java
*
* Copyright PortSwigger Ltd. All rights reserved.
*
* This code may be used to extend the functionality of Burp Suite Free Edition
* and Burp Suite Professional, provided that this usage does not violate the
* license terms for those products.
*/
/**
* All extensions must implement this interface.
*
* Implementations must be called BurpExtender, in the package burp, must be
* declared public, and must provide a default (public, no-argument)
* constructor.
*/
public interface IBurpExtender
{
/**
* This method is invoked when the extension is loaded. It registers an
* instance of the
* <code>IBurpExtenderCallbacks</code> interface, providing methods that may
* be invoked by the extension to perform various actions.
*
* @param callbacks An
* <code>IBurpExtenderCallbacks</code> object.
*/
void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks);
}
Loading

0 comments on commit 43b39e8

Please sign in to comment.