Created
March 10, 2021 14:22
-
-
Save d3vilbug/0a55139c24b183b36dd1d4e9fa2658e0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package burp; | |
import java.io.PrintWriter; | |
import java.net.URL; | |
import java.security.NoSuchAlgorithmException; | |
import java.util.Arrays; | |
import java.util.Base64; | |
import java.util.List; | |
import java.util.logging.Level; | |
import java.util.logging.Logger; | |
import javax.crypto.Cipher; | |
import javax.crypto.NoSuchPaddingException; | |
import javax.crypto.SecretKey; | |
import javax.crypto.spec.IvParameterSpec; | |
import javax.crypto.spec.SecretKeySpec; | |
/** | |
* | |
* @author bugzy | |
*/ | |
public class BurpExtender implements IBurpExtender, IProxyListener, IHttpListener{ | |
public String ExtensionName = "AES_Killer v3.0"; | |
public IBurpExtenderCallbacks callbacks; | |
public IExtensionHelpers helpers; | |
public PrintWriter stdout; | |
public PrintWriter stderr; | |
public Boolean isDebug = true; | |
public Cipher cipher; | |
public IvParameterSpec iv_param; | |
public SecretKey sec_key; | |
public String Host_URL = "http://<URL/IP/Host>"; | |
public String[] offusicatedChar = {"+", "/"}; | |
public String[] replaceWithChar = {"-", "_"}; | |
// Endpoints and their corresponding parameters in order | |
public String[] endpoints = { | |
"/Login", | |
"/api/GetAccountBalance", | |
"/api/TarnsferPayment" | |
}; | |
public String[][] parameters = { | |
{"username", "password"}, | |
{"AccNo"}, | |
{"AccNo", "Amount"} | |
}; | |
// Endpoint Classification | |
public String[] get_ep = { "/api/GetAccountBalance" }; | |
public String[] json_ep = { "/api/TarnsferPayment" }; | |
public String[] form_ep = { "/Login" }; | |
@Override | |
public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { | |
this.callbacks = callbacks; | |
this.helpers = callbacks.getHelpers(); | |
this.stdout = new PrintWriter(callbacks.getStdout(), true); | |
this.stderr = new PrintWriter(callbacks.getStderr(), true); | |
this.callbacks.setExtensionName(this.ExtensionName); | |
try { | |
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); | |
sec_key = new SecretKeySpec(Base64.getDecoder().decode(" <Base64 encoded SecretKey> "),"AES"); | |
iv_param = new IvParameterSpec(Base64.getDecoder().decode(" <Base64 encoded IV> ")); | |
} catch (NoSuchAlgorithmException ex) { | |
Logger.getLogger(BurpExtender.class.getName()).log(Level.SEVERE, null, ex); | |
} catch (NoSuchPaddingException ex) { | |
Logger.getLogger(BurpExtender.class.getName()).log(Level.SEVERE, null, ex); | |
} | |
this.callbacks.registerHttpListener(this); | |
this.callbacks.registerProxyListener(this); | |
this.stdout.println("AES_Killer Installed !!!"); | |
} | |
private void print_output(String _src, String str){ | |
if(! isDebug){ return; } | |
this.stdout.println(_src.toString() + " :: " + str.toString() + "\n"); | |
} | |
private void print_error(String _src, String str){ | |
if(! isDebug){ return; } | |
this.stderr.println(_src + " :: " + str); | |
} | |
private String do_Decrypt(String paramString){ | |
try{ | |
String temp_params = removeOff(this.helpers.urlDecode(paramString)); | |
cipher.init(2, sec_key ,iv_param); | |
temp_params = new String (cipher.doFinal(this.helpers.base64Decode(temp_params)), "UTF-8"); | |
return temp_params; | |
}catch(Exception ex){ | |
print_error("do_Decrypt", ex.getMessage()); | |
return paramString; | |
} | |
} | |
private String do_Encrypt(String paramString){ | |
try{ | |
String temp_params = paramString; | |
cipher.init(1, sec_key ,iv_param); | |
temp_params = new String (this.helpers.base64Encode(cipher.doFinal(temp_params.getBytes()))); | |
// return this.helpers.urlEncode(doOff(temp_params)); | |
return temp_params; | |
}catch(Exception ex){ | |
print_error("do_Encryp", ex.getMessage()); | |
return paramString; | |
} | |
} | |
public String removeOff(String paramString) { | |
if (paramString != null) { | |
for(int i =0; i< this.offusicatedChar.length; i++){ | |
paramString = paramString.replace(this.replaceWithChar[i], this.offusicatedChar[i]); | |
} | |
return paramString; | |
} | |
return paramString; | |
} | |
public String doOff(String paramString) { | |
if (paramString != null) { | |
for(int i =0; i< this.offusicatedChar.length; i++){ | |
paramString = paramString.replace(this.offusicatedChar[i], this.replaceWithChar[i]); | |
} | |
return paramString; | |
} | |
return paramString; | |
} | |
public String get_endpoint(String _url){ | |
try{ | |
URL abc = new URL(_url); | |
return abc.getPath().toString(); | |
}catch (Exception ex){ | |
print_error("get_endpoint", _url); | |
return _url; | |
} | |
} | |
public int get_ep_index(String _endpoint){ | |
return Arrays.asList(this.endpoints).indexOf(_endpoint); | |
} | |
public boolean ep_exists(String _endpoint){ | |
if (Arrays.asList(this.endpoints).contains(_endpoint)){ | |
return true; | |
} | |
return false; | |
} | |
public boolean is_ep_get(String _endpoint){ | |
if (Arrays.asList(this.get_ep).contains(_endpoint)){ | |
return true; | |
} | |
return false; | |
} | |
public boolean is_ep_json(String _endpoint){ | |
if (Arrays.asList(this.json_ep).contains(_endpoint)){ | |
return true; | |
} | |
return false; | |
} | |
public boolean is_ep_form(String _endpoint){ | |
if (Arrays.asList(this.form_ep).contains(_endpoint)){ | |
return true; | |
} | |
return false; | |
} | |
public String get_param(byte[] _tmp_req, String _req_param){ | |
IParameter _parameters = this.helpers.getRequestParameter(_tmp_req, _req_param); | |
String _param = _parameters.getValue().toString(); | |
_param = this.helpers.urlDecode(_param); | |
return _param; | |
} | |
// This can vary depending upon application backend | |
public String remove_padding(String _pad_param){ | |
_pad_param = _pad_param.replaceAll("\u0000", ""); | |
_pad_param = _pad_param.substring(4, _pad_param.length()); | |
_pad_param = _pad_param.substring(0, _pad_param.length() - 10); | |
return _pad_param; | |
} | |
// This can vary depending upon application backend | |
public String add_null(String _str){ | |
StringBuilder _null_str = new StringBuilder(); | |
for(int i=0; i< _str.length(); i++){ | |
_null_str.append(String.valueOf("\u0000")); | |
_null_str.append(String.valueOf("\u0000")); | |
_null_str.append(String.valueOf("\u0000")); | |
_null_str.append(_str.toCharArray()[i]); | |
} | |
return _null_str.toString(); | |
} | |
// This can vary depending upon application backend | |
public String add_padding(String _nml_param){ | |
return ("<desire string>" + add_null("<desire string>") + add_null(_nml_param) + add_null("<desire string>") + String.valueOf("\u0000")+ String.valueOf("\u0000")+ String.valueOf("\u0000")); | |
} | |
// This can vary depending upon application backend | |
public String return_padding(){ | |
return ("1" + add_null("<desire string>") + add_null("<desire string>") + String.valueOf("\u0000")+ String.valueOf("\u0000")+ String.valueOf("\u0000")); | |
} | |
public byte[] update_parameter(byte[] _tmp_req, String _parameter, String _new_value){ | |
byte[] _tmp_new_req; | |
IParameter old_param = this.helpers.getRequestParameter(_tmp_req, _parameter); | |
IParameter new_param = this.helpers.buildParameter(_parameter, _new_value, old_param.getType()); | |
_tmp_new_req = this.helpers.removeParameter(_tmp_req, old_param); | |
_tmp_new_req = this.helpers.addParameter(_tmp_new_req, new_param); | |
return _tmp_new_req; | |
} | |
public byte[] update_parameter_json(byte[] _tmp_req, String _parameter, String _new_value){ | |
IRequestInfo reqInfo = helpers.analyzeRequest(_tmp_req); | |
String tmpreq = new String(_tmp_req); | |
String messageBody = new String(tmpreq.substring(reqInfo.getBodyOffset())).trim(); | |
int _lst_index = messageBody.indexOf(_parameter) + _parameter.length() + 3; | |
String _rst_msg = messageBody.substring(_lst_index, messageBody.length()); | |
int _qut_index = _rst_msg.indexOf("\""); | |
String _new_str = _rst_msg.substring(_qut_index, _rst_msg.length()); | |
String _final_body = messageBody.substring(0, _lst_index) + _new_value + _new_str; | |
byte[] _tmp_new_req = this.helpers.buildHttpMessage(reqInfo.getHeaders(), _final_body.getBytes()); | |
return _tmp_new_req; | |
} | |
public byte[] get_dec_params(byte[] _tmp_req, String _endpoint){ | |
int _index = get_ep_index(_endpoint); | |
String[] _params = this.parameters[_index]; | |
if(is_ep_get(_endpoint) || is_ep_form(_endpoint)){ | |
for(int i=0; i< _params.length; i++){ | |
String _param = get_param(_tmp_req, _params[i]); | |
_param = this.helpers.urlDecode(_param); | |
_param = this.do_Decrypt(_param); | |
_param = remove_padding(_param); | |
_tmp_req = update_parameter(_tmp_req, _params[i], _param); | |
} | |
} | |
else if (is_ep_json(_endpoint)){ | |
for(int i=0; i< _params.length; i++){ | |
String _param = get_param(_tmp_req, _params[i]); | |
_param = this.helpers.urlDecode(_param); | |
_param = this.do_Decrypt(_param); | |
_param = remove_padding(_param); | |
_tmp_req = update_parameter_json(_tmp_req, _params[i], _param); | |
} | |
} | |
return _tmp_req; | |
} | |
public byte[] get_enc_params(byte[] _tmp_req, String _endpoint){ | |
int _index = get_ep_index(_endpoint); | |
String[] _params = this.parameters[_index]; | |
if(is_ep_get(_endpoint) || is_ep_form(_endpoint)){ | |
for(int i=0; i< _params.length; i++){ | |
String _param = get_param(_tmp_req, _params[i]); | |
_param = add_padding(_param); | |
_param = this.do_Encrypt(_param); | |
_param = this.doOff(_param); | |
// _param = this.helpers.urlEncode(_param); | |
_tmp_req = update_parameter(_tmp_req, _params[i], _param); | |
} | |
} | |
else if (is_ep_json(_endpoint)){ | |
for(int i=0; i< _params.length; i++){ | |
String _param = get_param(_tmp_req, _params[i]); | |
_param = add_padding(_param); | |
_param = this.do_Encrypt(_param); | |
_tmp_req = update_parameter_json(_tmp_req, _params[i], _param); | |
} | |
} | |
return _tmp_req; | |
} | |
@Override | |
public void processProxyMessage(boolean messageIsRequest, IInterceptedProxyMessage message) { | |
if(messageIsRequest){ | |
IHttpRequestResponse messageInfo = message.getMessageInfo(); | |
IRequestInfo reqInfo = helpers.analyzeRequest(messageInfo); | |
String URL = new String(reqInfo.getUrl().toString()); | |
List headers = reqInfo.getHeaders(); | |
if(URL.contains(this.Host_URL)){ | |
String _endpoint = get_endpoint(URL); | |
if(!ep_exists(_endpoint)){ return; } | |
byte[] tmpreq = message.getMessageInfo().getRequest(); | |
byte[] _dec_req = get_dec_params(tmpreq, _endpoint); | |
this.helpers.analyzeRequest(_dec_req).getHeaders().add("AES-Killer: v3.0"); | |
messageInfo.setRequest(_dec_req); | |
print_output("PPM", "decrypted request :: " + new String(_dec_req)); | |
} | |
}else { | |
// modify accordingly | |
} | |
} | |
@Override | |
public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) { | |
if(messageIsRequest){ | |
IRequestInfo reqInfo = helpers.analyzeRequest(messageInfo); | |
String URL = new String(reqInfo.getUrl().toString()); | |
List headers = reqInfo.getHeaders(); | |
if(URL.contains(this.Host_URL)){ | |
String _endpoint = get_endpoint(URL); | |
if(!ep_exists(_endpoint)){ return; } | |
byte[] _enc_req = get_enc_params(messageInfo.getRequest(), _endpoint); | |
messageInfo.setRequest(_enc_req); | |
print_output("PHTM :: Final Request\n ", new String(_enc_req)); | |
} | |
} | |
else{ | |
// modify accordingly | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment