BGINFO - A Posh Recreation
Recently I have been building a lot of Windows Servers in different environments - one
Grumpy Admin is lazy, we all know he is lazy – no one more than his partner! So like a large portion of the internet world Grumpy Admin uses Chrome and uses the save password options in chrome. Yes I agree that perhaps I should use lastpast or something else… but did I mention I am lazy!
But security is about risk vs reward, you as long as you are always on the right side of the equation then sometime you can accept risks. For me the risk is moderate and the rewards are high IE i don’t have to remember stuff or type stuff!
That doesn’t mean that I don’t protect high valued accounts like my Google,Facebook,Hotmail,PayPal etc and vital company mails and thing that can cause me problems – these accounts all have unique and strong passwords and two factor. All good things, you expect from a IT guy. I also have some throw away level passwords… So for example, password I use for signing up to newsletters and the likes all pointless.
However, there is a large number of websites, where I have signed up and saved the password and it will be months before I go back – and I am often pleasantly surprised to find I already have an account.
My account password hygiene is on paper actually quite poor really.
I use easy to remember password with maybe a small variation which would allow a decent fuzzer to crack them but adding 1 / 2 /3 4 at the end of the password.
I know, I know, I really should practice what I preach to come to password security.
This brings me to today; I need to know a password I had forgotten about! So as I have done on so many times before I went in to my chrome and settings, and advance and to the password manager, entered my Windows Account password and clicked reveal and found my password! They even for lazy people like me provide a search box to search your stored passwords. God, knows I need it as well, I have close to 500 of the bad boys saved in Chrome! I wonder how many are dead, out of date etc. A full clean up will be in order after I done this blog post!
So excellent, I find the password that I am looking for and then I checked another, and they were the same! So with my CISSP hat on I thought, I really should do an audit and capture, what passwords are being used and where to see how bad I really am…. I have the results, and they are as I mentioned above GRIM! if I publish them, I expect ISC2 to revoke my CISSP certificate! Bad Grumpy Admin….BAD!!!
It was a shocking high percentage of passwords in the store that were perhaps the exact same or very similar. Simple passwords, password reuse all the sins people like me tell our users off for!!! It makes me grumpy to think about how bad I actually am! Nevermind, only one way to improve right?
Google also provides a very handy website to check your passwords that it saves but as I have a sync password I am unable to view them from the website bah! So that isn’t actually that helpful and stuff like that just makes me Grumpy!
I also seen and read on a number of blog that by using the chrome://flags you can enable a hidden, well disabled by default – password import and export features . This did the job perfectly for me, put it inside CSV format… What more could I want!
Knowing that they were easy to export got my inner geek thinking… how does it store these, passwords, are they encrypted, what encryption do they use etc etc….
So I went poking around, did some reading and researched and discovered that Chrome stores them in a basic SQLlITE database and uses the built in Windows Encryption methods through the Windows Data Protection API’s ( DPAPI) to protect them using the current windows account. This seems reasonable as this means I cannot steal your password file and load it up on my computer. I have to open it and access it from the computer the account resides on. Well i caveat that of course, there a number of things you can do to break that but that not my intention really!
Now I have previously about 2 years ago, done some work with PowerShell and SQLLITE – So I know it more than possible to open a SQLLITE DB in PowerShell, remember how to do it is quite different though. So I thought, rather than doing some actual work this afternoon, I will see if I can replicate the export via PowerShell. Because we all know how much Grumpy Admin loves PowerShell. Right lets get to it!
So the first thing I need to do is get SQLite installed, well the assemblies, that provide/expose the correct function, that I can then use to connect to and use inside of my PowerShell Scripts or functions…
Helpfully Microsoft TechNet blogs has a brilliant guide on how to do this! So in the first few hit in Google I find this –
After a quick read, I download and install the correct binary files. I know, that I’m on a 64x system, so I don;t need to do the old [intptr]::Size trick to work it out as mentioned on the page!
Done, now to start building my actually script – it’s simple, really !
First I need to know where my database is!
So I simple use $env:localappdata and with some lazy cd and ls/dir commands I find the Chrome path 🙂 Easy as! and then some simple PowerShell to combine that with the rest of the path and the database name to get something usable!
The results can be seen here!
Very simple, there might be a smart method of doing this but for now this will do for me, remember Grumpy Admin is LAZY!!!!
The actual DB file is called “Login Data” with no file ext!
Next thing I need to do is to load in my SQLite binary! using the add-type command!
The Microsoft guide is good, you can cut and paste, just ensure your path is correct!!!!
As you can see above, I also cut and paste the basic connection code – why reinvent the wheel!
So it’s a new-object SQLiteConnection
Next thing I do, is again rip off their DB search code, and slightly modify their SQL statement. From my exploring of the login data database, I find out the table is called logins. So I just do a
select * from logins
I could do some smarter stuff but meh! I am lazy and doing extra work just makes me Grumpy!
They also create a new object of the type System.Data.DataSet as you can see they use their adapter object to FILL the $data dataset object!
Now that good, but nothing happens when you run it! Or does it!
Let have a quick look, drop in to the Posh prompt and , lets access the $data object as you can see. There is Table and rows. Elements to it! Lets dump that to screen and see what we have!
ok great, just to be safe, I will do what Grumpy Admin does normally and throw a GM at it and see what methods and properties I have to play with!
Now lets create a simple foreach row loop as you do with database stuff and start extracting the information that we want to present!
lets start but dumping only the three things we care about – the site, the username and the password
So my code for this will look like this
and lets run that now….
OH ok… what going on…. lets tidy it up a bit and see what going on…
it appears that the password is encoded and stored in BYTE format… so a quick google and I find this!
which leads me to the core function decoding part of the python script….
which a right click and google search on that win32crypt function leads me to…
and in the comments the answer I need to decode these password strings!
add-type -assembly name system.security
[system.security.cruptography.protectdata]::unprotect
I have to do some more simple googling about how to use this function which leads to
https://msdn.microsoft.com/en-us/library/ms995355.aspx
the link was purple so I must of been there before 🙂 which is good sign! Grumpy admin is terrible and tends to forget what he has already learned or done in the past!
So i manage to hobble this line
$password=[System.Text.Encoding]::Default.GetString( [System.Security.Cryptography.ProtectedData]::Unprotect( $row.password_value, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser ) )
and then I throw that inside my solution!
After a few attempts to get the final solution how I want it and a simple working script – wasn’t that as good as clicking the Export Button?
$path="$env:LOCALAPPDATA"+"\Google\Chrome\User Data\Default\" $file="Login Data" $dbfile=$path+$file Add-Type -AssemblyName System.Security Add-Type -Path "C:\Program Files\System.Data.SQLite\2012\bin\System.Data.SQLite.dll" $con = New-Object -TypeName System.Data.SQLite.SQLiteConnection $con.ConnectionString = "Data Source="+$dbfile $con.Open() $sql =$con.CreateCommand() $sql.CommandText = "select * from logins" $adapter = New-Object -TypeName System.Data.SQLite.SQLiteDataAdapter $sql $data = New-Object System.Data.DataSet [void]$adapter.Fill($data) foreach ($row in $Data.Tables[0].Rows) { $location=$row.origin_url $username=$row.username_value $password=[System.Text.Encoding]::Default.GetString( [System.Security.Cryptography.ProtectedData]::Unprotect( $row.password_value, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser ) ) write-output "URL:$location USERNAME:$username Password:$password" } $con.Close()
Job done, as ever here is the proof!
WEll you didn’t expect me to give you all my passwords and usernames etc did you! ha ha i guess, I have exposed a few usernames – I guess I will take the hit as I’m far to lazy to get my red pen out! Going forward, I guess this might work for other chrome databases like, bookmarks etc? I don’t know will have to have a play!
Hazzy