11package com .staticflow ;
22
3- import burp .IBurpExtender ;
4- import burp .IBurpExtenderCallbacks ;
5- import burp .IExtensionStateListener ;
63
7- import javax .swing .*;
8- import java .awt .*;
9- import java .awt .event .*;
10- import java .util .regex .Matcher ;
11- import java .util .regex .Pattern ;
12-
13- public class RepeaterSearch implements IBurpExtender , IExtensionStateListener {
14-
15- public static final String REPEATER = "Repeater" ;
16- public static final String SEARCH = "Search" ;
17- public static final String ENTER_QUERY = "Enter query..." ;
18- private Component repeaterComponent ;
19- private IBurpExtenderCallbacks callbacks ;
20- private boolean searchResponseForText ;
21- private boolean searchRequestForText ;
22- private boolean useRegex ;
4+ import burp .api .montoya .BurpExtension ;
5+ import burp .api .montoya .MontoyaApi ;
6+ import burp .api .montoya .extension .ExtensionUnloadingHandler ;
7+
8+ /**
9+ * The entry point for a Burp Suite extension that adds a custom search bar to the Repeater tab.
10+ * This extension allows users to search through the request body and/or the response body of requests
11+ * using a simple string or a regular expression (regex).
12+ *
13+ * The `RepeaterSearch` class implements the `BurpExtension` and `ExtensionUnloadingHandler` interfaces,
14+ * allowing it to handle extension initialization and unloading events.
15+ *
16+ * Upon initialization, the `initialize` method registers the extension's unloading handler, sets the
17+ * necessary callbacks, and adds the search bar to the Repeater tab.
18+ *
19+ * When the extension is unloaded, the `extensionUnloaded` method is called to perform any necessary
20+ * clean-up operations.
21+ *
22+ * @see BurpExtension
23+ * @see ExtensionUnloadingHandler
24+ */
25+ public class RepeaterSearch implements BurpExtension , ExtensionUnloadingHandler {
2326
2427 @ Override
25- public void registerExtenderCallbacks (IBurpExtenderCallbacks iBurpExtenderCallbacks ) {
26- this .searchRequestForText = true ;
27- this .callbacks = iBurpExtenderCallbacks ;
28- iBurpExtenderCallbacks .registerExtensionStateListener (this );
29- this .repeaterComponent = BurpGuiControl .getBaseBurpComponent (REPEATER );
30- JPanel combined = new JPanel (new GridBagLayout ());
31- JPanel searchBarPanel = new JPanel (new GridBagLayout ());
32- JPanel searchBarButtonsPanel = new JPanel ();
33- searchBarButtonsPanel .setLayout (new BoxLayout (searchBarButtonsPanel ,
34- BoxLayout .Y_AXIS ));
35- JButton searchButton = new JButton (SEARCH );
36- JTextField searchBar = new JTextField (ENTER_QUERY );
37- GridBagConstraints c = new GridBagConstraints ();
38- GridBagConstraints gbc = new GridBagConstraints ();
39-
40- c .gridx = 0 ;
41- c .gridy = 0 ;
42- c .weightx = 0.90 ;
43- c .weighty = 0.05 ;
44- c .fill = GridBagConstraints .BOTH ;
45- searchBar .addMouseListener (new MouseListener () {
46- @ Override
47- public void mouseClicked (MouseEvent e ) {
48- if (searchBar .getText ().equals (ENTER_QUERY )) {
49- searchBar .setText ("" );
50- }
51- }
52-
53- @ Override
54- public void mousePressed (MouseEvent e ) {
55- //UnNeeded
56- }
57-
58- @ Override
59- public void mouseReleased (MouseEvent e ) {
60- //UnNeeded
61- }
62-
63- @ Override
64- public void mouseEntered (MouseEvent e ) {
65- //UnNeeded
66- }
67-
68- @ Override
69- public void mouseExited (MouseEvent e ) {
70- if (searchBar .getText ().isEmpty ()) {
71- searchBar .setText (ENTER_QUERY );
72- }
73- }
74- });
75- gbc .gridx = 0 ;
76- gbc .gridy = 0 ;
77- gbc .fill = GridBagConstraints .BOTH ;
78- gbc .weightx = 1 ;
79- gbc .weighty = 0.50 ;
80- searchBarPanel .add (searchBar ,gbc );
81- searchBar .addKeyListener (new KeyListener () {
82- @ Override
83- public void keyTyped (KeyEvent e ) {
84- searchButton .setText (SEARCH );
85- resetRepeaterTabs ();
86- }
87-
88- @ Override
89- public void keyPressed (KeyEvent e ) {
90- //UnNeeded
91- }
92-
93- @ Override
94- public void keyReleased (KeyEvent e ) {
95- //UnNeeded
96- }
97- });
98- searchButton .addActionListener (e -> {
99- if (searchButton .getText ().equals (SEARCH )) {
100- searchRepeaterTabsForString (searchBar .getText ());
101- searchButton .setText ("Clear" );
102- } else {
103- resetRepeaterTabs ();
104- searchBar .setText (ENTER_QUERY );
105- searchButton .setText (SEARCH );
106- resetRepeaterTabs ();
107- }
108- });
109- searchBarButtonsPanel .add (searchButton );
110- JCheckBox searchRequest = new JCheckBox ("Request" );
111- searchRequest .setSelected (true );
112- searchRequest .addChangeListener (e -> searchRequestForText = !searchRequestForText );
113- searchBarButtonsPanel .add (searchRequest );
114- JCheckBox searchResponse = new JCheckBox ("Response" );
115- searchResponse .addChangeListener (e -> searchResponseForText = !searchResponseForText );
116- searchBarButtonsPanel .add (searchResponse );
117- JCheckBox searchRegex = new JCheckBox ("Regex" );
118- searchRegex .addChangeListener (e -> useRegex = !useRegex );
119- searchBarButtonsPanel .add (searchRegex );
120- combined .add (searchBarPanel ,c );
121- c .gridx = 1 ;
122- c .weightx = 0.10 ;
123- combined .add (searchBarButtonsPanel ,c );
124- c .gridy = 1 ;
125- c .gridx = 0 ;
126- c .gridwidth = 2 ;
127- c .weighty = 0.95 ;
128- combined .add (repeaterComponent ,c );
129- iBurpExtenderCallbacks .customizeUiComponent (combined );
130- BurpGuiControl .addBaseBurpComponent (REPEATER ,combined );
28+ public void initialize (MontoyaApi api ) {
29+ api .extension ().registerUnloadingHandler (this );
30+ ExtensionState .getInstance ().setCallbacks (api );
31+ Utils .addSearchBarToRepeaterTab ();
13132 }
13233
13334 @ Override
13435 public void extensionUnloaded () {
135- resetRepeaterTabs ();
136- BurpGuiControl .replaceBaseBurpComponent (REPEATER ,this .repeaterComponent );
137- }
138-
139- private void resetRepeaterTabs (){
140- JTabbedPane repeaterTabs = ((JTabbedPane )this .repeaterComponent );
141- for (int i =0 ; i < repeaterTabs .getTabCount ()-1 ; i ++) {
142- repeaterTabs .setBackgroundAt (i ,new Color (0xBBBBBB ));
143-
144- }
145- }
146-
147- private void searchRepeaterTabsForString (String search ) {
148- JTabbedPane repeaterTabs = ((JTabbedPane )this .repeaterComponent );
149- for ( int i =0 ; i < repeaterTabs .getTabCount ()-1 ; i ++) {
150- try {
151- if ( searchRequestForText ) {
152- JTextArea requestTextArea =
153- BurpGuiControl .getRepeaterTabRequestTextArea ((Container ) repeaterTabs .getComponentAt (i ));
154- if (searchTextArea (search ,requestTextArea ) ) {
155- repeaterTabs .setBackgroundAt (i ,new Color (0xff6633 ));
156- }
157- } else if ( searchResponseForText ) {
158- JTextArea responseTextArea =
159- BurpGuiControl .getRepeaterTabResponseTextArea ((Container ) repeaterTabs .getComponentAt (i ));
160- if (searchTextArea (search , responseTextArea )) {
161- repeaterTabs .setBackgroundAt (i ,new Color (0xff6633 ));
162- }
163- }
164- }catch (ArrayIndexOutOfBoundsException e ) {
165- this .callbacks .printError (e .getMessage ());
166- }
167- }
168- }
169-
170- private boolean searchTextArea (String search , JTextArea textArea ) {
171- if (useRegex ) {
172- Pattern pattern = Pattern .compile (search ,Pattern .MULTILINE );
173- Matcher matcher = pattern .matcher (textArea .getText ());
174- return matcher .find ();
175- } else {
176- return textArea .getText ().contains (search );
177- }
36+ Utils .cleanUpExtension ();
17837 }
17938
18039}
0 commit comments