View Javadoc
1   /*******************************************************************************
2    * Copyhacked (H) 2012-2025.
3    * This program and the accompanying materials
4    * are made available under no term at all, use it like
5    * you want, but share and discuss it
6    * every time possible with every body.
7    *
8    * Contributors:
9    *      ron190 at ymail dot com - initial implementation
10   *******************************************************************************/
11  package com.jsql.view.swing.tab;
12  
13  import com.formdev.flatlaf.extras.FlatSVGIcon;
14  import com.jsql.model.bean.database.AbstractElementDatabase;
15  import com.jsql.util.I18nUtil;
16  import com.jsql.util.LogLevelUtil;
17  import com.jsql.util.StringUtil;
18  import com.jsql.view.swing.action.ActionCloseTabResult;
19  import com.jsql.view.swing.action.HotkeyUtil;
20  import com.jsql.view.swing.popupmenu.JPopupMenuText;
21  import com.jsql.view.swing.terminal.*;
22  import com.jsql.view.swing.tab.dnd.DnDTabbedPane;
23  import com.jsql.view.swing.tab.dnd.TabTransferHandler;
24  import com.jsql.view.swing.table.PanelTable;
25  import com.jsql.view.swing.text.JPopupTextArea;
26  import com.jsql.view.swing.util.MediatorHelper;
27  import com.jsql.view.swing.util.UiStringUtil;
28  import com.jsql.view.swing.util.UiUtil;
29  import org.apache.commons.lang3.StringUtils;
30  import org.apache.logging.log4j.LogManager;
31  import org.apache.logging.log4j.Logger;
32  
33  import javax.swing.*;
34  import javax.swing.event.HyperlinkEvent;
35  import java.awt.*;
36  import java.awt.event.FocusAdapter;
37  import java.awt.event.FocusEvent;
38  import java.io.IOException;
39  import java.net.MalformedURLException;
40  import java.net.URISyntaxException;
41  import java.util.UUID;
42  import java.util.function.IntConsumer;
43  
44  /**
45   * TabbedPane containing result injection panels.
46   */
47  public class TabResults extends DnDTabbedPane {
48  
49      /**
50       * Log4j logger sent to view.
51       */
52      private static final Logger LOGGER = LogManager.getRootLogger();
53  
54      public static final String TAB_EXPLOIT_FAILURE_INCORRECT_URL = "Tab exploit failure: incorrect URL";
55      public static final String RCE_SHELL = "RCE shell";
56  
57      /**
58       * Create the panel containing injection results.
59       */
60      public TabResults() {
61          this.setName("tabResults");
62          this.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
63          this.setTransferHandler(new TabTransferHandler());
64          this.putClientProperty("JTabbedPane.tabClosable", true);
65          this.putClientProperty("JTabbedPane.tabCloseCallback", (IntConsumer) ActionCloseTabResult::perform);
66          UIManager.put("TabbedPane.closeHoverForeground", LogLevelUtil.COLOR_RED);
67          HotkeyUtil.addShortcut(this);  // Add hotkeys to root-pane ctrl-tab, ctrl-shift-tab, ctrl-w
68          this.addMouseWheelListener(new TabbedPaneMouseWheelListener());
69          MediatorHelper.register(this);
70      }
71  
72      public void addFileTab(String label, String content, String path) {
73          JTextArea fileText = new JPopupTextArea().getProxy();
74          fileText.setText(content);
75          fileText.setFont(new Font(UiUtil.FONT_NAME_MONO_NON_ASIAN, Font.PLAIN, 14));
76          fileText.setCaretPosition(0);
77          this.addTextTab(label, path, fileText, UiUtil.DOWNLOAD.getIcon());
78          MediatorHelper.tabManagersCards().addToLists(path, label);
79      }
80  
81      public void addReportTab(String content) {
82          JEditorPane editorPane = new JEditorPane();
83          editorPane.setContentType("text/html");
84          editorPane.setText("<html><span style=\"white-space: nowrap; font-family:'"+ UiUtil.FONT_NAME_MONO_NON_ASIAN +"'\">" + content + "</span></html>");
85          editorPane.setFont(UIManager.getFont("TextArea.font"));  // required to increase text size
86          editorPane.setDragEnabled(true);
87          editorPane.setEditable(false);
88          editorPane.setCaretPosition(0);
89          editorPane.getCaret().setBlinkRate(0);
90          editorPane.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
91          editorPane.setComponentPopupMenu(new JPopupMenuText(editorPane));
92          editorPane.addHyperlinkListener(linkEvent -> {
93              if (HyperlinkEvent.EventType.ACTIVATED.equals(linkEvent.getEventType())) {
94                  try {
95                      Desktop.getDesktop().browse(linkEvent.getURL().toURI());
96                  } catch (IOException | URISyntaxException | UnsupportedOperationException e) {
97                      LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Failing to browse Url", e);
98                  }
99              }
100         });
101         editorPane.addFocusListener(new FocusAdapter() {
102             @Override
103             public void focusGained(FocusEvent focusEvent) {
104                 editorPane.getCaret().setVisible(true);
105                 editorPane.getCaret().setSelectionVisible(true);
106                 editorPane.getCaret().setBlinkRate(0);
107             }
108         });
109         UiUtil.init(editorPane);  // silent delete
110 
111         this.addTextTab("Vulnerability report", "Analysis report with all payloads detected", editorPane, UiUtil.APP_ICON.getIcon());
112     }
113 
114     public void addTextTab(String label, String toolTipText, JComponent componentText, FlatSVGIcon icon) {
115         var scroller = new JScrollPane(componentText);
116         this.addTab(label + StringUtils.SPACE, scroller);
117         this.setSelectedComponent(scroller);  // Focus on the new tab
118         this.setToolTipTextAt(this.indexOfComponent(scroller), toolTipText);
119         var header = new TabHeader(label, icon);
120         this.setTabComponentAt(this.indexOfComponent(scroller), header);
121 
122         this.updateUI();  // required: light, open/close prefs, dark => light artifacts
123     }
124 
125     public void addTabExploitWeb(String url) {
126         try {
127             var terminalID = UUID.randomUUID();
128             var terminal = new ExploitWeb(terminalID, url);
129             MediatorHelper.frame().getMapUuidShell().put(terminalID, terminal);
130 
131             JScrollPane scroller = new JScrollPane(terminal);
132             this.addTab("Web shell", scroller);
133             this.setSelectedComponent(scroller);  // Focus on the new tab
134 
135             var header = new TabHeader("Web shell", UiUtil.TERMINAL.getIcon());
136             this.setTabComponentAt(this.indexOfComponent(scroller), header);
137             terminal.requestFocusInWindow();
138 
139             this.updateUI();  // required: light, open/close prefs, dark => light artifacts
140         } catch (MalformedURLException | URISyntaxException e) {
141             LOGGER.log(LogLevelUtil.CONSOLE_ERROR, TabResults.TAB_EXPLOIT_FAILURE_INCORRECT_URL, e);
142         }
143     }
144 
145     public void addTabExploitUdfMysql() {
146         try {
147             var terminalID = UUID.randomUUID();
148             var terminal = new ExploitUdfMysql(terminalID);
149             MediatorHelper.frame().getMapUuidShell().put(terminalID, terminal);
150 
151             JScrollPane scroller = new JScrollPane(terminal);
152             this.addTab("UDF shell", scroller);
153             this.setSelectedComponent(scroller);  // Focus on the new tab
154 
155             var header = new TabHeader("UDF shell", UiUtil.TERMINAL.getIcon());
156             this.setTabComponentAt(this.indexOfComponent(scroller), header);
157             terminal.requestFocusInWindow();
158 
159             this.updateUI();  // required: light, open/close prefs, dark => light artifacts
160         } catch (MalformedURLException | URISyntaxException e) {
161             LOGGER.log(LogLevelUtil.CONSOLE_ERROR, TabResults.TAB_EXPLOIT_FAILURE_INCORRECT_URL, e);
162         }
163     }
164 
165     public void addTabExploitRceOracle() {
166         try {
167             var terminalID = UUID.randomUUID();
168             var terminal = new ExploitRceOracle(terminalID);
169             MediatorHelper.frame().getMapUuidShell().put(terminalID, terminal);
170 
171             JScrollPane scroller = new JScrollPane(terminal);
172             this.addTab(TabResults.RCE_SHELL, scroller);
173             this.setSelectedComponent(scroller);  // Focus on the new tab
174 
175             var header = new TabHeader(TabResults.RCE_SHELL, UiUtil.TERMINAL.getIcon());
176             this.setTabComponentAt(this.indexOfComponent(scroller), header);
177             terminal.requestFocusInWindow();
178 
179             this.updateUI();  // required: light, open/close prefs, dark => light artifacts
180         } catch (MalformedURLException | URISyntaxException e) {
181             LOGGER.log(LogLevelUtil.CONSOLE_ERROR, TabResults.TAB_EXPLOIT_FAILURE_INCORRECT_URL, e);
182         }
183     }
184 
185     public void addTabExploitRcePostgres() {
186         try {
187             var terminalID = UUID.randomUUID();
188             var terminal = new ExploitRcePostgres(terminalID);
189             MediatorHelper.frame().getMapUuidShell().put(terminalID, terminal);
190 
191             JScrollPane scroller = new JScrollPane(terminal);
192             this.addTab(TabResults.RCE_SHELL, scroller);
193             this.setSelectedComponent(scroller);  // Focus on the new tab
194 
195             var header = new TabHeader(TabResults.RCE_SHELL, UiUtil.TERMINAL.getIcon());
196             this.setTabComponentAt(this.indexOfComponent(scroller), header);
197             terminal.requestFocusInWindow();
198 
199             this.updateUI();  // required: light, open/close prefs, dark => light artifacts
200         } catch (MalformedURLException | URISyntaxException e) {
201             LOGGER.log(LogLevelUtil.CONSOLE_ERROR, TabResults.TAB_EXPLOIT_FAILURE_INCORRECT_URL, e);
202         }
203     }
204 
205     public void addTabExploitRceWalPostgres() {
206         try {
207             var terminalID = UUID.randomUUID();
208             var terminal = new ExploitRceWalPostgres(terminalID);
209             MediatorHelper.frame().getMapUuidShell().put(terminalID, terminal);
210 
211             JScrollPane scroller = new JScrollPane(terminal);
212             this.addTab(TabResults.RCE_SHELL, scroller);
213             this.setSelectedComponent(scroller);  // Focus on the new tab
214 
215             var header = new TabHeader(TabResults.RCE_SHELL, UiUtil.TERMINAL.getIcon());
216             this.setTabComponentAt(this.indexOfComponent(scroller), header);
217             terminal.requestFocusInWindow();
218 
219             this.updateUI();  // required: light, open/close prefs, dark => light artifacts
220         } catch (MalformedURLException | URISyntaxException e) {
221             LOGGER.log(LogLevelUtil.CONSOLE_ERROR, TabResults.TAB_EXPLOIT_FAILURE_INCORRECT_URL, e);
222         }
223     }
224 
225     public void addTabExploitRceProgramPostgres() {
226         try {
227             var terminalID = UUID.randomUUID();
228             var terminal = new ExploitRceProgramPostgres(terminalID);
229             MediatorHelper.frame().getMapUuidShell().put(terminalID, terminal);
230 
231             JScrollPane scroller = new JScrollPane(terminal);
232             this.addTab(TabResults.RCE_SHELL, scroller);
233             this.setSelectedComponent(scroller);  // Focus on the new tab
234 
235             var header = new TabHeader(TabResults.RCE_SHELL, UiUtil.TERMINAL.getIcon());
236             this.setTabComponentAt(this.indexOfComponent(scroller), header);
237             terminal.requestFocusInWindow();
238 
239             this.updateUI();  // required: light, open/close prefs, dark => light artifacts
240         } catch (MalformedURLException | URISyntaxException e) {
241             LOGGER.log(LogLevelUtil.CONSOLE_ERROR, TabResults.TAB_EXPLOIT_FAILURE_INCORRECT_URL, e);
242         }
243     }
244 
245     public void addTabExploitRceSqlite() {
246         try {
247             var terminalID = UUID.randomUUID();
248             var terminal = new ExploitRceSqlite(terminalID);
249             MediatorHelper.frame().getMapUuidShell().put(terminalID, terminal);
250 
251             JScrollPane scroller = new JScrollPane(terminal);
252             this.addTab(TabResults.RCE_SHELL, scroller);
253             this.setSelectedComponent(scroller);  // Focus on the new tab
254 
255             var header = new TabHeader(TabResults.RCE_SHELL, UiUtil.TERMINAL.getIcon());
256             this.setTabComponentAt(this.indexOfComponent(scroller), header);
257             terminal.requestFocusInWindow();
258 
259             this.updateUI();  // required: light, open/close prefs, dark => light artifacts
260         } catch (MalformedURLException | URISyntaxException e) {
261             LOGGER.log(LogLevelUtil.CONSOLE_ERROR, TabResults.TAB_EXPLOIT_FAILURE_INCORRECT_URL, e);
262         }
263     }
264 
265     public void addTabExploitSql(String url, String user, String pass) {
266         try {
267             var terminalID = UUID.randomUUID();
268             var terminal = new ExploitSql(terminalID, url, user, pass);
269             MediatorHelper.frame().getMapUuidShell().put(terminalID, terminal);
270 
271             JScrollPane scroller = new JScrollPane(terminal);
272             this.addTab("SQL shell", scroller);
273             this.setSelectedComponent(scroller);  // Focus on the new tab
274 
275             var header = new TabHeader("SQL shell", UiUtil.TERMINAL.getIcon());
276             this.setTabComponentAt(this.indexOfComponent(scroller), header);
277             terminal.requestFocusInWindow();
278 
279             this.updateUI();  // required: light, open/close prefs, dark => light artifacts
280         } catch (MalformedURLException | URISyntaxException e) {
281             LOGGER.log(LogLevelUtil.CONSOLE_ERROR, TabResults.TAB_EXPLOIT_FAILURE_INCORRECT_URL, e);
282         }
283     }
284     
285     public void addTabValues(String[][] data, String[] columnNames, AbstractElementDatabase table) {
286         var panelTable = new PanelTable(data, columnNames);
287         
288         this.addTab(StringUtil.detectUtf8(table.toString()), panelTable);
289         panelTable.setComponentOrientation(ComponentOrientation.getOrientation(I18nUtil.getCurrentLocale()));
290         
291         this.setSelectedComponent(panelTable);  // Focus on the new tab
292 
293         var header = new TabHeader(UiStringUtil.detectUtf8Html(table.toString()), UiUtil.TABLE_BOLD.getIcon());
294         this.setTabComponentAt(this.indexOfComponent(panelTable), header);
295 
296         this.updateUI();  // required: light, open/close prefs, dark => light artifacts
297     }
298 }