ServerInputConnection.java

1
package com.jsql.view.swing.terminal;
2
3
import com.jsql.util.LogLevelUtil;
4
import org.apache.commons.lang3.StringUtils;
5
import org.apache.logging.log4j.LogManager;
6
import org.apache.logging.log4j.Logger;
7
8
import java.io.BufferedReader;
9
import java.io.DataOutputStream;
10
import java.io.IOException;
11
import java.io.InputStreamReader;
12
import java.net.Socket;
13
14
public class ServerInputConnection {
15
16
    /**
17
     * Log4j logger sent to view.
18
     */
19
    private static final Logger LOGGER = LogManager.getRootLogger();
20
21
    private final BufferedReader bufferedReader;
22
    private final Socket clientSocket;
23
    private final ServerInput serverInput;
24
    private final ExploitReverseShell exploitReverseShell;
25
    private boolean running = true;
26
    private String command;
27
28
    public ServerInputConnection(ExploitReverseShell exploitReverseShell, Socket clientSocket, ServerInput serverInput) throws IOException {
29
        this.clientSocket = clientSocket;
30
        this.exploitReverseShell = exploitReverseShell;
31
        this.serverInput = serverInput;
32
        LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "Reverse established by {}", clientSocket);
33
        LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Type 'exit' in reverse shell to close the connection");
34
        this.bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
35
    }
36
37
    public void run() throws IOException {
38
        try (DataOutputStream dataOutputStream = new DataOutputStream(this.clientSocket.getOutputStream())) {
39
            Thread readerThread = new Thread(() -> {
40
                try {
41 1 1. lambda$run$0 : removed call to com/jsql/view/swing/terminal/ServerInputConnection::handleSocketReading → NO_COVERAGE
                    this.handleSocketReading();
42
                } catch (IOException e) {
43
                    LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Error reading from socket: {}", e.getMessage());
44
                } finally {
45 1 1. lambda$run$0 : removed call to com/jsql/view/swing/terminal/ServerInputConnection::closeResources → NO_COVERAGE
                    this.closeResources();
46
                }
47
            });
48 1 1. run : removed call to java/lang/Thread::start → NO_COVERAGE
            readerThread.start();
49
50 1 1. run : negated conditional → NO_COVERAGE
            while (this.running) {
51 1 1. run : removed call to com/jsql/view/swing/terminal/ServerInputConnection::processAndSendCommand → NO_COVERAGE
                this.processAndSendCommand(dataOutputStream);
52
            }
53
54
            try {
55 1 1. run : removed call to java/lang/Thread::join → NO_COVERAGE
                readerThread.join(2000);
56
            } catch (InterruptedException e) {
57 1 1. run : removed call to java/lang/Thread::interrupt → NO_COVERAGE
                Thread.currentThread().interrupt();
58
                LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Reader thread interrupted");
59
            }
60
        }
61
    }
62
63
    private void processAndSendCommand(DataOutputStream dataOutputStream) throws IOException {
64 1 1. processAndSendCommand : negated conditional → NO_COVERAGE
        if (StringUtils.isNotEmpty(this.command)) {
65
            var commandWithoutPrompt = this.command.replaceAll("[^$]*\\$\\s*", "");
66
            this.command = null;
67 1 1. processAndSendCommand : removed call to java/io/DataOutputStream::writeBytes → NO_COVERAGE
            dataOutputStream.writeBytes(commandWithoutPrompt + "\n");
68
        }
69
    }
70
71
    private void handleSocketReading() throws IOException {
72
        int length = 1024;
73
        char[] buffer = new char[length];
74
        int charsRead;
75 1 1. handleSocketReading : negated conditional → NO_COVERAGE
        while (this.running) {
76
            charsRead = this.bufferedReader.read(buffer, 0, length);
77 1 1. handleSocketReading : negated conditional → NO_COVERAGE
            if (charsRead != -1) {
78
                String result = new String(buffer, 0, charsRead);  // discard unused chars from buffer
79 2 1. handleSocketReading : removed call to com/jsql/view/swing/terminal/ExploitReverseShell::append → NO_COVERAGE
2. handleSocketReading : negated conditional → NO_COVERAGE
                this.exploitReverseShell.append(result.matches("\\$$") ? result +" " : result);  // space after internal prompt
80 1 1. handleSocketReading : removed call to com/jsql/view/swing/terminal/ExploitReverseShell::reset → NO_COVERAGE
                this.exploitReverseShell.reset(false);
81
            } else {
82
                break;
83
            }
84
        }
85
    }
86
87
    private void closeResources() {
88
        try {
89
            LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Reverse connection closed");
90
            this.running = false;
91 1 1. closeResources : removed call to com/jsql/view/swing/terminal/ServerInput::close → NO_COVERAGE
            this.serverInput.close();
92
        } catch (IOException e) {
93
            LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Error closing resources: {}", e.getMessage());
94
        }
95
    }
96
97
    public void setCommand(String command) {
98
        this.command = command;
99
    }
100
}

Mutations

41

1.1
Location : lambda$run$0
Killed by : none
removed call to com/jsql/view/swing/terminal/ServerInputConnection::handleSocketReading → NO_COVERAGE

45

1.1
Location : lambda$run$0
Killed by : none
removed call to com/jsql/view/swing/terminal/ServerInputConnection::closeResources → NO_COVERAGE

48

1.1
Location : run
Killed by : none
removed call to java/lang/Thread::start → NO_COVERAGE

50

1.1
Location : run
Killed by : none
negated conditional → NO_COVERAGE

51

1.1
Location : run
Killed by : none
removed call to com/jsql/view/swing/terminal/ServerInputConnection::processAndSendCommand → NO_COVERAGE

55

1.1
Location : run
Killed by : none
removed call to java/lang/Thread::join → NO_COVERAGE

57

1.1
Location : run
Killed by : none
removed call to java/lang/Thread::interrupt → NO_COVERAGE

64

1.1
Location : processAndSendCommand
Killed by : none
negated conditional → NO_COVERAGE

67

1.1
Location : processAndSendCommand
Killed by : none
removed call to java/io/DataOutputStream::writeBytes → NO_COVERAGE

75

1.1
Location : handleSocketReading
Killed by : none
negated conditional → NO_COVERAGE

77

1.1
Location : handleSocketReading
Killed by : none
negated conditional → NO_COVERAGE

79

1.1
Location : handleSocketReading
Killed by : none
removed call to com/jsql/view/swing/terminal/ExploitReverseShell::append → NO_COVERAGE

2.2
Location : handleSocketReading
Killed by : none
negated conditional → NO_COVERAGE

80

1.1
Location : handleSocketReading
Killed by : none
removed call to com/jsql/view/swing/terminal/ExploitReverseShell::reset → NO_COVERAGE

91

1.1
Location : closeResources
Killed by : none
removed call to com/jsql/view/swing/terminal/ServerInput::close → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.19.1