카테고리 없음

dir

1231. 2025. 4. 15. 11:13

package burp;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;

public class BurpExtender implements IBurpExtender, ITab, Runnable {

    private IBurpExtenderCallbacks callbacks;
    private IExtensionHelpers helpers;

    private JPanel mainPanel;
    private JTable resultTable;
    private JTextArea requestTextArea;
    private JTextArea responseTextArea;
    private DefaultTableModel tableModel;
    private List<IHttpRequestResponse> httpMessages = new ArrayList<>();

    @Override
    public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks) {
        this.callbacks = callbacks;
        this.helpers = callbacks.getHelpers();

        callbacks.setExtensionName("Dir Index Checker");
        SwingUtilities.invokeLater(this);
    }

    @Override
    public void run() {
        mainPanel = new JPanel(new BorderLayout());

        // Top button panel
        JButton scanButton = new JButton("Scan Site Map for Directory Indexing");
        scanButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                scanSiteMap();
            }
        });

        JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        topPanel.add(scanButton);
        mainPanel.add(topPanel, BorderLayout.NORTH);

        // Table for results
        String[] columnNames = {"URL", "Status", "Indexing", "Time"};
        tableModel = new DefaultTableModel(columnNames, 0);
        resultTable = new JTable(tableModel);
        JScrollPane tableScrollPane = new JScrollPane(resultTable);
        mainPanel.add(tableScrollPane, BorderLayout.CENTER);

        // Split pane for request/response view
        requestTextArea = new JTextArea();
        responseTextArea = new JTextArea();
        requestTextArea.setEditable(false);
        responseTextArea.setEditable(false);
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
                new JScrollPane(requestTextArea), new JScrollPane(responseTextArea));
        splitPane.setDividerLocation(500);
        mainPanel.add(splitPane, BorderLayout.SOUTH);

        // Event on row selection
        resultTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                int selectedRow = resultTable.getSelectedRow();
                if (selectedRow >= 0 && selectedRow < httpMessages.size()) {
                    IHttpRequestResponse message = httpMessages.get(selectedRow);
                    requestTextArea.setText(helpers.bytesToString(message.getRequest()));
                    responseTextArea.setText(helpers.bytesToString(message.getResponse()));
                }
            }
        });

        callbacks.addSuiteTab(this);
    }

    private void scanSiteMap() {
        tableModel.setRowCount(0);
        httpMessages.clear();

        IHttpRequestResponse[] siteMapItems = callbacks.getSiteMap(null);
        Set<String> visited = new HashSet<>();

        for (IHttpRequestResponse item : siteMapItems) {
            IRequestInfo reqInfo = helpers.analyzeRequest(item);
            URL url = reqInfo.getUrl();

            String urlString = url.toString();
            if (!urlString.endsWith("/")) continue; // only directory paths

            if (visited.contains(urlString)) continue;
            visited.add(urlString);

            byte[] responseBytes = item.getResponse();
            if (responseBytes == null) continue;

            IResponseInfo resInfo = helpers.analyzeResponse(responseBytes);
            int statusCode = resInfo.getStatusCode();
            String body = helpers.bytesToString(responseBytes).substring(resInfo.getBodyOffset());

            boolean isIndexed = body.contains("Index of")
                    || body.matches("(?i).*<title>\s*Index of.*</title>.*")
                    || body.matches("(?i).*<a href\s*=\s*"[^"]+".*>.*</a>.*");

            String indexingStr = isIndexed ? "YES" : "NO";
            String timeStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());

            tableModel.addRow(new Object[]{urlString, statusCode, indexingStr, timeStr});
            httpMessages.add(item);
        }

        if (tableModel.getRowCount() == 0) {
            JOptionPane.showMessageDialog(mainPanel,
                    "No directory-style URLs or valid responses found in Site Map.",
                    "Notice", JOptionPane.INFORMATION_MESSAGE);
        }
    }

    @Override
    public String getTabCaption() {
        return "Dir Index Checker";
    }

    @Override
    public Component getUiComponent() {
        return mainPanel;
    }
}