用python调查应用程序结构

用Python调查应用程序结构

SQLite 数据库在几个不同的应用程序中是很流行的选择,对于local/client 存储类型来说。尤其是 WEB 浏览器,因为与编程语言不相关绑定。 与其相对应的 client/server 关系数据库,SQLite 数据库存储整个数据库在主机 上作为单个文件。

了解Skype SQLite3数据库

作为 4.0 版本,流行的聊天工具 Skype 改变了它的内部数据库格式,使用 SQLite 格式。在 Windows 系统中,Skype 存储了的一个名叫 main.db 的数据库 在路径 C:\Documents and Settings\\ApplicationData\Skype\目录下,在 MAC OS X 系统中,相同的数据库放在 /Users//Library/Application\ Support/Skype/目录下。
SQLite 数据库维护了一个表名为sqlite _master,这个表包含了列名为tbl_name,用来描述数据库中的每一个表。执行这句 SELECT 语句允许我们查 看 Skype 的 main.db 数据库中的表。我们可以看到,该数据库保存的表包含电 话,账户,消息甚至是 SMS 消息的信息。

investigator$ sqlite3 main.db
SQLite version 3.7.9 2011-11-01 00:52:41
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> SELECT tbl_name FROM sqlite_master WHERE
type=="table";
DbMeta
Contacts
LegacyMessages
Calls
Accounts
Transfers
Voicemails
Chats
Messages
ContactGroups
Videos
SMSes
CallMembers
ChatMembers
Alerts
Conversations
Participants
sqlite> SELECT fullname, skypename, city, country,
datetime(profile_timestamp,'unixepoch') FROM accounts;
TJ OConnor|<accountname>|New York|us|22010-01-17 16:28:18

使用Python的Sqlite3自动完成Skype数据库查询

利用 sqlite3 库来编写一个小的 Python 程序来完成这些。注意我们的函数 printProfile(),它创建一个到 main.db 数据库的连接,创建一个连接之后,它需要一个光标提示然后执行我们先前的 SELECT 语句,SELECT 语句的结果返回一个包含数组的数组。对于每个返回的结果,它包含用户,Skype 用户名,位置和介绍数据的索引列。

# coding=UTF-8
import sqlite3


def printProfile(skypeDB):
    conn = sqlite3.connect(skypeDB)
    c = conn.cursor()
    C.execute("SELECT fullname,skypename,city,country,datatime(profile_timestamp,'unixepoch')FROM Accounts;")
    for row in c:
        print('[*] --Found Account--')
        print('[+] User:' + str(row[0]))
        print('[+] Skype Username:' + str(row[1]))
        print('[+] Location:' + str(row[2]) + ',' + str(row[3]))
        print('[+] Profile Date:' + str(row[4]))


def main():
    skypeDB = "main.db"
    printProfile(skypeDB)


if __name__ == "__main__":
    main()

所有这些个人信息当我们调查或者是攻击一个目标时都 是有用的,所以我们将信息收集起来。让我们输出 SELECT 语句返回的信息, 注意几个字段,比如生日可能是 null,在这种情况下,我们利用条件语句只打印不等于空的结果

def printContacts(skypeDB):
    conn = sqlite3.connect(skypeDB)
    c = conn.cursor()
    c.execute("SELECT displayname, skypename, city, country,phone_mobile, birthday FROM Contacts;")
    for row in c:
        print('\n[*] --Found Contact--')
        print('[+] User:' + str(row[0]))
        print('[+] Skype Username:' + str(row[1]))
        if str(row[2]) != '' and str(row[2]) != 'None':
            print('[+]Location:' + str(row[2]) + ',' + str(row[3]))
        if str(row[4]) != 'None':
            print('[+]Mobile Number:' + str(row[4]))
        if str(row[5]) != 'None':
            print('[+]Birthday:' + str(row[5]))

直到限制我们只是从特定的表中提取特定的列检查,然而当我们向将两个表中的信息一起输出,需要WHERE x = x来确认,返回包含所有存储在Skype数据库中的Skype的通过记录时间和身份。

def printCallLog(skypeDB):
    conn = sqlite3.connect(skypeDB)
    c = conn.cursor()
    c.execute(("SELECT datetime(begin_timestamp,'unixepoch'),identity FROM calls, conversations WHERE calls.conv_dbid = conversations.id;"))
    print('\n[*]--Found Calls--')
    for row in c:
        print('[+] Time: ' + str(row[0]) + ' | Partner: ' + str(row[1]))

最后printMessage

def printMessage(skypeDB):
    conn = sqlite3.connect(skypeDB)
    c = conn.cursor()
    c.execute("SELECT datetime(timestamp,'unixepoch'),dialog_partner, author, body_xml FROM Messages;")
    print('\n[*]--Found Messages--')
    for row in c:
        try:
            if 'partlist' not in str(row[3]):
                if str(row[1]) != str(row[2]):
                    msgDirection = 'To' + str(row[1]) + ':'
                else:
                    msgDirection = 'From' + str(row[2]) + ':'
                print('Time: ' + str(row[0]) + '' + msgDirection + str(row[3]))
        except:
            pass
# coding=UTF-8
import sqlite3
import optparse
import os


def printProfile(skypeDB):
    conn = sqlite3.connect(skypeDB)
    c = conn.cursor()
    C.execute("SELECT fullname,skypename,city,country,datatime(profile_timestamp,'unixepoch')FROM Accounts;")
    for row in c:
        print('[*] --Found Account--')
        print('[+] User:' + str(row[0]))
        print('[+] Skype Username:' + str(row[1]))
        print('[+] Location:' + str(row[2]) + ',' + str(row[3]))
        print('[+] Profile Date:' + str(row[4]))


