恭贺新禧,阿胶,藏宝阁梦幻站-遇见枕头,睡眠新革命,我有遇见枕头,带来好睡眠

admin 2019-07-12 阅读:132

用 Python 解析火狐 Sqlite3 数据库

在上一节中,咱们研讨了 Skype 存储的单一的运用数据库。该数据库供给了大

量的查询数据。在本节中,咱们将探求火狐存储的是一系列的什么样的数据库。

火狐存储这些数据库的默许目录为 C:\Documents and

Settings\\Application Data\Mozilla\Firefox\Profiles\\,

在 Windows 体系下,在 MAC OS X 体系中存储在

/Users//Library/Application\ Support/Firefox/Profiles/

folder>目录下。让咱们列出存储在目录中的数据库吧。

investigator$ ls *.sqlite

places.sqlite downloads.sqlite search.sqlite

addons.sqlite extensions.sqlite signons.sqlite

chromeappsstore.sqlite formhistory.sqlite webappsstore.sqlite

content-prefs.sqlite permissions.sqlite

cookies.sqlite places.sqlite

查看目录列表,很明显火狐存储了恰当丰厚的数据。可是咱们该从哪儿开端调

查?让咱们从 downloads.sqlite 数据库开端查询。downloads.sqlite 文件存储了

火狐用户下载文件的信息。它包括了一个表明为 moz_downloads,用来存储文

件名,下载源,下载日期,文件巨细,存储在本地的方位等信息。咱们运用一

个 Python 脚原本履行 SELECT 句子来查询恰当的列:称号,来历和日期时刻。

留意火狐用的也是 UNIX 时刻日期。但为了存储 UNIX 时刻日期到数据库,它将

日期乘以 1000000 秒,因而咱们正确的时刻格局应该是除以 1000000 秒。

import sqlite3

def printDownloads(downloadDB):

conn = sqlite3.connect(downloadDB)

c = conn.cursor()

c.execute('SELECT name, source, datetime(endTime/1000000,

\'unixepoch\') FROM moz_downloads;')

print '\n[*] --- Files Downloaded --- '

for row in c:

print('[+] File: ' + str(row[0]) + ' from source: ' + str(row[1]) +

' at: ' + str(row[2]))

对 downloads.sqlite 文件运转脚本,咱们看到,此配置文件包括了咱们曾经下

载文件的信息。事实上,咱们是在前面学习元数据时下载的文件。

investigator$ python firefoxDownloads.py

[*] --- Files Downloaded ---

[+] File: ANONOPS_The_Press_Release.pdf from source:

http://www.wired.com/images_blogs/threatlevel/2010/12/ANON

OPS_The_

Press_Release.pdf at: 2011-12-14 05:54:31

好极了!咱们现在知道什么时候用户运用火狐下载过什么文件。可是,假如查询

者想运用用户的认证从头登陆到网站该怎么办?例如,警方查询员承认用户从

根据邮件的网站上下载了对儿童有害的图片该怎么办?警方查询员想从头登陆

到网站,最有或许的是短少暗码或许是用户认证的电子邮件。进入 cookies,由

于 HTTP 西意缺少状况规划,网站运用 cookies 来保护状况。

考虑一下,例如,当用户登陆到站点,假如阅读器不能保护 cookies,用户需求

登陆能阅览每一个人的私家邮件。火狐存储了这些 cookies 在 cookies. sqlite 数

据库中。如查询员能够提取 cookies 并重用,就供给了需求认证才干登陆到资

源的条件。

让咱们快速编写一个 Python 脚本提取用户的 cookies。咱们衔接到数据库并执

行咱们的 SELECT 句子。在数据库中,moz_cookies 保护这 cookies,从

cookies.sqlite 数据库中的 moz_cookies 表中,咱们将查询主机,称号,

cookies 的值,并在屏幕中打印出来。

def printCookies(cookiesDB):

try:

conn = sqlite3.connect(cookiesDB)

c = conn.cursor()

c.execute('SELECT host, name, value FROM moz_cookies')

print('\n[*] -- Found Cookies --')

