Skip to content

Commit

Permalink
- bump SharpDPAPI version and remove unused code
Browse files Browse the repository at this point in the history
- support offline statekey decryption from non-domain joined machines
- allow user to specify NTLM (domain-joined) or SHA1 (non-domain) hash instead of a password (i.e. Pass-the-Hash) for offline statekey decryption
  • Loading branch information
rxwx committed Jan 5, 2023
1 parent 2b15020 commit 9ec2486
Show file tree
Hide file tree
Showing 42 changed files with 352 additions and 4,040 deletions.
35 changes: 2 additions & 33 deletions ChloniumUI/ChloniumUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,6 @@
</ApplicationDefinition>
<Compile Include="ExportMethods.cs" />
<Compile Include="ImportMethods.cs" />
<Compile Include="SharpDPAPI\SharpChrome\Commands\Backupkey.cs" />
<Compile Include="SharpDPAPI\SharpChrome\Commands\Cookies.cs" />
<Compile Include="SharpDPAPI\SharpChrome\Commands\ICommand.cs" />
<Compile Include="SharpDPAPI\SharpChrome\Commands\Logins.cs" />
<Compile Include="SharpDPAPI\SharpChrome\Commands\Statekeys.cs" />
<Compile Include="SharpDPAPI\SharpChrome\Domain\ArgumentParser.cs" />
<Compile Include="SharpDPAPI\SharpChrome\Domain\ArgumentParserResult.cs" />
<Compile Include="SharpDPAPI\SharpChrome\Domain\CommandCollection.cs" />
<Compile Include="SharpDPAPI\SharpChrome\Domain\Info.cs" />
<Compile Include="SharpDPAPI\SharpChrome\lib\Bcrypt.cs" />
<Compile Include="SharpDPAPI\SharpChrome\lib\Chrome.cs" />
<Compile Include="SharpDPAPI\SharpChrome\SQLite\csharp-sqlite-src\alter_c.cs" />
Expand Down Expand Up @@ -160,27 +151,6 @@
<Compile Include="SharpDPAPI\SharpChrome\SQLite\csharp-sqlite-src\where_c.cs" />
<Compile Include="SharpDPAPI\SharpChrome\SQLite\csharp-sqlite-src\_Custom.cs" />
<Compile Include="SharpDPAPI\SharpChrome\SQLite\SQLite.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Commands\Backupkey.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Commands\Blob.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Commands\Certificate.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Commands\Credentials.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Commands\ICommand.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Commands\Keepass.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Commands\Machinecredentials.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Commands\Machinemasterkeys.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Commands\Machinetriage.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Commands\Machinevaults.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Commands\Masterkeys.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Commands\PS.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Commands\RDG.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Commands\Search.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Commands\Triage.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Commands\Vaults.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Domain\ArgumentParser.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Domain\ArgumentParserResult.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Domain\CommandCollection.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Domain\Info.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\Domain\Version.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\lib\Backup.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\lib\BigInteger.cs" />
<Compile Include="SharpDPAPI\SharpDPAPI\lib\Certificate.cs" />
Expand Down Expand Up @@ -232,9 +202,7 @@
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<None Include="SharpDPAPI\CHANGELOG.md" />
<None Include="SharpDPAPI\LICENSE" />
<None Include="SharpDPAPI\README.md" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Costura.Fody">
Expand All @@ -259,8 +227,9 @@
<Resource Include="FodyWeavers.xml" />
<EmbeddedResource Include="Costura32\SQLite.Interop.dll" />
<EmbeddedResource Include="Costura64\SQLite.Interop.dll" />
</ItemGroup>
<ItemGroup>
<Content Include="SharpDPAPI\.gitignore" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
18 changes: 9 additions & 9 deletions ChloniumUI/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@
<ColumnDefinition Width="278*"/>
<ColumnDefinition Width="437*"/>
</Grid.ColumnDefinitions>
<TextBox Name="StateKeyText" MaxLength="64" HorizontalAlignment="Left" Height="23" Margin="23,27,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="502" Grid.Column="1" Grid.ColumnSpan="2"/>
<TextBlock HorizontalAlignment="Left" Margin="12,28,0,0" TextWrapping="Wrap" Text="State Key" VerticalAlignment="Top" Grid.ColumnSpan="2" Height="20" Width="66" FontWeight="Bold" Foreground="White"/>
<TextBox Name="StateKeyText" MaxLength="64" HorizontalAlignment="Left" Height="23" Margin="23,27,0,0" TextWrapping="NoWrap" Text="" VerticalAlignment="Top" Width="502" Grid.Column="1" Grid.ColumnSpan="2"/>
<TextBlock HorizontalAlignment="Left" Margin="12,28,0,0" TextWrapping="NoWrap" Text="State Key" VerticalAlignment="Top" Grid.ColumnSpan="2" Height="20" Width="66" FontWeight="Bold" Foreground="White"/>
<Button Foreground="#FF707070" Background="Black" Content="Check" HorizontalAlignment="Left" Margin="262,27,0,0" VerticalAlignment="Top" Width="75" Grid.Column="2" Height="23" Click="StateKeyCheck_Click" FontWeight="Bold"/>
<TextBox Name="TextBox_File" HorizontalAlignment="Left" Height="23" Margin="23,63,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="502" Grid.Column="1" Grid.ColumnSpan="2"/>
<TextBlock Foreground="White" HorizontalAlignment="Left" Margin="12,64,0,0" TextWrapping="Wrap" Text="Database" VerticalAlignment="Top" Grid.ColumnSpan="2" Height="20" Width="66" FontWeight="Bold"/>
<TextBox Name="TextBox_File" HorizontalAlignment="Left" Height="23" Margin="23,63,0,0" TextWrapping="NoWrap" Text="" VerticalAlignment="Top" Width="502" Grid.Column="1" Grid.ColumnSpan="2"/>
<TextBlock Foreground="White" HorizontalAlignment="Left" Margin="12,64,0,0" TextWrapping="NoWrap" Text="Database" VerticalAlignment="Top" Grid.ColumnSpan="2" Height="20" Width="66" FontWeight="Bold"/>
<Button Foreground="#FF707070" Background="Black" Content="Browse.." HorizontalAlignment="Left" Margin="262,63,0,0" VerticalAlignment="Top" Width="75" Grid.Column="2" Height="23" Click="File_Click" FontWeight="Bold"/>
<Button Foreground="#FF707070" Background="Black" Content="Export to Text File" Grid.Column="1" HorizontalAlignment="Left" Margin="115,169,0,0" VerticalAlignment="Top" Width="142" Height="32" Click="Export_Click" FontWeight="Bold"/>
<Button Foreground="#FF707070" Background="Black" Content="Import" Grid.Column="2" HorizontalAlignment="Left" Margin="4,169,0,0" VerticalAlignment="Top" Width="140" Height="32" Click="Import_Click" FontWeight="Bold"/>
<ComboBox DisplayMemberPath="BrowserName" Name="ComboBox" Grid.Column="1" HorizontalAlignment="Left" Margin="23,99,0,0" VerticalAlignment="Top" Width="502" SelectionChanged="ComboBox_SelectionChanged" Grid.ColumnSpan="2" Height="20" />
<ComboBox DisplayMemberPath="Value" Name="ComboBox_Importer" Grid.Column="1" HorizontalAlignment="Left" Margin="23,135,0,0" VerticalAlignment="Top" Width="502" SelectionChanged="ComboBox_Importer_SelectionChanged" Grid.ColumnSpan="2" Height="20" />
<TextBlock Foreground="White" HorizontalAlignment="Left" Margin="12,135,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Text="Importer" Grid.ColumnSpan="2" Height="20" Width="66" FontWeight="Bold" />
<TextBlock Foreground="White" HorizontalAlignment="Left" Margin="12,99,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Text="Browser" Grid.ColumnSpan="2" Height="20" Width="66" FontWeight="Bold"/>
<TextBlock Foreground="White" HorizontalAlignment="Left" Margin="12,135,0,0" TextWrapping="NoWrap" VerticalAlignment="Top" Text="Importer" Grid.ColumnSpan="2" Height="20" Width="66" FontWeight="Bold" />
<TextBlock Foreground="White" HorizontalAlignment="Left" Margin="12,99,0,0" TextWrapping="NoWrap" VerticalAlignment="Top" Text="Browser" Grid.ColumnSpan="2" Height="20" Width="66" FontWeight="Bold"/>
</Grid>
</TabItem>
<TabItem Header="Offline Statekey Decryption">
Expand All @@ -44,13 +44,13 @@
<ColumnDefinition Width="749*"/>
</Grid.ColumnDefinitions>
<TextBox Name="PasswordOrPVK" MaxLength="2000" HorizontalAlignment="Left" Height="23" Margin="103,27,0,0" TextWrapping="NoWrap" Text="" VerticalAlignment="Top" Width="422" Grid.Column="1"/>
<TextBlock Foreground="White" HorizontalAlignment="Left" Margin="7,30,0,0" TextWrapping="Wrap" Text="Password or Backup Key" VerticalAlignment="Top" Grid.ColumnSpan="2" Height="20" Width="131" FontWeight="Bold"/>
<TextBlock Foreground="White" HorizontalAlignment="Left" Margin="7,30,0,0" TextWrapping="NoWrap" Text="Password or Backup Key" VerticalAlignment="Top" Grid.ColumnSpan="2" Height="20" Width="148" FontWeight="Bold"/>
<Button Foreground="#FF707070" Background="Black" Content="Check" HorizontalAlignment="Left" Margin="611,27,0,0" VerticalAlignment="Top" Width="75" Grid.Column="1" Height="23" Click="PasswordOrPVK_Check" FontWeight="Bold" />
<TextBox Name="TextBox_Masterkey" HorizontalAlignment="Left" Height="23" Margin="103,63,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="422" Grid.Column="1"/>
<TextBox Name="TextBox_Masterkey" HorizontalAlignment="Left" Height="23" Margin="103,63,0,0" TextWrapping="NoWrap" Text="" VerticalAlignment="Top" Width="422" Grid.Column="1"/>
<TextBlock Foreground="White" HorizontalAlignment="Left" Margin="7,66,0,0" TextWrapping="NoWrap" Text="DPAPI Masterkey Directory" VerticalAlignment="Top" Grid.ColumnSpan="2" Height="20" Width="156" FontWeight="Bold"/>
<Button Foreground="#FF707070" Background="Black" Content="Browse.." HorizontalAlignment="Left" Margin="530,63,0,0" VerticalAlignment="Top" Width="75" Grid.Column="1" Height="23" Click="DPAPIMasterKey_Browse" FontWeight="Bold"/>
<TextBox Name="TextBox_LocalState" HorizontalAlignment="Left" Height="23" Margin="103,98,0,0" TextWrapping="NoWrap" Text="" VerticalAlignment="Top" Width="422" Grid.Column="1"/>
<TextBlock Foreground="White" HorizontalAlignment="Left" Margin="7,98,0,0" TextWrapping="Wrap" Text="Local State File" VerticalAlignment="Top" Grid.ColumnSpan="2" Height="23" Width="93" FontWeight="Bold"/>
<TextBlock Foreground="White" HorizontalAlignment="Left" Margin="7,98,0,0" TextWrapping="NoWrap" Text="Local State File" VerticalAlignment="Top" Grid.ColumnSpan="2" Height="23" Width="93" FontWeight="Bold"/>
<Button Foreground="#FF707070" Background="Black" Content="Browse.." HorizontalAlignment="Left" Margin="530,98,0,0" VerticalAlignment="Top" Width="75" Grid.Column="1" Height="23" Click="LocalState_Browse" FontWeight="Bold"/>
<Button Foreground="#FF707070" Background="Black" Content="Decrypt Statekey" Grid.Column="1" HorizontalAlignment="Left" Margin="222,143,0,0" VerticalAlignment="Top" Width="169" Height="32" Click="Decrypt_Click" FontWeight="Bold" />
<Button Foreground="#FF707070" Background="Black" Content="Browse.." HorizontalAlignment="Left" Margin="531,27,0,0" VerticalAlignment="Top" Width="75" Grid.Column="1" Height="23" Click="PasswordOrPVK_Browse" FontWeight="Bold"/>
Expand Down
40 changes: 21 additions & 19 deletions ChloniumUI/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using static ChloniumUI.Browsers;
using static ChloniumUI.ExportMethods;
using static ChloniumUI.ImportMethods;
using System.Text.RegularExpressions;

