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

Mutations

38

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

42

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

45

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

47

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

48

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

52

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

54

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

61

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

64

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

72

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

74

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

76

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

77

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

88

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