Showing posts with label Firefox. Show all posts
Showing posts with label Firefox. Show all posts

Sunday, July 3, 2016

Powersell to organize FireFox bookmarks

FireFox bookmarks are stored in the user's profile directory, in a sqlite database name "places.sqlite". As I keep working more on different things to do with PowerShell, I was at first annoyed that the scripts I had already written for simple file maintenance and organization couldn't be used as is with organizing the enormous amounts of bookmarks that I have. I searched around the interwebs and found a few decent examples but still wanted to roll my own.

Below is the current script as is. I only tested this on my version of FF, 47.0. However, this is a rather simplistic script and, following a best practice to backup data first, making a copy of the places.sqlite file will allow one to "roll back" to the original state.

One last note: I started this intending to make use of "System.Data.Sqlite" library. This was not hard to implement but was lengthier than I wanted. I then went to PSSqlite and found it to be a little easier to use.

#*******************************************************
#** File: Organize-FireFoxBM.ps1
#** Author: Dave Werden
#** General Notes:
#** - add 'COLLATE nocase' to end of search queries for
#**   case-insensitive searches. Similar to 'LIKE'
#**
#** - FK <= 8 is standard FF Folders
#** - Position == 0 is root level
#*******************************************************



#Need to check for pssqlite module before executing script
if(!(Get-Module pssqlite)) {
    Import-Module pssqlite
}

#*******************************************************
#** Bookmarks are stored in a profile folder in a
#** sqlite file: places.sqlite
#*******************************************************

#firefox profile folder
$profFFBasePath = "$($env:APPDATA)\Mozilla\Firefox\"
$profINIFile = "$($profFFBasePath)\profiles.ini"
$profFFProfPath = "$($profFFBasePath)\Profiles\"

#get firefox default profile name (folder name)
$profName = gc $profINIFile | select-string "Path" | split-string -separator "/" | select-string "default"

