● 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 / storage / db.py
← Back to directory
180 lines · 6.5 KB
Raw
1import json
2import sqlite3
3from pathlib import Path
4
5from lanyard.vision.models import BadgeFinding
6
7
8class Database:
9 def __init__(self, db_path: Path | str):
10 self.db_path = Path(db_path)
11 self.db_path.parent.mkdir(parents=True, exist_ok=True)
12 self._init_tables()
13
14 def _get_conn(self) -> sqlite3.Connection:
15 conn = sqlite3.connect(self.db_path)
16 conn.row_factory = sqlite3.Row
17 return conn
18
19 def _init_tables(self) -> None:
20 with self._get_conn() as conn:
21 conn.execute("""
22 CREATE TABLE IF NOT EXISTS images (
23 id INTEGER PRIMARY KEY AUTOINCREMENT,
24 image_url TEXT UNIQUE,
25 post_url TEXT,
26 post_author TEXT,
27 post_caption TEXT,
28 analyzed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
29 )
30 """)
31 conn.execute("""
32 CREATE TABLE IF NOT EXISTS findings (
33 id INTEGER PRIMARY KEY AUTOINCREMENT,
34 image_id INTEGER,
35 has_badge INTEGER,
36 confidence REAL,
37 badge_type TEXT,
38 employee_name TEXT,
39 company_name TEXT,
40 department_or_role TEXT,
41 id_or_badge_number TEXT,
42 security_features TEXT,
43 summary TEXT,
44 crop_path TEXT,
45 original_path TEXT,
46 template_path TEXT,
47 card_corners TEXT,
48 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
49 FOREIGN KEY (image_id) REFERENCES images(id)
50 )
51 """)
52 try:
53 conn.execute("ALTER TABLE images ADD COLUMN post_author TEXT")
54 except Exception:
55 pass
56 try:
57 conn.execute("ALTER TABLE images ADD COLUMN post_caption TEXT")
58 except Exception:
59 pass
60 try:
61 conn.execute("ALTER TABLE findings ADD COLUMN template_path TEXT")
62 except Exception:
63 pass
64 try:
65 conn.execute("ALTER TABLE findings ADD COLUMN card_corners TEXT")
66 except Exception:
67 pass
68 conn.commit()
69
70 def is_image_analyzed(self, image_url: str) -> bool:
71 with self._get_conn() as conn:
72 cur = conn.execute("SELECT id FROM images WHERE image_url = ?", (image_url,))
73 return cur.fetchone() is not None
74
75 def record_image(
76 self,
77 image_url: str,
78 post_url: str | None = None,
79 post_author: str | None = None,
80 post_caption: str | None = None,
81 ) -> int:
82 with self._get_conn() as conn:
83 cur = conn.execute(
84 """
85 INSERT OR IGNORE INTO images (image_url, post_url, post_author, post_caption)
86 VALUES (?, ?, ?, ?)
87 """,
88 (image_url, post_url or "", post_author or "", post_caption or ""),
89 )
90 conn.commit()
91 if cur.lastrowid and cur.lastrowid > 0:
92 return cur.lastrowid
93 cur = conn.execute("SELECT id FROM images WHERE image_url = ?", (image_url,))
94 row = cur.fetchone()
95 return row["id"] if row else -1
96
97 def record_finding(
98 self,
99 image_id: int,
100 finding: BadgeFinding,
101 crop_path: str | None = None,
102 original_path: str | None = None,
103 template_path: str | None = None,
104 ) -> int:
105 corners_json = json.dumps(finding.card_corners.model_dump()) if finding.card_corners else None
106 with self._get_conn() as conn:
107 cur = conn.execute(
108 """
109 INSERT INTO findings (
110 image_id, has_badge, confidence, badge_type,
111 employee_name, company_name, department_or_role,
112 id_or_badge_number, security_features, summary,
113 crop_path, original_path, template_path, card_corners
114 ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
115 """,
116 (
117 image_id,
118 1 if finding.has_badge else 0,
119 finding.confidence,
120 finding.badge_type,
121 finding.employee_name,
122 finding.company_name,
123 finding.department_or_role,
124 finding.id_or_badge_number,
125 json.dumps(finding.security_features),
126 finding.summary,
127 crop_path or "",
128 original_path or "",
129 template_path or "",
130 corners_json,
131 ),
132 )
133 conn.commit()
134 return cur.lastrowid or -1
135
136 def update_finding_cr80(
137 self,
138 finding_id: int,
139 template_path: str,
140 card_corners: dict | None = None,
141 ) -> None:
142 with self._get_conn() as conn:
143 if card_corners is not None:
144 conn.execute(
145 "UPDATE findings SET template_path = ?, card_corners = ? WHERE id = ?",
146 (template_path, json.dumps(card_corners), finding_id),
147 )
148 else:
149 conn.execute(
150 "UPDATE findings SET template_path = ? WHERE id = ?",
151 (template_path, finding_id),
152 )
153 conn.commit()
154
155 def get_all_badge_findings(self) -> list[dict]:
156 with self._get_conn() as conn:
157 cur = conn.execute("""
158 SELECT f.*, i.image_url, i.post_url, i.post_author, i.post_caption
159 FROM findings f
160 JOIN images i ON f.image_id = i.id
161 WHERE f.has_badge = 1
162 ORDER BY f.confidence DESC, f.id DESC
163 """)
164 rows = cur.fetchall()
165 results = []
166 for r in rows:
167 item = dict(r)
168 try:
169 item["security_features"] = json.loads(item.get("security_features") or "[]")
170 except Exception:
171 item["security_features"] = []
172 if item.get("card_corners"):
173 try:
174 item["card_corners"] = json.loads(item["card_corners"])
175 except Exception:
176 item["card_corners"] = None
177 else:
178 item["card_corners"] = None
179 results.append(item)
180 return results