├── .gitignore
├── LICENSE
├── README.md
├── SECURITY.md
├── cve-enrich-diff.png
├── ghsa-enrich-diff.png
├── puncia-actions.yml
├── puncia.png
├── puncia
├── __init__.py
└── __main__.py
└── setup.py
/.gitignore:
--------------------------------------------------------------------------------
1 | pypi.sh
2 | build
3 | dist
4 | *.egg-info
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022-2025 Automated Reconnaissance & Pwning Syndicate
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Panthera(P.)uncia
2 |
3 | ### Official CLI utility for Osprey Vision, Subdomain Center & Exploit Observer
4 |
5 | [](https://pepy.tech/project/puncia)
6 |
7 |
8 |
9 |
10 |
11 | Puncia utilizes three of our intelligent APIs to gather the results -
12 |
13 | - [Subdomain Center - The World's Largest Subdomain & Shadow IT Intelligence Database](https://subdomain.center)
14 | - [Exploit Observer - The World's Largest Exploit & Vulnerability Intelligence Database](https://exploit.observer)
15 | - [Osprey Vision - The World's Most Bleeding Edge AI for Information Discovery](https://osprey.vision)
16 |
17 | **Please note that although these results can sometimes be pretty inaccurate & unreliable, they can greatly differ from time to time due to their self-improvement capabilities.**
18 |
19 | **Aggressive rate-limits can be avoided with an API key: https://www.arpsyndicate.io/pricing.html**
20 |
21 | ## Practical Applications
22 |
23 | 1. **Mapping External Attack Surfaces**
24 | Identify and monitor exposed subdomains and infrastructure components across the internet.
25 | 2. **Advanced Vulnerability Research & Monitoring**
26 | Discover and track known and emerging threats, including obscure or unlisted vulnerabilities.
27 | 3. **Contextual Enrichment of CVE/GHSA Data**
28 | Add depth and actionable intelligence to known vulnerabilities for better prioritization.
29 | 4. **LLM-Driven Summarization & Prompt Execution**
30 | Leverage AI to summarize web content or generate code and analysis based on natural language prompts.
31 | 5. **Automated Vulnerability Advisory Creation**
32 | Instantly generate detailed, multilingual security advisories for discovered vulnerabilities.
33 | 6. **Vulnerability Detection in Software Bill of Materials (SBOM)**
34 | Analyze software components for known exploits and security issues using structured SBOM data.
35 | 7. **Seamless Integration with CI/CD & Threat Intel Workflows**
36 | Automate intelligence gathering and vulnerability checks within development or security pipelines.
37 | 8. **Monitoring Nation-State Exploit Trends**
38 | Stay ahead of threats by tracking vulnerabilities flagged by foreign actors but not yet recognized by mainstream databases.
39 | 9. **Replica Domain Detection & Brand Protection**
40 | Identify replica or lookalike domains that could be used in phishing or impersonation attacks.
41 | 10. **Bulk Threat Intelligence Processing**
42 | Run batch queries (domains, vulnerabilities, etc.) for scalable analysis across large datasets or enterprise asset inventories.
43 | 11. **Passive Reconnaissance for Red Teams**
44 | Conduct stealthy reconnaissance by using passive data sources (no direct interaction with targets).
45 | 12. **Open Source Intelligence (OSINT) Collection**
46 | Combine subdomain, exploit, and content summarization features to enhance OSINT investigations.
47 | 13. **Security Blog & Research Digest Automation**
48 | Automatically summarize technical blog posts and reports into actionable briefs.
49 | 14. **Cross-Language Security Intelligence Delivery**
50 | Translate advisories or technical content into other languages for global teams and multilingual incident response.
51 | 15. **Compliance & Risk Management Support**
52 | Enrich vulnerability data to support compliance audits (e.g., ISO 27001, SOC 2) with deeper context.
53 |
54 |
55 | ## Installation
56 |
57 | 1. From PyPi - `pip3 install puncia`
58 | 2. From Source - `pip3 install .`
59 |
60 |
61 | ## Usage
62 |
63 | 1. (PAID) Store an API key (storekey) - `puncia storekey `
64 | 2. (FREEMIUM) Interact with the LLM (chat) - `puncia chat "" `
65 | 3. (PAID) Summarize Webpages with the LLM (summarize) - `puncia summarize "" `
66 | 4. (FREEMIUM) Query Domains (subdomain) - `puncia subdomain `
67 | 5. (FREEMIUM) Query Replica Domains (replica) - `puncia replica `
68 | 6. Query Exploit & Vulnerability Identifiers (exploit)
69 | - (FREE) European VIDs with no associated CVEs (^EU_NON_CVE) - `puncia exploit ^EU_NON_CVE `
70 | - (FREE) Russian VIDs with no associated CVEs (^RU_NON_CVE) - `puncia exploit ^RU_NON_CVE `
71 | - (FREE) Chinese VIDs with no associated CVEs (^CN_NON_CVE) - `puncia exploit ^CN_NON_CVE `
72 | - (FREE) Vulnerability & Exploit Identifers Watchlist (^WATCHLIST_IDES) - `puncia exploit ^WATCHLIST_IDES `
73 | - (FREE) Vulnerability & Exploit Identifers Watchlist with Descriptions (^WATCHLIST_INFO) - `puncia exploit ^WATCHLIST_INFO `
74 | - (FREE) Vulnerable Technologies Watchlist (^WATCHLIST_TECH) - `puncia exploit ^WATCHLIST_TECH `
75 | - (FREEMIUM) [Supported Vulnerability Identifiers](https://github.com/ARPSyndicate/docs?tab=readme-ov-file#supported-vulnerability-identifiers) - `puncia exploit `
76 | 7. (PAID) Generate Vulnerability Advisory with the LLM (advisory) - `puncia advisory "|" `
77 | 8. (FREEMIUM) Enrich CVE/GHSA Identifiers (enrich) - `puncia enrich `
78 | 9. Multiple Queries (bulk/sbom)
79 |
80 | - (FREEMIUM) Bulk Input JSON File Format - `puncia bulk `
81 | ```json
82 | {
83 | "subdomain": [
84 | "domainA.com",
85 | "domainB.com"
86 | ],
87 | "replica": [
88 | "domainA.com",
89 | "domainB.com"
90 | ],
91 | "exploit": [
92 | "eoidentifierA",
93 | "eoidentifierB"
94 | ],
95 | "enrich": [
96 | "eoidentifierA",
97 | "eoidentifierB"
98 | ],
99 | "advisory": [
100 | "eoidentifierA",
101 | "eoidentifierB|GERMAN"
102 | ]
103 | }
104 | ```
105 | - (FREEMIUM) [SBOM Input JSON File Format](https://github.com/CycloneDX/bom-examples/blob/master/SBOM/protonmail-webclient-v4-0912dff/bom.json) - `puncia sbom `
106 |
107 | 10. (FREEMIUM) External Import
108 |
109 | ```python
110 | import puncia
111 | import asyncio
112 |
113 | async def main():
114 | # Without API Key
115 | print(await puncia.query_api("exploit", "CVE-2021-3450"))
116 | print(await puncia.query_api("subdomain", "arpsyndicate.io"))
117 | print(await puncia.query_api("chat", "write a xss fuzzer in python"))
118 |
119 | # With API Key
120 | await puncia.store_key("ARPS-xxxxxxxxxx")
121 | api_key = await puncia.read_key()
122 | print(await puncia.query_api("subdomain", "arpsyndicate.io", apikey=api_key))
123 | print(await puncia.query_api("exploit", "CVE-2021-3450", apikey=api_key))
124 | print(await puncia.query_api("chat", "write a xss fuzzer in python", apikey=api_key))
125 | print(await puncia.query_api("summarize", "https://www.osintteam.com/combating-the-darkest-depths-of-cyber-intelligence-the-pall-mall-process/", apikey=api_key))
126 | print(await puncia.query_api("advisory", "CVE-2025-31324", apikey=api_key))
127 | print(await puncia.query_api("advisory", "CVE-2025-31324|FRENCH", apikey=api_key))
128 |
129 | # Run the main async function
130 | asyncio.run(main())
131 | ```
132 |
133 |
134 |
135 | ### CVE Enrichment
136 |
137 |
138 |
139 | ### GHSA Enrichment
140 |
141 |
142 |
143 | ## Noteworthy Mentions
144 |
145 | - [Passive Subdomain Enumeration: Uncovering More Subdomains than Subfinder & Amass](https://osintteam.com/passive-subdomain-enumeration-uncovering-more-subdomains-than-subfinder-amass/)
146 | - [Around 1000 exploitable cybersecurity vulnerabilities that MITRE & NIST ‘might’ have missed but China or Russia didn’t.](https://blog.arpsyndicate.io/over-a-1000-vulnerabilities-that-mitre-nist-might-have-missed-but-china-or-russia-did-not-871b2364a526)
147 | - [Utilizing GitHub Actions for gathering Subdomain & Exploit Intelligence](https://blog.arpsyndicate.io/utilizing-github-actions-for-gathering-subdomain-exploit-intelligence-bbc79c19bb85)
148 | - [Introducing Exploit Observer — More than Shodan Exploits, Less than Vulners](https://blog.arpsyndicate.io/introducing-exploit-observer-more-than-shodan-exploits-less-than-vulners-23eaea466e4a)
149 | - [PUNCIA — The Panthera(P.)uncia of Cybersecurity](https://blog.arpsyndicate.io/puncia-the-panthera-p-uncia-of-cybersecurity-ft-puncia-subdomain-center-exploit-observer-9a9d8cca9576)
150 | - [Subdomain Enumeration Tool Face-off - 2023 Edition](https://blog.blacklanternsecurity.com/p/subdomain-enumeration-tool-face-off-4e5)
151 |
152 | ## More from [A.R.P. Syndicate](https://www.arpsyndicate.io)
153 |
154 | - [VEDAS Advisories](https://vedas.arpsyndicate.io)
155 | - [CTI Grid](https://ctigrid.arpsyndicate.io)
156 | - [Open Source Intelligence](https://asm.arpsyndicate.io/intelligence.html)
157 | - [Attack Surface Management](https://asm.arpsyndicate.io)
158 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | ### Security Policy
2 |
3 | A.R.P. Syndicate takes security seriously and is committed to ensuring the safety and privacy of its users' data. If you discover any security vulnerabilities or have concerns about the security of our application, please follow the guidelines below to report them responsibly.
4 |
5 | #### Reporting a Vulnerability
6 |
7 | To report a security vulnerability, please navigate to the **[Security](https://github.com/ARPSyndicate/puncia/security)** tab and follow the instructions to report a vulnerability.
8 |
9 | When reporting a vulnerability, please include as much information as possible to help us understand and resolve the issue quickly. Ideally, your report should contain:
10 |
11 | - A detailed description of the vulnerability.
12 | - Steps to reproduce the issue.
13 | - Any relevant information, such as screenshots or logs.
14 |
15 | #### Response Time
16 |
17 | We will acknowledge receipt of your report within 48 hours and provide an initial assessment of the report within 5 business days. Our team will keep you informed about the progress and any actions we take as a result of your report.
18 |
19 | #### Disclosure Policy
20 |
21 | We follow a responsible disclosure policy to protect our users while we work on resolving any reported vulnerabilities. We kindly request that you:
22 |
23 | - Allow us a reasonable amount of time to investigate and address your report before any public disclosure.
24 | - Avoid exploiting the vulnerability or sharing it with others before it is resolved.
25 |
26 | #### Contact
27 |
28 | For any security-related questions or concerns, please feel free to reach out at [ayush@arpsyndicate.io].
29 |
30 | Thank you for helping us keep our application secure!
31 |
32 | ---
33 |
34 | By adhering to this Security Policy, you help us maintain a safe and secure environment for all users. We appreciate your cooperation and responsible disclosure practices.
35 |
36 | ---
--------------------------------------------------------------------------------
/cve-enrich-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARPSyndicate/puncia/5e784c63efc17a47bc81f87d6d14611f24fb95b6/cve-enrich-diff.png
--------------------------------------------------------------------------------
/ghsa-enrich-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARPSyndicate/puncia/5e784c63efc17a47bc81f87d6d14611f24fb95b6/ghsa-enrich-diff.png
--------------------------------------------------------------------------------
/puncia-actions.yml:
--------------------------------------------------------------------------------
1 | name: puncia-actions
2 |
3 | on:
4 | schedule:
5 | - cron: '0 0 * * *'
6 | push:
7 | branches:
8 | - main
9 | pull_request:
10 | branches:
11 | - main
12 |
13 | jobs:
14 | puncia:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - uses: actions/checkout@v2
18 | - name: Set up Python
19 | uses: actions/setup-python@v2
20 | with:
21 | python-version: '3.9'
22 |
23 | - name: Install Puncia
24 | run: |
25 | pip3 install puncia
26 |
27 | - name: Run Puncia
28 | run: |
29 | puncia bulk ${{ github.workspace }}/inputs.json ${{ github.workspace }}/
30 |
31 | - name: Commit and push changes
32 | run: |
33 | git config --local user.email "puncia@github.local"
34 | git config --local user.name "Puncia Actions"
35 | git add .
36 | git commit -m "$(date)"
37 | git push
--------------------------------------------------------------------------------
/puncia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ARPSyndicate/puncia/5e784c63efc17a47bc81f87d6d14611f24fb95b6/puncia.png
--------------------------------------------------------------------------------
/puncia/__init__.py:
--------------------------------------------------------------------------------
1 | from .__main__ import query_api, store_key, read_key
2 |
3 | __all__ = ["query_api", "store_key", "read_key"]
--------------------------------------------------------------------------------
/puncia/__main__.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | import json
4 | import asyncio
5 | import aiohttp
6 | from aiofiles import open as aio_open
7 |
8 |
9 | API_URLS = {
10 | "subdomain": "https://api.subdomain.center/?domain=",
11 | "replica": "https://api.subdomain.center/?engine=octopus&domain=",
12 | "exploit": "https://api.exploit.observer/?keyword=",
13 | "enrich": "https://api.exploit.observer/?enrich=True&keyword=",
14 | "chat": "https://api.osprey.vision/",
15 | "auth_subdomain": "https://api.subdomain.center/beta/?auth={0}&domain=",
16 | "auth_replica": "https://api.subdomain.center/beta/?auth={0}&engine=octopus&domain=",
17 | "auth_exploit": "https://api.exploit.observer/beta/?auth={0}&keyword=",
18 | "auth_enrich": "https://api.exploit.observer/beta/?auth={0}&enrich=True&keyword=",
19 | "auth_chat": "https://api.osprey.vision/beta/",
20 | "auth_summarize": "https://api.osprey.vision/summarize/",
21 | "auth_advisory": "https://api.osprey.vision/advisory/",
22 | "russia": "https://api.exploit.observer/russia/",
23 | "europe": "https://api.exploit.observer/europe/",
24 | "china": "https://api.exploit.observer/china/",
25 | "watchlist_ides": "https://api.exploit.observer/watchlist/identifiers",
26 | "watchlist_info": "https://api.exploit.observer/watchlist/describers",
27 | "watchlist_tech": "https://api.exploit.observer/watchlist/technologies",
28 | }
29 |
30 |
31 | async def store_key(key=""):
32 | home = os.path.expanduser("~")
33 | async with aio_open(home + "/.puncia", "w") as f:
34 | await f.write(key)
35 |
36 |
37 | async def read_key():
38 | try:
39 | home = os.path.expanduser("~")
40 | async with aio_open(home + "/.puncia", "r") as f:
41 | return (await f.read()).strip()
42 | except FileNotFoundError:
43 | return ""
44 |
45 |
46 | async def query_api(mode, query, output_file=None, cid=None, apikey=""):
47 | async with aiohttp.ClientSession() as session:
48 | if len(apikey) > 0 and mode in [
49 | "exploit",
50 | "subdomain",
51 | "enrich",
52 | "replica",
53 | "chat",
54 | "summarize",
55 | "advisory",
56 | ]:
57 | url = API_URLS.get("auth_" + mode).format(apikey)
58 | else:
59 | await asyncio.sleep(5)
60 | url = API_URLS.get(mode)
61 | if not url:
62 | print("Invalid Mode / Missing Authentication")
63 | return
64 |
65 | if "^" in query and "exploit" in mode:
66 | if query == "^EU_NON_CVE":
67 | url = API_URLS.get("europe")
68 | query = "noncve"
69 | mode = "spec_exploit"
70 | cid = "European VIDs with no associated CVEs"
71 | elif query == "^RU_NON_CVE":
72 | url = API_URLS.get("russia")
73 | query = "noncve"
74 | mode = "spec_exploit"
75 | cid = "Russian VIDs with no associated CVEs"
76 | elif query == "^CN_NON_CVE":
77 | url = API_URLS.get("china")
78 | query = "noncve"
79 | mode = "spec_exploit"
80 | cid = "Chinese VIDs with no associated CVEs"
81 | elif query == "^WATCHLIST_IDES":
82 | url = API_URLS.get("watchlist_ides")
83 | query = ""
84 | mode = "spec_exploit"
85 | cid = "Vulnerability & Exploit Watchlist"
86 | elif query == "^WATCHLIST_INFO":
87 | url = API_URLS.get("watchlist_info")
88 | query = ""
89 | mode = "spec_exploit"
90 | cid = "Vulnerability & Exploit Watchlist (with descriptions)"
91 | elif query == "^WATCHLIST_TECH":
92 | url = API_URLS.get("watchlist_tech")
93 | query = ""
94 | mode = "spec_exploit"
95 | cid = "Vulnerable Technologies Watchlist"
96 |
97 | retries = 1
98 | counter = 0
99 | response_data = None
100 |
101 | while counter <= retries:
102 | try:
103 | if mode in ["chat", "auth_chat"]:
104 | reschat = ""
105 | data = {"prompt": query}
106 | if "/beta" in url:
107 | data["auth"] = apikey
108 | async with session.post(url, json=data) as response:
109 | async for line in response.content:
110 | if sys.argv[0].endswith("puncia"):
111 | print(line.decode("utf-8"), flush=True, end="")
112 | reschat += line.decode("utf-8")
113 | if sys.argv[0].endswith("puncia"):
114 | print("\n")
115 | if output_file:
116 | with open(output_file, "w") as f:
117 | f.write(reschat)
118 | counter = counter + 1
119 | if reschat and len(reschat) > 1:
120 | return reschat
121 |
122 | elif mode in ["summarize", "auth_summarize"]:
123 | reschat = ""
124 | data = {"links": query}
125 | data["auth"] = apikey
126 | async with session.post(url, json=data) as response:
127 | async for line in response.content:
128 | if sys.argv[0].endswith("puncia"):
129 | print(line.decode("utf-8"), flush=True, end="")
130 | reschat += line.decode("utf-8")
131 | if sys.argv[0].endswith("puncia"):
132 | print("\n")
133 | if output_file:
134 | with open(output_file, "w") as f:
135 | f.write(reschat)
136 | counter = counter + 1
137 | if reschat and len(reschat) > 1:
138 | return reschat
139 | elif mode in ["advisory", "auth_advisory"]:
140 | reschat = ""
141 | if len(query.split("|")) == 2:
142 | data = {"vulnid": query.split("|")[0], "lang": query.split("|")[1].upper()}
143 | else:
144 | data = {"vulnid": query, "lang": "ENGLISH"}
145 | data["auth"] = apikey
146 | async with session.post(url, json=data) as response:
147 | async for line in response.content:
148 | if sys.argv[0].endswith("puncia"):
149 | print(line.decode("utf-8"), flush=True, end="")
150 | reschat += line.decode("utf-8")
151 | if sys.argv[0].endswith("puncia"):
152 | print("\n")
153 | if output_file:
154 | with open(output_file, "w") as f:
155 | f.write(reschat)
156 | counter = counter + 1
157 | if reschat and len(reschat) > 1:
158 | return reschat
159 | else:
160 | async with session.get(url + query) as response:
161 | response_data = await response.json()
162 |
163 | if response_data:
164 | if len(response_data) > 1:
165 | break
166 | except Exception as ne:
167 | exc_type, exc_value, exc_tb = sys.exc_info()
168 | line_number = exc_tb.tb_lineno
169 | print(f"Error: {str(ne)} at line {line_number}")
170 | counter += 1
171 | await asyncio.sleep(2)
172 |
173 | if response_data and mode == "spec_exploit" and output_file:
174 | try:
175 | async with aio_open(output_file, "w") as f:
176 | await f.write(json.dumps(response_data, indent=4, sort_keys=True))
177 | except Exception as ne:
178 | exc_type, exc_value, exc_tb = sys.exc_info()
179 | line_number = exc_tb.tb_lineno
180 | print(f"Error: {str(ne)} at line {line_number}")
181 | return response_data
182 |
183 | if response_data and output_file:
184 | async with aio_open(output_file, "w") as f:
185 | await f.write(json.dumps(response_data, indent=4, sort_keys=True))
186 |
187 | return response_data
188 |
189 |
190 | def sbom_process(sbom):
191 | fingps = []
192 |
193 | def add_component(name, version):
194 | if name and version:
195 | fingps.append(f"{name}@{version}")
196 |
197 | metadata_component = sbom.get("metadata", {}).get("component", {})
198 | add_component(metadata_component.get("name"), metadata_component.get("version"))
199 | components = sbom.get("components", [])
200 | for subcom in components:
201 | add_component(subcom.get("name"), subcom.get("version"))
202 | return fingps
203 |
204 |
205 | async def process_bulk(input_file, output_directory, apikey):
206 | tasks = []
207 | for mode, queries in input_file.items():
208 | for query in queries:
209 | output_file = f"{output_directory}/{mode}/{query}.json"
210 | os.makedirs(os.path.dirname(output_file), exist_ok=True)
211 | tasks.append(query_api(mode, query, output_file, apikey=apikey))
212 | await asyncio.gather(*tasks)
213 |
214 |
215 | async def main():
216 | try:
217 | if len(sys.argv) < 3:
218 | print("---------")
219 | print("Panthera(P.)uncia [v0.33]")
220 | print("A.R.P. Syndicate [https://www.arpsyndicate.io]")
221 | print("---------")
222 | sys.exit(
223 | "usage: puncia [output_file/output_directory]\nrefer: https://github.com/ARPSyndicate/puncia#usage"
224 | )
225 |
226 | mode = sys.argv[1]
227 | query = sys.argv[2]
228 | output_file = sys.argv[3] if len(sys.argv) == 4 else None
229 | apikey = await read_key()
230 |
231 | if mode == "storekey":
232 | await store_key(query)
233 | print("Key stored successfully!")
234 | elif mode == "bulk" or mode == "sbom":
235 | if not os.path.isfile(query):
236 | sys.exit("JSON file as QUERY input required for BULK mode")
237 | if not output_file:
238 | sys.exit("BULK & SBOM Mode requires an Output Directory")
239 |
240 | with open(query, "r") as f:
241 | input_file = json.load(f)
242 |
243 | if mode == "sbom":
244 | input_file = {"exploit": sbom_process(input_file)}
245 |
246 | await process_bulk(input_file, output_file, apikey)
247 | else:
248 | result = await query_api(mode, query, output_file, apikey=apikey)
249 | if result and mode not in ["chat", "summarize", "advisory"]:
250 | print(json.dumps(result, indent=4, sort_keys=True))
251 | except Exception as ne:
252 | exc_type, exc_value, exc_tb = sys.exc_info()
253 | line_number = exc_tb.tb_lineno
254 | print(f"Error: {str(ne)} at line {line_number}")
255 |
256 |
257 | def scriptrun():
258 | asyncio.run(main())
259 |
260 |
261 | if __name__ == "__main__":
262 | scriptrun()
263 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup, find_packages
2 |
3 | setup(
4 | name="puncia",
5 | version="0.33",
6 | author="A.R.P. Syndicate",
7 | author_email="ayush@arpsyndicate.io",
8 | keywords="information discovery cyber intelligence llm ai chat subdomains subdomain exploits exploit sbom cyclonedx arpsyndicate panthera uncia puncia snow leopard",
9 | url="https://github.com/ARPSyndicate/puncia",
10 | project_urls={
11 | "A.R.P. Syndicate": "https://www.arpsyndicate.io",
12 | "Subdomain Center": "https://subdomain.center",
13 | "Exploit Observer": "https://exploit.observer",
14 | "Osprey Vision": "https://osprey.vision",
15 | },
16 | license="MIT",
17 | long_description=open("README.md").read(),
18 | long_description_content_type="text/markdown",
19 | description="Panthera(P.)uncia - Official CLI utility for Osprey Vision, Subdomain Center & Exploit Observer",
20 | packages=find_packages(),
21 | install_requires=[
22 | "requests",
23 | "aiohttp",
24 | "aiofiles",
25 | "asyncio"
26 | ],
27 | entry_points={"console_scripts": ["puncia=puncia.__main__:scriptrun"]},
28 | )
29 |
--------------------------------------------------------------------------------