for row in c:

host = str(row[0])

name = str(row[1])

value = str(row[2])

print('[+] Host: ' + host + ', Cookie: ' + name + ', Value: ' +

value)

except Exception as e:

if 'encrypted' in str(e):

print('\n[*] Error reading your cookies database.')

print('[*] Upgrade your Python-Sqlite3 Library')

更新 sqlite3

你或许会留意到假如你测验用默许的 sqlite3 翻开 cookies.sqlite 数据库会陈述

文件被加密或许是这不是一个数据库。默许装置的 Sqlite3 的版别是

Sqlite3.6.22 不支持 WAL 日志形式。最新版别的火狐运用 PRAGMA

journal_mode=WAL 形式在 cookies.sqlite 和 places.sqlite 数据库中。企图用旧

版别的 Sqlite3 或许是 sqlite3 模块会报错。

SQLite version 3.6.22

Enter ".help" for instructions

Enter SQL statements terminated with a ";"

sqlite> select * from moz_cookies;

Error: file is encrypted or is not a database

After upgrading your Sqlite3 binary and Pyton-Sqlite3 libraries to

a version > 3.7, you should be able to open the newer Firefox

databases.

investigator:∼# sqlite3.7 ∼/.mozilla/firefox/nq474mcm.default/

cookies.sqlite

SQLite version 3.7.13 2012-06-11 02:05:22

Enter ".help" for instructions

Enter SQL statements terminated with a ";"

sqlite> select * from moz_cookies;

1|backtrack-linux.org|__<..SNIPPED..>

4|sourceforge.net|sf_mirror_attempt|<..SNIPPED..>

To avoid our script crashing on this unhandled error, with the

cookies.sqlite and places.sqlite databases, we put exceptions to

catch the encrypted database error message. To avoid receiving

this error, upgrade your Python-Sqlite3 library or use the older

Firefox cookies.sqlite and places.sqlite databases included on the

companion Web site.

为了防止咱们的脚本在这个过错上溃散,咱们将 cookies.sqlite 和

places.sqlite 数据库放在反常处理中。为了防止这个过错,晋级你的 Python-

sqlite3 库或运用旧版别的火狐。

查询者或许也期望罗列阅读前史,火狐存储这些数据在 places.sqlite 数据库中。

在这里,moz_places 表给咱们供给了名贵的列,包括了什么时候用户访问了什

么网站的信息。而咱们的脚本 printHistory()函数只考虑到 moz_places 表,而

维基百科引荐运用 moz_places 表和 moz_historyvisits 表得到阅读器前史。

def printHistory(placesDB):

try:

conn = sqlite3.connect(placesDB)

c = conn.cursor()

c.execute("select url, datetime(visit_date/1000000,

'unixepoch') from moz_places, moz_historyvisits where visit_count >

0 and moz_places.id==moz_historyvisits.place_id;")

print('\n[*] -- Found History --')

for row in c:

url = str(row[0])

date = str(row[1])

print '[+] ' + date + ' - Visited: ' + url

except Exception as e:

if 'encrypted' in str(e):

print('\n[*] Error reading your places database.')

print('[*] Upgrade your Python-Sqlite3 Library')

exit(0)

让咱们运用终究的常识和从前的正则表达式的常识扩展咱们的函数。阅读前史

及其有价值,对深化了解一些特定的 URL 很有用。Google 查找查询包括查找

URL 内部的权限,比如说,在无线的章节里,咱们将就此打开深化。可是,现

在让咱们只提取查找条件 URL 右边的条目。假如在咱们的前史里发现包括

Google,咱们发现他的特色 q=后边跟随者&。这个特定的字符序列标识

Google 查找。假如咱们真的找到这个条目,咱们将经过用空格替换一些 URL 中

用的字符来收拾输出。终究,咱们将打印校正后的输出到屏幕上,现在咱们有

一个函数能够查找 places.sqlite 文件并打印 Google 查找查询前史。

import sqlite3, re

def printGoogle(placesDB):

conn = sqlite3.connect(placesDB)