namespace ChloniumUI
{
Expand Down Expand Up @@ -450,7 +451,7 @@ private bool ValidatePasswordOrPvk(string value, bool quiet = false)
if (File.Exists(value))
{
byte[] content = File.ReadAllBytes(value);
if (BitConverter.ToUInt32(content, 0) != 2964713758)
if (BitConverter.ToUInt32(content, 0) != 0xb0b5f11e)
{
MessageBox.Show("Selected file does not appear to be a valid backup key");
return false;
Expand All @@ -470,7 +471,9 @@ private bool ValidatePasswordOrPvk(string value, bool quiet = false)
if (PasswordOrPVK.Text.Length <= 256 && PasswordOrPVK.Text.Length > 0)
{
if (!quiet)
MessageBox.Show("Will assume data provided is a password");
MessageBox.Show(string.Format("Will assume data provided is {0}",
Regex.IsMatch(PasswordOrPVK.Text, @"^([a-f0-9]{32}|[a-f0-9]{40})$", RegexOptions.IgnoreCase)
? "a hash" : "a password"));
this.password = PasswordOrPVK.Text;
return true;
}
Expand All @@ -480,7 +483,7 @@ private bool ValidatePasswordOrPvk(string value, bool quiet = false)
try
{
byte[] content = Convert.FromBase64String(PasswordOrPVK.Text);
if (BitConverter.ToUInt32(content, 0) != 2964713758)
if (BitConverter.ToUInt32(content, 0) != 0xb0b5f11e)
{
MessageBox.Show("Base64 backup key provided, but is not valid");
return false;
Expand Down Expand Up @@ -566,28 +569,25 @@ private void PasswordOrPVK_Browse(object sender, RoutedEventArgs e)

private bool ValidateMasterKeyDirectory(string folderName)
{
bool isValidDirectory = false;
foreach (string file in Directory.GetFiles(folderName, "*", SearchOption.TopDirectoryOnly))
int keys = 0;
if ((File.GetAttributes(folderName) & FileAttributes.Directory) == FileAttributes.Directory)
{
try
foreach (var file in Directory.GetFiles(folderName))
{
byte[] content = File.ReadAllBytes(file);
if (content.Length == 0x2E4)
{
isValidDirectory = true;
}
if (isValidDirectory)
try
{
return true;
FileInfo f = new FileInfo(file);
if (Helpers.IsGuid(f.Name))
{
var masterKeyBytes = File.ReadAllBytes(file);
if (Helpers.IsGuid(Encoding.Unicode.GetString(masterKeyBytes, 12, 72)))
keys++;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
catch { }
}
}
MessageBox.Show("Selected directory does not contain any DPAPI masterkeys");
return false;
return keys > 0;
}

private void DPAPIMasterKey_Browse(object sender, RoutedEventArgs e)
Expand All @@ -599,6 +599,8 @@ private void DPAPIMasterKey_Browse(object sender, RoutedEventArgs e)
{
if (ValidateMasterKeyDirectory(dlg.SelectedPath))
TextBox_Masterkey.Text = dlg.SelectedPath;
else
MessageBox.Show("Selected directory does not contain any DPAPI masterkeys");
}
}

Expand Down
Loading

0 comments on commit 9ec2486

Please sign in to comment.