def printContacts(skypeDB):
    conn = sqlite3.connect(skypeDB)
    c = conn.cursor()
    c.execute("SELECT displayname, skypename, city, country,phone_mobile, birthday FROM Contacts;")
    for row in c:
        print('\n[*] --Found Contact--')
        print('[+] User:' + str(row[0]))
        print('[+] Skype Username:' + str(row[1]))
        if str(row[2]) != '' and str(row[2]) != 'None':
            print('[+]Location:' + str(row[2]) + ',' + str(row[3]))
        if str(row[4]) != 'None':
            print('[+]Mobile Number:' + str(row[4]))
        if str(row[5]) != 'None':
            print('[+]Birthday:' + str(row[5]))


def printCallLog(skypeDB):
    conn = sqlite3.connect(skypeDB)
    c = conn.cursor()
    c.execute((
        "SELECT datetime(begin_timestamp,'unixepoch'),identity FROM calls, conversations WHERE calls.conv_dbid = conversations.id;"))
    print('\n[*]--Found Calls--')
    for row in c:
        print('[+] Time: ' + str(row[0]) + ' | Partner: ' + str(row[1]))


def printMessage(skypeDB):
    conn = sqlite3.connect(skypeDB)
    c = conn.cursor()
    c.execute("SELECT datetime(timestamp,'unixepoch'),dialog_partner, author, body_xml FROM Messages;")
    print('\n[*]--Found Messages--')
    for row in c:
        try:
            if 'partlist' not in str(row[3]):
                if str(row[1]) != str(row[2]):
                    msgDirection = 'To' + str(row[1]) + ':'
                else:
                    msgDirection = 'From' + str(row[2]) + ':'
                print('Time: ' + str(row[0]) + '' + msgDirection + str(row[3]))
        except:
            pass


def main():
    parser = optparse.OptionParser("usage%prog -p  ")
    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:
        skypeDB = os.path.join(pathName, 'main.db')
        if os.path.isfile(skypeDB):
            printProfile(skypeDB)
            printContacts(skypeDB)
            printCallLog(skypeDB)
            printMessages(skypeDB)
        else:
            print '[!] Skype Database does not exist:' + skypeDB


if __name__ == "__main__":
    main()

运行该脚本,添加-p选项来确定skype配置数据库路径,脚本打印出存储在目标机器上的账户配置,联系人,电话和消息。

investigator$ python skype-parse.py -p
/root/.Skype/not.myaccount
[*] -- Found Account --
[+] User
: TJ OConnor
[+] Skype Username : 
[+] Location : New York, US
[+] Profile Date : 2010-01-17 16:28:18
[*] -- Found Contact --
[+] User
: Some User
[+] Skype Username : some.user
[+] Location
[+] Mobile Number
[+] Birthday
: Basking Ridge, NJ,us
: +19085555555
: 19750101
[*] -- Found Calls --
[+] Time: xxxx.xx.xx 15:45:20 | Partner: +xxxxxxxxxx

用python解析火狐sqlite3数据库

火狐存储这些数据库的默认路径是:C:\Documents and Settings\\Application Data\Mozilla\Firefox\Profiles\\或者``/Users//Library/Application\ Support/Firefox/Profiles/

┌─[showmeshell@parrot]─[~/.mozilla/firefox/iyGIUuytfv.Parrot]
└──╼ $ls *.sqlite
content-prefs.sqlite  formhistory.sqlite  places.sqlite
cookies.sqlite        kinto.sqlite        storage.sqlite
favicons.sqlite       permissions.sqlite  webappsstore.sqlite

download.sqlite文件存储了火狐用户下载文件的信息,包含一个声明为moz_downloads,用来存储文件名,下载源,下载日期,文件大小,存储在本地的位置等信息。

# 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 printCookie(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  ")
    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):
            printCookie(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 dost not exist: ' + placesDB)


if __name__ == "__main__":
    main()

Google 搜索查询包含搜索URL 内部的权限
只提取搜索条件 URL 右边的条目。如果在我们的历史里发现包含
Google,我们发现他的特点 q=后面跟随着&。这个特定的字符序列标识
Google 搜索。如果我们真的找到这个条目,我们将通过用空格替换一些 URL 中
用的字符来清理输出。最后,我们将打印校正后的输出到屏幕上,现在我们有
一个函数可以搜索 places.sqlite 文件并打印 Google 搜索查询历史。

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:
...........................

用python调查设备移动的iTunes备份

当用户对 iPhone 或者 iPad 设备进行备份时,它将文件存储到机器的特殊目录。 对于 Windows 系统,iTunes 程序存储移动设备备份目录在 C:\Documents and Settings\\Application Data\AppleComputer\MobileSync\Backup下,在 Mac OS X 系统上储存目录在 /Users//Library/Application Support/MobileSync/Backup/。 iTunes 程序备份移动设备存储所有的移动设备到这些目录下。

使用 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)

想要能 够自动的对不同的备份进行调查。为了执行这个,我们编写了一个简单的函数 名为 isMessageTable(),这个函数将连接数据库并枚举数据库模式信息。如果 文件包含名为 messages 的表,则返回 True,否则函数返回 False

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;’

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 备份的目录。接下来,我们将列出该目录的内容并测试每一个文件 直到找到文本信息数据库

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 ")
    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()
    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()

你可能感兴趣的:(web)