From 5e1906fefe72fc0b04cfcd30dbf12af785183b11 Mon Sep 17 00:00:00 2001 From: snowpeacock <74353652+snowpeacock@users.noreply.github.com> Date: Wed, 19 Feb 2025 17:53:35 +0100 Subject: [PATCH 01/16] style : logo branding (#214) * style: change logo * chore: add GT in readme * chore: typo --------- Co-authored-by: snowpeacock --- README.md | 2 +- ad_miner/sources/html/assets/favicon.png | Bin 3003 -> 1822 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 231f6a9..bb81c76 100755 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ You can also observe indicators over time to help measuring mitigation efficienc Main page

-AD Miner has been initially created by Forvis Mazars Cybersecurity team. +AD Miner has been initially created by Forvis Mazars and is maintained by Grant Thornton Cybersecurity Audit & Advisory Team. ## Prerequisites diff --git a/ad_miner/sources/html/assets/favicon.png b/ad_miner/sources/html/assets/favicon.png index 39bd702c3a1aaf8985865e26617708498cd28267..b69e1efdddb2246c7f9c34a6b7a6da4240fcfa18 100644 GIT binary patch delta 1808 zcmV+r2k-d17oHA~BYy#eX+uL$Nkc;*aB^>EX>4Tx04R}tkv&MmKpe$iQ>CIU4(%Y~ zkfDl$T~x%eR-p(LO0CeUgUO{|(4-+rad8w}3l4rPRvlcNb#-tR1i=pwcfm=~MN0f% zQfLw5!Ery{-Fw`<1B7Oksb)_cP&LcQBoksTzbXb^As~zajDI5}F;kyQr&I78U-$6w z^)AM)XFRyI`PY2v7&YLqYJTvj-5aaOB!*1jiyVX&aBEOVXa2$ERD64DSM zqmBxyun?nFBY(w2hV~O4{$a_@99*t>dpXf!R;e8yzir1PpEi7uOw4-UBXofT1T{G9*Xx(-ewD z;QfrgDG!8if&MkOxAs0xAAl@%mAU~A4uP=}Wv_d@yMM2{w|~#H`}+ZOv2v#g>C(dh z000SaNLh0L01ejw01ejxLMWSf000F*Nklf$6|F;0izh zzXAqWir_=z$)iDWMa3KLs!OoE3*1;_>H#2QwEVbg2yilLJn%WtKY-dBM$1{HPVQB~ z#yi03fW`xi8FtO2)c%bvYZB`L4X&!qTebn0hkt;%&S<%z*rb|DBp`2jIHd6a^Glgj zQ=t*?XapGJ9aoJ=906%p4F<+U0%n<*I0CF?M1*ixB{2m0M2JgrewYz+aC1Lh<)5o&!|S_F3kN6LhF z(tl|AeUdXlj3;*klYspJRp%Nly=v+Q48yV>iY7=q0M}^Q5(Gb0=>!PKSvcPxuJadd zIMC1cj%~mv1N-yYnt9R&#jkh*tYs!p2jqp|zN{zrMVfb1wEIid8+hCwE{WRsiYI^$ z?g7sAM>>v2R7?n@T~!a%3&Fm&W_jZHbASEM%|^>_tBQcMs|Hxh1Hc_XqqT)9&{}XZ z>X4tur{i4x|Am0-=O}TkohEB}1{idPX@h~APaEfBJY{my9-AZh!01 zO|YR!^|3JA!d}xHI1ZnSc+s8(?u^|7(yr=bEi-@_6mDcsNETRFmlE%^E@;XZS^crV z#uyxHn9=gL*!BP?qb{_TEYRG^c>MGE&GwvK@3?Ac(YTFACd9T0rd>4vSPP6ScC2Gr z?ld*`?PkvCmkC=cLV=ab6iMJ}g90%rh`w$^s1GY!>o0l6cm&HmzR?F3# zYDN|-OlBD^zw2&No7dEiV5+|{hLJr89*okJ&X@`tEnf$w0cW~k+yUHTv|L!qgN!G4 zBbW$;>FnNXJb9=`%i)IEs()8L$0Wa&AL1LZ!DzXv%+h!`@D?y7fLaHIcN$k2EhqLU z0WtOn8iCosWC|A_o#jtpsSq?<%M>`-2zknA`BLHuI7x)7YO##=3$NaOhWBG_En7Fd za;o*^WYkv_8l`_DXf&SOR22jS44th&J+KEDWwiV&woS0o#Avw>cz?(rUQ9G^ktD|h zPVBwjOM$gcMvbec5SR?C2&i@d!Ij372NUlBfGR_0D3+%a?*UFmO@Old0Ebg4>NhQr zxg>kQ_z=1Sb2*%(hkwA3koqI5VGjr+9Z4r(e@Ol9Nhe@+2;GB5%WR?vFj}so{C4=F zs>lR^$I8(81;O)GL4eWnYhY#ol_Nqh&3N)iwRiwV%eR5MD1P6t1wlIN{Wta#TMPUv yGj!DeERO)UQMiUb2l$!7U+OT{Eiy delta 2980 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 a{{mn0$^HZlt5*O3000O{MNUMnLSTYf>8IWR From e0b995366f947ac91637130f35aa418697136106 Mon Sep 17 00:00:00 2001 From: snowpeacock <74353652+snowpeacock@users.noreply.github.com> Date: Wed, 19 Feb 2025 17:53:52 +0100 Subject: [PATCH 02/16] fix: AZBase objects without tenantid attribute crashes AD Miner (#213) Co-authored-by: snowpeacock --- ad_miner/sources/modules/common_analysis.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/ad_miner/sources/modules/common_analysis.py b/ad_miner/sources/modules/common_analysis.py index bc4287c..ed77d73 100644 --- a/ad_miner/sources/modules/common_analysis.py +++ b/ad_miner/sources/modules/common_analysis.py @@ -696,7 +696,10 @@ def generateADCSListPage(requests_results, arguments): page.render() -tenant_id_name = {"F8CDEF31-A31E-4B4A-93E4-5F571E91255A": "Microsoft Entra"} +tenant_id_name = { + "F8CDEF31-A31E-4B4A-93E4-5F571E91255A": "Microsoft Entra", + None: "Unknown", +} def setTenantIDName(requests_results, arguments): @@ -771,8 +774,7 @@ def genAzureUsers(requests_results, arguments): tenant_name = tenant_id_name.get(tenant_id, tenant_id) data.append( { - "Tenant Name": ' ' - + tenant_name, + "Tenant Name": ' ' + tenant_name, "Name": ' ' + user["Name"], "Synced on premise": ( '' @@ -822,8 +824,7 @@ def genAzureAdmin(requests_results, arguments): tenant_name = tenant_id_name.get(tenant_id, tenant_id) data.append( { - "Tenant Name": ' ' - + tenant_name, + "Tenant Name": ' ' + tenant_name, "Name": ' ' + admin["Name"], } ) @@ -863,8 +864,7 @@ def genAzureGroups(requests_results, arguments): tenant_name = tenant_id_name.get(tenant_id, tenant_id) data.append( { - "Tenant Name": ' ' - + tenant_name, + "Tenant Name": ' ' + tenant_name, "Name": ' ' + group["Name"], "Description": group["Description"], } @@ -967,7 +967,11 @@ def genAzureDevices(requests_results, arguments): os = dict["os"] if "windows" in dict["os"].lower(): os = ' ' + os - elif "mac" in dict["os"].lower() or "iphone" in dict["os"].lower() or "ios" in dict["os"].lower(): + elif ( + "mac" in dict["os"].lower() + or "iphone" in dict["os"].lower() + or "ios" in dict["os"].lower() + ): os = ' ' + os elif "android" in dict["os"].lower(): os = ' ' + os From b78bebd1a8d078c7659b90cb939efdb778fec8ca Mon Sep 17 00:00:00 2001 From: Jop <57217348+leJoPra@users.noreply.github.com> Date: Fri, 28 Feb 2025 10:21:39 +0100 Subject: [PATCH 03/16] style: new readme logo --- doc/img/ADMiner-Logo-Color.png | Bin 0 -> 89907 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/img/ADMiner-Logo-Color.png diff --git a/doc/img/ADMiner-Logo-Color.png b/doc/img/ADMiner-Logo-Color.png new file mode 100644 index 0000000000000000000000000000000000000000..00c8c00e50ed303d6edfdb593304b6bf760ab49f GIT binary patch literal 89907 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 Nu3o2;zKVY6{{V60aqa*B literal 0 HcmV?d00001 From 0e9ea383dddcaab63ef3cc99c13a7f72fc49b8cf Mon Sep 17 00:00:00 2001 From: Jop <57217348+leJoPra@users.noreply.github.com> Date: Fri, 28 Feb 2025 10:22:28 +0100 Subject: [PATCH 04/16] style: add new logo in readme --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index bb81c76..53ab993 100755 --- a/README.md +++ b/README.md @@ -1,17 +1,18 @@
-# AD Miner # +AD_Miner +
- - Latest AD_Miner version - - Latest release - - Latest commit in dev + + Latest AD_Miner version + + Latest release + + Latest commit in dev Rawsec's CyberSecurity Inventory badge From 9d1f04383dec091dd62d509377b92343fd840a46 Mon Sep 17 00:00:00 2001 From: mr-pmillz <58376398+mr-pmillz@users.noreply.github.com> Date: Mon, 16 Jun 2025 12:08:38 -0400 Subject: [PATCH 05/16] add try except handle KeyError for DCOnly collection method --- ad_miner/sources/modules/neo4j_class.py | 67 +++++++++++++------------ 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/ad_miner/sources/modules/neo4j_class.py b/ad_miner/sources/modules/neo4j_class.py index 75573c4..7e8d2fd 100644 --- a/ad_miner/sources/modules/neo4j_class.py +++ b/ad_miner/sources/modules/neo4j_class.py @@ -1113,40 +1113,43 @@ def compute_common_cache(self, requests_results): logger.print_debug("[Done]") - if not requests_results["users_admin_on_servers_1"]: - requests_results["users_admin_on_servers_1"] = [] - if not requests_results["users_admin_on_servers_2"]: - requests_results["users_admin_on_servers_2"] = [] - - users_admin_on_servers_all_data = ( - requests_results["users_admin_on_servers_1"] - + requests_results["users_admin_on_servers_2"] - ) - users_admin_on_servers_all_data = [ - dict(t) for t in {tuple(d.items()) for d in users_admin_on_servers_all_data} - ] - users_admin_on_servers = generic_computing.getCountValueFromKey( - users_admin_on_servers_all_data, "computer" - ) - users_admin_on_servers_list = generic_computing.getListAdminTo( - users_admin_on_servers_all_data, - "computer", - "user", - ) - - if users_admin_on_servers is not None and users_admin_on_servers != {}: - servers_with_most_paths = users_admin_on_servers[ - list(users_admin_on_servers.keys())[0] + try: + if not requests_results["users_admin_on_servers_1"]: + requests_results["users_admin_on_servers_1"] = [] + if not requests_results["users_admin_on_servers_2"]: + requests_results["users_admin_on_servers_2"] = [] + + users_admin_on_servers_all_data = ( + requests_results["users_admin_on_servers_1"] + + requests_results["users_admin_on_servers_2"] + ) + users_admin_on_servers_all_data = [ + dict(t) for t in {tuple(d.items()) for d in users_admin_on_servers_all_data} ] - else: - servers_with_most_paths = [] + users_admin_on_servers = generic_computing.getCountValueFromKey( + users_admin_on_servers_all_data, "computer" + ) + users_admin_on_servers_list = generic_computing.getListAdminTo( + users_admin_on_servers_all_data, + "computer", + "user", + ) - requests_results["users_admin_on_servers_list"] = users_admin_on_servers_list - requests_results["servers_with_most_paths"] = servers_with_most_paths - requests_results["users_admin_on_servers"] = users_admin_on_servers - requests_results["users_admin_on_servers_all_data"] = ( - users_admin_on_servers_all_data - ) + if users_admin_on_servers is not None and users_admin_on_servers != {}: + servers_with_most_paths = users_admin_on_servers[ + list(users_admin_on_servers.keys())[0] + ] + else: + servers_with_most_paths = [] + + requests_results["users_admin_on_servers_list"] = users_admin_on_servers_list + requests_results["servers_with_most_paths"] = servers_with_most_paths + requests_results["users_admin_on_servers"] = users_admin_on_servers + requests_results["users_admin_on_servers_all_data"] = ( + users_admin_on_servers_all_data + ) + except KeyError as ke: + print(f"KeyError: {ke}") # Dico for ACL anomaly and futur other controls to retrieve paths to DA on computer ID dico_paths_computers_to_DA = {} From 6993e09cffea1c92960a4fd4ca78608567424539 Mon Sep 17 00:00:00 2001 From: snowpeacock Date: Tue, 13 Jan 2026 17:47:57 +0100 Subject: [PATCH 06/16] fix: key error whith user admin on servers --- ad_miner/sources/modules/neo4j_class.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ad_miner/sources/modules/neo4j_class.py b/ad_miner/sources/modules/neo4j_class.py index 7e8d2fd..31e72d5 100644 --- a/ad_miner/sources/modules/neo4j_class.py +++ b/ad_miner/sources/modules/neo4j_class.py @@ -1114,9 +1114,9 @@ def compute_common_cache(self, requests_results): logger.print_debug("[Done]") try: - if not requests_results["users_admin_on_servers_1"]: + if "users_admin_on_servers_1" not in requests_results: requests_results["users_admin_on_servers_1"] = [] - if not requests_results["users_admin_on_servers_2"]: + if "users_admin_on_servers_2" not in requests_results: requests_results["users_admin_on_servers_2"] = [] users_admin_on_servers_all_data = ( @@ -1149,7 +1149,7 @@ def compute_common_cache(self, requests_results): users_admin_on_servers_all_data ) except KeyError as ke: - print(f"KeyError: {ke}") + logger.print_error(f"KeyError while generating users admin on servers data: {ke}") # Dico for ACL anomaly and futur other controls to retrieve paths to DA on computer ID dico_paths_computers_to_DA = {} From b18d922710d98f1b4dc9aacc380ecfabc4a20a17 Mon Sep 17 00:00:00 2001 From: m4lwhere Date: Thu, 13 Feb 2025 07:31:26 -0500 Subject: [PATCH 07/16] ops: add Dockerfile and documentation --- Dockerfile | 11 +++++++++++ README.md | 14 ++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..24a8248 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM python:3.11-slim + +# Set the working directory in the container +WORKDIR /tmp + +# Install necessary system dependencies for Git +RUN apt-get update && apt-get install -y git \ + && rm -rf /var/lib/apt/lists/* + +# Install AD-Miner from the Git repository +RUN pip install --no-cache-dir 'git+https://github.com/Mazars-Tech/AD_Miner.git' diff --git a/README.md b/README.md index 53ab993..6e3b2ab 100755 --- a/README.md +++ b/README.md @@ -92,6 +92,20 @@ ADMiner is also available on some Linux distributions: - BlackArch: `pacman -S ad-miner` - NixOS: `nix-env -iA nixos.ad-miner` +A Docker image is available to build. Build the image with the following commmand: + +```sh +docker build -t ad-miner . +``` + +To run this with the BloodHound Community Edition data, use the commands below: + +```sh +docker run -v ${PWD}:/tmp ad-miner AD-miner -b bolt://host.docker.internal:7687 -u neo4j -p bloodhoundcommunityedition -cf docker-test +``` + +Note that mounting the volume with `-v` is critical to get the output of the data. This assumes that the BHCE server is running on the Docker host with default settings. + ## Usage ## Run the tool: From 9ff4f654be6f6c5f61a71a3590cc026b7e68d964 Mon Sep 17 00:00:00 2001 From: snowpeacock Date: Tue, 13 Jan 2026 18:09:22 +0100 Subject: [PATCH 08/16] ops: update Dockerfile and Readme --- Dockerfile | 2 +- README.md | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 24a8248..1217178 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,4 +8,4 @@ RUN apt-get update && apt-get install -y git \ && rm -rf /var/lib/apt/lists/* # Install AD-Miner from the Git repository -RUN pip install --no-cache-dir 'git+https://github.com/Mazars-Tech/AD_Miner.git' +RUN pip install --no-cache-dir 'git+https://github.com/AD-Security/AD_Miner.git' diff --git a/README.md b/README.md index 6e3b2ab..faa89f0 100755 --- a/README.md +++ b/README.md @@ -98,10 +98,16 @@ A Docker image is available to build. Build the image with the following commman docker build -t ad-miner . ``` -To run this with the BloodHound Community Edition data, use the commands below: +To run this on Windows with the BloodHound Community Edition data, use the commands below: ```sh -docker run -v ${PWD}:/tmp ad-miner AD-miner -b bolt://host.docker.internal:7687 -u neo4j -p bloodhoundcommunityedition -cf docker-test +docker run -v ${PWD}:/tmp ad-miner AD-miner -b bolt://host.docker.internal:7687 -u neo4j -p bloodhoundcommunityedition -cf YOUR_PREFIX +``` + +To run this on Linux with the BloodHound Community Edition data, use the commands below: + +```sh +docker run -v ${PWD}:/tmp --network host ad-miner AD-miner -b bolt://localhost:7687 -u neo4j -p bloodhoundcommunityedition -cf YOUR_PREFIX ``` Note that mounting the volume with `-v` is critical to get the output of the data. This assumes that the BHCE server is running on the Docker host with default settings. From 0864035691bee7a1d2cdc5ddf835167e8e957e1f Mon Sep 17 00:00:00 2001 From: snowpeacock Date: Fri, 23 Jan 2026 11:12:06 +0100 Subject: [PATCH 09/16] chore: update password in readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index faa89f0..6efb1e0 100755 --- a/README.md +++ b/README.md @@ -101,13 +101,13 @@ docker build -t ad-miner . To run this on Windows with the BloodHound Community Edition data, use the commands below: ```sh -docker run -v ${PWD}:/tmp ad-miner AD-miner -b bolt://host.docker.internal:7687 -u neo4j -p bloodhoundcommunityedition -cf YOUR_PREFIX +docker run -v ${PWD}:/tmp ad-miner AD-miner -b bolt://host.docker.internal:7687 -u neo4j -p mypassword -cf YOUR_PREFIX ``` To run this on Linux with the BloodHound Community Edition data, use the commands below: ```sh -docker run -v ${PWD}:/tmp --network host ad-miner AD-miner -b bolt://localhost:7687 -u neo4j -p bloodhoundcommunityedition -cf YOUR_PREFIX +docker run -v ${PWD}:/tmp --network host ad-miner AD-miner -b bolt://localhost:7687 -u neo4j -p mypassword -cf YOUR_PREFIX ``` Note that mounting the volume with `-v` is critical to get the output of the data. This assumes that the BHCE server is running on the Docker host with default settings. From 82d9257fbff437294c666d023609150931d0f75a Mon Sep 17 00:00:00 2001 From: snowpeacock Date: Fri, 23 Jan 2026 14:44:37 +0100 Subject: [PATCH 10/16] ops: update readme, .gitignore and dependancies --- .gitignore | 5 +- README.md | 8 +- poetry.lock | 189 ++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 1 + requirements.txt | 1 + 5 files changed, 195 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 595392e..9220370 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ AD_Miner/sources/modules/temporary* *node_modules* /tests /test - +evolution_data/ # Byte-compiled / optimized / DLL files __pycache__/ @@ -170,6 +170,3 @@ cython_debug/ # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ - -# VS Code -.vscode/ diff --git a/README.md b/README.md index 6efb1e0..537cfb8 100755 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ To run AD Miner, you first need a neo4j database which contains the Active Direc The easier way is to do the following command using `pipx`: ```shell -pipx install 'git+https://github.com/Mazars-Tech/AD_Miner.git' +pipx install 'git+https://github.com/AD-Security/AD_Miner.git' ``` ADMiner is also available on some Linux distributions: @@ -174,13 +174,15 @@ In the graph pages, you can right-click on the graph nodes to cluster them or to If you have multiple AD-Miner reports over time, you can easily track the evolution with the `--evolution` argument: each AD-Miner report generates a JSON data file alongside the `index.html` file. You just need to gather these different JSON files into a single folder and specify the path to that folder after the `--evolution` argument. -A tab called 'Evolution over time' then appears on the main page. + AD-miner -c -cf My_Report -b bolt://server:7687 -u neo4j -p mypassword -r 180 --evolution evolution_folder/ + +An 'Evolution over time' tab appears on the main page, providing evolution graphs for each category (Permissions, Passwords, Kerberos, and Misc).

-Also, views by categories 'permissions,' 'passwords,' 'kerberos' also allow you to track changes over time. +Detailed evolution for each control is also available and can be accessed via the “Show evolution” button for each category. A logarithmic scale is available to better highlight subtle variations over time.

diff --git a/poetry.lock b/poetry.lock index d369392..65be45d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,137 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. + +[[package]] +name = "certifi" +version = "2026.1.4" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.7" +files = [ + {file = "certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c"}, + {file = "certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win32.whl", hash = "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_riscv64.whl", hash = "sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-win32.whl", hash = "sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win32.whl", hash = "sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win_arm64.whl", hash = "sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50"}, + {file = "charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f"}, + {file = "charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a"}, +] [[package]] name = "colorama" @@ -11,6 +144,20 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "idna" +version = "3.11" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}, + {file = "idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + [[package]] name = "neo4j" version = "5.24.0" @@ -103,6 +250,27 @@ files = [ {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"}, ] +[[package]] +name = "requests" +version = "2.32.5" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.9" +files = [ + {file = "requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6"}, + {file = "requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset_normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + [[package]] name = "tqdm" version = "4.66.4" @@ -123,7 +291,24 @@ notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] +[[package]] +name = "urllib3" +version = "2.6.3" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.9" +files = [ + {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}, + {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}, +] + +[package.extras] +brotli = ["brotli (>=1.2.0)", "brotlicffi (>=1.2.0.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["backports-zstd (>=1.0.0)"] + [metadata] lock-version = "2.0" python-versions = ">=3.10" -content-hash = "7b87590c2c9b8cfe2e1a0543382806c2e2982b8c0c8ae7b981733c169c1ddf2f" +content-hash = "fad5947e08ae828864771a7835ddb90d86bba4acd36b407ea9b5e65ecdbc16cd" diff --git a/pyproject.toml b/pyproject.toml index 01a8812..dbc0dae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,6 +12,7 @@ dev-dependencies = { } numpy = "==2.1.1" pytz = "==2022.7.1" tqdm = "==4.66.4" + requests = "^2.32.5" [tool.poetry.scripts] AD-miner = "ad_miner.__main__:main" diff --git a/requirements.txt b/requirements.txt index e89531d..6bb571f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ neo4j==5.24.0 numpy==2.1.1 pytz==2022.7.1 tqdm==4.66.4 +requests==2.32.5 From 4430f969b0dcc42f7d35f87b62c475747005d496 Mon Sep 17 00:00:00 2001 From: snowpeacock Date: Fri, 23 Jan 2026 15:05:51 +0100 Subject: [PATCH 11/16] feat: update 01 2026 update core modules --- ad_miner/__main__.py | 51 ++ .../sources/html/bootstrap/css/custom.css | 5 + .../html/components/grid/grid_template.html | 17 +- .../sources/html/templates/main_header.html | 4 +- ad_miner/sources/js/graph.js | 28 +- ad_miner/sources/js/icon.js | 16 +- ad_miner/sources/modules/common_analysis.py | 288 +++-------- ad_miner/sources/modules/config.json | 271 +++++----- .../modules/exploitability_ratings.json | 40 +- ad_miner/sources/modules/generic_formating.py | 19 +- ad_miner/sources/modules/graph_class.py | 21 +- ad_miner/sources/modules/grid_class.py | 47 ++ ad_miner/sources/modules/known_RIDs.json | 29 +- ad_miner/sources/modules/macro_graph_class.py | 45 ++ ad_miner/sources/modules/main_page.py | 9 +- ad_miner/sources/modules/neo4j_class.py | 480 +++++++++--------- ad_miner/sources/modules/path_neo4j.py | 10 +- ad_miner/sources/modules/smolcard_class.py | 2 +- ad_miner/sources/modules/utils.py | 16 +- 19 files changed, 738 insertions(+), 660 deletions(-) create mode 100644 ad_miner/sources/modules/macro_graph_class.py diff --git a/ad_miner/__main__.py b/ad_miner/__main__.py index 456bc36..7d6baa6 100644 --- a/ad_miner/__main__.py +++ b/ad_miner/__main__.py @@ -8,6 +8,9 @@ import traceback import signal import sys +import subprocess +import requests +from importlib.metadata import version, PackageNotFoundError # Local library imports from ad_miner.sources.modules import logger, utils, generic_formating, main_page @@ -142,6 +145,48 @@ def prepare_render(arguments) -> None: shutil.copy2(js_file, folder_name / "js") +def get_version_and_commit(): + # Either using pip(x) you get the version number or in dev environment the git commit + try: + ver = version("ad-miner") + except PackageNotFoundError: + ver = "unknown" + + commit = "" + try: + root = Path(__file__).resolve().parent + commit = subprocess.check_output( + ["git", "rev-parse", "--short", "HEAD"], cwd=root, stderr=subprocess.DEVNULL, text=True + ).strip() + except Exception: + commit = "unknown" + return ver, commit + + +def get_last_version(): + try: + r = requests.get("https://www.ad-miner.com/version.json", timeout=0.5) + data = r.json() + return data["lastversion"] + except Exception: + return "unreachable" + + +def check_version(lastversion, currentversion): + try: + last = tuple(map(int, lastversion.lstrip("v").split("."))) + current = tuple(map(int, currentversion.lstrip("v").split("."))) + + if last > current: + logger.print_error(f"New AD Miner version {lastversion} available.") + logger.print_error( + "Update with pipx or manually on https://github.com/AD-Security/AD_Miner" + ) + return + except Exception: + return + + def main() -> None: """Main execution function for the script.""" start = time.time() @@ -163,6 +208,12 @@ def main() -> None: prepare_render(arguments) + AD_miner_version, AD_miner_commit = get_version_and_commit() + arguments.version = AD_miner_version + arguments.commit = AD_miner_commit + + check_version(get_last_version(), AD_miner_version) + neo4j_version, extract_date, total_objects, number_relations, boolean_azure = pre_request( arguments ) diff --git a/ad_miner/sources/html/bootstrap/css/custom.css b/ad_miner/sources/html/bootstrap/css/custom.css index 8338397..7e40799 100755 --- a/ad_miner/sources/html/bootstrap/css/custom.css +++ b/ad_miner/sources/html/bootstrap/css/custom.css @@ -389,4 +389,9 @@ a:hover{ .percentage-evolution { font-size: small; font-weight: 800; +} + +.ag-cell-value i.bi { + margin-right: 4px; + vertical-align: middle; } \ No newline at end of file diff --git a/ad_miner/sources/html/components/grid/grid_template.html b/ad_miner/sources/html/components/grid/grid_template.html index 4945fb7..4719b92 100755 --- a/ad_miner/sources/html/components/grid/grid_template.html +++ b/ad_miner/sources/html/components/grid/grid_template.html @@ -99,10 +99,18 @@ rowData2.push(new_dico); } } + else if (window.location.href.includes('computers_with_administrators_details')) { + if (rowData[i]['Computer'] == parameter) { + var new_dico = {}; + new_dico['Users'] = rowData[i]['Users']; + new_dico['Distinguished Name'] = rowData[i]['Distinguished Name']; + rowData2.push(new_dico); + } + } else if (window.location.href.includes('users_rdp_access') || window.location.href.includes('computers_list_of_rdp_users')) { if (rowData[i][keys[0]].includes(parameter)) { - const startSubstring = "

"; + const startSubstring = "

"; const endSubstring = "

"; const startIndex = rowData[i][keys[1]].indexOf(startSubstring) + startSubstring.length; @@ -130,7 +138,12 @@ } } } - columnDefs2 = [{field: parameter}]; + if (window.location.href.includes('computers_with_administrators_details')) { + columnDefs2 = [{field: 'Users'},{field: 'Distinguished Name'}] + } + else { + columnDefs2 = [{field: parameter}]; + } return [rowData2, columnDefs2]; } diff --git a/ad_miner/sources/html/templates/main_header.html b/ad_miner/sources/html/templates/main_header.html index 9257e76..489fc9e 100644 --- a/ad_miner/sources/html/templates/main_header.html +++ b/ad_miner/sources/html/templates/main_header.html @@ -125,7 +125,7 @@