Skip to content

Commit ee4c642

Browse files
committed
2 parents b06ce82 + 913bfbc commit ee4c642

File tree

6 files changed

+266
-0
lines changed

6 files changed

+266
-0
lines changed

README.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<<<<<<< HEAD
12
# 🕵️♂️ Malware Sniffer · [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
23

34
_A cybersecurity companion that sniffs out suspicious URLs with style_ 🔍✨
@@ -102,3 +103,109 @@ MIT Licensed - Go build something secure! 🛡️
102103
---
103104

104105
Made with ❤️ by [0xGrayy] · [Report Issue](https://github.com/0xGrayy/malwareSniffer/issues)
106+
=======
107+
# 🕵️♂️ Malware Sniffer · [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
108+
109+
_A cybersecurity companion that sniffs out suspicious URLs with style_ 🔍✨
110+
111+
<div align="center">
112+
<img src="./assets/demo.gif" alt="Animated demo showing scanning process" width="800">
113+
<p><em>Watch Malware Sniffer in action – from scanning to detailed report</em></p>
114+
</div>
115+
116+
## 🌟 Why Malware Sniffer?
117+
118+
In today's digital jungle, every click matters. Malware Sniffer is your trusty sidekick that:
119+
120+
**Instant Safety Check**: Scan any URL against 70+ security engines in real-time
121+
**Beautiful Reports**: Get clear, color-coded results with emoji storytelling
122+
**Developer Friendly**: Perfect for integrating into your security workflows
123+
**Zero Hassle**: Set up in 2 minutes with automatic progress tracking
124+
125+
## 🚀 Getting Started
126+
127+
### 📦 Installation
128+
129+
```bash
130+
git clone https://github.com/0xGrayy/malwareSniffer.git
131+
cd malwareSniffer
132+
npm install
133+
```
134+
135+
### 🔐 Configuration
136+
137+
1. Get your free API key from [VirusTotal](https://www.virustotal.com)
138+
2. Create `.env` file:
139+
140+
```env
141+
VIRUSTOTAL_API_KEY=your_actual_key_here
142+
```
143+
144+
### 🕹️ Quick Start
145+
146+
```typescript
147+
import { scanUrl } from "./virusTotal";
148+
149+
// Be the cybersecurity hero your app needs 🦸
150+
scanUrl("https://your-url-here.com");
151+
```
152+
153+
## 📊 What You'll See
154+
155+
![Sample Scan Output](./assets/image-2.png)
156+
_Real scan results showing safety breakdown and detection details_
157+
158+
## 🛠️ Tech Stack
159+
160+
- **`axios`** → Smooth API communication
161+
- **`chalk`** → Terminal colors
162+
- **`cli-progress`** → That satisfying progress bar
163+
- **`figlet`** → Fancy ASCII art headers
164+
- **`moment`** → Precision timing metrics
165+
166+
## 🖌️ Feature Highlights
167+
168+
### 🎨 Visual Progress Tracking
169+
170+
![Progress Bar Demo](./assets/image-1.png)
171+
_Watch the scan unfold with live ETA updates_
172+
173+
### 🔍 Deep Analysis
174+
175+
```markdown
176+
📌 Google Safebrowsing → 🛑 Malicious (blacklist)
177+
📌 CRDF → ⚠️ Suspicious (heuristic)
178+
📌 Quttera → ✅ Harmless (signature)
179+
```
180+
181+
### 📈 Safety at a Glance
182+
183+
```
184+
Safety Score: 92% 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟥
185+
```
186+
187+
## 🤝 Join the Security Squad
188+
189+
We welcome contributors! Here's how to help:
190+
191+
1. 🐛 **Report bugs** – Help us squash them!
192+
2. 💡 **Suggest features** – What's missing?
193+
3. 📖 **Improve docs** – Make things clearer
194+
4. 🧪 **Write tests** – Keep things reliable
195+
196+
**First time contributing?** Check our [contribution guide](CONTRIBUTING.md)!
197+
198+
## ⚠️ Important Notes
199+
200+
- This tool **doesn't guarantee 100% safety** – always practice defense-in-depth
201+
- API rate limits apply – be kind to VirusTotal's servers
202+
- Keep your API key secret – treat it like your WiFi password 🔑
203+
204+
## 📜 License
205+
206+
MIT Licensed - Go build something secure! 🛡️
207+
208+
---
209+
210+
Made with ❤️ by [0xGrayy] · [Report Issue](https://github.com/0xGrayy/malwareSniffer/issues)
211+
>>>>>>> 913bfbc0c48e5bdbb30449cbd1df4b0c0c1ecd09

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@
77
"build": "npx tsc",
88
"start": "node dist/index.js",
99
"autobuild": "npx tsc -w",
10+
<<<<<<< HEAD
1011
"autostart": "cls && npx tsc && node dist/index.js",
1112
"push": "git add . && git commit -m \"V1.1.5\" && git push",
1213
"changelog": "git log --pretty=format:\"1. [**%s - `%h`**](https://github.com/0xGrayy/malwareSniffer/commit/%H)\" > CHANGELOG.md"
14+
=======
15+
"autostart": "cls && npx tsc && node dist/index.js"
16+
>>>>>>> 913bfbc0c48e5bdbb30449cbd1df4b0c0c1ecd09
1317
},
1418
"keywords": [],
1519
"author": "",

src/global.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
1+
<<<<<<< HEAD
12
declare module "cli-progress";
23
declare module "figlet";
4+
=======
5+
declare module "cli-progress";
6+
declare module "figlet";
7+
>>>>>>> 913bfbc0c48e5bdbb30449cbd1df4b0c0c1ecd09

src/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1+
<<<<<<< HEAD
12
import { scanUrl } from "./virusTotal";
23

34
// Example: Scan a URL
45
scanUrl("https://youtube.com/");
6+
=======
7+
import { scanUrl } from "./virusTotal";
8+
9+
// Example: Scan a URL
10+
scanUrl("https://youtube.com/");
11+
>>>>>>> 913bfbc0c48e5bdbb30449cbd1df4b0c0c1ecd09

src/virusTotal.ts

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<<<<<<< HEAD
12
import axios from "axios";
23
import * as dotenv from "dotenv";
34
import chalk from "chalk";
@@ -125,3 +126,132 @@ export async function scanUrl(url: string): Promise<void> {
125126
console.error(chalk.red.bold("❌ Error:"), err.response?.data || err.message);
126127
}
127128
}
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

tsconfig.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<<<<<<< HEAD
12
{
23
"compilerOptions": {
34
"outDir": "./dist",
@@ -8,3 +9,15 @@
89
"esModuleInterop": true
910
}
1011
}
12+
=======
13+
{
14+
"compilerOptions": {
15+
"outDir": "./dist",
16+
"rootDir": "./src",
17+
"module": "CommonJS",
18+
"target": "ESNext",
19+
"strict": true,
20+
"esModuleInterop": true
21+
}
22+
}
23+
>>>>>>> 913bfbc0c48e5bdbb30449cbd1df4b0c0c1ecd09

0 commit comments

Comments
 (0)