-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
176 lines (154 loc) · 5.67 KB
/
Program.cs
File metadata and controls
176 lines (154 loc) · 5.67 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
// <copyright file="Program.cs" company="Peter Rosser">
// Copyright (c) Peter Rosser. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
// </copyright>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PeterRosser.GetStoredCredentials
{
// ReSharper disable MemberCanBePrivate.Local
// ReSharper disable UnusedMember.Local
using static FormattableString;
internal class Program
{
private const string ArgDecode = "decode";
private const string ArgHelp = "help";
private const string ArgHelpAlt = "?";
private const string ArgHelpAlt2 = "h";
private const string ArgShowPasswords = "showpasswords";
private static readonly string[] ArgsHelp = {ArgHelp, ArgHelpAlt, ArgHelpAlt2};
private static string AddBase64Padding(string text)
{
return (text + "==").Substring(0, 3 * text.Length % 4);
}
private static string Base64FromWebSafe(string base64)
{
if (base64.Contains("-") || base64.Contains("/"))
{
return AddBase64Padding(base64);
}
return AddBase64Padding(base64.Replace('-', '+').Replace('_', '/'));
}
private static string GetPassword(Credential cred, bool decode)
{
return decode ? TryDecodePassword(cred) : cred.Password;
}
private static bool IsProbablyClearText(string text)
{
return !string.IsNullOrEmpty(text) && text.All(c => c >= '!' && c <= 0xa0);
}
private static void Main(string[] args)
{
var showPasswords = false;
var decode = false;
foreach (string arg in args)
{
string trimmed = arg.TrimStart('-', '/');
if (string.Equals(trimmed, ArgShowPasswords, StringComparison.OrdinalIgnoreCase))
{
showPasswords = true;
}
else if (string.Equals(trimmed, ArgDecode, StringComparison.OrdinalIgnoreCase))
{
decode = true;
}
else if (ArgsHelp.Any(x => string.Equals(trimmed, x, StringComparison.OrdinalIgnoreCase)))
{
Console.WriteLine(Invariant($@"GetStoredCredentials [OPTIONS]
Options:
-{ArgDecode}
Attempts to Base64 decode the password value prior to printing it to the
console. -ShowPasswords must also be set!
-{ArgShowPasswords}
Prints the values of the passwords that were found to be in the clear
-{ArgHelp}
This text
"));
return;
}
}
IReadOnlyList<Credential> creds = CredentialManager.EnumerateCrendentials();
var count = 0;
Console.WriteLine(Invariant($"Checking for credentials stored in the clear"));
foreach (Credential cred in creds)
{
if (IsProbablyClearText(cred.Password))
{
++count;
Warn(Invariant($"Application: {cred.ApplicationName}"));
Warn(Invariant($"Type: {cred.CredentialType}"));
Warn(Invariant($"Username: {cred.UserName}"));
if (showPasswords)
{
Warn(Invariant($"Password: {GetPassword(cred, decode)}"));
}
Warn(string.Empty);
}
}
if (count > 0)
{
Warn(string.Empty);
Warn(Invariant($"{count} passwords were probably in the clear."));
if (!showPasswords)
{
Warn(string.Empty);
Warn(Invariant($"Run again with -showpasswords to print the passwords to the console."));
}
}
else
{
Success(Invariant($"No credentials were detected to be obviously in the clear. :)"));
}
}
private static void Print(string message, ConsoleColor color)
{
try
{
Console.ForegroundColor = color;
Console.WriteLine(message);
}
finally
{
Console.ResetColor();
}
}
private static void Success(string message)
{
Print(message, ConsoleColor.Green);
}
private static string TryDecodePassword(Credential cred)
{
try
{
byte[] decoded = Convert.FromBase64String(Base64FromWebSafe(cred.Password));
foreach (Encoding encoding in new[]
{
Encoding.UTF8,
Encoding.Unicode,
Encoding.ASCII,
Encoding.BigEndianUnicode,
Encoding.UTF32,
Encoding.UTF7
})
{
string test = encoding.GetString(decoded);
if (IsProbablyClearText(test))
{
return test;
}
}
}
catch (FormatException)
{
// not obviously base64-encoded
}
return cred.Password;
}
private static void Warn(string message)
{
Print(message, ConsoleColor.Yellow);
}
}
}