-
Notifications
You must be signed in to change notification settings - Fork 4
/
SSH.cs
159 lines (153 loc) · 7.67 KB
/
SSH.cs
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
namespace Reecon
{
class SSH // Commonly Port 22 or 2222
{
public static (string, string) GetInfo(string ip, int port)
{
string sshVersion = "- SSH Version: " + SSH.GetVersion(ip, port);
string authMethods = "- Authentication Methods: " + SSH.GetAuthMethods(ip, port);
string returnInfo = sshVersion + Environment.NewLine + authMethods;
return ("SSH", returnInfo);
}
// Get version
public static string GetVersion(string ip, int port)
{
int timeout = 10000;
Byte[] buffer = new Byte[512];
using (Socket sshSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
sshSocket.ReceiveTimeout = timeout; // ms
sshSocket.SendTimeout = timeout; // ms
try
{
var result = sshSocket.BeginConnect(ip, port, null, null); // Error if an invalid IP
bool success = result.AsyncWaitHandle.WaitOne(timeout, true);
if (success)
{
int bytes = sshSocket.Receive(buffer, buffer.Length, 0);
string responseMessage = Encoding.ASCII.GetString(buffer, 0, bytes);
responseMessage = responseMessage.Trim();
string versionMessage = "";
if (responseMessage.Contains("\r"))
{
versionMessage = responseMessage.Split("\r")[0].Trim('\n');
}
else
{
versionMessage = responseMessage;
}
// SSH-2.0-OpenSSH_6.6.1p1
// SSH-2.0-dropbear_0.45
// SSH-2.0-dropbear_2016.74
if (versionMessage.StartsWith("SSH-2.0-"))
{
versionMessage = versionMessage.Remove(0, 8);
versionMessage = versionMessage.Replace("_", " ");
versionMessage += " (protocol 2.0)"; // Nmap's format
}
else if (versionMessage.Trim() == "")
{
// Can also get here on closed ports - What the?
versionMessage = "Port is open, but no version info";
}
else
{
versionMessage = $"Weird SSH Version: {versionMessage}";
}
// https://gist.github.com/0x4D31/35ddb0322530414bbb4c3288292749cc
if (responseMessage.ToLower().Contains("libssh"))
{
versionMessage += Environment.NewLine;
versionMessage += "--> libssh detected - Bug Reelix!";
}
return versionMessage;
}
else
{
sshSocket.Close();
return "Closed";
}
}
catch (SocketException se)
{
if (se.Message.StartsWith("No connection could be made because the target machine actively refused it"))
{
return "Port is closed";
}
return "SSG.GetVersion - Fatal Woof: " + se.Message;
}
catch (Exception ex)
{
Console.WriteLine("SSH.GetVersion - Something broke: " + ex.Message);
return "SSH.GetVersion - Borked - Bug Reelix";
}
}
}
// Get Auth Methods
public static string GetAuthMethods(string ip, int port)
{
string returnString = "";
if (string.IsNullOrEmpty(ip))
{
Console.WriteLine("Error in ssh.GetAuthMethods - Missing IP");
return "";
}
List<string> outputLines = General.GetProcessOutput("ssh", $"-o PreferredAuthentications=none -o StrictHostKeyChecking=no -o ConnectTimeout=5 {ip} -p {port} -oHostKeyAlgorithms=ssh-ed25519,ssh-rsa");
// kex_exchange_identification: read: Connection reset by peer
if (outputLines.Count == 1 && outputLines[0].EndsWith("Connection refused"))
{
return "- Port is closed";
}
if (outputLines.Any(x => x.Contains("no matching key exchange method found. Their offer:")))
{
string theLine = outputLines.First(x => x.Contains("no matching key exchange method found. Their offer:"));
string authMethods = theLine.Remove(0, theLine.IndexOf("Their offer: ") + 13);
return "Unknown - Weird Auth Algos: " + authMethods + Environment.NewLine + $"--> ssh {ip} -p {port} -o PreferredAuthentications=none -o StrictHostKeyChecking=no -o ConnectTimeout=5 -oHostKeyAlgorithms=ABOVE";
}
// Similar
if (outputLines.Any(x => x.Contains("no matching host key type found. Their offer")))
{
string theLine = outputLines.First(x => x.Contains("no matching host key type found. Their offer"));
string authMethods = theLine.Remove(0, theLine.IndexOf("Their offer: ") + 13);
return "Unknown - Weird Auth Algos: " + authMethods + Environment.NewLine + $"--> ssh {ip} -p {port} -o PreferredAuthentications=none -o StrictHostKeyChecking=no -o ConnectTimeout=5 -oHostKeyAlgorithms=ABOVE";
}
if (outputLines.Count == 1 && outputLines[0].Trim() == "kex_exchange_identification: Connection closed by remote host")
{
return "- They have no auth methods to give you";
}
if (outputLines.Contains("kex_exchange_identification: read: Connection reset by peer"))
{
returnString = "- Port is open, but connection reset with no info :(";
return returnString;
}
if (!outputLines.Any(x => x.Contains("Permission denied")))
{
if ((outputLines.Count == 1 || outputLines.Count == 2) && outputLines[0].Contains("Connection timed out"))
{
return "Timed out :(";
}
else
{
Console.WriteLine("Error in ssh.GetAuthMethods - No Permission denied found");
foreach (string line in outputLines)
{
Console.WriteLine($"Debug: --> {line}");
}
return "";
}
}
returnString = outputLines.First(x => x.Contains("Permission denied"));
returnString = returnString.Remove(0, returnString.IndexOf("("));
returnString = returnString.Replace("(", "").Replace(")", "");
// ssh - oPreferredAuthentications = none - oStrictHostKeyChecking = no 10.10.10.147
// [email protected]: Permission denied(publickey, password).
// [email protected]: Permission denied (publickey,keyboard-interactive).
return returnString;
}
}
}