반응형

웹 아티팩트 : 웹에서 사용한 기록들이 사용자의 컴퓨터 내에 저장되는 것으로 사용자가 검색한 기록, 방문한 사이트, 접근 시간 등을 알 수 있다.

 

history : 사용자가 방문한 웹 사이트 접속 정보

cache : 한번 접속했던 웹 사이트를 다시 접속 할 때 이미지나 정보들을 빠르게 로딩하기 위해 사이트로부터 자동으로 받는 데이터

cookie : 웹 사이트에서 사용하는 사용자에 관한 데이터

download file : 사용자가 다운로드했던 파일들에 관한 정보

 

아래의 정보들은 firefox 버전에 따라 다른 폴더와 다른 파일로 저장될 수 있다.

 

현재 이 글에서 사용되는 firefox의 버전은 116.0.2이다.


C:\Users\<사용자 이름>\AppData\Local\Mozilla\Firefox\Profiles
C:\Users\<사용자 이름>\AppData\Roaming\Mozilla\Firefox\Profiles

firefox에 관한 정보들이 담기는 곳은 크게 두 곳이다.

 

C:\Users\<사용자 이름>\AppData\Local\Mozilla\Firefox\Profiles

or

C:\Users\<사용자 이름>\AppData\Roaming\Mozilla\Firefox\Profiles


프로필 경로 확인

 

 

profiles.ini 파일에서 프로필의 백업 경로를 확인할 수 있는데

(C:\Users\<사용자 이름>\AppData\Roaming\Mozilla\Firefox)

 

 

위와 같은 형식으로 적혀있고, 프로필이 여러 개이면 Profile 뒤에 숫자가 증가하는 방식이다.

 

현재 firefox에 로그인은 안되어 있고, 정보를 긁어올 프로필은 0번이다.

 

그렇다면 정보가 담긴 places.sqlite 파일이 있는 폴더는 xql49pjc.default-release이다.

(default-release 앞에 있는 값은 랜덤값이므로 사진과 다를 것이다.)


cache 파일 위치와 이외 정보 파일들의 위치

C:\Users\<사용자 이름>\AppData\Local\Mozilla\Firefox\Profiles\<random value>.default-release\cache2\entries

 

cache 파일들은 C:\Users\<사용자 이름>\AppData\Local\Mozilla\Firefox\Profiles\<random value>.default-release\cache2\entries 폴더 안에 있다.

 

 

이외의 파일들은 C:\Users\<사용자 이름>\AppData\Roaming\Mozilla\Firefox\Profiles\.default-release 폴더 아래에서 확인할 수 있다.


places.sqlite 정보 확인

 

 

접속 기록은 places.sqlite 파일 내에 moz_places 테이블에서 확인할 수 있다.

(sqlite 파일을 열어보기 위해 DB Browser for SQLite 프로그램을 사용한다.)

 


소스 코드

 

https://chat.openai.com/share/3afd2094-871d-459c-b44f-b337818fe370

 

ChatGPT

A conversational AI system that listens, learns, and challenges

chat.openai.com

 

chatGPT를 이용해 코드를 짤 때는 만들고 싶어하는 기능을 얼마나 자세하고 명확하게 설명하느냐가 중요하다.

 

그렇기 때문에 개발자는 더더욱 빠삭하게 자세하게 정확하게 정보를 알고 있어야 한다.

 

위의 URL에 접속하면 어떻게 chatgpt를 이용해 firefox 접속 정보를 가져오는 코드를 만들었는지 과정이 담겨있다.

 

chatgpt가 만들어준 틀에 내가 원하는 기능이 원활하게 동작되도록 아주 조금의 코드 수정만 했다.

 

import os
import sqlite3
import csv

def find_firefox_profile():
    # profiles.ini 파일을 찾아 프로파일 디렉토리 경로를 반환
    possible_paths = [
        os.path.expandvars(r"%APPDATA%\Mozilla\Firefox\profiles.ini"),
        os.path.expandvars(r"%LOCALAPPDATA%\Mozilla\Firefox\profiles.ini")
    ]

    for path in possible_paths:
        if os.path.exists(path):
            with open(path, 'r') as f:
                profile_dir = None
                for line in f:
                    if line.startswith("Path="):
                        profile_dir = line.strip()[5:]
                        if(profile_dir.endswith("default-release")):
                            break
                if profile_dir:
                    return os.path.join(os.path.dirname(path), profile_dir)

    return None