c = conn.cursor()

c.execute("select url, datetime(visit_date/1000000, 'unixepoch')

from moz_places, moz_historyvisits where visit_count > 0 and

moz_places.id==moz_historyvisits.place_id;")

print('\n[*] -- Found Google --')

for row in c:

url = str(row[0])

date = str(row[1])

if 'google' in url.lower():

r = re.findall(r'q=.*\&', url)

if r:

search=r[0].split('&')[0]

search=search.replace('q=', '').replace('+', ' ')

print('[+] '+date+' - Searched For: ' + search)

将一切的包装在一起,咱们现在有下载文件信息,读取 cookies 和阅读前史,

乃至是用户的 Google 的查找前史功用。该选项的解析应该看看前面十分类似的

Skype 数据库的探求。

你或许留意到运用 os.join.path 函数来创立完好的途径会问为什么不是只增加

途径和文件的字符串值在一起。是什么让咱们不这样运用让咱们来看一个比如:

downloadDB = pathName + “\\downloads.sqlite”替换

downloadDB = os.path.join(pathName,“downloads.sqlite”)

考虑一下,Windows 用户运用 C:\Users\\来表明途径,而

Linux 和 Mac OS 运用/home//来表明用户途径,不同的操作体系

中,斜杠表明的含义不一样,这点当咱们创立文件的完好途径时不得不考虑。

OS 库答应咱们创立一个独立于操作体系都能作业的脚本。

# coding=UTF-8

import sqlite3

import re

import optparse

import os

def printDownloads(downloadDB):

conn = sqlite3.connect(downloadDB)

c = conn.cursor()

c.execute('SELECT name, source, datetime(endTime/1000000,

\'unixepoch\') FROM moz_downloads;')

print '\n[*] --- Files Downloaded --- '

for row in c:

print('[+] File: ' + str(row[0]) + ' from source: ' + str(row[1]) + '

at: ' + str(row[2]))

def printCookies(cookiesDB):

try:

conn = sqlite3.connect(cookiesDB)

c = conn.cursor()

c.execute('SELECT host, name, value FROM moz_cookies')

print('\n[*] -- Found Cookies --')

for row in c:

host = str(row[0])

name = str(row[1])

value = str(row[2])

print('[+] Host: ' + host + ', Cookie: ' + name + ', Value: ' +

value)

except Exception as e:

if 'encrypted' in str(e):

print('\n[*] Error reading your cookies database.')

print('[*] Upgrade your Python-Sqlite3 Library')

def printHistory(placesDB):

try:

conn = sqlite3.connect(placesDB)

c = conn.cursor()

c.execute("select url, datetime(visit_date/1000000, 'unixepoch')

from moz_places, moz_historyvisits where visit_count > 0 and

moz_places.id==moz_historyvisits.place_id;")

print('\n[*] -- Found History --')

for row in c:

url = str(row[0])

date = str(row[1])

print '[+] ' + date + ' - Visited: ' + url

except Exception as e:

if 'encrypted' in str(e):

print('\n[*] Error reading your places database.')

print('[*] Upgrade your Python-Sqlite3 Library')

exit(0)

def printGoogle(placesDB):

conn = sqlite3.connect(placesDB)

c = conn.cursor()

c.execute("select url, datetime(visit_date/1000000, 'unixepoch')

from moz_places, moz_historyvisits where visit_count > 0 and

moz_places.id==moz_historyvisits.place_id;")

print('\n[*] -- Found Google --')

for row in c:

url = str(row[0])

date = str(row[1])

if 'google' in url.lower():

r = re.findall(r'q=.*\&', url)

if r:

search=r[0].split('&')[0]

search=search.replace('q=', '').replace('+', ' ')

print('[+] '+date+' - Searched For: ' + search)

def main():

parser = optparse.OptionParser("usage%prog -p

path> ")

parser.add_option('-p', dest='pathName', type='string',

help='specify skype profile path')

(options, args) = parser.parse_args()

pathName = options.pathName

if pathName == None:

print(parser.usage)

exit(0)

elif os.path.isdir(pathName) == False:

print('[!] Path Does Not Exist: ' + pathName)

exit(0)

else:

downloadDB = os.path.join(pathName, 'downloads.sqlite')

if os.path.isfile(downloadDB):

printDownloads(downloadDB)

else:

print('[!] Downloads Db does not exist: '+downloadDB)

cookiesDB = os.path.join(pathName, 'cookies.sqlite')

if os.path.isfile(cookiesDB):

printCookies(cookiesDB)

else:

print('[!] Cookies Db does not exist:' + cookiesDB)

placesDB = os.path.join(pathName, 'places.sqlite')

if os.path.isfile(placesDB):

printHistory(placesDB)

printGoogle(placesDB)

else:

print('[!] PlacesDb does not exist: ' + placesDB)

if __name__ == "__main__":

main()

运转咱们的脚本查询火狐用户的配置文件,咱们能够看到这些成果。鄙人一节

中,咱们将运用部分咱们前面学到的技巧,可是经过在数据库的干草堆中查找

一根针来扩展咱们的 SQLite 常识。

investigator$ python parse-firefox.py -p ∼/Library/Application\

Support/Firefox/Profiles/5ab3jj51.default/

[*] --- Files Downloaded ---

[+] File: ANONOPS_The_Press_Release.pdf from source:

http://www.wired.com/images_blogs/threatlevel/2010/12/ANON

OPS_The_

Press_Release.pdf at: 2011-12-14 05:54:31

[*] -- Found Cookies --

[+] Host: .mozilla.org, Cookie: wtspl, Value: 894880

[+] Host: www.webassessor.com, Cookie: __utma, Value:

1.224660440401.13211820353.1352185053.131218016553.1

[*] -- Found History --

[+] 2011-11-20 16:28:15 - Visited: http://www.mozilla.com/en-

US/

firefox/8.0/firstrun/

[+] 2011-11-20 16:28:16 - Visited: http://www.mozilla.org/en-US/

firefox/8.0/firstrun/

[*] -- Found Google --

[+] 2011-12-14 05:33:57 - Searched For: The meaning of life?

[+] 2011-12-14 05:52:40 - Searched For: Pterodactyl

[+] 2011-12-14 05:59:50 - Searched For: How did Lost end?

用 Python 查询移动设备的 iTunes 备份

在 2011 年 4 月,安全研讨人员和前苹果职工公开了 iPhone 和 Ipad IOS 操作

体系的一个隐私问题。一个重要的查询之后发现 IOS 体系事实上盯梢和记载设

备的 GPS 坐标并存储在手机的 consolidated.db 数据库中。在这个数据库中一

个名为 Cell-Location 的表包括了搜集的手机的 GPS 坐标。该设备经过归纳了最

近的手机信号发射塔来承认定位信息为用户供给更好的服务。可是,安全人员

提出,该收据或许会被歹意的运用,用来盯梢 iPhone/Ipad 用户的完好活动路

线。此外,运用备份和存储移动设备的信息到电脑上也记载了这些信息。尽管

定位记载信息现已从苹果体系中移出了,但发现数据的进程任然还在。在本节

中,咱们将重复这一进程,从 iPhone 设备中提取备份信息。具体来说,咱们将

运用 Python 脚本从 IOS 备份中提取一切的文本音讯。

当用户对 iPhone 或许 iPad 设备进行备份时,它将文件存储到机器的特别目录。

关于 Windows 体系,iTunes 程序存储移动设备备份目录在 C:\Documents and

Settings\\Application

Data\AppleComputer\MobileSync\Backup 下,在 Mac OS X 体系上贮存目录在

/Users//Library/Application Support/MobileSync/Backup/。

iTunes 程序备份移动设备存储一切的移动设备到这些目录下。让咱们来探求我

的 iPhone 最近的备份文件。

investigator$ ls

68b16471ed678a3a470949963678d47b7a415be3

68c96ac7d7f02c20e30ba2acc8d91c42f7d2f77f

68b16471ed678a3a470949963678d47b7a415be3

68d321993fe03f7fe6754f5f4ba15a9893fe38db

69005cb27b4af77b149382d1669ee34b30780c99

693a31889800047f02c64b0a744e68d2a2cff267

6957b494a71f191934601d08ea579b889f417af9

698b7961028238a63d02592940088f232d23267e

6a2330120539895328d6e84d5575cf44a082c62d

<..SNIPPED..>

为了取得关于每个文件更多的信息,咱们将运用 UNIX 指令 file 来提取每个文件

的文件类型。这个指令运用文件头的字节信息类承认文件类型。这为咱们供给

了更多的信息,咱们看到移动备份目录包括了一些 sqlite3 数据库,JPEG 图画,

原始数据和 ASCII 文本文件。

investigator$ file *

68b16471ed678a3a470949963678d47b7a415be3: data

68c96ac7d7f02c20e30ba2acc8d91c42f7d2f77f: SQLite 3.x database

68b16471ed678a3a470949963678d47b7a415be3: JPEG image data

68d321993fe03f7fe6754f5f4ba15a9893fe38db: JPEG image data

69005cb27b4af77b149382d1669ee34b30780c99: JPEG image data

693a31889800047f02c64b0a744e68d2a2cff267: SQLite 3.x

database

6957b494a71f191934601d08ea579b889f417af9: SQLite 3.x

database

698b7961028238a63d02592940088f232d23267e: JPEG image data

6a2330120539895328d6e84d5575cf44a082c62d: ASCII English

text

<..SNIPPED..>

file 指令让咱们知道一些文件包括 SQLite 数据库并对灭个数据库的内容有少数

的描绘。咱们将运用 Python 脚本快速的快速的枚举在移动备份目录下找到的每

一个数据库的一切的表。留意咱们将再次在咱们的 Python 脚本中运用

sqlite3。咱们的脚本列出作业目录的内容然后测验衔接每一个数据库。关于那

些成功的衔接,脚本将履行指令:SELECT tbl_name FROM sqlite_master

WHERE type==‘table’。,每一个 SQLite 数据库保护了一个

sqlite_master 的表包括了数据库的整体结构,说明晰数据库的整体架构。上面

的指令答应咱们罗列数据库形式。

import os

import sqlite3

def printTables(iphoneDB):

try:

conn = sqlite3.connect(iphoneDB)

c = conn.cursor()

c.execute('SELECT tbl_name FROM sqlite_master WHERE

type==\"table\";')

print("\n[*] Database: "+iphoneDB)

for row in c:

print("[-] Table: "+str(row))

except:

pass

finally:

conn.close()

dirList = os.listdir(os.getcwd())

for fileName in dirList:

printTables(fileName)

运转咱们的脚本,咱们罗列了移动备份目录里的一切的数据库形式。当脚本找

到多个数据库,咱们将收拾输出咱们关怀的特定的数据库。留意文件名为

d0d7e5fb2ce288813306e4d4636395e047a3d28 包括了一个 SQLite 数据库里边

有一个名为 messages 的表。该数据库包括了存储在 iPhone 备份中的文本音讯

列表。

investigator$ python listTables.py

<..SNIPPED...>

[*] Database: 3939d33868ebfe3743089954bf0e7f3a3a1604fd

[-] Table: (u'ItemTable',)

[*] Database: d0d7e5fb2ce288813306e4d4636395e047a3d28

[-] Table: (u'_SqliteDatabaseProperties',)

[-] Table: (u'message',)

[-] Table: (u'sqlite_sequence',)

[-] Table: (u'msg_group',)

[-] Table: (u'group_member',)

[-] Table: (u'msg_pieces',)

[-] Table: (u'madrid_attachment',)

[-] Table: (u'madrid_chat',)

[*] Database: 3de971e20008baa84ec3b2e70fc171ca24eb4f58

[-] Table: (u'ZFILE',)

[-] Table: (u'Z_1LABELS',)

<..SNIPPED..>

尽管现在咱们知道 SQLite 数据库文件

d0d7e5fb2ce288813306e4d4636395e047a3d28 包括了文本音讯,咱们想要能

够主动的对不同的备份进行查询。为了履行这个,咱们编写了一个简略的函数

名为 isMessageTable(),这个函数将衔接数据库并枚举数据库形式信息。假如

文件包括名为 messages 的表,则回来 True,不然函数回来 False。现在咱们有

才能快速扫描目录下的上千个文件并承认包括 messages 表的特定数据库。

def isMessageTable(iphoneDB):

try:

conn = sqlite3.connect(iphoneDB)

c = conn.cursor()

c.execute('SELECT tbl_name FROM sqlite_master WHERE

type==\"table\";')

for row in c:

if 'message' in str(row):

return True

except:

return False

现在,咱们能够定位文本音讯数据库了,咱们期望能够打印包括在数据库中的

内容,如时刻,地址,文本音讯。为此,咱们衔接数据库并履行以下指令:

‘select datetime(date,\‘unixepoch\’), address, text from message WHERE

address>0;’咱们能够打印查询成果到屏幕上。留意,咱们将运用一些反常处

理,假如 isMessageTable()回来的数据库不是咱们需求的文本信息数据库,它

将不包括数据,地址,和文本的列。假如咱们去错了数据库,咱们将答应脚本

捕获反常并持续履行,直到找到正确的数据库。

def printMessage(msgDB):

try:

conn = sqlite3.connect(msgDB)

c = conn.cursor()

c.execute('select datetime(date,\'unixepoch\'),address, text

from message WHERE address>0;')

for row in c:

date = str(row[0])

addr = str(row[1])

text = row[2]

print('\n[+] Date: '+date+', Addr: '+addr + ' Message: ' +

text)

except:

pass

包装这些函数在一起,咱们能够构建终究的脚本。咱们将增加一个选项解析来

履行 iPhone 备份的目录。接下来,咱们将列出该目录的内容并测验每一个文件

直到找到文本信息数据库。一旦咱们找到这个文件,咱们能够打印数据库的内

容在屏幕上。

# coding=UTF-8

import os

import sqlite3

import optparse

def isMessageTable(iphoneDB):

try:

conn = sqlite3.connect(iphoneDB)

c = conn.cursor()

c.execute('SELECT tbl_name FROM sqlite_master WHERE

type==\"table\";')

for row in c:

if 'message' in str(row):

return True

except:

return False

def printMessage(msgDB):

try:

conn = sqlite3.connect(msgDB)

c = conn.cursor()

c.execute('select datetime(date,\'unixepoch\'),address, text from

message WHERE address>0;')

for row in c:

date = str(row[0])

addr = str(row[1])

text = row[2]

print('\n[+] Date: '+date+', Addr: '+addr + ' Message: ' + text)

except:

pass

def main():

parser = optparse.OptionParser("usage%prog -p

Directory> ")

parser.add_option('-p', dest='pathName',

type='string',help='specify skype profile path')

(options, args) = parser.parse_args()

pathName = options.pathName

if pathName == None:

print parser.usage

exit(0)

else:

dirList = os.listdir(pathName)

for fileName in dirList:

iphoneDB = os.path.join(pathName, fileName)

if isMessageTable(iphoneDB):

try:

print('\n[*] --- Found Messages ---')

printMessage(iphoneDB)

except:

pass

if __name__ == '__main__':

main()

对 iPhone 备份目录运转这个脚本,咱们能够看到一些存储在 iPhone 备份中的

最近的文本音讯。

investigator$ python iphoneMessages.py -p ∼/Library/Application\

Support/MobileSync/Backup/192fd8d130aa644ea1c644aedbe2370

8221146a8/

[*] --- Found Messages ---

[+] Date: 2011-12-25 03:03:56, Addr: 55555554333 Message:

Happy

holidays, brother.

[+] Date: 2011-12-27 00:03:55, Addr: 55555553274 Message: You

didnt

respond to my message, are you still working on the book?

[+] Date: 2011-12-27 00:47:59, Addr: 55555553947 Message: Quick

question, should I delete mobile device backups on iTunes?

<..SNIPPED..>