From a8e315a36446534b9132e63ddf746f5827b41319 Mon Sep 17 00:00:00 2001 From: d3vilbug Date: Sat, 24 Apr 2021 02:41:22 +0500 Subject: [PATCH] SRePlay v2.0 .... --- README.md | 28 +++++-- build.gradle | 2 +- src/main/java/burp/BurpExtender.java | 54 +++++++++----- src/main/java/burp/SRePlay.form | 85 +++++++++++++++------ src/main/java/burp/SRePlay.java | 108 ++++++++++++++++++++------- 5 files changed, 198 insertions(+), 79 deletions(-) diff --git a/README.md b/README.md index 6c1844d..e4e992e 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,9 @@ **Burpsuite Plugin to bypass strict RePlay protection** - + + + ### Requirements - Burpsuite @@ -18,13 +20,26 @@ It is design for a scenario where we can't replay requests more than once as the - It will extract the value of token from the last response and automatically update the request with the new token on the fly +### Usage Guide + +The detailed usage guide can be found SRePlay - Bypass Strict Replay Protection. + ### How it works -- Provide the Host URL (e.g https://abc.com) -- Provide token parameter name to capture and replace token -- One initial value for parameter -- Click on *`Start SRePlay`* +- Provide `Host URL` +- Provide `Response parameter name` +- Provide `Request parameter name` +- Provide `Parameter Initial Value` +- Press `Start SRePlay` + + + + + +### SRePlay in Action + + + - ### Limitation - Will only work with single thread on Scanner and Intruder @@ -36,4 +51,3 @@ It is design for a scenario where we can't replay requests more than once as the ### Improvements - Multi-session / threading support -- Repeater / Intruder / Scanner UI customization diff --git a/build.gradle b/build.gradle index 5f4f159..0cfde56 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { } group 'com.bugzy.burp.SReplay' -version '1.0' +version '2.0' repositories { mavenCentral() diff --git a/src/main/java/burp/BurpExtender.java b/src/main/java/burp/BurpExtender.java index 17d8bed..a4d2ceb 100644 --- a/src/main/java/burp/BurpExtender.java +++ b/src/main/java/burp/BurpExtender.java @@ -11,7 +11,7 @@ */ public class BurpExtender implements IBurpExtender, IHttpListener, ITab{ - public String ExtensionName = "Strict Replay (SRePlay)"; + public String ExtensionName = "SRePlay"; public String TabName = "SRePlay"; public String myHeader = "SRePlay: Bypass"; @@ -30,7 +30,8 @@ public class BurpExtender implements IBurpExtender, IHttpListener, ITab{ public SRePlay _SRePlay; public String _host; - public String _parameter; + public String _req_parameter; + public String _res_parameter; public String _value; @@ -42,7 +43,9 @@ public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { this.stderr = new PrintWriter(callbacks.getStderr(), true); this.callbacks.setExtensionName(this.ExtensionName); this._SRePlay = new SRePlay(this); - + + + this.callbacks.addSuiteTab(this); this.stdout.println("SRePlay - Installed !!!"); } @@ -67,7 +70,6 @@ public void stop_SRePlay(){ this.callbacks.removeHttpListener(this); } - public String get_host(String _url){ try{ URL abc = new URL(_url); @@ -77,14 +79,12 @@ public String get_host(String _url){ return _url; } } - - + @Override public String getTabCaption() { return this.TabName; } - @Override public Component getUiComponent() { return this._SRePlay; @@ -102,8 +102,7 @@ private String update_req_json(byte[] _req, String _param, String _value){ if(_fi < 0) { return messageBody; } _fi = _fi + _param.length() + 3; - int _si = messageBody.indexOf("\",", _fi); - + int _si = messageBody.indexOf("\"", _fi); messageBody = messageBody.substring(0, _fi) + _value + messageBody.substring(_si, messageBody.length()); return messageBody; @@ -112,25 +111,31 @@ private String update_req_json(byte[] _req, String _param, String _value){ @Override public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) { + if(this._repeater && (toolFlag == IBurpExtenderCallbacks.TOOL_REPEATER)) {} + else if(this._intruder && (toolFlag == IBurpExtenderCallbacks.TOOL_INTRUDER)) {} + else if(this._scanner && (toolFlag == IBurpExtenderCallbacks.TOOL_SCANNER)) {} + else { return; } + + if(messageIsRequest){ IRequestInfo reqInfo = helpers.analyzeRequest(messageInfo); String URL = new String(reqInfo.getUrl().toString()); List headers = reqInfo.getHeaders(); - - if(IBurpExtenderCallbacks.TOOL_REPEATER != toolFlag && IBurpExtenderCallbacks.TOOL_INTRUDER != toolFlag && IBurpExtenderCallbacks.TOOL_SCANNER != toolFlag){ return; } - + if(this._host.contains(get_host(URL))){ + print_output("PHTM-Req :: Host URL Detected", URL); + byte[] _request = messageInfo.getRequest(); if(reqInfo.getContentType() == 4){ - String messageBody = update_req_json(_request, _parameter, _value); + String messageBody = update_req_json(_request, _req_parameter, _value); headers.add(this.myHeader); _request = this.helpers.buildHttpMessage(headers, messageBody.getBytes()); } else { - IParameter _p = this.helpers.getRequestParameter(_request, _parameter); + IParameter _p = this.helpers.getRequestParameter(_request, _req_parameter); if (_p == null || _p.getName().toString().length() == 0){ return; } - IParameter _newP = this.helpers.buildParameter(_parameter, _value, _p.getType()); + IParameter _newP = this.helpers.buildParameter(_req_parameter, _value, _p.getType()); _request = this.helpers.removeParameter(_request, _p); _request = this.helpers.addParameter(_request, _newP); headers.add(this.myHeader); @@ -139,8 +144,11 @@ public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequ String tmpreq = new String(_request); String messageBody = new String(tmpreq.substring(reqInfo2.getBodyOffset())).trim(); _request = this.helpers.buildHttpMessage(headers, messageBody.getBytes()); + } - + + print_output("PHTM-Req :: Final Encrypted Request", new String(_request)); + messageInfo.setRequest(_request); } @@ -150,18 +158,26 @@ public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequ String URL = new String(reqInfo.getUrl().toString()); List headers = reqInfo.getHeaders(); - if(IBurpExtenderCallbacks.TOOL_REPEATER != toolFlag && IBurpExtenderCallbacks.TOOL_INTRUDER != toolFlag && IBurpExtenderCallbacks.TOOL_SCANNER != toolFlag){ return; } - if(!headers.contains(this.myHeader)){ return; } + if(this._host.contains(get_host(URL))){ + print_output("PHTM-Res :: Host URL Detected", URL); + byte[] _response = messageInfo.getResponse(); - IParameter _p = this.helpers.getRequestParameter(_response, _parameter); + IParameter _p = this.helpers.getRequestParameter(_response, _res_parameter); if (_p == null || _p.getName().toString().length() == 0){ return; } this._value = _p.getValue().toString(); + + print_output("PHTM-Res :: new parameter value", _p.getValue().toString()); } + } } + + + + } \ No newline at end of file diff --git a/src/main/java/burp/SRePlay.form b/src/main/java/burp/SRePlay.form index 052ce40..fa11d32 100644 --- a/src/main/java/burp/SRePlay.form +++ b/src/main/java/burp/SRePlay.form @@ -11,7 +11,7 @@ - + @@ -43,13 +43,22 @@ - - - - - + + + + + + + + + + + + + + - + @@ -73,28 +82,39 @@ - - - + + - + - - - + + + + + + + + + + + + + + + - + - + @@ -109,7 +129,7 @@ - + @@ -120,7 +140,6 @@ - @@ -156,15 +175,19 @@ + + + + - + - + - - + + @@ -173,14 +196,16 @@ - + + + - + @@ -201,8 +226,20 @@ + + + + + + + + + + + + diff --git a/src/main/java/burp/SRePlay.java b/src/main/java/burp/SRePlay.java index c2de5d0..3997322 100644 --- a/src/main/java/burp/SRePlay.java +++ b/src/main/java/burp/SRePlay.java @@ -28,9 +28,9 @@ public SRePlay(BurpExtender _b) { this.jCheckBox2.setSelected(true); this.jCheckBox3.setSelected(true); - this.jCheckBox1.setEnabled(false); - this.jCheckBox2.setEnabled(false); - this.jCheckBox3.setEnabled(false); +// this.jCheckBox1.setEnabled(false); +// this.jCheckBox2.setEnabled(false); +// this.jCheckBox3.setEnabled(false); } /** @@ -57,6 +57,9 @@ private void initComponents() { jCheckBox1 = new javax.swing.JCheckBox(); jCheckBox2 = new javax.swing.JCheckBox(); jCheckBox3 = new javax.swing.JCheckBox(); + jLabel4 = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + jTextField4 = new javax.swing.JTextField(); setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.LINE_AXIS)); @@ -64,12 +67,11 @@ private void initComponents() { jLabel1.setText("Target Hosts URL"); - jLabel2.setText("Parameter to capture and replace"); + jLabel2.setText("Response Parameter to capture"); jTextField1.setToolTipText(""); jButton1.setText("Start SRePlay"); - jButton1.setActionCommand("Start SRePlay"); jButton1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton1ActionPerformed(evt); @@ -93,6 +95,8 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { jCheckBox3.setText("Scanner"); + jLabel4.setText("Select where to override the token"); + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( @@ -100,27 +104,34 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addGroup(jPanel3Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addComponent(jCheckBox3) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(jCheckBox1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 46, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jCheckBox2) - .addGap(31, 31, 31)) + .addGap(21, 21, 21)) .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(jCheckBox3) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addComponent(jLabel4) + .addGap(0, 9, Short.MAX_VALUE)))) ); jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() + .addContainerGap(7, Short.MAX_VALUE) + .addComponent(jLabel4) + .addGap(18, 18, 18) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jCheckBox1) .addComponent(jCheckBox2)) .addGap(18, 18, 18) .addComponent(jCheckBox3) - .addContainerGap(28, Short.MAX_VALUE)) + .addGap(16, 16, 16)) ); + jLabel5.setText("Request Parameter to replace with"); + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( @@ -129,12 +140,18 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addGap(31, 31, 31) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(jLabel2) - .addComponent(jLabel1) - .addComponent(jTextField2, javax.swing.GroupLayout.DEFAULT_SIZE, 307, Short.MAX_VALUE) - .addComponent(jTextField1)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 276, Short.MAX_VALUE) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2) + .addComponent(jLabel1) + .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 251, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 113, Short.MAX_VALUE) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTextField4, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 249, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5, javax.swing.GroupLayout.Alignment.TRAILING))) + .addComponent(jTextField2)) + .addGap(18, 18, 18) .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(39, 39, 39)) .addGroup(jPanel2Layout.createSequentialGroup() @@ -151,25 +168,32 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addGap(22, 22, 22) - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) - .addComponent(jLabel2) - .addGap(16, 16, 16) - .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2) + .addComponent(jLabel5)) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(16, 16, 16) + .addComponent(jTextField4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(18, 18, 18) .addComponent(jLabel3) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(37, 37, 37) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jButton1) .addComponent(jButton2)) - .addContainerGap(7, Short.MAX_VALUE)) + .addContainerGap(86, Short.MAX_VALUE)) ); jTabbedPane1.addTab("SRePlay", jPanel2); @@ -180,20 +204,41 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { add(jPanel1); }// //GEN-END:initComponents + private Boolean validate_tabs(){ + Boolean _val_tab = false; + if(jCheckBox1.isSelected()){ + this._burp._repeater = true; _val_tab = true; + } + + if (jCheckBox2.isSelected()){ + this._burp._intruder = true; _val_tab = true; + } + + if (jCheckBox3.isSelected()){ + this._burp._scanner = true; _val_tab = true; + } + return _val_tab; + } + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed String _host = this.jTextField2.getText().trim(); if(_host.length() == 0){ JOptionPane.showMessageDialog(this, "Provide Host URL !!!"); return; } - String _parameter = this.jTextField1.getText().trim(); - if(_parameter.length() == 0){ JOptionPane.showMessageDialog(this, "Provide Parameter to capture and replace !!!"); return; } + String _res_parameter = this.jTextField1.getText().trim(); + if(_res_parameter.length() == 0){ JOptionPane.showMessageDialog(this, "Provide Response Parameter to capture !!!"); return; } + + String _req_parameter = this.jTextField4.getText().trim(); + if(_req_parameter.length() == 0){ JOptionPane.showMessageDialog(this, "Provide Request Parameter to replace with !!!"); return; } String _value = this.jTextField3.getText().trim(); if(_value.length() == 0){ JOptionPane.showMessageDialog(this, "Provide Parameter Initial Value !!!"); return; } + if(!validate_tabs()) { JOptionPane.showMessageDialog(this, "Select where to override Token !!!"); return; } this._burp._host = _burp.get_host(_host); - this._burp._parameter = _parameter; + this._burp._req_parameter = _req_parameter; + this._burp._res_parameter = _res_parameter; this._burp._value = _value; this._burp.start_SRePlay(); this.jButton1.setEnabled(false); @@ -203,6 +248,10 @@ private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRS private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed // TODO add your handling code here: + this._burp._repeater = false; + this._burp._intruder = false; + this._burp._scanner = false; + this._burp.stop_SRePlay(); this.jButton1.setEnabled(true); @@ -220,6 +269,8 @@ private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRS private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel3; @@ -227,5 +278,6 @@ private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRS private javax.swing.JTextField jTextField1; private javax.swing.JTextField jTextField2; private javax.swing.JTextField jTextField3; + private javax.swing.JTextField jTextField4; // End of variables declaration//GEN-END:variables }