● Notice //GitHub (@shehzade) is temporarily suspended pending an automated false-positive review. All tools are hosted on this Code Mirror and available on request (contact); GitHub links will return once reinstated.
PUBLIC MIRRORPython

AI-driven badge OSINT, credential harvesting, and calibrated CR80 card cloning for physical red teams.

$ git clone https://shehzade.io/repos/lanyard.git Copy
Source ZIP (1.35 MB)
Code 35 Commits 2
lanyard / lanyard / vision / providers / ollama_provider.py
← Back to directory
69 lines · 2.1 KB
Raw
1import base64
2import json
3import time
4
5import httpx
6
7from lanyard.vision.models import BadgeFinding
8from lanyard.vision.providers.base import DETECTOR_PROMPT, BaseVisionProvider
9
10
11class OllamaVisionProvider(BaseVisionProvider):
12 def __init__(
13 self,
14 model_name: str = "qwen2.5vl",
15 api_key: str = "",
16 api_base: str = "http://localhost:11434",
17 ):
18 super().__init__(
19 model_name=model_name,
20 api_key=api_key,
21 api_base=api_base or "http://localhost:11434",
22 )
23 self.client = httpx.Client(timeout=120.0)
24
25 def analyze_image(self, image_bytes: bytes, mime_type: str = "image/jpeg") -> BadgeFinding:
26 b64_str = base64.b64encode(image_bytes).decode("utf-8")
27 schema_json = json.dumps(BadgeFinding.model_json_schema(), indent=2)
28
29 prompt = (
30 f"{DETECTOR_PROMPT}\n\n"
31 f"You MUST respond ONLY with a valid JSON object strictly matching this JSON schema:\n"
32 f"{schema_json}\n"
33 )
34
35 payload = {
36 "model": self.model_name,
37 "messages": [
38 {
39 "role": "user",
40 "content": prompt,
41 "images": [b64_str],
42 }
43 ],
44 "format": "json",
45 "stream": False,
46 "options": {
47 "temperature": 0.1,
48 },
49 }
50
51 url = f"{self.api_base.rstrip('/')}/api/chat"
52
53 max_retries = 3
54 for attempt in range(max_retries):
55 try:
56 resp = self.client.post(url, json=payload)
57 resp.raise_for_status()
58 data = resp.json()
59 content = data.get("message", {}).get("content", "")
60 if content:
61 parsed = json.loads(content)
62 return BadgeFinding(**parsed)
63 return BadgeFinding(has_badge=False, confidence=0.0)
64 except Exception:
65 if attempt == max_retries - 1:
66 raise
67 time.sleep(1.0)
68
69 return BadgeFinding(has_badge=False, confidence=0.0)