Repository navigation
Expand file tree
/
Copy pathShellHandles.cs
More file actions
229 lines (204 loc) · 9.87 KB
/
Copy pathShellHandles.cs
File metadata and controls
229 lines (204 loc) · 9.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
namespace BlinkkShell
{
internal static class ShellHandles
{
public static string ProcessCommand(string commandLine)
{
if (string.IsNullOrWhiteSpace(commandLine))
return "Empty command.";
string[] parts = commandLine.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries);
string command = parts[0].ToLowerInvariant();
string args = parts.Length > 1 ? parts[1] : string.Empty;
return command switch
{
"help" => GetHelpText(),
"this" => GetShellInfo(),
"whoami" => GetWhoAmIInfo(),
"cmdmsg" => ShowConsoleMessage(args),
"msg" => ShowMessageBox(args),
"ping" => "Pong!",
"procs" => GetProcessList(),
"kill" => KillProcess(args),
"shelluptime" => $"Shell Uptime: {DateTime.Now - Process.GetCurrentProcess().StartTime}",
"start" => StartProcess(args),
"sysinfo" => GetSystemInfo(),
"time" => GetLocalTime(),
"uptime" => $"System Uptime: {TimeSpan.FromMilliseconds(Environment.TickCount64)}",
_ => $"Unknown command: '{command}'. Type 'help' to see the available commands."
};
}
private static string GetHelpText()
{
return """
BlinkkShell commands
====================
help Show this command list.
this Show BlinkkShell server and process details.
sysinfo Show operating system and runtime details.
whoami Show the server account and administrator status.
uptime Show how long the computer has been running.
shelluptime Show how long the BlinkkShell process has been running.
time Show the server's local date and time.
start <proc> Start a new process on the server (Windows only).
ping Check that the server responds.
procs Show a list of running processes on the server.
kill <pid> Terminate a process by its ID (Windows only, requires admin).
cmdmsg <text> Display a message on the server console.
msg <text> Display a message on the server (Windows only).
exit Close this client session.
Commands are case-insensitive.
""";
}
private static string GetLocalTime()
{
return $"Local Date and Time: {DateTime.Now:yyyy-MM-dd HH:mm:ss}";
}
private static string GetProcessList()
{
Process[] processes = Process.GetProcesses();
StringBuilder processList = new StringBuilder("Running Processes:\n==================\n");
foreach (Process process in processes)
{
try
{
processList.AppendLine($" {process.ProcessName} (ID: {process.Id})");
}
catch
{
// Ignore processes that cannot be accessed
}
}
return processList.ToString();
}
private static string KillProcess(string processIdStr)
{
if (!OperatingSystem.IsWindows())
return "The kill command is only available on Windows.";
using WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
if (!principal.IsInRole(WindowsBuiltInRole.Administrator))
return "Permission denied. You must run the server as an administrator to terminate processes.";
if (!int.TryParse(processIdStr, out int processId) || processId <= 0)
return "Invalid process ID. Usage: kill <process_id>";
try
{
using Process process = Process.GetProcessById(processId);
string processName = process.ProcessName;
process.Kill();
return $"Process {processName} (PID: {processId}) has been terminated.";
}
catch (ArgumentException)
{
return $"No process with ID {processId} was found.";
}
catch (InvalidOperationException ex)
{
return $"Process {processId} could not be terminated: {ex.Message}";
}
catch (System.ComponentModel.Win32Exception ex)
{
return $"Access denied or failed to terminate process {processId}: {ex.Message}";
}
}
private static string GetShellInfo()
{
Process currentProcess = Process.GetCurrentProcess();
return $"""
BlinkkShell Channel
=================
Version : 1.2.0
Computer : {Environment.MachineName}
Account : {Environment.UserName}
Process ID : {currentProcess.Id}
""";
}
private static string GetSystemInfo()
{
return $"""
System information
==================
{"Computer",-21}: {Environment.MachineName}
{"Operating system",-21}: {RuntimeInformation.OSDescription}
{"OS architecture",-21}: {RuntimeInformation.OSArchitecture}
{"Process architecture",-21}: {RuntimeInformation.ProcessArchitecture}
{"Logical processors",-21}: {Environment.ProcessorCount}
{".NET runtime",-21}: {RuntimeInformation.FrameworkDescription}
""";
}
private static string GetWhoAmIInfo()
{
string username = Environment.UserName;
string domain = Environment.UserDomainName;
if (!OperatingSystem.IsWindows())
return $"Current User: {domain}\\{username}\nAdmin Mode: Unavailable (Windows only)";
using WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
bool isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
string adminStatus = isAdmin ? "YES (Administrator / Elevated)" : "NO (Standard User)";
return $"Current User: {domain}\\{username}\nAdmin Mode: {adminStatus}";
}
private static string ShowConsoleMessage(string message)
{
if (string.IsNullOrWhiteSpace(message))
return "Usage: consolemsg <message_text>";
Console.WriteLine($"Remote message: {message}");
return "Message displayed on server console.";
}
private static string ShowMessageBox(string message)
{
if (string.IsNullOrWhiteSpace(message))
return "Usage: msg <message_text>";
if (!OperatingSystem.IsWindows())
return "The message command is only available on Windows.";
string encodedMessage = Convert.ToBase64String(Encoding.UTF8.GetBytes(message));
string script = "$message = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('" +
encodedMessage +
"')); Add-Type -AssemblyName System.Windows.Forms; " +
"$form = New-Object System.Windows.Forms.Form; " +
"$form.TopMost = $true; " +
"[System.Windows.Forms.MessageBox]::Show($form, $message, 'BlinkkShell Message', [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information); " +
"$form.Dispose();";
try
{
using Process? process = Process.Start(new ProcessStartInfo
{
FileName = "powershell",
ArgumentList = { "-NoProfile", "-EncodedCommand", Convert.ToBase64String(Encoding.Unicode.GetBytes(script)) },
CreateNoWindow = true,
UseShellExecute = false
});
return process == null ? "Failed to start the message window." : "Message displayed on screen.";
}
catch (Exception exception) when (exception is InvalidOperationException or System.ComponentModel.Win32Exception)
{
return $"Failed to display the message: {exception.Message}";
}
}
private static string StartProcess(string processName)
{
if (!OperatingSystem.IsWindows())
return "The start command is only available on Windows.";
if (string.IsNullOrWhiteSpace(processName))
return "Usage: start <process>";
try
{
using Process? process = Process.Start(new ProcessStartInfo
{
FileName = "cmd.exe",
ArgumentList = { "/C", processName },
CreateNoWindow = true,
UseShellExecute = false
});
return process == null ? "Failed to start the process." : $"Process started with ID: {process.Id}";
}
catch (Exception exception) when (exception is InvalidOperationException or System.ComponentModel.Win32Exception)
{
return $"Failed to start the process: {exception.Message}";
}
}
}
}