#set var for full path to default profile folder where the bookmarks are located and go there
$profBookMarksPath = $($profFFProfPath + "\" +  $profName)
cd $profBookMarksPath

#*******************************************************
#** Need a sqlite provider
#** sqlite provider DL'd from https://psqlite.codeplex.com/
#** unzipped to system PS modules folder...had to unblock DLLs
#*******************************************************

$database = ".\places.sqlite"

#*******************************************************
## query strings - Data pulls only
#*******************************************************

#This query will return the ID,  URL, GUID, Title, and Parent Folder of all bookmars
$sqlQueryBMs = "SELECT moz_places.id, moz_places.URL, moz_places.GUID, moz_bookmarks.title, moz_bookmarks.id, moz_bookmarks.parent
                FROM moz_places, moz_bookmarks
                WHERE moz_bookmarks.fk = moz_places.id"

#*******************************************************
## query strings - Data inserts only
## Trigger needed to be inplace before inserting folders
#*******************************************************

#I hand-jammed this in for my own organization plan...
#could do this with an array and a loop/LINQ
#could also..maybe will...add subfolders using this method
$sqlInserts = 'insert into moz_bookmarks (type, parent, title,dateAdded) VALUES (2,2,"BMs_Temp",CURRENT_TIMESTAMP),
                (2,2,"My_Family",CURRENT_TIMESTAMP),
                (2,2,"My_Job",CURRENT_TIMESTAMP),
                (2,2,"My_Money",CURRENT_TIMESTAMP),
                (2,2,"My_Radio",CURRENT_TIMESTAMP),
                (2,2,"My_Searches",CURRENT_TIMESTAMP),
                (2,2,"My_Coding",CURRENT_TIMESTAMP),
                (2,2,"My_Hobbies",CURRENT_TIMESTAMP)'

#Entries into moz_bookmarks need a GUID
#This will add a GUID to any newly created folder
#need to fix trigger to create more firefox-centric guids!
$sqlCreateTrigger = "CREATE TRIGGER AutoGenerateGUID
                    AFTER INSERT ON moz_bookmarks
                    FOR EACH ROW
                    WHEN (NEW.guid IS NULL)
                    BEGIN
                       UPDATE moz_bookmarks SET guid = (select hex( randomblob(4)) || hex( randomblob(2)) ||
                                  substr( hex( randomblob(2)), 2) )  WHERE rowid = NEW.rowid;
                    END"


#*******************************************************
## query strings - Data mods only
#*******************************************************

#Steps
#   1. What taxonomy do I use to sort bookmarks
#   2a. Pull all Bookmarks from original folders and move to target folders
#       i. Based upon keyword search of URL (and/or Title?) 
#       ii. DO NOT pull from target folders
#   2b. Pull all Bookmarks from original folders and move to a single temp Folder
#       i. Would probably make it easier to:
#            1) Find Dups
#            2) Clean up/Identify 'straglers' after all move operations completed
#
#Choice: 2b
#
#   3. Automated Cleanup of empty folders


#first, modify bookmarks to have parent id of our temp folder
$sqlMoveAllToTemp = 'UPDATE moz_bookmarks set parent = (Select id from moz_bookmarks where title = "BMs_Temp") 
                     where fk > 4
                     AND parent < (Select id from moz_bookmarks where title = "BMs_Temp")'

#Taxonomy...arrays of keywords :-)
$keywordsFamily = @("werden","ancestry","family","DNA","genealogy","worden")
$keywordsJob = @("compsec","embed","FCA","NGC","jobsearch","usajobs")
$keywordsMoney = @("bank","finance","money","account","loan","finance","credit","checking","savings")
$keywordsRadio = @("RF","frequency","shortwave","QR","CW","Morse","HF","UHF","VHF")
$keywordsSearches = @("google")
$keywordsCoding = @("python","perl","linux","database","php","coding","code","scripting","visual studio","netbeans","java")
$keywordsHobbies = @("jeep","wrangler","fish","guitar","Audible","audio book")


foreach ($word in $keywordsHobbies)
{
    $sqlUpdate = "UPDATE moz_bookmarks
                    SET parent = (SELECT id from moz_bookmarks WHERE title = `"My_Hobbies`") WHERE moz_bookmarks.title like `"%$($word)%`" COLLATE nocase;"
    Invoke-SqliteQuery -DataSource $database -QueryTimeout 10 -Query $sqlUpdate -SqlParameters @{ word = $word }
}

foreach ($word in $keywordsSearches)
{
    $sqlUpdate = "UPDATE moz_bookmarks
                    SET parent = (SELECT id from moz_bookmarks WHERE title = `"My_Searches`") WHERE moz_bookmarks.title like `"%$($word)%`" COLLATE nocase;"
    Invoke-SqliteQuery -DataSource $database -QueryTimeout 10 -Query $sqlUpdate -SqlParameters @{ word = $word }
}

foreach ($word in $keywordsMoney)
{
    $sqlUpdate = "UPDATE moz_bookmarks
                    SET parent = (SELECT id from moz_bookmarks WHERE title = `"My_Money`") WHERE moz_bookmarks.title like `"%$($word)%`" COLLATE nocase;"
    Invoke-SqliteQuery -DataSource $database -QueryTimeout 10 -Query $sqlUpdate -SqlParameters @{ word = $word }
}

foreach ($word in $keywordsJob)
{
    $sqlUpdate = "UPDATE moz_bookmarks
                    SET parent = (SELECT id from moz_bookmarks WHERE title = `"My_Job`") WHERE moz_bookmarks.title like `"%$($word)%`" COLLATE nocase;"
    Invoke-SqliteQuery -DataSource $database -QueryTimeout 10 -Query $sqlUpdate -SqlParameters @{ word = $word }
}

foreach ($word in $keywordsCoding)
{
    $sqlUpdate = "UPDATE moz_bookmarks
                    SET parent = (SELECT id from moz_bookmarks WHERE title = `"My_Coding`") WHERE moz_bookmarks.title like `"%$($word)%`" COLLATE nocase;"
    Invoke-SqliteQuery -DataSource $database -QueryTimeout 10 -Query $sqlUpdate -SqlParameters @{ word = $word }
}

foreach ($word in $keywordsRadio)
{
    $sqlUpdate = "UPDATE moz_bookmarks
                    SET parent = (SELECT id from moz_bookmarks WHERE title = `"My_Radio`") WHERE moz_bookmarks.title like `"%$($word)%`" COLLATE nocase;"
    Invoke-SqliteQuery -DataSource $database -QueryTimeout 10 -Query $sqlUpdate -SqlParameters @{ word = $word }
}

foreach ($word in $keywordsFamily)
{
    $sqlUpdate = "UPDATE moz_bookmarks
                    SET parent = (SELECT id from moz_bookmarks WHERE title = `"My_Family`") WHERE moz_bookmarks.title like `"%$($word)%`" COLLATE nocase;"
    Invoke-SqliteQuery -DataSource $database -QueryTimeout 10 -Query $sqlUpdate -SqlParameters @{ word = $word }
}


#*******************************************************
## Uncomment below to Execute other Queries from above
#*******************************************************

#Invoke-SqliteQuery -DataSource $database -QueryTimeout 10 -Query $sqlInserts

#Invoke-SqliteQuery -DataSource $database -QueryTimeout 10 -Query $sqlCreateTrigger

#Invoke-SqliteQuery -DataSource $database -QueryTimeout 10 -Query $sqlMoveAllToTemp


#*******************************************************
## Clean up
#*******************************************************


#drop the trigger...get original db back to original triggerless state
$sqlDeleteTrigger = "DROP TRIGGER AutoGenerateGUID"

Invoke-SqliteQuery -DataSource $database -QueryTimeout 10 -Query $sqlDeleteTrigger

Sunday, October 3, 2010

Skype shot my CSS in IE8!!!(???)

I recently had to create two seperate webpages that both used two differing Cascading Style Sheets. Each page needed to allow for the viewer to change between stylesheets. A task that should be easy...but one that proved that testing in the browser doesn't automatically indicate compatability with brower plug-ins. This is apparently especially true with Internet Exploder Explorer.

What I did: Tested both pages in Firefox and IE8. Both pages would initially load correctly. The initial "index.html" worked as advertised in both browsers: the viewer was able to switch repeatedly between CSS's through the use of some simple Javascript buttons. However, the second page (stored in the same parent directory and using the EXACT same relative paths) would NOT use the first stylesheet in IE8 after the initial page load. It would toggle between stylesheets, but when stylesheet 1 was selected, the viewer was presented with default, left-align, text.

What I have:

  • Skype

  • Windows 7 Professional

  • IE8

  • Firefox 3.6.10


Debugging/Troubleshooting:
There were NO issues with FireFox, so I was automatically inclined to believe that the failure lied with Microsoft. I re-wrote the webpage at least six times (not that fun) and re-wrote the CSS sheets at least three. Additionally, all were validated multiple times through the W3C tools (XHTML and CSS). However, NOTHING seemed to work.

The Lightbuld:
I decided that maybe I should try to isolate from outside my current box. My wife's computer is exactly the same, with the exception of not having Skype installed (I try to avoid having Skype as much as possible, which is a WHOLE different topic). On her laptop the webpages BOTH acted correctly between the two stylesheets, on both IE8 and FireFox. I did run the IE8 Developer Tools (F12) in attempt to identify the issue, but that was no help. It was when I looked at the plug-ins that I noticed a difference:
It MUST be the Skype plug-in.

Now What:
All I can deduce at this point is that the Skype Add-in for IE8 (the one that allows you call-by-click from numbers on website) is the culprit. However, I have NOT been able to identify why. I do seriously wonder if this is an indication of how IE8 renders XHTML pages when the Skype plug-in is installed, and, MORE IMPORTANTLY, if this is not an indication of a bug in skype that could indicate a vulnerability between IE8, Skype, and parsing. I haven't had a lot of time to research this, so at this point it is purely conjecture based upon what I have seen. However, I do have a friend who had the EXACT problem and indications that Skype is the culprit.

Yet One MORE reason NOT to like Skype!

Friday, August 14, 2009

Unpack the Junk instead of Opening it

Today I learned a new and awesome trick for unpacking javascript that is found in packet captures. I have pasted the method below from the original site, along with the link to the author's posting. In short, this is an invaluable tool and makes me love Firefox even more!

Update: This technique can also be used to deobfuscate Yahoo Counters.

[Copied text]
Without any intro – crap that I usually write explaining why I had to write this post, I’m going for the subject. You(general junta or web developers or scared security guys) might see some eval packed javascript which phishing idiots ask you to copy paste on your URL bar and hit enter key.
Unpacking JS is a PITA was an answer that my brain use to give whenever I think about it. Just now, I found a very easy method to convert it into readable Javascript without any extra tool (IE boys, run away) Its very simple in FF or Opera.
FF guys, all you need to do is …
Copy the eval packed JS. something like —- eval(function(p,a,c,k,e,d){e=function(c) …………………. }
Open Error Console on your firefox
Paste the packed JS in Code input tab
Add eval = alert; at the beginning of the code
Hit Evaluate
You will get the proper javascript for the packed javascript. Copy paste it into any code prettifier. It will become perfectly readable. Opera folks, follow this. Packed JS is a huge asset for Phishing as who would have expected that packed JS in this code will make you join around 26 communities and send some stupid message to all your friends without your knowledge as soon as you copy paste some JS code on your URL bar and hit enter.
[End copied text from: http://karteek.selfdabba.com/2008/08/unpack-js/]