├── .gitignore ├── README.md ├── figures ├── tls-attacks.png ├── tls-recommendations.png ├── tls-scoring.png └── tls-versions.png ├── license_header.txt ├── pom.xml └── src └── main ├── java ├── burp │ └── BurpExtender.java └── de │ └── rub │ └── nds │ └── burp │ ├── tlsattacker │ └── gui │ │ ├── UIMain.java │ │ ├── UIScanHistory.form │ │ ├── UIScanHistory.java │ │ ├── UIScanner.form │ │ ├── UIScanner.java │ │ └── UITab.java │ └── utilities │ ├── ANSIHelper.java │ └── table │ ├── TableEntry.java │ └── TableModel.java └── resources └── de.rub.nds.burp.tlsattacker.log4j2.xml /.gitignore: -------------------------------------------------------------------------------- 1 | dependency-reduced-pom.xml 2 | *.log 3 | nbactions.xml 4 | nb-configuration.xml 5 | pom.xml.next 6 | pom.xml.releaseBackup 7 | pom.xml.tag 8 | pom.xml.versionsBackup 9 | release.properties 10 | *.swo 11 | *.swp 12 | target/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TLS-Attacker-BurpExtension 2 | 3 | The extension is based on the [TLS-Attacker](https://github.com/RUB-NDS/TLS-Attacker) and developed by the [Chair for Network and Data Security from the Ruhr-University Bochum](http://nds.rub.de/) to assist pentesters and security researchers in the evaluation of TLS Server configurations with [Burp Suite](https://portswigger.net/burp). 4 | 5 | ## Build 6 | To compile the extension from source, you need to have Java and Maven installed, as well as [TLS-Attacker](https://github.com/RUB-NDS/TLS-Attacker) in Version 3.3.1 and [TLS-Scanner](https://github.com/RUB-NDS/TLS-Scanner) in Version 3.0.2. 7 | ```bash 8 | $ mvn clean package 9 | ``` 10 | The extension has been tested with Java 1.8. 11 | 12 | ## Installation 13 | - Build the JAR file as described above, or download it from [releases](https://github.com/RUB-NDS/TLS-Attacker-BurpExtension/releases). 14 | - Load the JAR file from the target folder into Burp's Extender. 15 | 16 | ## Usage 17 | Use the URL and port of the tested server and start the scan. 18 | The scan can last up to one minute, depending on the availability of the server. 19 | After the scan has been finished, you will find the following scanning output, for example: 20 | 21 | **Supported versions and cipher suites:** 22 | 23 | ![Alt text](figures/tls-versions.png "TLS versions and cipher suites") 24 | 25 | **Analyzed attacks and vulnerabilities:** 26 | 27 | ![Alt text](figures/tls-attacks.png "TLS vulnerabilities") 28 | 29 | **Resulting score based on the analyzed properties:** 30 | 31 | ![Alt text](figures/tls-scoring.png "Security score") 32 | 33 | **Recommendations to improve your implementation configuration:** 34 | 35 | ![Alt text](figures/tls-recommendations.png "Recommendations") 36 | -------------------------------------------------------------------------------- /figures/tls-attacks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tls-attacker/TLS-Attacker-BurpExtension/22c0dea77a6697af555f4e529e046b9f51441bc6/figures/tls-attacks.png -------------------------------------------------------------------------------- /figures/tls-recommendations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tls-attacker/TLS-Attacker-BurpExtension/22c0dea77a6697af555f4e529e046b9f51441bc6/figures/tls-recommendations.png -------------------------------------------------------------------------------- /figures/tls-scoring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tls-attacker/TLS-Attacker-BurpExtension/22c0dea77a6697af555f4e529e046b9f51441bc6/figures/tls-scoring.png -------------------------------------------------------------------------------- /figures/tls-versions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tls-attacker/TLS-Attacker-BurpExtension/22c0dea77a6697af555f4e529e046b9f51441bc6/figures/tls-versions.png -------------------------------------------------------------------------------- /license_header.txt: -------------------------------------------------------------------------------- 1 | TLS-Attacker-BurpExtension 2 | 3 | Copyright 2018 Ruhr University Bochum / Hackmanit GmbH 4 | 5 | Licensed under Apache License 2.0 6 | http://www.apache.org/licenses/LICENSE-2.0/ -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | de.rub.nds.tlsattacker 5 | TLS-Attacker-BurpExtension 6 | 1.2 7 | jar 8 | 2018 9 | 10 | 11 | 12 | net.portswigger.burp.extender 13 | burp-extender-api 14 | 1.7.22 15 | 16 | 17 | 18 | de.rub.nds.tlsscanner 19 | TLS-Scanner 20 | 3.0.2 21 | 22 | 23 | 24 | UTF-8 25 | 1.8 26 | 1.8 27 | 28 | 29 | 30 | 31 | 32 | com.mycila 33 | license-maven-plugin 34 | 2.11 35 | 36 |
${basedir}/license_header.txt
37 | true 38 | 39 | src/**/*.java 40 | 41 |
42 | 43 | 44 | 45 | check 46 | 47 | 48 | 49 |
50 | 51 | 52 | maven-compiler-plugin 53 | 3.7.0 54 | 55 | 1.8 56 | 1.8 57 | 58 | 59 | 60 | 61 | maven-assembly-plugin 62 | 2.6 63 | 64 | 65 | jar-with-dependencies 66 | 67 | 68 | 69 | 70 | make-assembly 71 | package 72 | 73 | single 74 | 75 | 76 | 77 | 78 |
79 |
80 |
81 | -------------------------------------------------------------------------------- /src/main/java/burp/BurpExtender.java: -------------------------------------------------------------------------------- 1 | /** 2 | * TLS-Attacker-BurpExtension 3 | * 4 | * Copyright 2018 Ruhr University Bochum / Hackmanit GmbH 5 | * 6 | * Licensed under Apache License 2.0 7 | * http://www.apache.org/licenses/LICENSE-2.0/ 8 | */ 9 | package burp; 10 | 11 | import de.rub.nds.burp.tlsattacker.gui.UITab; 12 | import org.apache.logging.log4j.Level; 13 | import org.apache.logging.log4j.LogManager; 14 | import org.apache.logging.log4j.core.Filter; 15 | import org.apache.logging.log4j.core.LoggerContext; 16 | import org.apache.logging.log4j.core.appender.WriterAppender; 17 | import org.apache.logging.log4j.core.config.Configuration; 18 | import org.apache.logging.log4j.core.config.LoggerConfig; 19 | import org.apache.logging.log4j.core.filter.ThresholdFilter; 20 | import org.apache.logging.log4j.core.layout.PatternLayout; 21 | import java.io.PrintWriter; 22 | import java.time.LocalTime; 23 | import org.apache.logging.log4j.Logger; 24 | 25 | /** 26 | * The first class called by Burp Suite. 27 | * This is the starting class for all other functionalities. 28 | * 29 | * @author Nurullah Erinola 30 | */ 31 | public class BurpExtender implements IBurpExtender { 32 | 33 | private static final Logger LOGGER = LogManager.getLogger(BurpExtender.class.getName()); 34 | public static final String EXTENSION_NAME = "TLS-Attacker"; 35 | 36 | private UITab tab; 37 | private static PrintWriter stdout; 38 | private static PrintWriter stderr; 39 | 40 | /** 41 | * Register all new functions like for the internals and GUI. 42 | */ 43 | @Override 44 | public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { 45 | // Set extension name 46 | callbacks.setExtensionName(EXTENSION_NAME); 47 | // Oprain streans 48 | stdout = new PrintWriter(callbacks.getStdout(), true); 49 | stderr = new PrintWriter(callbacks.getStderr(), true); 50 | 51 | LocalTime t = LocalTime.now(); 52 | String time = t.toString().substring(0, t.toString().length()-4); 53 | stdout.println("+------------------------------+"); 54 | stdout.println("| TLS-Attacker |"); 55 | stdout.println("| Started @ "+time+" |"); 56 | stdout.println("+------------------------------+"); 57 | 58 | // Setup Logger 59 | System.setProperty("log4j.configurationFile", "de.rub.nds.burp.tlsattacker.log4j2.xml"); 60 | addBurpLogger(); 61 | 62 | // Register a new Tab 63 | tab = new UITab(callbacks); 64 | LOGGER.info("Tab registered."); 65 | 66 | // Register a new context menu item 67 | callbacks.registerContextMenuFactory(tab.getUiComponent().getScanner()); 68 | 69 | LOGGER.info("Init. complete."); 70 | } 71 | 72 | private void addBurpLogger() { 73 | // currentContext must be set to false 74 | final LoggerContext ctx = (LoggerContext) LogManager.getContext(false); 75 | final Configuration config = ctx.getConfiguration(); 76 | 77 | // use empty string to get config of root logger, LogManager.ROOT_LOGGER_NAME did not work for unknown reasons 78 | LoggerConfig rootLoggerCfg = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME); 79 | 80 | PatternLayout layout = PatternLayout.newBuilder().withPattern("%d{HH:mm:ss}{GMT+0} [%t] %-5level: %c{1} - %msg%n%throwable").build(); 81 | 82 | // create appender to log <= INFO to burp's stdout writer 83 | Filter infoFilter = ThresholdFilter.createFilter(Level.WARN, Filter.Result.DENY, Filter.Result.ACCEPT); 84 | WriterAppender stdoutAppender = WriterAppender.newBuilder().setName("stdoutLogger").setTarget(stdout) 85 | .setLayout(layout).setFilter(infoFilter).build(); 86 | stdoutAppender.start(); 87 | 88 | // create appender to log >= INFO to burp's sterr writer 89 | Filter warnFilter = ThresholdFilter.createFilter(Level.WARN, Filter.Result.ACCEPT, Filter.Result.DENY); 90 | WriterAppender stderrAppender = WriterAppender.newBuilder().setName("stderrLogger").setTarget(stderr) 91 | .setLayout(layout).setFilter(warnFilter).build(); 92 | stderrAppender.start(); 93 | 94 | rootLoggerCfg.addAppender(stdoutAppender, null, null); 95 | rootLoggerCfg.addAppender(stderrAppender, null, null); 96 | 97 | ctx.updateLoggers(); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/de/rub/nds/burp/tlsattacker/gui/UIMain.java: -------------------------------------------------------------------------------- 1 | /** 2 | * TLS-Attacker-BurpExtension 3 | * 4 | * Copyright 2018 Ruhr University Bochum / Hackmanit GmbH 5 | * 6 | * Licensed under Apache License 2.0 7 | * http://www.apache.org/licenses/LICENSE-2.0/ 8 | */ 9 | package de.rub.nds.burp.tlsattacker.gui; 10 | 11 | import burp.IBurpExtenderCallbacks; 12 | import javax.swing.JTabbedPane; 13 | 14 | /** 15 | * The main window. 16 | * 17 | * @author Nurullah Erinola 18 | */ 19 | public class UIMain extends JTabbedPane { 20 | 21 | private final IBurpExtenderCallbacks callbacks; 22 | private UIScanner scanner; 23 | private UIScanHistory scanHistory; 24 | 25 | /** 26 | * Construct the main UI. 27 | * @param callbacks 28 | */ 29 | public UIMain(IBurpExtenderCallbacks callbacks) { 30 | this.callbacks = callbacks; 31 | initComponents(); 32 | } 33 | 34 | private void initComponents() { 35 | //register all components on the extension tab 36 | scanHistory = new UIScanHistory(); 37 | scanner = new UIScanner(scanHistory); 38 | this.addTab("TLS-Scanner", scanner); 39 | this.addTab("Scan History", scanHistory); 40 | 41 | // Customize the UI components 42 | callbacks.customizeUiComponent(this); 43 | } 44 | 45 | public UIScanner getScanner(){ 46 | return scanner; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/de/rub/nds/burp/tlsattacker/gui/UIScanHistory.form: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /src/main/java/de/rub/nds/burp/tlsattacker/gui/UIScanHistory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * TLS-Attacker-BurpExtension 3 | * 4 | * Copyright 2018 Ruhr University Bochum / Hackmanit GmbH 5 | * 6 | * Licensed under Apache License 2.0 7 | * http://www.apache.org/licenses/LICENSE-2.0/ 8 | */ 9 | package de.rub.nds.burp.tlsattacker.gui; 10 | 11 | import de.rub.nds.burp.utilities.ANSIHelper; 12 | import de.rub.nds.burp.utilities.table.TableEntry; 13 | import de.rub.nds.burp.utilities.table.TableModel; 14 | import de.rub.nds.tlsscanner.config.ScannerConfig; 15 | import de.rub.nds.tlsscanner.report.SiteReport; 16 | import java.awt.Toolkit; 17 | import java.awt.datatransfer.Clipboard; 18 | import java.awt.datatransfer.StringSelection; 19 | import javax.swing.JTable; 20 | import javax.swing.ListSelectionModel; 21 | import javax.swing.event.ListSelectionEvent; 22 | import javax.swing.event.ListSelectionListener; 23 | import javax.swing.table.TableRowSorter; 24 | 25 | /** 26 | * Scan History displays all scanned Hosts and their reports. 27 | * 28 | * @author Nurullah Erinola 29 | */ 30 | public class UIScanHistory extends javax.swing.JPanel { 31 | 32 | private TableModel tableModel; 33 | private JTable table; 34 | 35 | /** 36 | * Creates new form UIScanHistory 37 | */ 38 | public UIScanHistory() { 39 | initComponents(); 40 | initTable(); 41 | } 42 | 43 | /** 44 | * This method is called from within the constructor to initialize the form. 45 | * WARNING: Do NOT modify this code. The content of this method is always 46 | * regenerated by the Form Editor. 47 | */ 48 | @SuppressWarnings("unchecked") 49 | // //GEN-BEGIN:initComponents 50 | private void initComponents() { 51 | 52 | jLabel1 = new javax.swing.JLabel(); 53 | jLabel2 = new javax.swing.JLabel(); 54 | jScrollPane2 = new javax.swing.JScrollPane(); 55 | jTextPaneResult = new javax.swing.JTextPane(); 56 | jButtonCopy = new javax.swing.JButton(); 57 | jScrollPaneTable = new javax.swing.JScrollPane(); 58 | jButtonClear = new javax.swing.JButton(); 59 | 60 | jLabel1.setText("Select Host:"); 61 | 62 | jLabel2.setText("Report:"); 63 | 64 | jTextPaneResult.setEditable(false); 65 | jTextPaneResult.setFont(new java.awt.Font("Monospaced", 0, 14)); // NOI18N 66 | jScrollPane2.setViewportView(jTextPaneResult); 67 | 68 | jButtonCopy.setText("Copy"); 69 | jButtonCopy.setToolTipText("Copy report to clipboard."); 70 | jButtonCopy.addActionListener(new java.awt.event.ActionListener() { 71 | public void actionPerformed(java.awt.event.ActionEvent evt) { 72 | jButtonCopyActionPerformed(evt); 73 | } 74 | }); 75 | 76 | jButtonClear.setText("Clear"); 77 | jButtonClear.setToolTipText("Remove all entries from history."); 78 | jButtonClear.addActionListener(new java.awt.event.ActionListener() { 79 | public void actionPerformed(java.awt.event.ActionEvent evt) { 80 | jButtonClearActionPerformed(evt); 81 | } 82 | }); 83 | 84 | javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); 85 | this.setLayout(layout); 86 | layout.setHorizontalGroup( 87 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 88 | .addGroup(layout.createSequentialGroup() 89 | .addContainerGap() 90 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 91 | .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING) 92 | .addComponent(jScrollPaneTable) 93 | .addGroup(layout.createSequentialGroup() 94 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 95 | .addGroup(layout.createSequentialGroup() 96 | .addComponent(jLabel2) 97 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 98 | .addComponent(jButtonCopy)) 99 | .addGroup(layout.createSequentialGroup() 100 | .addComponent(jLabel1) 101 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 102 | .addComponent(jButtonClear))) 103 | .addGap(0, 372, Short.MAX_VALUE))) 104 | .addContainerGap()) 105 | ); 106 | layout.setVerticalGroup( 107 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 108 | .addGroup(layout.createSequentialGroup() 109 | .addContainerGap() 110 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 111 | .addComponent(jLabel1) 112 | .addComponent(jButtonClear)) 113 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 114 | .addComponent(jScrollPaneTable, javax.swing.GroupLayout.PREFERRED_SIZE, 111, javax.swing.GroupLayout.PREFERRED_SIZE) 115 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 116 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 117 | .addComponent(jLabel2) 118 | .addComponent(jButtonCopy)) 119 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 120 | .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 184, Short.MAX_VALUE) 121 | .addContainerGap()) 122 | ); 123 | }// //GEN-END:initComponents 124 | 125 | private void initTable() { 126 | tableModel = new TableModel(); 127 | table = new JTable(tableModel); 128 | table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 129 | table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { 130 | @Override 131 | public void valueChanged(ListSelectionEvent lse) { 132 | SiteReport report = tableModel.getTableList().get(table.getSelectedRow()).getSiteReport(); 133 | ScannerConfig config = tableModel.getTableList().get(table.getSelectedRow()).getConfig(); 134 | String fullReport = report.getFullReport(config.getReportDetail(), !config.isNoColor()); 135 | jTextPaneResult.setStyledDocument(ANSIHelper.getStyledDocument(fullReport)); 136 | jTextPaneResult.setCaretPosition(0); 137 | } 138 | }); 139 | jScrollPaneTable.setViewportView(table); 140 | 141 | //Enable sorting 142 | TableRowSorter sorter = new TableRowSorter<>(); 143 | table.setRowSorter(sorter); 144 | sorter.setModel(tableModel); 145 | } 146 | 147 | public void add(ScannerConfig config, SiteReport report) { 148 | tableModel.addRow(new TableEntry(tableModel.getRowCount(), report, config)); 149 | } 150 | 151 | private void jButtonCopyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCopyActionPerformed 152 | String toCopy = jTextPaneResult.getText(); 153 | StringSelection stringSelection = new StringSelection(toCopy); 154 | Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); 155 | clpbrd.setContents(stringSelection, null); 156 | }//GEN-LAST:event_jButtonCopyActionPerformed 157 | 158 | private void jButtonClearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonClearActionPerformed 159 | tableModel.clear(); 160 | jTextPaneResult.setText(""); 161 | }//GEN-LAST:event_jButtonClearActionPerformed 162 | 163 | // Variables declaration - do not modify//GEN-BEGIN:variables 164 | private javax.swing.JButton jButtonClear; 165 | private javax.swing.JButton jButtonCopy; 166 | private javax.swing.JLabel jLabel1; 167 | private javax.swing.JLabel jLabel2; 168 | private javax.swing.JScrollPane jScrollPane2; 169 | private javax.swing.JScrollPane jScrollPaneTable; 170 | private javax.swing.JTextPane jTextPaneResult; 171 | // End of variables declaration//GEN-END:variables 172 | } 173 | -------------------------------------------------------------------------------- /src/main/java/de/rub/nds/burp/tlsattacker/gui/UIScanner.form: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | -------------------------------------------------------------------------------- /src/main/java/de/rub/nds/burp/tlsattacker/gui/UIScanner.java: -------------------------------------------------------------------------------- 1 | /** 2 | * TLS-Attacker-BurpExtension 3 | * 4 | * Copyright 2018 Ruhr University Bochum / Hackmanit GmbH 5 | * 6 | * Licensed under Apache License 2.0 7 | * http://www.apache.org/licenses/LICENSE-2.0/ 8 | */ 9 | package de.rub.nds.burp.tlsattacker.gui; 10 | 11 | import burp.IContextMenuFactory; 12 | import burp.IContextMenuInvocation; 13 | import de.rub.nds.burp.utilities.ANSIHelper; 14 | import de.rub.nds.tlsattacker.core.config.delegate.GeneralDelegate; 15 | import de.rub.nds.tlsattacker.core.constants.StarttlsType; 16 | import de.rub.nds.tlsscanner.TlsScanner; 17 | import de.rub.nds.tlsscanner.config.ScannerConfig; 18 | import de.rub.nds.tlsscanner.constants.ScannerDetail; 19 | import de.rub.nds.tlsscanner.report.SiteReport; 20 | import java.awt.Toolkit; 21 | import java.awt.datatransfer.Clipboard; 22 | import java.awt.datatransfer.StringSelection; 23 | import java.awt.event.ActionListener; 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | import javax.swing.DefaultComboBoxModel; 27 | import javax.swing.JCheckBoxMenuItem; 28 | import javax.swing.JMenuItem; 29 | import javax.swing.SwingWorker; 30 | import org.apache.logging.log4j.LogManager; 31 | import org.apache.logging.log4j.Logger; 32 | 33 | /** 34 | * TLS-Scanner. 35 | * 36 | * @author Nurullah Erinola 37 | */ 38 | public class UIScanner extends javax.swing.JPanel implements IContextMenuFactory { 39 | 40 | private static final Logger LOGGER = LogManager.getLogger(UIScanner.class.getName()); 41 | private UIScanHistory scanHistory; 42 | 43 | /** 44 | * Creates new form UIScanner. 45 | */ 46 | public UIScanner(UIScanHistory scanHistory) { 47 | initComponents(); 48 | initJComboBoxes(); 49 | this.scanHistory = scanHistory; 50 | } 51 | 52 | /** 53 | * This method is called from within the constructor to initialize the form. 54 | * WARNING: Do NOT modify this code. The content of this method is always 55 | * regenerated by the Form Editor. 56 | */ 57 | @SuppressWarnings("unchecked") 58 | // //GEN-BEGIN:initComponents 59 | private void initComponents() { 60 | 61 | jButtonScan = new javax.swing.JButton(); 62 | jTextFieldHost = new javax.swing.JTextField(); 63 | jLabel1 = new javax.swing.JLabel(); 64 | jLabel3 = new javax.swing.JLabel(); 65 | jButtonCopy = new javax.swing.JButton(); 66 | jLabel2 = new javax.swing.JLabel(); 67 | jLabel4 = new javax.swing.JLabel(); 68 | jLabel5 = new javax.swing.JLabel(); 69 | jLabel6 = new javax.swing.JLabel(); 70 | jLabel7 = new javax.swing.JLabel(); 71 | jTextFieldParallelProbes = new javax.swing.JTextField(); 72 | jTextFieldOverallThreads = new javax.swing.JTextField(); 73 | jComboBoxDangerLevel = new javax.swing.JComboBox<>(); 74 | jComboBoxReportDetail = new javax.swing.JComboBox<>(); 75 | jComboBoxScanDetail = new javax.swing.JComboBox<>(); 76 | jCheckBoxNoColor = new javax.swing.JCheckBox(); 77 | jCheckBoxDefaultSetting = new javax.swing.JCheckBox(); 78 | jScrollPaneResult = new javax.swing.JScrollPane(); 79 | jTextPaneResult = new javax.swing.JTextPane(); 80 | jCheckBoxStarTls = new javax.swing.JCheckBox(); 81 | jComboBoxStarTLS = new javax.swing.JComboBox<>(); 82 | jLabel8 = new javax.swing.JLabel(); 83 | jTextFieldTimeout = new javax.swing.JTextField(); 84 | 85 | jButtonScan.setText("Scan"); 86 | jButtonScan.addActionListener(new java.awt.event.ActionListener() { 87 | public void actionPerformed(java.awt.event.ActionEvent evt) { 88 | jButtonScanActionPerformed(evt); 89 | } 90 | }); 91 | 92 | jTextFieldHost.setText("localhost:4433"); 93 | jTextFieldHost.setToolTipText("Who to connect to. Syntax: localhost:4433"); 94 | 95 | jLabel1.setText("Host:"); 96 | 97 | jLabel3.setText("Result:"); 98 | 99 | jButtonCopy.setText("Copy"); 100 | jButtonCopy.setToolTipText("Copy report to clipboard."); 101 | jButtonCopy.addActionListener(new java.awt.event.ActionListener() { 102 | public void actionPerformed(java.awt.event.ActionEvent evt) { 103 | jButtonCopyActionPerformed(evt); 104 | } 105 | }); 106 | 107 | jLabel2.setText("Parallel Probes:"); 108 | jLabel2.setToolTipText("Defines the number of threads responsible for different TLS probes. If set to 1, only one specific TLS probe (e.g., TLS version scan) can be run in time."); 109 | 110 | jLabel4.setText("Overall Threads:"); 111 | jLabel4.setToolTipText("The maximum number of threads used to execute TLS probes located in the scanning queue. This is also the maximum number of threads communicating with the analyzed server."); 112 | 113 | jLabel5.setText("Danger Level:"); 114 | jLabel5.setToolTipText("How aggressive the Scanner should test"); 115 | 116 | jLabel6.setText("Scan Detail:"); 117 | jLabel6.setToolTipText("How detailed do you want to scan."); 118 | 119 | jLabel7.setText("Report Detail:"); 120 | jLabel7.setToolTipText("How detailed do you want the report to be."); 121 | 122 | jTextFieldParallelProbes.setText("4"); 123 | jTextFieldParallelProbes.setToolTipText("Enter only numbers."); 124 | jTextFieldParallelProbes.setEnabled(false); 125 | 126 | jTextFieldOverallThreads.setText("100"); 127 | jTextFieldOverallThreads.setToolTipText("Enter only numbers."); 128 | jTextFieldOverallThreads.setEnabled(false); 129 | 130 | jComboBoxDangerLevel.setEnabled(false); 131 | 132 | jComboBoxReportDetail.setEnabled(false); 133 | 134 | jComboBoxScanDetail.setEnabled(false); 135 | 136 | jCheckBoxNoColor.setText("No color"); 137 | jCheckBoxNoColor.setToolTipText("If you don't want colored text."); 138 | 139 | jCheckBoxDefaultSetting.setSelected(true); 140 | jCheckBoxDefaultSetting.setText("Use default settings"); 141 | jCheckBoxDefaultSetting.addActionListener(new java.awt.event.ActionListener() { 142 | public void actionPerformed(java.awt.event.ActionEvent evt) { 143 | jCheckBoxDefaultSettingActionPerformed(evt); 144 | } 145 | }); 146 | 147 | jTextPaneResult.setEditable(false); 148 | jTextPaneResult.setFont(new java.awt.Font("Monospaced", 0, 14)); // NOI18N 149 | jScrollPaneResult.setViewportView(jTextPaneResult); 150 | 151 | jCheckBoxStarTls.setText("Scan STARTTLS:"); 152 | jCheckBoxStarTls.addActionListener(new java.awt.event.ActionListener() { 153 | public void actionPerformed(java.awt.event.ActionEvent evt) { 154 | jCheckBoxStarTlsActionPerformed(evt); 155 | } 156 | }); 157 | 158 | jComboBoxStarTLS.setEnabled(false); 159 | 160 | jLabel8.setText("Timeout:"); 161 | jLabel8.setToolTipText("The timeout used for the scans in ms."); 162 | 163 | jTextFieldTimeout.setText("1000"); 164 | jTextFieldTimeout.setToolTipText("Enter only numbers."); 165 | jTextFieldTimeout.setEnabled(false); 166 | 167 | javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); 168 | this.setLayout(layout); 169 | layout.setHorizontalGroup( 170 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 171 | .addGroup(layout.createSequentialGroup() 172 | .addContainerGap() 173 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 174 | .addComponent(jScrollPaneResult, javax.swing.GroupLayout.DEFAULT_SIZE, 799, Short.MAX_VALUE) 175 | .addGroup(layout.createSequentialGroup() 176 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) 177 | .addGroup(layout.createSequentialGroup() 178 | .addComponent(jLabel3) 179 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 180 | .addComponent(jButtonCopy)) 181 | .addComponent(jButtonScan, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 182 | .addGroup(layout.createSequentialGroup() 183 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 184 | .addComponent(jLabel2) 185 | .addComponent(jLabel6) 186 | .addComponent(jLabel5) 187 | .addComponent(jLabel1)) 188 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 189 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 190 | .addComponent(jTextFieldHost, javax.swing.GroupLayout.PREFERRED_SIZE, 525, javax.swing.GroupLayout.PREFERRED_SIZE) 191 | .addGroup(layout.createSequentialGroup() 192 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) 193 | .addComponent(jComboBoxScanDetail, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 194 | .addComponent(jComboBoxDangerLevel, javax.swing.GroupLayout.PREFERRED_SIZE, 118, javax.swing.GroupLayout.PREFERRED_SIZE) 195 | .addComponent(jTextFieldParallelProbes, javax.swing.GroupLayout.Alignment.TRAILING)) 196 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 197 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 198 | .addComponent(jLabel4) 199 | .addComponent(jLabel7) 200 | .addComponent(jLabel8)) 201 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 202 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) 203 | .addComponent(jTextFieldTimeout, javax.swing.GroupLayout.Alignment.LEADING) 204 | .addComponent(jComboBoxReportDetail, 0, 118, Short.MAX_VALUE) 205 | .addComponent(jTextFieldOverallThreads))) 206 | .addGroup(layout.createSequentialGroup() 207 | .addComponent(jCheckBoxDefaultSetting) 208 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 209 | .addComponent(jCheckBoxNoColor)) 210 | .addGroup(layout.createSequentialGroup() 211 | .addComponent(jCheckBoxStarTls) 212 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 213 | .addComponent(jComboBoxStarTLS, javax.swing.GroupLayout.PREFERRED_SIZE, 118, javax.swing.GroupLayout.PREFERRED_SIZE))))) 214 | .addGap(0, 0, Short.MAX_VALUE))) 215 | .addContainerGap()) 216 | ); 217 | layout.setVerticalGroup( 218 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 219 | .addGroup(layout.createSequentialGroup() 220 | .addContainerGap() 221 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 222 | .addComponent(jLabel1) 223 | .addComponent(jTextFieldHost, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 224 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 225 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 226 | .addComponent(jCheckBoxDefaultSetting) 227 | .addComponent(jCheckBoxNoColor)) 228 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 229 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 230 | .addComponent(jCheckBoxStarTls) 231 | .addComponent(jComboBoxStarTLS, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 232 | .addGap(18, 18, 18) 233 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 234 | .addComponent(jLabel2) 235 | .addComponent(jTextFieldParallelProbes, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 236 | .addComponent(jTextFieldOverallThreads, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 237 | .addComponent(jLabel4)) 238 | .addGap(9, 9, 9) 239 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 240 | .addComponent(jComboBoxScanDetail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 241 | .addComponent(jLabel6) 242 | .addComponent(jLabel7) 243 | .addComponent(jComboBoxReportDetail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 244 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 245 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 246 | .addComponent(jComboBoxDangerLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 247 | .addComponent(jLabel5) 248 | .addComponent(jLabel8) 249 | .addComponent(jTextFieldTimeout, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 250 | .addGap(19, 19, 19) 251 | .addComponent(jButtonScan) 252 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 253 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 254 | .addComponent(jLabel3) 255 | .addComponent(jButtonCopy)) 256 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 257 | .addComponent(jScrollPaneResult, javax.swing.GroupLayout.DEFAULT_SIZE, 185, Short.MAX_VALUE) 258 | .addContainerGap()) 259 | ); 260 | }// //GEN-END:initComponents 261 | 262 | private void initJComboBoxes() { 263 | // Init jComboBox for STARTLS protocol selection 264 | ArrayList list = new ArrayList<>(); 265 | list.add(StarttlsType.FTP.toString()); 266 | list.add(StarttlsType.IMAP.toString()); 267 | list.add(StarttlsType.POP3.toString()); 268 | list.add(StarttlsType.SMTP.toString()); 269 | jComboBoxStarTLS.setModel(new DefaultComboBoxModel(list.toArray())); 270 | // Init jComboBox for Scan Detail and Report Detail 271 | list = new ArrayList<>(); 272 | list.add(ScannerDetail.ALL.toString()); 273 | list.add(ScannerDetail.DETAILED.toString()); 274 | list.add(ScannerDetail.NORMAL.toString()); 275 | list.add(ScannerDetail.QUICK.toString()); 276 | jComboBoxScanDetail.setModel(new DefaultComboBoxModel(list.toArray())); 277 | jComboBoxScanDetail.setSelectedIndex(2); 278 | jComboBoxReportDetail.setModel(new DefaultComboBoxModel(list.toArray())); 279 | jComboBoxReportDetail.setSelectedIndex(2); 280 | // Init jComboBox for Danger Level 281 | list = new ArrayList<>(); 282 | for(int i = 1; i <= 10; i++) { 283 | list.add(String.valueOf(i)); 284 | } 285 | jComboBoxDangerLevel.setModel(new DefaultComboBoxModel(list.toArray())); 286 | jComboBoxDangerLevel.setSelectedIndex(9); 287 | } 288 | 289 | /** 290 | * Add new menu item to context menu. 291 | */ 292 | @Override 293 | public List createMenuItems(IContextMenuInvocation contextMenuInvocation) { 294 | List menuList = new ArrayList<>(); 295 | JMenuItem jMenuItemSendToScanner = new JCheckBoxMenuItem("Send to TLS-Scanner"); 296 | jMenuItemSendToScanner.addActionListener(new ActionListener() { 297 | @Override 298 | public void actionPerformed(java.awt.event.ActionEvent evt) { 299 | // Set selected Host 300 | jTextFieldHost.setText(contextMenuInvocation.getSelectedMessages()[0].getHttpService().getHost()); 301 | } 302 | }); 303 | menuList.add(jMenuItemSendToScanner); 304 | return menuList; 305 | } 306 | 307 | /** 308 | * Check user inputs. 309 | * @return True if checks failed. 310 | */ 311 | private boolean checkInputs() { 312 | boolean checkFailed = false; 313 | jTextPaneResult.setText(""); 314 | // check Host 315 | if(jTextFieldHost.getText() == null) { 316 | jTextPaneResult.setText(jTextPaneResult.getText() + "-Could not parse provided host: " + jTextFieldHost.getText() + "\n"); 317 | checkFailed = true; 318 | } else { 319 | String[] parsedHost = jTextFieldHost.getText().split(":"); 320 | switch (parsedHost.length) { 321 | case 1: 322 | break; 323 | case 2: 324 | if(parsedHost[1].matches("[0-9]+")) { 325 | int port = Integer.parseInt(parsedHost[1]); 326 | if (port >= 0 && port <= 65535) { 327 | break; 328 | } 329 | } 330 | jTextPaneResult.setText(jTextPaneResult.getText() + "-Port must be in interval [0,65535], but is " + parsedHost[1] + "\n"); 331 | checkFailed = true; 332 | break; 333 | default: 334 | jTextPaneResult.setText(jTextPaneResult.getText() + "-Could not parse provided host: " + jTextFieldHost.getText() + "\n"); 335 | checkFailed = true; 336 | break; 337 | } 338 | } 339 | if(!jCheckBoxDefaultSetting.isSelected()) { 340 | // check ParallelProbes, OverallThreads, Timeout 341 | if(!jTextFieldParallelProbes.getText().matches("[0-9]+")) { 342 | jTextPaneResult.setText(jTextPaneResult.getText() + "-Parallel Probes input is not a number or empty\n"); 343 | checkFailed = true; 344 | } 345 | if(!jTextFieldOverallThreads.getText().matches("[0-9]+")) { 346 | jTextPaneResult.setText(jTextPaneResult.getText() + "-Overall Threads input is not a number or empty\n"); 347 | checkFailed = true; 348 | } 349 | if(!jTextFieldTimeout.getText().matches("[0-9]+")) { 350 | jTextPaneResult.setText(jTextPaneResult.getText() + "-Timeout input is not a number or empty\n"); 351 | checkFailed = true; 352 | } 353 | } 354 | return checkFailed; 355 | } 356 | 357 | private void jButtonScanActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonScanActionPerformed 358 | // Check user inputs 359 | if(checkInputs()) { 360 | return; 361 | } 362 | // Create config 363 | ScannerConfig config = new ScannerConfig(new GeneralDelegate()); 364 | config.getClientDelegate().setHost(jTextFieldHost.getText()); 365 | config.setNoColor(jCheckBoxNoColor.isSelected()); 366 | config.setParallelProbes(4); 367 | config.setOverallThreads(100); 368 | config.setTimeout(1000); 369 | if(!jCheckBoxDefaultSetting.isSelected()) { 370 | config.setDangerLevel(Integer.parseInt((String) jComboBoxDangerLevel.getSelectedItem())); 371 | config.setParallelProbes(Integer.parseInt(jTextFieldParallelProbes.getText())); 372 | config.setOverallThreads(Integer.parseInt(jTextFieldOverallThreads.getText())); 373 | config.setTimeout(Integer.parseInt(jTextFieldTimeout.getText())); 374 | config.setReportDetail(ScannerDetail.valueOf((String) jComboBoxReportDetail.getSelectedItem())); 375 | config.setScanDetail(ScannerDetail.valueOf((String) jComboBoxScanDetail.getSelectedItem())); 376 | } 377 | if(jCheckBoxStarTls.isSelected()) { 378 | config.getStarttlsDelegate().setStarttlsType(StarttlsType.valueOf((String) jComboBoxStarTLS.getSelectedItem())); 379 | } 380 | // Clarify scan start 381 | jTextPaneResult.setStyledDocument(ANSIHelper.getStyledDocument("Scanning " + config.getClientDelegate().getHost() + " - please be patient...")); 382 | jButtonScan.setEnabled(false); 383 | // Use SwingWorker to execute scan in backround 384 | SwingWorker worker = new SwingWorker() { 385 | SiteReport report; 386 | 387 | @Override 388 | protected Boolean doInBackground() throws Exception { 389 | LOGGER.info("---------- Start scanning of {} ----------", config.getClientDelegate().getHost()); 390 | // Init scanner and start scan 391 | TlsScanner scanner = new TlsScanner(config); 392 | report = scanner.scan(); 393 | return true; 394 | } 395 | @Override 396 | protected void done() { 397 | LOGGER.info("---------- Scan of {} finished ----------", config.getClientDelegate().getHost()); 398 | jButtonScan.setEnabled(true); 399 | // Print scan result 400 | if(report != null) { 401 | String fullReport = report.getFullReport(config.getReportDetail(), !config.isNoColor()); 402 | jTextPaneResult.setStyledDocument(ANSIHelper.getStyledDocument(fullReport)); 403 | jTextPaneResult.setCaretPosition(0); 404 | // Send config and report to scan history 405 | scanHistory.add(config, report); 406 | } else { 407 | jTextPaneResult.setStyledDocument(ANSIHelper.getStyledDocument("Scan of " + config.getClientDelegate().getHost() + " failed...")); 408 | } 409 | } 410 | }; 411 | worker.execute(); 412 | }//GEN-LAST:event_jButtonScanActionPerformed 413 | 414 | private void jButtonCopyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCopyActionPerformed 415 | String toCopy = jTextPaneResult.getText(); 416 | StringSelection stringSelection = new StringSelection(toCopy); 417 | Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); 418 | clpbrd.setContents(stringSelection, null); 419 | }//GEN-LAST:event_jButtonCopyActionPerformed 420 | 421 | private void jCheckBoxDefaultSettingActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxDefaultSettingActionPerformed 422 | if(jCheckBoxDefaultSetting.isSelected()) { 423 | jComboBoxDangerLevel.setEnabled(false); 424 | jComboBoxReportDetail.setEnabled(false); 425 | jComboBoxScanDetail.setEnabled(false); 426 | jTextFieldOverallThreads.setEnabled(false); 427 | jTextFieldParallelProbes.setEnabled(false); 428 | jTextFieldTimeout.setEnabled(false); 429 | } else { 430 | jComboBoxDangerLevel.setEnabled(true); 431 | jComboBoxReportDetail.setEnabled(true); 432 | jComboBoxScanDetail.setEnabled(true); 433 | jTextFieldOverallThreads.setEnabled(true); 434 | jTextFieldParallelProbes.setEnabled(true); 435 | jTextFieldTimeout.setEnabled(true); 436 | } 437 | }//GEN-LAST:event_jCheckBoxDefaultSettingActionPerformed 438 | 439 | private void jCheckBoxStarTlsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxStarTlsActionPerformed 440 | if(jCheckBoxStarTls.isSelected()) { 441 | jComboBoxStarTLS.setEnabled(true); 442 | } else { 443 | jComboBoxStarTLS.setEnabled(false); 444 | } 445 | }//GEN-LAST:event_jCheckBoxStarTlsActionPerformed 446 | 447 | 448 | // Variables declaration - do not modify//GEN-BEGIN:variables 449 | private javax.swing.JButton jButtonCopy; 450 | private javax.swing.JButton jButtonScan; 451 | private javax.swing.JCheckBox jCheckBoxDefaultSetting; 452 | private javax.swing.JCheckBox jCheckBoxNoColor; 453 | private javax.swing.JCheckBox jCheckBoxStarTls; 454 | private javax.swing.JComboBox jComboBoxDangerLevel; 455 | private javax.swing.JComboBox jComboBoxReportDetail; 456 | private javax.swing.JComboBox jComboBoxScanDetail; 457 | private javax.swing.JComboBox jComboBoxStarTLS; 458 | private javax.swing.JLabel jLabel1; 459 | private javax.swing.JLabel jLabel2; 460 | private javax.swing.JLabel jLabel3; 461 | private javax.swing.JLabel jLabel4; 462 | private javax.swing.JLabel jLabel5; 463 | private javax.swing.JLabel jLabel6; 464 | private javax.swing.JLabel jLabel7; 465 | private javax.swing.JLabel jLabel8; 466 | private javax.swing.JScrollPane jScrollPaneResult; 467 | private javax.swing.JTextField jTextFieldHost; 468 | private javax.swing.JTextField jTextFieldOverallThreads; 469 | private javax.swing.JTextField jTextFieldParallelProbes; 470 | private javax.swing.JTextField jTextFieldTimeout; 471 | private javax.swing.JTextPane jTextPaneResult; 472 | // End of variables declaration//GEN-END:variables 473 | } 474 | -------------------------------------------------------------------------------- /src/main/java/de/rub/nds/burp/tlsattacker/gui/UITab.java: -------------------------------------------------------------------------------- 1 | /** 2 | * TLS-Attacker-BurpExtension 3 | * 4 | * Copyright 2018 Ruhr University Bochum / Hackmanit GmbH 5 | * 6 | * Licensed under Apache License 2.0 7 | * http://www.apache.org/licenses/LICENSE-2.0/ 8 | */ 9 | package de.rub.nds.burp.tlsattacker.gui; 10 | 11 | import burp.IBurpExtenderCallbacks; 12 | import burp.ITab; 13 | 14 | /** 15 | * An additional tab in Burp Suite. 16 | * 17 | * @author Nurullah Erinola 18 | */ 19 | public class UITab implements ITab { 20 | 21 | private UIMain main; 22 | private final IBurpExtenderCallbacks callbacks; 23 | 24 | /** 25 | * Create a new Tab. 26 | * @param callbacks 27 | */ 28 | public UITab(IBurpExtenderCallbacks callbacks) { 29 | this.callbacks = callbacks; 30 | this.main = new UIMain(callbacks); 31 | callbacks.customizeUiComponent(main); 32 | callbacks.addSuiteTab(this); 33 | } 34 | 35 | /** 36 | * @return Get the UI component that should be registered at the Burp Suite GUI. 37 | */ 38 | @Override 39 | public UIMain getUiComponent() { 40 | return main; 41 | } 42 | 43 | /** 44 | * @return Get the headline for the Tab. 45 | */ 46 | @Override 47 | public String getTabCaption() { 48 | return "TLS-Attacker"; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/de/rub/nds/burp/utilities/ANSIHelper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * TLS-Attacker-BurpExtension 3 | * 4 | * Copyright 2018 Ruhr University Bochum / Hackmanit GmbH 5 | * 6 | * Licensed under Apache License 2.0 7 | * http://www.apache.org/licenses/LICENSE-2.0/ 8 | */ 9 | package de.rub.nds.burp.utilities; 10 | 11 | import de.rub.nds.tlsscanner.constants.AnsiColor; 12 | import java.awt.Color; 13 | import javax.swing.text.BadLocationException; 14 | import javax.swing.text.DefaultStyledDocument; 15 | import javax.swing.text.SimpleAttributeSet; 16 | import javax.swing.text.StyleConstants; 17 | import javax.swing.text.StyledDocument; 18 | import org.apache.commons.lang3.StringUtils; 19 | 20 | /** 21 | * Printer for the SiteReport. 22 | * 23 | * @author Nurullah Erinola 24 | */ 25 | public class ANSIHelper { 26 | 27 | // self defined colors 28 | private static final Color LIGHT_ORANGE = new Color(255, 153, 0); 29 | private static final Color DARK_RED = new Color(204, 0, 0); 30 | private static final Color DARK_BLUE = new Color(0, 0, 204); 31 | private static final Color DARK_GREEN = new Color(0, 153, 0); 32 | private static final Color DARK_VIOLET = new Color(148,0,211); 33 | 34 | private static final String ANSI_START = "\u001B["; 35 | private static final String ANSI_END = "m"; 36 | 37 | public static StyledDocument getStyledDocument(String report) { 38 | StyledDocument document = new DefaultStyledDocument(); 39 | SimpleAttributeSet attributes = new SimpleAttributeSet(); 40 | 41 | int currentPos = 0; // current char position in report 42 | int startIndex = 0; // start of escape sequence 43 | int endIndex = 0; // end of escape sequence 44 | 45 | String tmp = ""; 46 | 47 | if (report.length() > 0) { 48 | // Search start of escape sequence 49 | startIndex = report.indexOf(ANSI_START); 50 | // No escape sequence found, print all 51 | if (startIndex == -1) { 52 | append(document, attributes, report); 53 | return document; 54 | } 55 | // Escape sequence is not first char, print all text to escape sequence 56 | if (startIndex > 0) { 57 | tmp = report.substring(0, startIndex); 58 | document = append(document, attributes, tmp); 59 | currentPos = startIndex; 60 | } 61 | 62 | while (true) { 63 | // Search the end of the escape sequence 64 | endIndex = report.indexOf(ANSI_END, currentPos); 65 | 66 | // End of escape sequence not found, print all 67 | if (endIndex == -1) { 68 | document = append(document, attributes, report.substring(currentPos, report.length())); 69 | break; 70 | // End of escape sequence found, parse 71 | } else { 72 | tmp = report.substring(currentPos, endIndex+1); 73 | attributes = parseAndAdd(attributes, tmp); 74 | currentPos = endIndex+1; 75 | } 76 | 77 | // Search start of next escape sequence 78 | startIndex = report.indexOf(ANSI_START, currentPos); 79 | 80 | // No further escape sequence available, print all 81 | if (startIndex == -1) { 82 | document = append(document, attributes, report.substring(currentPos, report.length())); 83 | break; 84 | // Further escape sequence available, print substring between escape sequence 85 | } else { 86 | document = append(document, attributes, report.substring(currentPos, startIndex)); 87 | currentPos = startIndex; 88 | } 89 | } 90 | } 91 | return document; 92 | } 93 | 94 | private static String replaceTabs(String string) { 95 | String[] splitted = string.split("\n", -1); 96 | for(int i = 0; i < splitted.length; i++) { 97 | int pos = splitted[i].indexOf("\t"); 98 | while(pos != -1) { 99 | splitted[i] = splitted[i].replaceFirst("\t", StringUtils.repeat(" ", 8-(pos%8))); 100 | pos = splitted[i].indexOf("\t"); 101 | } 102 | } 103 | return String.join("\n", splitted); 104 | } 105 | 106 | private static StyledDocument append(StyledDocument document, SimpleAttributeSet attributes, String toAppend) { 107 | try { 108 | document.insertString(document.getLength(), replaceTabs(toAppend), attributes); 109 | } catch (BadLocationException exp) { 110 | 111 | } 112 | return document; 113 | } 114 | 115 | private static SimpleAttributeSet parseAndAdd(SimpleAttributeSet attrSet, String ansi) { 116 | switch(AnsiColor.getAnsiColor(ansi)) { 117 | case RESET: 118 | attrSet = new SimpleAttributeSet(); 119 | break; 120 | case BLACK: 121 | attrSet.addAttribute(StyleConstants.Foreground, Color.BLACK); 122 | break; 123 | case RED: 124 | attrSet.addAttribute(StyleConstants.Foreground, DARK_RED); 125 | break; 126 | case GREEN: 127 | attrSet.addAttribute(StyleConstants.Foreground, DARK_GREEN); 128 | break; 129 | case YELLOW: 130 | attrSet.addAttribute(StyleConstants.Foreground, LIGHT_ORANGE); 131 | break; 132 | case BLUE: 133 | attrSet.addAttribute(StyleConstants.Foreground, DARK_BLUE); 134 | break; 135 | case PURPLE: 136 | attrSet.addAttribute(StyleConstants.Foreground, DARK_VIOLET); 137 | break; 138 | case CYAN: 139 | attrSet.addAttribute(StyleConstants.Foreground, Color.CYAN); 140 | break; 141 | case WHITE: 142 | attrSet.addAttribute(StyleConstants.Foreground, Color.WHITE); 143 | break; 144 | case BLACK_BACKGROUND: 145 | attrSet.addAttribute(StyleConstants.Background, Color.BLACK); 146 | break; 147 | case RED_BACKGROUND: 148 | attrSet.addAttribute(StyleConstants.Background, DARK_RED); 149 | break; 150 | case GREEN_BACKGROUND: 151 | attrSet.addAttribute(StyleConstants.Background, DARK_GREEN); 152 | break; 153 | case YELLOW_BACKGROUND: 154 | attrSet.addAttribute(StyleConstants.Background, LIGHT_ORANGE); 155 | break; 156 | case BLUE_BACKGROUND: 157 | attrSet.addAttribute(StyleConstants.Background, DARK_BLUE); 158 | break; 159 | case PURPLE_BACKGROUND: 160 | attrSet.addAttribute(StyleConstants.Background, DARK_VIOLET); 161 | break; 162 | case CYAN_BACKGROUND: 163 | attrSet.addAttribute(StyleConstants.Background, Color.CYAN); 164 | break; 165 | case WHITE_BACKGROUND: 166 | attrSet.addAttribute(StyleConstants.Background, Color.WHITE); 167 | break; 168 | case BOLD: 169 | attrSet.addAttribute(StyleConstants.CharacterConstants.Bold, Boolean.TRUE); 170 | break; 171 | case UNDERLINE: 172 | StyleConstants.setUnderline(attrSet, true); 173 | break; 174 | default: 175 | break; 176 | } 177 | return attrSet; 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /src/main/java/de/rub/nds/burp/utilities/table/TableEntry.java: -------------------------------------------------------------------------------- 1 | /** 2 | * TLS-Attacker-BurpExtension 3 | * 4 | * Copyright 2018 Ruhr University Bochum / Hackmanit GmbH 5 | * 6 | * Licensed under Apache License 2.0 7 | * http://www.apache.org/licenses/LICENSE-2.0/ 8 | */ 9 | package de.rub.nds.burp.utilities.table; 10 | 11 | import de.rub.nds.tlsscanner.config.ScannerConfig; 12 | import de.rub.nds.tlsscanner.report.SiteReport; 13 | 14 | /** 15 | * A table entry for the class Table. 16 | * 17 | * @author Nurullah Erinola 18 | */ 19 | public class TableEntry { 20 | 21 | private ScannerConfig config; 22 | private SiteReport report; 23 | private String counter; 24 | private String host; 25 | private String danger; 26 | private String noColor; 27 | private String scanDetail; 28 | private String reportDetail; 29 | private String starTls; 30 | 31 | /** 32 | * Construct a new table entry. 33 | */ 34 | public TableEntry(int counter, SiteReport report, ScannerConfig config) { 35 | this.report = report; 36 | this.config = config; 37 | this.host = report.getHost(); 38 | this.counter = Integer.toString(counter); 39 | this.danger = Integer.toString(config.getDangerLevel()); 40 | this.noColor = Boolean.toString(config.isNoColor()); 41 | this.scanDetail = config.getScanDetail().toString(); 42 | this.reportDetail = config.getReportDetail().toString(); 43 | this.starTls = config.getStarttlsDelegate().getStarttlsType().toString(); 44 | } 45 | 46 | public SiteReport getSiteReport() { 47 | return report; 48 | } 49 | 50 | public ScannerConfig getConfig() { 51 | return config; 52 | } 53 | 54 | public String getCounter() { 55 | return counter; 56 | } 57 | 58 | public String getHost() { 59 | return host; 60 | } 61 | 62 | public String getDanger() { 63 | return danger; 64 | } 65 | 66 | public String getNoColor() { 67 | return noColor; 68 | } 69 | 70 | public String getScanDetail() { 71 | return scanDetail; 72 | } 73 | 74 | public String getReportDetail() { 75 | return reportDetail; 76 | } 77 | 78 | public String getStarTls() { 79 | return starTls; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/de/rub/nds/burp/utilities/table/TableModel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * TLS-Attacker-BurpExtension 3 | * 4 | * Copyright 2018 Ruhr University Bochum / Hackmanit GmbH 5 | * 6 | * Licensed under Apache License 2.0 7 | * http://www.apache.org/licenses/LICENSE-2.0/ 8 | */ 9 | package de.rub.nds.burp.utilities.table; 10 | 11 | import java.util.ArrayList; 12 | import javax.swing.table.AbstractTableModel; 13 | 14 | /** 15 | * Helper class for the class Table. 16 | * 17 | * @author Nurullah Erinola 18 | */ 19 | public class TableModel extends AbstractTableModel{ 20 | 21 | private ArrayList list; 22 | private String[] columnNames = {"#", "Host", "Scan Detail", "Report Detail", "Danger Level", "STARTLS", "No color"}; 23 | 24 | /** 25 | * Construct a new Table Helper 26 | */ 27 | public TableModel() { 28 | list = new ArrayList<>(); 29 | } 30 | 31 | /** 32 | * Get the table list. 33 | * @return The list saved during the construction. 34 | */ 35 | public ArrayList getTableList(){ 36 | return list; 37 | } 38 | 39 | /** 40 | * Add a row to the list and the table. 41 | * @param entry The new row. 42 | */ 43 | public void addRow(TableEntry entry){ 44 | list.add(entry); 45 | int tmp = list.size()-1; 46 | fireTableRowsInserted(tmp, tmp); 47 | } 48 | 49 | /** 50 | * Remove all entries from the table list. 51 | */ 52 | public void clear(){ 53 | list.clear(); 54 | fireTableDataChanged(); 55 | } 56 | 57 | /** 58 | * Get the number of rows. 59 | * @return Number of rows. 60 | */ 61 | @Override 62 | public int getRowCount() 63 | { 64 | return list.size(); 65 | } 66 | 67 | /** 68 | * 69 | * @return Number of columns. 70 | */ 71 | @Override 72 | public int getColumnCount() 73 | { 74 | return columnNames.length; 75 | } 76 | 77 | /** 78 | * Get the name of the column. 79 | * @param columnIndex Index of the column. 80 | * @return The name of the column. 81 | */ 82 | @Override 83 | public String getColumnName(int columnIndex) 84 | { 85 | return columnNames[columnIndex]; 86 | } 87 | 88 | /** 89 | * Get the class of the column. 90 | * @param columnIndex Index of the column. 91 | * @return The class of the column. 92 | */ 93 | @Override 94 | public Class getColumnClass(int columnIndex) 95 | { 96 | return String.class; 97 | } 98 | 99 | /** 100 | * Get the value at a position. 101 | * @param rowIndex The row. 102 | * @param columnIndex The column. 103 | * @return Value for the specified entry. Null if not found. 104 | */ 105 | @Override 106 | public Object getValueAt(int rowIndex, int columnIndex) 107 | { 108 | TableEntry entry = list.get(rowIndex); 109 | 110 | switch (columnIndex) 111 | { 112 | case 0: 113 | return entry.getCounter(); 114 | case 1: 115 | return entry.getHost(); 116 | case 2: 117 | return entry.getScanDetail(); 118 | case 3: 119 | return entry.getReportDetail(); 120 | case 4: 121 | return entry.getDanger(); 122 | case 5: 123 | return entry.getStarTls(); 124 | case 6: 125 | return entry.getNoColor(); 126 | default: 127 | return null; 128 | } 129 | } 130 | 131 | @Override 132 | public boolean isCellEditable(int rowIndex, int columnIndex) { 133 | return false; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/main/resources/de.rub.nds.burp.tlsattacker.log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | --------------------------------------------------------------------------------