ManagerExploit.java
/*******************************************************************************
* Copyhacked (H) 2012-2025.
* This program and the accompanying materials
* are made available under no term at all, use it like
* you want, but share and discuss it
* every time possible with every body.
*
* Contributors:
* ron190 at ymail dot com - initial implementation
******************************************************************************/
package com.jsql.view.swing.manager;
import com.jsql.model.accessible.ExploitMode;
import com.jsql.model.exception.JSqlException;
import com.jsql.util.I18nUtil;
import com.jsql.util.LogLevelUtil;
import com.jsql.view.swing.manager.util.*;
import com.jsql.view.swing.text.JPasswordFieldPlaceholder;
import com.jsql.view.swing.text.JPopupTextField;
import com.jsql.view.swing.text.JTextFieldPlaceholder;
import com.jsql.view.swing.text.JToolTipI18n;
import com.jsql.view.swing.util.I18nViewUtil;
import com.jsql.view.swing.util.MediatorHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
/**
* Manager for uploading PHP SQL shell to the host and send queries.
*/
public class ManagerExploit extends AbstractManagerList {
/**
* Log4j logger sent to view.
*/
private static final Logger LOGGER = LogManager.getRootLogger();
public static final String SHELL_URL_TOOLTIP = "SHELL_URL_TOOLTIP";
private final AtomicReference<JTextField> username = new AtomicReference<>();
private final AtomicReference<JTextField> password = new AtomicReference<>();
private final AtomicReference<JTextField> netshare = new AtomicReference<>();
protected final JTextField textfieldUrlShell;
public static final String EXPLOIT_UDF = "EXPLOIT_UDF";
public static final String EXPLOIT_WEB = "EXPLOIT_WEB";
public static final String EXPLOIT_SQL = "EXPLOIT_SQL";
public static final String EXPLOIT_UPLOAD = "EXPLOIT_UPLOAD";
private final JComboBox<Object> comboBoxExploitTypes = new JComboBox<>(new Object[]{
new ModelItemType(ManagerExploit.EXPLOIT_UDF, "EXPLOIT_UDF_TOOLTIP"),
ComboBoxMethodRenderer.SEPARATOR,
new ModelItemType(ManagerExploit.EXPLOIT_WEB, "EXPLOIT_WEB_TOOLTIP"),
new ModelItemType(ManagerExploit.EXPLOIT_SQL, "EXPLOIT_SQL_TOOLTIP"),
new ModelItemType(ManagerExploit.EXPLOIT_UPLOAD, "EXPLOIT_UPLOAD_TOOLTIP"),
});
private final JComboBox<Object> comboBoxExploitModes = new JComboBox<>(new Object[]{
ExploitMode.AUTO,
ComboBoxMethodRenderer.SEPARATOR,
ExploitMode.QUERY_BODY,
ExploitMode.TEMP_TABLE,
ComboBoxMethodRenderer.SEPARATOR,
ExploitMode.NETSHARE
});
public ManagerExploit() {
super("swing/list/payload.txt");
var tooltipShellUrl = new AtomicReference<>(new JToolTipI18n(I18nUtil.valueByKey(ManagerExploit.SHELL_URL_TOOLTIP)));
var placeholderResult = new JTextFieldPlaceholder(I18nUtil.valueByKey("SHELL_URL_LABEL")) {
@Override
public JToolTip createToolTip() {
return tooltipShellUrl.get();
}
};
this.textfieldUrlShell = new JPopupTextField(placeholderResult).getProxy();
I18nViewUtil.addComponentForKey("SHELL_URL_LABEL", this.textfieldUrlShell);
I18nViewUtil.addComponentForKey(ManagerExploit.SHELL_URL_TOOLTIP, tooltipShellUrl.get());
this.textfieldUrlShell.setToolTipText(I18nUtil.valueByKey(ManagerExploit.SHELL_URL_TOOLTIP));
this.buildRunButton("SHELL_RUN_BUTTON_LABEL", "SHELL_RUN_BUTTON_TOOLTIP");
this.run.setEnabled(false);
this.buildPrivilege();
var southPanel = new JPanel();
southPanel.setLayout(new BoxLayout(southPanel, BoxLayout.Y_AXIS));
southPanel.add(this.textfieldUrlShell);
southPanel.add(this.lastLine);
this.add(southPanel, BorderLayout.SOUTH);
var userPassPanel = new JPanel();
var groupLayout = new GroupLayout(userPassPanel);
userPassPanel.setLayout(groupLayout);
this.run.addActionListener(new ActionExploit(this.comboBoxExploitTypes));
Arrays.asList(
new ModelExploit(this.netshare, "EXPLOIT_NETSHARE_LABEL", "EXPLOIT_NETSHARE_TOOLTIP"),
new ModelExploit(this.username, "SQL_SHELL_USERNAME_LABEL", "SQL_SHELL_USERNAME_TOOLTIP"),
new ModelExploit(this.password, "SQL_SHELL_PASSWORD_LABEL", "SQL_SHELL_PASSWORD_TOOLTIP", true)
).forEach(model -> {
var tooltip = new AtomicReference<>(new JToolTipI18n(I18nUtil.valueByKey(model.tooltipI18n)));
if (model.isPassword) {
model.textfield.set(new JPopupTextField(new JPasswordFieldPlaceholder(I18nUtil.valueByKey(model.labelI18n)) {
@Override
public JToolTip createToolTip() {
return tooltip.get();
}
}).getProxy());
} else {
model.textfield.set(new JPopupTextField(new JTextFieldPlaceholder(I18nUtil.valueByKey(model.labelI18n)) {
@Override
public JToolTip createToolTip() {
return tooltip.get();
}
}).getProxy());
}
I18nViewUtil.addComponentForKey(model.labelI18n, model.textfield.get());
I18nViewUtil.addComponentForKey(model.tooltipI18n, tooltip.get());
model.textfield.get().setToolTipText(I18nUtil.valueByKey(model.tooltipI18n));
});
Arrays.asList(this.username.get(), this.password.get(), this.scrollListPaths, this.textfieldUrlShell, this.netshare.get())
.forEach(component -> component.setVisible(false));
this.comboBoxExploitTypes.setRenderer(new ComboBoxTypeRenderer());
this.comboBoxExploitTypes.addActionListener(new SeparatorListener(this.comboBoxExploitTypes));
this.comboBoxExploitTypes.addItemListener(e -> {
if (e.getStateChange() != ItemEvent.SELECTED || e.getItem() == ComboBoxMethodRenderer.SEPARATOR) {
return;
}
Arrays.asList(this.username.get(), this.password.get(), this.scrollListPaths, this.textfieldUrlShell)
.forEach(component -> component.setVisible(false));
ModelItemType selectedItem = (ModelItemType) e.getItem();
if (!ManagerExploit.EXPLOIT_UDF.equals(selectedItem.getKeyLabel())) {
this.scrollListPaths.setVisible(true);
this.textfieldUrlShell.setVisible(true);
if (ManagerExploit.EXPLOIT_SQL.equals(selectedItem.getKeyLabel())) {
this.username.get().setVisible(true);
this.password.get().setVisible(true);
}
}
this.updateUI(); // required to adapt panel
});
this.comboBoxExploitModes.addItemListener(e -> {
if (e.getStateChange() == ItemEvent.SELECTED && e.getItem() instanceof ExploitMode) {
ExploitMode selectedItem = (ExploitMode) e.getItem();
this.netshare.get().setVisible(false);
if (selectedItem.equals(ExploitMode.NETSHARE)) {
this.netshare.get().setVisible(true);
}
this.updateUI(); // required to adapt panel
}
});
this.comboBoxExploitModes.setRenderer(new ComboBoxMethodRenderer());
this.comboBoxExploitModes.addActionListener(new SeparatorListener(this.comboBoxExploitModes));
var labelUsing = new JLabel("via");
labelUsing.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
groupLayout.setHorizontalGroup(
groupLayout
.createParallelGroup()
.addGroup(
groupLayout
.createSequentialGroup()
.addComponent(this.comboBoxExploitTypes)
.addComponent(labelUsing, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(this.comboBoxExploitModes, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
)
.addGroup(
groupLayout.createParallelGroup()
.addComponent(this.netshare.get())
.addComponent(this.username.get())
.addComponent(this.password.get())
)
);
groupLayout.setVerticalGroup(
groupLayout
.createSequentialGroup()
.addGroup(
groupLayout
.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(this.comboBoxExploitTypes)
.addComponent(labelUsing)
.addComponent(this.comboBoxExploitModes)
)
.addGroup(
groupLayout
.createParallelGroup()
.addComponent(this.netshare.get())
)
.addGroup(
groupLayout
.createParallelGroup()
.addComponent(this.username.get())
)
.addGroup(
groupLayout
.createParallelGroup()
.addComponent(this.password.get())
)
);
this.add(userPassPanel, BorderLayout.NORTH);
}
protected class ActionExploit implements ActionListener {
private final JComboBox<Object> comboBoxExploitTypes;
public ActionExploit(JComboBox<Object> comboBoxExploitTypes) {
this.comboBoxExploitTypes = comboBoxExploitTypes;
}
@Override
public void actionPerformed(ActionEvent evt) {
var modelSelectItem = (ModelItemType) this.comboBoxExploitTypes.getSelectedItem();
var labelSelectItem = Objects.requireNonNull(modelSelectItem).getKeyLabel();
if (!ManagerExploit.isValid(labelSelectItem)) {
LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Currently unsupported for [{}], contribute and share exploit method on GitHub to improve the app", MediatorHelper.model().getMediatorVendor().getVendor());
return;
}
if (ManagerExploit.EXPLOIT_UDF.equals(labelSelectItem)) {
new SwingWorker<>() {
@Override
protected Object doInBackground() { Thread.currentThread().setName("SwingWorkerExploit");
ActionExploit.this.start(null, null, null);
return null;
}
}.doInBackground();
return;
}
if (
ManagerExploit.EXPLOIT_SQL.equals(labelSelectItem)
&& (ManagerExploit.this.password.get().getText().isEmpty() || ManagerExploit.this.username.get().getText().isEmpty())
) {
LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Missing credentials (tips: search and read file containing hardcoded credentials)");
return;
}
if (ManagerExploit.this.listPaths.getSelectedValuesList().isEmpty()) {
LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Select at least one directory in the list");
return;
}
String urlShell = ManagerExploit.this.textfieldUrlShell.getText();
if (!urlShell.isEmpty() && !urlShell.matches("(?i)^https?://.*")) {
if (!urlShell.matches("(?i)^\\w+://.*")) {
LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "Undefined shell URL protocol, forcing to [https://]");
urlShell = "https://"+ urlShell;
} else {
LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Unknown URL protocol");
return;
}
}
if (StringUtils.isNotEmpty(urlShell)) {
try {
new URI(urlShell);
} catch (URISyntaxException e) {
LOGGER.log(LogLevelUtil.CONSOLE_ERROR, String.format("Incorrect URL: %s", e.getMessage()));
return;
}
}
AtomicReference<File> fileToUpload = new AtomicReference<>();
if (ManagerExploit.EXPLOIT_UPLOAD.equals(labelSelectItem)) {
fileToUpload.set(ManagerExploit.chooseFile());
if (fileToUpload.get() == null) {
LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Missing file, please select a file");
return;
}
}
String urlShellFinal = urlShell;
new SwingWorker<>() {
@Override
protected Object doInBackground() { Thread.currentThread().setName("SwingWorkerExploitNonUdf");
ManagerExploit.this.horizontalGlue.setVisible(false);
ManagerExploit.this.progressBar.setVisible(true);
ManagerExploit.this.listPaths.getSelectedValuesList().forEach(pathExploit -> {
LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, String.format("Checking path [%s]...", pathExploit));
ActionExploit.this.start(pathExploit.toString(), urlShellFinal, fileToUpload.get());
});
ManagerExploit.this.endProcess();
return null;
}
}.doInBackground();
}
private void start(String pathExploit, String urlShellFinal, File fileToUpload) {
try {
ManagerExploit.this.createPayload(pathExploit, urlShellFinal, fileToUpload);
} catch (JSqlException e) {
LOGGER.log(LogLevelUtil.CONSOLE_ERROR, String.format("Payload creation failure: %s", e.getMessage()));
}
}
}
private static boolean isValid(String labelSelectItem) {
return
ManagerExploit.EXPLOIT_UDF.equals(labelSelectItem) && Arrays.asList(
MediatorHelper.model().getMediatorVendor().getMysql(),
MediatorHelper.model().getMediatorVendor().getPostgres()
).contains(MediatorHelper.model().getMediatorVendor().getVendor())
|| Arrays.asList(ManagerExploit.EXPLOIT_WEB, ManagerExploit.EXPLOIT_UPLOAD).contains(labelSelectItem) && Arrays.asList(
MediatorHelper.model().getMediatorVendor().getDerby(),
MediatorHelper.model().getMediatorVendor().getHsqldb(),
MediatorHelper.model().getMediatorVendor().getH2(),
MediatorHelper.model().getMediatorVendor().getSqlite(),
MediatorHelper.model().getMediatorVendor().getMysql(),
MediatorHelper.model().getMediatorVendor().getPostgres()
).contains(MediatorHelper.model().getMediatorVendor().getVendor())
|| Arrays.asList(ManagerExploit.EXPLOIT_SQL).contains(labelSelectItem) && Arrays.asList(
MediatorHelper.model().getMediatorVendor().getMysql(),
MediatorHelper.model().getMediatorVendor().getPostgres()
).contains(MediatorHelper.model().getMediatorVendor().getVendor());
}
private static File chooseFile() {
var filechooser = new JFileChooser(MediatorHelper.model().getMediatorUtils().getPreferencesUtil().getPathFile());
filechooser.setDialogTitle(I18nUtil.valueByKey("UPLOAD_DIALOG_TEXT"));
int returnVal = filechooser.showOpenDialog(MediatorHelper.frame());
if (returnVal == JFileChooser.APPROVE_OPTION) {
return filechooser.getSelectedFile();
}
return null;
}
protected void createPayload(String pathExploit, String urlShell, File fileToUpload) throws JSqlException {
var exploitMethod = ExploitMode.forName(Objects.requireNonNull(this.comboBoxExploitModes.getSelectedItem()).toString())
.orElse(ExploitMode.AUTO);
if (pathExploit != null && !pathExploit.endsWith("/")) {
pathExploit += "/";
}
String pathNetshare = this.netshare.get().getText();
if (exploitMethod == ExploitMode.NETSHARE && !pathNetshare.endsWith("\\")) {
pathNetshare = pathNetshare +"\\";
}
var modelItemType = Objects.requireNonNull((ModelItemType) this.comboBoxExploitTypes.getSelectedItem());
if (ManagerExploit.EXPLOIT_UDF.equals(modelItemType.getKeyLabel())) {
if (MediatorHelper.model().getMediatorVendor().getVendor() == MediatorHelper.model().getMediatorVendor().getMysql()) {
MediatorHelper.model().getResourceAccess().getExploitMysql().createUdf(pathNetshare, exploitMethod);
} else if (MediatorHelper.model().getMediatorVendor().getVendor() == MediatorHelper.model().getMediatorVendor().getPostgres()) {
MediatorHelper.model().getResourceAccess().getExploitPostgres().createUdf(null);
}
} else if (ManagerExploit.EXPLOIT_WEB.equals(modelItemType.getKeyLabel())) {
if (MediatorHelper.model().getMediatorVendor().getVendor() == MediatorHelper.model().getMediatorVendor().getMysql()) {
MediatorHelper.model().getResourceAccess().getExploitMysql().createWeb(
pathExploit,
urlShell,
pathNetshare,
exploitMethod
);
} else if (MediatorHelper.model().getMediatorVendor().getVendor() == MediatorHelper.model().getMediatorVendor().getPostgres()) {
MediatorHelper.model().getResourceAccess().getExploitPostgres().createWeb(pathExploit, urlShell);
} else if (MediatorHelper.model().getMediatorVendor().getVendor() == MediatorHelper.model().getMediatorVendor().getSqlite()) {
MediatorHelper.model().getResourceAccess().getExploitSqlite().createWeb(pathExploit, urlShell);
} else if (MediatorHelper.model().getMediatorVendor().getVendor() == MediatorHelper.model().getMediatorVendor().getHsqldb()) {
MediatorHelper.model().getResourceAccess().getExploitHsqldb().createWeb(pathExploit, urlShell);
} else if (MediatorHelper.model().getMediatorVendor().getVendor() == MediatorHelper.model().getMediatorVendor().getH2()) {
MediatorHelper.model().getResourceAccess().getExploitH2().createWeb(pathExploit, urlShell);
} else if (MediatorHelper.model().getMediatorVendor().getVendor() == MediatorHelper.model().getMediatorVendor().getDerby()) {
MediatorHelper.model().getResourceAccess().getExploitDerby().createWeb(pathExploit, urlShell);
}
} else if (ManagerExploit.EXPLOIT_SQL.equals(modelItemType.getKeyLabel())) {
if (MediatorHelper.model().getMediatorVendor().getVendor() == MediatorHelper.model().getMediatorVendor().getMysql()) {
MediatorHelper.model().getResourceAccess().getExploitMysql().createSql(
pathExploit,
urlShell,
pathNetshare,
exploitMethod,
this.username.get().getText(),
this.password.get().getText()
);
} else if (MediatorHelper.model().getMediatorVendor().getVendor() == MediatorHelper.model().getMediatorVendor().getPostgres()) {
MediatorHelper.model().getResourceAccess().getExploitPostgres().createSql(
pathExploit,
urlShell,
this.username.get().getText(),
this.password.get().getText()
);
}
} else if (ManagerExploit.EXPLOIT_UPLOAD.equals(modelItemType.getKeyLabel())) {
if (MediatorHelper.model().getMediatorVendor().getVendor() == MediatorHelper.model().getMediatorVendor().getMysql()) {
MediatorHelper.model().getResourceAccess().getExploitMysql().createUpload(
pathExploit,
urlShell,
pathNetshare,
exploitMethod,
fileToUpload
);
} else if (MediatorHelper.model().getMediatorVendor().getVendor() == MediatorHelper.model().getMediatorVendor().getPostgres()) {
MediatorHelper.model().getResourceAccess().getExploitPostgres().createUpload(pathExploit, urlShell, fileToUpload);
} else if (MediatorHelper.model().getMediatorVendor().getVendor() == MediatorHelper.model().getMediatorVendor().getSqlite()) {
MediatorHelper.model().getResourceAccess().getExploitSqlite().createUpload(pathExploit, urlShell, fileToUpload);
} else if (MediatorHelper.model().getMediatorVendor().getVendor() == MediatorHelper.model().getMediatorVendor().getHsqldb()) {
MediatorHelper.model().getResourceAccess().getExploitHsqldb().createUpload(pathExploit, urlShell, fileToUpload);
} else if (MediatorHelper.model().getMediatorVendor().getVendor() == MediatorHelper.model().getMediatorVendor().getH2()) {
MediatorHelper.model().getResourceAccess().getExploitH2().createUpload(pathExploit, urlShell, fileToUpload);
} else if (MediatorHelper.model().getMediatorVendor().getVendor() == MediatorHelper.model().getMediatorVendor().getDerby()) {
MediatorHelper.model().getResourceAccess().getExploitDerby().createUpload(pathExploit, urlShell, fileToUpload);
}
}
}
}