|
1 | | -<<<<<<< HEAD |
2 | 1 | import axios from "axios"; |
3 | 2 | import * as dotenv from "dotenv"; |
4 | 3 | import chalk from "chalk"; |
@@ -126,132 +125,3 @@ export async function scanUrl(url: string): Promise<void> { |
126 | 125 | console.error(chalk.red.bold("❌ Error:"), err.response?.data || err.message); |
127 | 126 | } |
128 | 127 | } |
129 | | -======= |
130 | | -import axios from "axios"; |
131 | | -import * as dotenv from "dotenv"; |
132 | | -import chalk from "chalk"; |
133 | | -import cliProgress from "cli-progress"; |
134 | | -import figlet from "figlet"; |
135 | | -import moment from "moment"; |
136 | | - |
137 | | -dotenv.config(); |
138 | | - |
139 | | -const VIRUSTOTAL_API_KEY = process.env.VIRUSTOTAL_API_KEY; |
140 | | - |
141 | | -if (!VIRUSTOTAL_API_KEY) { |
142 | | - throw new Error(chalk.red.bold("❌ Missing VirusTotal API Key in .env file!")); |
143 | | -} |
144 | | - |
145 | | -export async function scanUrl(url: string): Promise<void> { |
146 | | - try { |
147 | | - console.log(chalk.blue.bold(figlet.textSync("Malware Sniffer", { horizontalLayout: "full" }))); |
148 | | - console.log(chalk.blue.bold(`\n🚀 Starting URL Scan: ${chalk.underline(url)}\n`)); |
149 | | - |
150 | | - const startTime = moment(); |
151 | | - |
152 | | - const response = await axios.post( |
153 | | - "https://www.virustotal.com/api/v3/urls", |
154 | | - new URLSearchParams({ url }), |
155 | | - { |
156 | | - headers: { |
157 | | - "x-apikey": VIRUSTOTAL_API_KEY, |
158 | | - "Content-Type": "application/x-www-form-urlencoded", |
159 | | - }, |
160 | | - } |
161 | | - ); |
162 | | - |
163 | | - const scanId = response.data.data.id; |
164 | | - console.log(chalk.yellow.bold(`🔍 Scanning in progress...`)); |
165 | | - console.log(chalk.cyan.bold(`📌 Scan ID: ${scanId}`)); |
166 | | - |
167 | | - const progressBar = new cliProgress.SingleBar( |
168 | | - { |
169 | | - format: `⏳ Progress: [{bar}] {percentage}% | ETA: {eta}s`, |
170 | | - barCompleteChar: "█", |
171 | | - barIncompleteChar: "░", |
172 | | - }, |
173 | | - cliProgress.Presets.shades_classic |
174 | | - ); |
175 | | - |
176 | | - progressBar.start(100, 0); |
177 | | - let status = "queued"; |
178 | | - let scanResults: any; |
179 | | - let elapsedTime = 0; |
180 | | - |
181 | | - while (status === "queued") { |
182 | | - await new Promise((resolve) => setTimeout(resolve, 5000)); |
183 | | - |
184 | | - elapsedTime += 5; |
185 | | - progressBar.update((elapsedTime / 30) * 100); |
186 | | - |
187 | | - const result = await axios.get( |
188 | | - `https://www.virustotal.com/api/v3/analyses/${scanId}`, |
189 | | - { |
190 | | - headers: { "x-apikey": VIRUSTOTAL_API_KEY }, |
191 | | - } |
192 | | - ); |
193 | | - |
194 | | - scanResults = result.data.data.attributes; |
195 | | - status = scanResults.status; |
196 | | - |
197 | | - if (status === "queued") { |
198 | | - console.log(chalk.gray("⏳ Still processing... Waiting...")); |
199 | | - } |
200 | | - } |
201 | | - |
202 | | - progressBar.stop(); |
203 | | - |
204 | | - const engines = scanResults.results; |
205 | | - const detectedEngines = Object.values(engines).filter((res: any) => res.category === "malicious").length; |
206 | | - const totalEngines = Object.keys(engines).length; |
207 | | - const safeScore = ((totalEngines - detectedEngines) / totalEngines) * 100; |
208 | | - |
209 | | - const endTime = moment(); |
210 | | - const duration = moment.duration(endTime.diff(startTime)).seconds(); |
211 | | - |
212 | | - console.log("\n📊 " + chalk.bold.underline("Scan Results Summary:")); |
213 | | - console.log(chalk.gray(`🕒 Scan Duration: ${duration} seconds`)); |
214 | | - console.log(chalk.green.bold(`🔹 Total Engines Checked: ${totalEngines}`)); |
215 | | - console.log(chalk.red.bold(`🔸 Malicious Detections: ${detectedEngines}`)); |
216 | | - console.log(chalk.yellow.bold(`🟡 Suspicious Engines: ${Object.values(engines).filter((res: any) => res.category === "suspicious").length}`)); |
217 | | - console.log(chalk.green.bold(`✅ Safe Score: ${safeScore.toFixed(2)}%`)); |
218 | | - |
219 | | - console.log("\n📈 " + chalk.bold("Detection Chart:")); |
220 | | - console.log(chalk.green("🟩".repeat(Math.round(safeScore / 10))) + chalk.red("🟥".repeat(Math.round((100 - safeScore) / 10)))); |
221 | | - console.log(chalk.green.bold(`Safe: ${safeScore.toFixed(2)}%`)); |
222 | | - console.log(chalk.red.bold(`Malicious: ${(100 - safeScore).toFixed(2)}%\n`)); |
223 | | - |
224 | | - console.log(chalk.bold("🔍 Detailed Results:")); |
225 | | - Object.entries(engines).forEach(([engine, data]: any) => { |
226 | | - let categoryColor; |
227 | | - switch (data.category) { |
228 | | - case "malicious": |
229 | | - categoryColor = chalk.red.bold("🛑 Malicious"); |
230 | | - break; |
231 | | - case "harmless": |
232 | | - categoryColor = chalk.green.bold("✅ Harmless"); |
233 | | - break; |
234 | | - case "suspicious": |
235 | | - categoryColor = chalk.yellow.bold("⚠️ Suspicious"); |
236 | | - break; |
237 | | - default: |
238 | | - categoryColor = chalk.gray(data.category); |
239 | | - } |
240 | | - |
241 | | - console.log( |
242 | | - chalk.cyan(`📌 ${engine}:`) + |
243 | | - ` ${categoryColor} | ` + |
244 | | - chalk.gray(`Method: ${data.method}`) |
245 | | - ); |
246 | | - }); |
247 | | - |
248 | | - if (detectedEngines > 0) { |
249 | | - console.log(chalk.red.bold("\n⚠️ WARNING: This URL is potentially unsafe!")); |
250 | | - } else { |
251 | | - console.log(chalk.green.bold("\n✅ This URL appears safe!")); |
252 | | - } |
253 | | - } catch (err: any) { |
254 | | - console.error(chalk.red.bold("❌ Error:"), err.response?.data || err.message); |
255 | | - } |
256 | | -} |
257 | | ->>>>>>> 913bfbc0c48e5bdbb30449cbd1df4b0c0c1ecd09 |
0 commit comments