def find_places_database(profile_path):
    # places.sqlite 파일을 찾아 데이터베이스 경로를 반환
    profile_folders = os.listdir(profile_path)
    for folder in profile_folders:
        db_path = os.path.join(profile_path, "places.sqlite")

        if os.path.exists(db_path):
            return db_path
    return None

def extract_sites_from_history(history_db_path):
    if not os.path.exists(history_db_path):
        print("History database not found.")
        return []

    connection = sqlite3.connect(history_db_path)
    cursor = connection.cursor()

    query = "SELECT url, title FROM moz_places;"
    cursor.execute(query)
    sites = [(row[0], row[1]) for row in cursor.fetchall()]

    connection.close()

    return sites

def write_to_csv(sites, filename):
    with open(filename, 'w', newline='', encoding='utf-8') as file:
        writer = csv.writer(file)
        writer.writerow(["Site", "URL"])
        writer.writerows(sites)

def main():
    profile_path = find_firefox_profile()
    
    if not profile_path:
        print("Firefox profile not found.")
        return

    history_db_path = find_places_database(profile_path)
    
    if not history_db_path:
        print("Places database not found.")
        return

    sites = extract_sites_from_history(history_db_path)
    
    if not sites:
        print("No sites found in history.")
    else:
        csv_filename = "visited_sites.csv"
        write_to_csv(sites, csv_filename)
        print(f"Visited sites saved to '{csv_filename}'.")

if __name__ == "__main__":
    main()

 


실행 결과

 

visited_sites.csv 파일로 만들어주도록 chatgpt에게 요청했었기 때문에 수집 결과를 csv 파일로 만들어줬다.

 

 

한글이 깨져서 나오는데 이는 chatgpt에게 한글이 깨져서 출력된다고 하면 이전에 작성된 코드를 수정하여 한글이 깨지지 않도록 인코딩하여 저장하도록 바꿔준다.


수정된 코드

import os
import sqlite3
import csv

def find_firefox_profile():
    # profiles.ini 파일을 찾아 프로파일 디렉토리 경로를 반환
    possible_paths = [
        os.path.expandvars(r"%APPDATA%\Mozilla\Firefox\profiles.ini"),
        os.path.expandvars(r"%LOCALAPPDATA%\Mozilla\Firefox\profiles.ini")
    ]

    for path in possible_paths:
        if os.path.exists(path):
            with open(path, 'r') as f:
                profile_dir = None
                for line in f:
                    if line.startswith("Path="):
                        profile_dir = line.strip()[5:]
                        if(profile_dir.endswith("default-release")):
                            break
                if profile_dir:
                    return os.path.join(os.path.dirname(path), profile_dir)

    return None

def find_places_database(profile_path):
    # places.sqlite 파일을 찾아 데이터베이스 경로를 반환
    profile_folders = os.listdir(profile_path)
    for folder in profile_folders:
        db_path = os.path.join(profile_path, "places.sqlite")

        if os.path.exists(db_path):
            return db_path
    return None

def extract_sites_from_history(history_db_path):
    if not os.path.exists(history_db_path):
        print("History database not found.")
        return []

    connection = sqlite3.connect(history_db_path)
    cursor = connection.cursor()

    query = "SELECT url, title FROM moz_places;"
    cursor.execute(query)
    sites = [(row[0], row[1]) for row in cursor.fetchall()]

    connection.close()

    return sites

def write_to_csv(sites, filename):
    with open(filename, 'w', newline='', encoding='utf-8-sig') as file:
        writer = csv.writer(file)
        writer.writerow(["Site", "URL"])
        writer.writerows(sites)

def main():
    profile_path = find_firefox_profile()
    
    if not profile_path:
        print("Firefox profile not found.")
        return

    history_db_path = find_places_database(profile_path)
    
    if not history_db_path:
        print("Places database not found.")
        return

    sites = extract_sites_from_history(history_db_path)
    
    if not sites:
        print("No sites found in history.")
    else:
        csv_filename = "visited_sites.csv"
        write_to_csv(sites, csv_filename)
        print(f"Visited sites saved to '{csv_filename}'.")

if __name__ == "__main__":
    main()

수정된 코드로 다시 실행하면 위와 같이 한글이 깨지지 않고 출력된다.

반응형

+ Recent posts