├── .erb ├── mocks │ └── fileMock.js ├── img │ └── erb-logo.png ├── configs │ ├── .eslintrc │ ├── webpack.config.eslint.ts │ ├── webpack.paths.ts │ ├── webpack.config.base.ts │ ├── webpack.config.renderer.dev.dll.ts │ ├── webpack.config.preload.dev.ts │ ├── webpack.config.main.prod.ts │ ├── webpack.config.renderer.prod.ts │ └── webpack.config.renderer.dev.ts └── scripts │ ├── .eslintrc │ ├── delete-source-maps.js │ ├── link-modules.ts │ ├── check-node-env.js │ ├── clean.js │ ├── check-port-in-use.js │ ├── electron-rebuild.js │ ├── check-build-exists.ts │ ├── notarize.js │ └── check-native-dep.js ├── src ├── renderer │ ├── components │ │ ├── Charts.css │ │ ├── host │ │ │ ├── actions │ │ │ │ └── handleVulnList.js │ │ │ ├── HostSoftware.js │ │ │ ├── HostServices.js │ │ │ ├── HostOverview.js │ │ │ ├── HostManager.js │ │ │ ├── VulnList.tsx │ │ │ └── NewHost.tsx │ │ ├── VulnPieGraph.js │ │ ├── agent │ │ │ ├── Agent.css │ │ │ ├── TerminalCanvas.js │ │ │ ├── AgentFinder.js │ │ │ └── TerminalPrompt.js │ │ ├── TopRemediations.js │ │ ├── VulnOverTime.js │ │ ├── TopVulns.js │ │ ├── MenuBar.tsx │ │ ├── WindowControls.js │ │ ├── VulnFilter.js │ │ ├── DashCards.js │ │ ├── ToolBar.js │ │ ├── VulnsBySeverity.js │ │ ├── Home.css │ │ └── MenuBar2.js │ ├── preload.d.ts │ ├── index.ejs │ ├── index.tsx │ ├── containers │ │ ├── Main.css │ │ ├── Dashboard.js │ │ ├── Agents.js │ │ └── Hosts.js │ ├── App.css │ ├── Nav.tsx │ ├── actions │ │ └── api │ │ │ └── db.js │ └── App.tsx ├── __tests__ │ └── App.test.tsx └── main │ ├── util.ts │ ├── preload.ts │ ├── main.ts │ └── menu.ts ├── assets ├── icon.icns ├── icon.ico ├── icon.png ├── logo.png ├── icons │ ├── 128x128.png │ ├── 16x16.png │ ├── 24x24.png │ ├── 256x256.png │ ├── 32x32.png │ ├── 48x48.png │ ├── 512x512.png │ ├── 64x64.png │ ├── 96x96.png │ └── 1024x1024.png ├── entitlements.mac.plist ├── assets.d.ts └── icon.svg ├── .husky └── pre-commit ├── .vscode ├── extensions.json ├── settings.json ├── tasks.json └── launch.json ├── .github ├── config.yml ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── 3-Feature_request.md │ ├── 2-Question.md │ └── 1-Bug_report.md ├── stale.yml └── workflows │ ├── test.yml │ └── publish.yml ├── .editorconfig ├── .gitattributes ├── release └── app │ ├── package-lock.json │ └── package.json ├── .gitignore ├── .eslintignore ├── tsconfig.json ├── .eslintrc.js ├── README.md ├── LICENSE ├── CODE_OF_CONDUCT.md ├── package.json └── CHANGELOG.md /.erb/mocks/fileMock.js: -------------------------------------------------------------------------------- 1 | export default 'test-file-stub'; 2 | -------------------------------------------------------------------------------- /src/renderer/components/Charts.css: -------------------------------------------------------------------------------- 1 | .titletext { 2 | color: white; 3 | } 4 | -------------------------------------------------------------------------------- /assets/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icon.icns -------------------------------------------------------------------------------- /assets/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icon.ico -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icon.png -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/logo.png -------------------------------------------------------------------------------- /.erb/img/erb-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/.erb/img/erb-logo.png -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /assets/icons/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/128x128.png -------------------------------------------------------------------------------- /assets/icons/16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/16x16.png -------------------------------------------------------------------------------- /assets/icons/24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/24x24.png -------------------------------------------------------------------------------- /assets/icons/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/256x256.png -------------------------------------------------------------------------------- /assets/icons/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/32x32.png -------------------------------------------------------------------------------- /assets/icons/48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/48x48.png -------------------------------------------------------------------------------- /assets/icons/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/512x512.png -------------------------------------------------------------------------------- /assets/icons/64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/64x64.png -------------------------------------------------------------------------------- /assets/icons/96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/96x96.png -------------------------------------------------------------------------------- /assets/icons/1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/1024x1024.png -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["dbaeumer.vscode-eslint", "EditorConfig.EditorConfig"] 3 | } 4 | -------------------------------------------------------------------------------- /.github/config.yml: -------------------------------------------------------------------------------- 1 | requiredHeaders: 2 | - Prerequisites 3 | - Expected Behavior 4 | - Current Behavior 5 | - Possible Solution 6 | - Your Environment 7 | -------------------------------------------------------------------------------- /.erb/configs/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-console": "off", 4 | "global-require": "off", 5 | "import/no-dynamic-require": "off" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/renderer/components/host/actions/handleVulnList.js: -------------------------------------------------------------------------------- 1 | export async function handleVulnList (vulnList) { 2 | 3 | console.log(vulnList.CVEDataFormat) 4 | 5 | } 6 | -------------------------------------------------------------------------------- /.erb/configs/webpack.config.eslint.ts: -------------------------------------------------------------------------------- 1 | /* eslint import/no-unresolved: off, import/no-self-import: off */ 2 | 3 | module.exports = require('./webpack.config.renderer.dev').default; 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [electron-react-boilerplate, amilajack] 4 | patreon: amilajack 5 | open_collective: electron-react-boilerplate-594 6 | -------------------------------------------------------------------------------- /.erb/scripts/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-console": "off", 4 | "global-require": "off", 5 | "import/no-dynamic-require": "off", 6 | "import/no-extraneous-dependencies": "off" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | *.exe binary 3 | *.png binary 4 | *.jpg binary 5 | *.jpeg binary 6 | *.ico binary 7 | *.icns binary 8 | *.eot binary 9 | *.otf binary 10 | *.ttf binary 11 | *.woff binary 12 | *.woff2 binary 13 | -------------------------------------------------------------------------------- /src/__tests__/App.test.tsx: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom'; 2 | import { render } from '@testing-library/react'; 3 | import App from '../renderer/App'; 4 | 5 | describe('App', () => { 6 | it('should render', () => { 7 | expect(render()).toBeTruthy(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /.erb/scripts/delete-source-maps.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import rimraf from 'rimraf'; 3 | import webpackPaths from '../configs/webpack.paths'; 4 | 5 | export default function deleteSourceMaps() { 6 | rimraf.sync(path.join(webpackPaths.distMainPath, '*.js.map')); 7 | rimraf.sync(path.join(webpackPaths.distRendererPath, '*.js.map')); 8 | } 9 | -------------------------------------------------------------------------------- /release/app/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-react-boilerplate", 3 | "version": "4.5.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "electron-react-boilerplate", 9 | "version": "4.5.0", 10 | "hasInstallScript": true, 11 | "license": "MIT" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.erb/scripts/link-modules.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import webpackPaths from '../configs/webpack.paths'; 3 | 4 | const { srcNodeModulesPath } = webpackPaths; 5 | const { appNodeModulesPath } = webpackPaths; 6 | 7 | if (!fs.existsSync(srcNodeModulesPath) && fs.existsSync(appNodeModulesPath)) { 8 | fs.symlinkSync(appNodeModulesPath, srcNodeModulesPath, 'junction'); 9 | } 10 | -------------------------------------------------------------------------------- /assets/entitlements.mac.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-unsigned-executable-memory 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/renderer/preload.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | interface Window { 3 | electron: { 4 | ipcRenderer: { 5 | myPing(): void; 6 | on( 7 | channel: string, 8 | func: (...args: unknown[]) => void 9 | ): (() => void) | undefined; 10 | once(channel: string, func: (...args: unknown[]) => void): void; 11 | }; 12 | }; 13 | } 14 | } 15 | 16 | export {}; 17 | -------------------------------------------------------------------------------- /src/renderer/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 12 | Sirius Scan 13 | 14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /src/renderer/index.tsx: -------------------------------------------------------------------------------- 1 | import { createRoot } from 'react-dom/client'; 2 | import App from './App'; 3 | 4 | const container = document.getElementById('root')!; 5 | const root = createRoot(container); 6 | root.render(); 7 | 8 | // calling IPC exposed from preload script 9 | window.electron.ipcRenderer.once('ipc-example', (arg) => { 10 | // eslint-disable-next-line no-console 11 | console.log(arg); 12 | }); 13 | window.electron.ipcRenderer.myPing(); 14 | -------------------------------------------------------------------------------- /.erb/scripts/check-node-env.js: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | 3 | export default function checkNodeEnv(expectedEnv) { 4 | if (!expectedEnv) { 5 | throw new Error('"expectedEnv" not set'); 6 | } 7 | 8 | if (process.env.NODE_ENV !== expectedEnv) { 9 | console.log( 10 | chalk.whiteBright.bgRed.bold( 11 | `"process.env.NODE_ENV" must be "${expectedEnv}" to use this webpack config` 12 | ) 13 | ); 14 | process.exit(2); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/3-Feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: You want something added to the boilerplate. 🎉 4 | labels: 'enhancement' 5 | --- 6 | 7 | 16 | -------------------------------------------------------------------------------- /.erb/scripts/clean.js: -------------------------------------------------------------------------------- 1 | import rimraf from 'rimraf'; 2 | import process from 'process'; 3 | import webpackPaths from '../configs/webpack.paths'; 4 | 5 | const args = process.argv.slice(2); 6 | const commandMap = { 7 | dist: webpackPaths.distPath, 8 | release: webpackPaths.releasePath, 9 | dll: webpackPaths.dllPath, 10 | }; 11 | 12 | args.forEach((x) => { 13 | const pathToRemove = commandMap[x]; 14 | if (pathToRemove !== undefined) { 15 | rimraf.sync(pathToRemove); 16 | } 17 | }); 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/2-Question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Ask a question.❓ 4 | labels: 'question' 5 | --- 6 | 7 | ## Summary 8 | 9 | 10 | 11 | 20 | -------------------------------------------------------------------------------- /.erb/scripts/check-port-in-use.js: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | import detectPort from 'detect-port'; 3 | 4 | const port = process.env.PORT || '1212'; 5 | 6 | detectPort(port, (err, availablePort) => { 7 | if (port !== String(availablePort)) { 8 | throw new Error( 9 | chalk.whiteBright.bgRed.bold( 10 | `Port "${port}" on "localhost" is already in use. Please use another port. ex: PORT=4343 npm start` 11 | ) 12 | ); 13 | } else { 14 | process.exit(0); 15 | } 16 | }); 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Coverage directory used by tools like istanbul 11 | coverage 12 | .eslintcache 13 | 14 | # Dependency directory 15 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 16 | node_modules 17 | 18 | # OSX 19 | .DS_Store 20 | 21 | release/app/dist 22 | release/build 23 | .erb/dll 24 | 25 | .idea 26 | npm-debug.log.* 27 | *.css.d.ts 28 | *.sass.d.ts 29 | *.scss.d.ts 30 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Coverage directory used by tools like istanbul 11 | coverage 12 | .eslintcache 13 | 14 | # Dependency directory 15 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 16 | node_modules 17 | 18 | # OSX 19 | .DS_Store 20 | 21 | release/app/dist 22 | release/build 23 | .erb/dll 24 | 25 | .idea 26 | npm-debug.log.* 27 | *.css.d.ts 28 | *.sass.d.ts 29 | *.scss.d.ts 30 | 31 | # eslint ignores hidden directories by default: 32 | # https://github.com/eslint/eslint/issues/8429 33 | !.erb 34 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | ".eslintrc": "jsonc", 4 | ".prettierrc": "jsonc", 5 | ".eslintignore": "ignore" 6 | }, 7 | 8 | "javascript.validate.enable": false, 9 | "javascript.format.enable": false, 10 | "typescript.format.enable": false, 11 | 12 | "search.exclude": { 13 | ".git": true, 14 | ".eslintcache": true, 15 | ".erb/dll": true, 16 | "release/{build,app/dist}": true, 17 | "node_modules": true, 18 | "npm-debug.log.*": true, 19 | "test/**/__snapshots__": true, 20 | "package-lock.json": true, 21 | "*.{css,sass,scss}.d.ts": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /assets/assets.d.ts: -------------------------------------------------------------------------------- 1 | type Styles = Record; 2 | 3 | declare module '*.svg' { 4 | const content: string; 5 | export default content; 6 | } 7 | 8 | declare module '*.png' { 9 | const content: string; 10 | export default content; 11 | } 12 | 13 | declare module '*.jpg' { 14 | const content: string; 15 | export default content; 16 | } 17 | 18 | declare module '*.scss' { 19 | const content: Styles; 20 | export default content; 21 | } 22 | 23 | declare module '*.sass' { 24 | const content: Styles; 25 | export default content; 26 | } 27 | 28 | declare module '*.css' { 29 | const content: Styles; 30 | export default content; 31 | } 32 | -------------------------------------------------------------------------------- /src/main/util.ts: -------------------------------------------------------------------------------- 1 | /* eslint import/prefer-default-export: off, import/no-mutable-exports: off */ 2 | import { URL } from 'url'; 3 | import path from 'path'; 4 | 5 | export let resolveHtmlPath: (htmlFileName: string) => string; 6 | 7 | if (process.env.NODE_ENV === 'development') { 8 | const port = process.env.PORT || 1212; 9 | resolveHtmlPath = (htmlFileName: string) => { 10 | const url = new URL(`http://localhost:${port}`); 11 | url.pathname = htmlFileName; 12 | return url.href; 13 | }; 14 | } else { 15 | resolveHtmlPath = (htmlFileName: string) => { 16 | return `file://${path.resolve(__dirname, '../renderer/', htmlFileName)}`; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "npm", 6 | "label": "Start Webpack Dev", 7 | "script": "start:renderer", 8 | "options": { 9 | "cwd": "${workspaceFolder}" 10 | }, 11 | "isBackground": true, 12 | "problemMatcher": { 13 | "owner": "custom", 14 | "pattern": { 15 | "regexp": "____________" 16 | }, 17 | "background": { 18 | "activeOnStart": true, 19 | "beginsPattern": "Compiling\\.\\.\\.$", 20 | "endsPattern": "(Compiled successfully|Failed to compile)\\.$" 21 | } 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /src/renderer/containers/Main.css: -------------------------------------------------------------------------------- 1 | .maincontainer { 2 | position: relative; 3 | top: 67px; 4 | height: 100vh; 5 | background-color: #333; 6 | width: 100vw; 7 | padding-top: 30px; 8 | } 9 | .maincontent { 10 | padding-left: 65px; 11 | } 12 | .dashbanner { 13 | padding-left: 20px; 14 | padding-right: 20px; 15 | padding-bottom: 50px; 16 | } 17 | .MuiPaper-root.info { 18 | background-color: #7373ba; 19 | color: white; 20 | } 21 | .MuiPaper-root.critical { 22 | background-color: #931717; 23 | color: white; 24 | } 25 | .MuiPaper-root.moderate { 26 | background-color: #87876e; 27 | color: white; 28 | } 29 | .MuiPaper-root.secure { 30 | background-color: #247424; 31 | color: white; 32 | } 33 | -------------------------------------------------------------------------------- /.erb/scripts/electron-rebuild.js: -------------------------------------------------------------------------------- 1 | import { execSync } from 'child_process'; 2 | import fs from 'fs'; 3 | import { dependencies } from '../../release/app/package.json'; 4 | import webpackPaths from '../configs/webpack.paths'; 5 | 6 | if ( 7 | Object.keys(dependencies || {}).length > 0 && 8 | fs.existsSync(webpackPaths.appNodeModulesPath) 9 | ) { 10 | const electronRebuildCmd = 11 | '../../node_modules/.bin/electron-rebuild --force --types prod,dev,optional --module-dir .'; 12 | const cmd = 13 | process.platform === 'win32' 14 | ? electronRebuildCmd.replace(/\//g, '\\') 15 | : electronRebuildCmd; 16 | execSync(cmd, { 17 | cwd: webpackPaths.appPath, 18 | stdio: 'inherit', 19 | }); 20 | } 21 | -------------------------------------------------------------------------------- /release/app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-react-boilerplate", 3 | "version": "4.5.0", 4 | "description": "A foundation for scalable desktop apps", 5 | "main": "./dist/main/main.js", 6 | "author": { 7 | "name": "Electron React Boilerplate Maintainers", 8 | "email": "electronreactboilerplate@gmail.com", 9 | "url": "https://github.com/electron-react-boilerplate" 10 | }, 11 | "scripts": { 12 | "electron-rebuild": "node -r ts-node/register ../../.erb/scripts/electron-rebuild.js", 13 | "link-modules": "node -r ts-node/register ../../.erb/scripts/link-modules.ts", 14 | "postinstall": "npm run electron-rebuild && npm run link-modules" 15 | }, 16 | "dependencies": {}, 17 | "license": "MIT" 18 | } 19 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - discussion 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: wontfix 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2021", 4 | "module": "commonjs", 5 | "lib": ["dom", "es2021"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "jsx": "react-jsx", 9 | "strict": true, 10 | "pretty": true, 11 | "sourceMap": true, 12 | "baseUrl": "./src", 13 | "noUnusedLocals": true, 14 | "noUnusedParameters": true, 15 | "noImplicitReturns": true, 16 | "noFallthroughCasesInSwitch": true, 17 | "moduleResolution": "node", 18 | "esModuleInterop": true, 19 | "allowSyntheticDefaultImports": true, 20 | "resolveJsonModule": true, 21 | "allowJs": true, 22 | "outDir": "release/app/dist" 23 | }, 24 | "exclude": ["test", "release/build", "release/app/dist", ".erb/dll"] 25 | } 26 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Electron: Main", 6 | "type": "node", 7 | "request": "launch", 8 | "protocol": "inspector", 9 | "runtimeExecutable": "npm", 10 | "runtimeArgs": [ 11 | "run start:main --inspect=5858 --remote-debugging-port=9223" 12 | ], 13 | "preLaunchTask": "Start Webpack Dev" 14 | }, 15 | { 16 | "name": "Electron: Renderer", 17 | "type": "chrome", 18 | "request": "attach", 19 | "port": 9223, 20 | "webRoot": "${workspaceFolder}", 21 | "timeout": 15000 22 | } 23 | ], 24 | "compounds": [ 25 | { 26 | "name": "Electron: All", 27 | "configurations": ["Electron: Main", "Electron: Renderer"] 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | release: 7 | runs-on: ${{ matrix.os }} 8 | 9 | strategy: 10 | matrix: 11 | os: [macos-latest, windows-latest, ubuntu-latest] 12 | 13 | steps: 14 | - name: Check out Git repository 15 | uses: actions/checkout@v1 16 | 17 | - name: Install Node.js and NPM 18 | uses: actions/setup-node@v2 19 | with: 20 | node-version: 16 21 | cache: npm 22 | 23 | - name: npm install 24 | run: | 25 | npm install 26 | 27 | - name: npm test 28 | env: 29 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | run: | 31 | npm run package 32 | npm run lint 33 | npm exec tsc 34 | npm test 35 | -------------------------------------------------------------------------------- /.erb/scripts/check-build-exists.ts: -------------------------------------------------------------------------------- 1 | // Check if the renderer and main bundles are built 2 | import path from 'path'; 3 | import chalk from 'chalk'; 4 | import fs from 'fs'; 5 | import webpackPaths from '../configs/webpack.paths'; 6 | 7 | const mainPath = path.join(webpackPaths.distMainPath, 'main.js'); 8 | const rendererPath = path.join(webpackPaths.distRendererPath, 'renderer.js'); 9 | 10 | if (!fs.existsSync(mainPath)) { 11 | throw new Error( 12 | chalk.whiteBright.bgRed.bold( 13 | 'The main process is not built yet. Build it by running "npm run build:main"' 14 | ) 15 | ); 16 | } 17 | 18 | if (!fs.existsSync(rendererPath)) { 19 | throw new Error( 20 | chalk.whiteBright.bgRed.bold( 21 | 'The renderer process is not built yet. Build it by running "npm run build:renderer"' 22 | ) 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /.erb/scripts/notarize.js: -------------------------------------------------------------------------------- 1 | const { notarize } = require('electron-notarize'); 2 | const { build } = require('../../package.json'); 3 | 4 | exports.default = async function notarizeMacos(context) { 5 | const { electronPlatformName, appOutDir } = context; 6 | if (electronPlatformName !== 'darwin') { 7 | return; 8 | } 9 | 10 | if (process.env.CI !== 'true') { 11 | console.warn('Skipping notarizing step. Packaging is not running in CI'); 12 | return; 13 | } 14 | 15 | if (!('APPLE_ID' in process.env && 'APPLE_ID_PASS' in process.env)) { 16 | console.warn( 17 | 'Skipping notarizing step. APPLE_ID and APPLE_ID_PASS env variables must be set' 18 | ); 19 | return; 20 | } 21 | 22 | const appName = context.packager.appInfo.productFilename; 23 | 24 | await notarize({ 25 | appBundleId: build.appId, 26 | appPath: `${appOutDir}/${appName}.app`, 27 | appleId: process.env.APPLE_ID, 28 | appleIdPassword: process.env.APPLE_ID_PASS, 29 | }); 30 | }; 31 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: 'erb', 3 | rules: { 4 | // A temporary hack related to IDE not resolving correct package.json 5 | 'import/no-extraneous-dependencies': 'off', 6 | 'import/no-unresolved': 'error', 7 | // Since React 17 and typescript 4.1 you can safely disable the rule 8 | 'react/react-in-jsx-scope': 'off', 9 | }, 10 | parserOptions: { 11 | ecmaVersion: 2020, 12 | sourceType: 'module', 13 | project: './tsconfig.json', 14 | tsconfigRootDir: __dirname, 15 | createDefaultProgram: true, 16 | }, 17 | settings: { 18 | 'import/resolver': { 19 | // See https://github.com/benmosher/eslint-plugin-import/issues/1396#issuecomment-575727774 for line below 20 | node: {}, 21 | webpack: { 22 | config: require.resolve('./.erb/configs/webpack.config.eslint.ts'), 23 | }, 24 | typescript: {}, 25 | }, 26 | 'import/parsers': { 27 | '@typescript-eslint/parser': ['.ts', '.tsx'], 28 | }, 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sirius Scan 2 | 3 | Sirius is the first truly open-source general purpose vulnerability scanner. Today, the information security community remains the best and most expedient source for cybersecurity intelligence. The community itself regularly outperforms commercial vendors. This is the primary advantage Sirius Scan intends to leverage. 4 | 5 | The framework is built around four general vulnerability identification concepts: The vulnerability database, network vulnerability scanning, agent-based discovery, and custom assessor analysis. With these powers combined around an easy to use interface Sirius hopes to enable industry evolution. 6 | 7 | ## Getting Started 8 | 9 | Sirius is now in Alpha! Wooo! Currently, there is no automatic installation utility (that will be coming with the Beta release). For now, the following guide should help you get started. 10 | 11 | ### Dependencies 12 | 13 | - MongoDB 14 | - NodeJS 15 | - npm 16 | - Go 17 | 18 | ### Sirius UI 19 | 20 | To install the UI clone this repository and instantiate it with npm. 21 | 22 | ``` 23 | npm start 24 | ``` 25 | -------------------------------------------------------------------------------- /src/main/preload.ts: -------------------------------------------------------------------------------- 1 | import { contextBridge, ipcRenderer, IpcRendererEvent } from 'electron'; 2 | 3 | contextBridge.exposeInMainWorld('electron', { 4 | ipcRenderer: { 5 | myPing() { 6 | ipcRenderer.send('ipc-example', 'ping'); 7 | }, 8 | on(channel: string, func: (...args: unknown[]) => void) { 9 | const validChannels = ['ipc-example']; 10 | if (validChannels.includes(channel)) { 11 | const subscription = (_event: IpcRendererEvent, ...args: unknown[]) => 12 | func(...args); 13 | // Deliberately strip event as it includes `sender` 14 | ipcRenderer.on(channel, subscription); 15 | 16 | return () => ipcRenderer.removeListener(channel, subscription); 17 | } 18 | 19 | return undefined; 20 | }, 21 | once(channel: string, func: (...args: unknown[]) => void) { 22 | const validChannels = ['ipc-example']; 23 | if (validChannels.includes(channel)) { 24 | // Deliberately strip event as it includes `sender` 25 | ipcRenderer.once(channel, (_event, ...args) => func(...args)); 26 | } 27 | }, 28 | }, 29 | }); 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-present Electron React Boilerplate 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.erb/configs/webpack.paths.ts: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | const rootPath = path.join(__dirname, '../..'); 4 | 5 | const dllPath = path.join(__dirname, '../dll'); 6 | 7 | const srcPath = path.join(rootPath, 'src'); 8 | const srcMainPath = path.join(srcPath, 'main'); 9 | const srcRendererPath = path.join(srcPath, 'renderer'); 10 | 11 | const releasePath = path.join(rootPath, 'release'); 12 | const appPath = path.join(releasePath, 'app'); 13 | const appPackagePath = path.join(appPath, 'package.json'); 14 | const appNodeModulesPath = path.join(appPath, 'node_modules'); 15 | const srcNodeModulesPath = path.join(srcPath, 'node_modules'); 16 | 17 | const distPath = path.join(appPath, 'dist'); 18 | const distMainPath = path.join(distPath, 'main'); 19 | const distRendererPath = path.join(distPath, 'renderer'); 20 | 21 | const buildPath = path.join(releasePath, 'build'); 22 | 23 | export default { 24 | rootPath, 25 | dllPath, 26 | srcPath, 27 | srcMainPath, 28 | srcRendererPath, 29 | releasePath, 30 | appPath, 31 | appPackagePath, 32 | appNodeModulesPath, 33 | srcNodeModulesPath, 34 | distPath, 35 | distMainPath, 36 | distRendererPath, 37 | buildPath, 38 | }; 39 | -------------------------------------------------------------------------------- /src/renderer/App.css: -------------------------------------------------------------------------------- 1 | /* 2 | * @NOTE: Prepend a `~` to css file paths that are in your node_modules 3 | * See https://github.com/webpack-contrib/sass-loader#imports 4 | */ 5 | body { 6 | position: relative; 7 | color: white; 8 | height: 100vh; 9 | font-family: sans-serif; 10 | overflow-y: hidden; 11 | display: flex; 12 | justify-content: center; 13 | align-items: center; 14 | } 15 | 16 | button { 17 | background-color: white; 18 | padding: 10px 20px; 19 | border-radius: 10px; 20 | border: none; 21 | appearance: none; 22 | font-size: 1.3rem; 23 | box-shadow: 0px 8px 28px -6px rgba(24, 39, 75, 0.12), 24 | 0px 18px 88px -4px rgba(24, 39, 75, 0.14); 25 | transition: all ease-in 0.1s; 26 | cursor: pointer; 27 | opacity: 0.9; 28 | } 29 | 30 | button:hover { 31 | transform: scale(1.05); 32 | opacity: 1; 33 | } 34 | 35 | li { 36 | list-style: none; 37 | } 38 | 39 | a { 40 | text-decoration: none; 41 | height: fit-content; 42 | width: fit-content; 43 | margin: 10px; 44 | } 45 | 46 | a:hover { 47 | opacity: 1; 48 | text-decoration: none; 49 | } 50 | 51 | .Hello { 52 | display: flex; 53 | justify-content: center; 54 | align-items: center; 55 | margin: 20px 0; 56 | } 57 | -------------------------------------------------------------------------------- /src/renderer/Nav.tsx: -------------------------------------------------------------------------------- 1 | import { MemoryRouter as Router, Routes, Route } from 'react-router-dom'; 2 | import icon from '../../assets/icon.svg'; 3 | import './App.css'; 4 | 5 | const Hello = () => { 6 | return ( 7 |
8 |
9 | icon 10 |
11 |

sutff

12 |
13 | 18 | 24 | 25 | 30 | 36 | 37 |
38 |
39 | ); 40 | }; 41 | 42 | export default function App() { 43 | return ( 44 | 45 | 46 | } /> 47 | 48 | 49 | ); 50 | } 51 | -------------------------------------------------------------------------------- /.erb/configs/webpack.config.base.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Base webpack config used across other specific configs 3 | */ 4 | 5 | import webpack from 'webpack'; 6 | import webpackPaths from './webpack.paths'; 7 | import { dependencies as externals } from '../../release/app/package.json'; 8 | 9 | const configuration: webpack.Configuration = { 10 | externals: [...Object.keys(externals || {})], 11 | 12 | stats: 'errors-only', 13 | 14 | module: { 15 | rules: [ 16 | { 17 | test: /\.[jt]sx?$/, 18 | exclude: /node_modules/, 19 | use: { 20 | loader: 'ts-loader', 21 | options: { 22 | // Remove this line to enable type checking in webpack builds 23 | transpileOnly: true, 24 | }, 25 | }, 26 | }, 27 | ], 28 | }, 29 | 30 | output: { 31 | path: webpackPaths.srcPath, 32 | // https://github.com/webpack/webpack/issues/1114 33 | library: { 34 | type: 'commonjs2', 35 | }, 36 | }, 37 | 38 | /** 39 | * Determine the array of extensions that should be used to resolve modules. 40 | */ 41 | resolve: { 42 | extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'], 43 | modules: [webpackPaths.srcPath, 'node_modules'], 44 | }, 45 | 46 | plugins: [ 47 | new webpack.EnvironmentPlugin({ 48 | NODE_ENV: 'production', 49 | }), 50 | ], 51 | }; 52 | 53 | export default configuration; 54 | -------------------------------------------------------------------------------- /src/renderer/components/VulnPieGraph.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | import { PieChart, Pie, Sector, Cell, Label } from 'recharts'; 5 | 6 | class VulnPieGraph extends React.Component { 7 | //props: Props; 8 | 9 | constructor(props) { 10 | super(props); 11 | 12 | this.state = { 13 | open: false 14 | }; 15 | } 16 | 17 | 18 | render() { 19 | const data = [ 20 | { name: 'Group A', value: 400 }, 21 | { name: 'Group B', value: 100 }, 22 | { name: 'Group C', value: 300 }, 23 | { name: 'Group D', value: 500 }, 24 | ]; 25 | const COLORS = ['#0088FE', 'red', '#FFBB28', '#FF8042']; 26 | 27 | return ( 28 | 29 | 39 | 44 | 45 | ); 46 | } 47 | } 48 | 49 | export default VulnPieGraph; 50 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | publish: 10 | # To enable auto publishing to github, update your electron publisher 11 | # config in package.json > "build" and remove the conditional below 12 | if: ${{ github.repository_owner == 'electron-react-boilerplate' }} 13 | 14 | runs-on: ${{ matrix.os }} 15 | 16 | strategy: 17 | matrix: 18 | os: [macos-latest] 19 | 20 | steps: 21 | - name: Checkout git repo 22 | uses: actions/checkout@v1 23 | 24 | - name: Install Node and NPM 25 | uses: actions/setup-node@v1 26 | with: 27 | node-version: 16 28 | cache: npm 29 | 30 | - name: Install dependencies 31 | run: | 32 | npm install 33 | 34 | - name: Publish releases 35 | env: 36 | # These values are used for auto updates signing 37 | APPLE_ID: ${{ secrets.APPLE_ID }} 38 | APPLE_ID_PASS: ${{ secrets.APPLE_ID_PASS }} 39 | CSC_LINK: ${{ secrets.CSC_LINK }} 40 | CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }} 41 | # This is used for uploading release assets to github 42 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 43 | run: | 44 | npm run postinstall 45 | npm run build 46 | npm exec electron-builder -- --publish always --win --mac --linux 47 | -------------------------------------------------------------------------------- /src/renderer/components/agent/Agent.css: -------------------------------------------------------------------------------- 1 | .terminalprompt { 2 | position: fixed; 3 | bottom: -10px; 4 | left: 65px; 5 | background-color: black; 6 | padding: 15px; 7 | min-height: 15px; 8 | color: yellow; 9 | width: 100vw; 10 | font-family: monospace; 11 | font-size: 22px; 12 | } 13 | .terminaldressing { 14 | position: fixed; 15 | bottom: 59px; 16 | left: 65px; 17 | padding-bottom: 2px; 18 | margin-bottom: 3px; 19 | background-color: #0080ff; 20 | border-top: 1px solid white; 21 | color: #fff; 22 | width: 100vw; 23 | font-family: monospace; 24 | } 25 | .terminalprompt input { 26 | color: white; 27 | font-family: monospace; 28 | font-size: 22px; 29 | } 30 | .terminalcanvas { 31 | position: fixed; 32 | color: white; 33 | height: 800px; 34 | bottom: 80px; 35 | left: 85px; 36 | font-family: monospace; 37 | font-size: 22px; 38 | overflow: scroll; 39 | } 40 | .terminalbg { 41 | position: relative; 42 | left: 50px; 43 | bottom: 160px; 44 | background-color: rgb(35 33 33); 45 | opacity: .4; 46 | z-index: -1; 47 | } 48 | .commandoutput { 49 | font-size: 16px; 50 | } 51 | .terminalcontainer { 52 | position: relative; 53 | min-width: 100vw; 54 | height: 100vh; 55 | background-color: rgb(21 21 21); 56 | } 57 | .terminalbody { 58 | position: absolute; 59 | left: 65px; 60 | min-height: 100vh; 61 | } 62 | .terminalblock{ 63 | position: relative; 64 | min-width: 80vw; 65 | z-index: 10; 66 | } 67 | .terminalheader { 68 | position: absolute; 69 | top: 90px; 70 | z-index: 100; 71 | } 72 | -------------------------------------------------------------------------------- /src/renderer/components/host/HostSoftware.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import Paper from '@mui/material/Paper'; 6 | import Card from '@mui/material/Card'; 7 | import CardActions from '@mui/material/CardActions'; 8 | import CardContent from '@mui/material/CardContent'; 9 | import Typography from '@mui/material/Typography'; 10 | 11 | import Chip from '@mui/material/Chip'; 12 | import Autocomplete from '@mui/material/Autocomplete'; 13 | import TextField from '@mui/material/TextField'; 14 | import Stack from '@mui/material/Stack'; 15 | 16 | import Security from '@mui/icons-material/Security'; 17 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 18 | import { faWindows } from '@fortawesome/free-brands-svg-icons'; 19 | 20 | import '../Home.css'; 21 | 22 | class HostOverview extends React.Component { 23 | //props: Props; 24 | 25 | constructor(props) { 26 | super(props); 27 | 28 | this.state = { 29 | open: false 30 | }; 31 | } 32 | 33 | 34 | render() { 35 | return ( 36 |
37 | 38 | 39 | 40 | Software 41 |
42 |
43 | 44 | 45 | Struts 2.3 46 | 47 |
48 |
49 |
50 | ); 51 | } 52 | } 53 | 54 | export default HostOverview; 55 | -------------------------------------------------------------------------------- /src/renderer/components/host/HostServices.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import Paper from '@mui/material/Paper'; 6 | import Card from '@mui/material/Card'; 7 | import CardActions from '@mui/material/CardActions'; 8 | import CardContent from '@mui/material/CardContent'; 9 | import Typography from '@mui/material/Typography'; 10 | 11 | import Chip from '@mui/material/Chip'; 12 | import Autocomplete from '@mui/material/Autocomplete'; 13 | import TextField from '@mui/material/TextField'; 14 | import Stack from '@mui/material/Stack'; 15 | 16 | import Security from '@mui/icons-material/Security'; 17 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 18 | import { faWindows } from '@fortawesome/free-brands-svg-icons'; 19 | 20 | import '../Home.css'; 21 | 22 | class HostOverview extends React.Component { 23 | //props: Props; 24 | 25 | constructor(props) { 26 | super(props); 27 | 28 | this.state = { 29 | open: false 30 | }; 31 | } 32 | 33 | 34 | render() { 35 | return ( 36 |
37 | 38 | 39 | 40 | Services 41 |
42 |
43 | 44 | 45 | Apache 2.4.1 46 | 47 |
48 |
49 |
50 | ); 51 | } 52 | } 53 | 54 | export default HostOverview; 55 | -------------------------------------------------------------------------------- /src/renderer/components/TopRemediations.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import Paper from '@mui/material/Paper'; 6 | import Card from '@mui/material/Card'; 7 | import CardActions from '@mui/material/CardActions'; 8 | import CardContent from '@mui/material/CardContent'; 9 | import Typography from '@mui/material/Typography'; 10 | 11 | import './Home.css'; 12 | 13 | class TopRemediations extends React.Component { 14 | //props: Props; 15 | 16 | constructor(props) { 17 | super(props); 18 | 19 | this.state = { 20 | open: false 21 | }; 22 | } 23 | 24 | 25 | render() { 26 | return ( 27 |
28 | 29 | 30 | 31 | Top Remediations 32 |
33 |
34 | 35 | 1 - Microsoft Windows Cumultive Updates 36 | 37 |
38 | 39 | 2 - Wordpress Updates 40 | 41 |
42 | 43 | 3 - Apache Webserver Update 44 | 45 |
46 |
47 |
48 |
49 | ); 50 | } 51 | } 52 | 53 | export default TopRemediations; 54 | -------------------------------------------------------------------------------- /src/renderer/components/VulnOverTime.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts'; 5 | 6 | class VulnOverTime extends React.Component { 7 | //props: Props; 8 | 9 | constructor(props) { 10 | super(props); 11 | 12 | this.state = { 13 | open: false 14 | }; 15 | } 16 | 17 | 18 | render() { 19 | const data = [ 20 | { 21 | name: '', 22 | uv: 4000, 23 | pv: 2400, 24 | amt: 2400, 25 | }, 26 | { 27 | name: '', 28 | uv: 3000, 29 | pv: 1398, 30 | amt: 2210, 31 | }, 32 | { 33 | name: '', 34 | uv: 2000, 35 | pv: 9800, 36 | amt: 2290, 37 | }, 38 | { 39 | name: '', 40 | uv: 2780, 41 | pv: 3908, 42 | amt: 2000, 43 | }, 44 | { 45 | name: '', 46 | uv: 1890, 47 | pv: 4800, 48 | amt: 2181, 49 | }, 50 | { 51 | name: '', 52 | uv: 2390, 53 | pv: 3800, 54 | amt: 2500, 55 | }, 56 | { 57 | name: '', 58 | uv: 3490, 59 | pv: 4300, 60 | amt: 2100, 61 | }, 62 | { 63 | name: '', 64 | uv: 1490, 65 | pv: 2300, 66 | amt: 1100, 67 | }, 68 | ]; 69 | 70 | return ( 71 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | ); 89 | } 90 | } 91 | 92 | export default VulnOverTime; 93 | -------------------------------------------------------------------------------- /src/renderer/components/TopVulns.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import Paper from '@mui/material/Paper'; 6 | import Card from '@mui/material/Card'; 7 | import CardActions from '@mui/material/CardActions'; 8 | import CardContent from '@mui/material/CardContent'; 9 | import Typography from '@mui/material/Typography'; 10 | 11 | import './Home.css'; 12 | 13 | class TopVulns extends React.Component { 14 | //props: Props; 15 | 16 | constructor(props) { 17 | super(props); 18 | 19 | this.state = { 20 | open: false 21 | }; 22 | } 23 | 24 | 25 | render() { 26 | return ( 27 |
28 | 29 | 30 | 31 | Top Vulnerabilities 32 |
33 |
34 | 35 | 5 - CVE-2017-0145 - Remote Code Execution 36 | 37 |
38 | 39 | 2 - CVE-2020-8196 - Application Delivery Controller (ADC), Gateway, and SDWAN WANOP 40 | 41 |
42 | 43 | 78 - CVE-2021-38647 - Microsoft Azure Open Management Infrastructure (OMI) Remote Code Execution Vulnerability 44 | 45 |
46 | 47 | 13 - CVE-2021-34473 - Microsoft Exchange Server Remote Code Execution Vulnerability 48 | 49 |
50 |
51 |
52 |
53 | ); 54 | } 55 | } 56 | 57 | export default TopVulns; 58 | -------------------------------------------------------------------------------- /.erb/configs/webpack.config.renderer.dev.dll.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Builds the DLL for development electron renderer process 3 | */ 4 | 5 | import webpack from 'webpack'; 6 | import path from 'path'; 7 | import { merge } from 'webpack-merge'; 8 | import baseConfig from './webpack.config.base'; 9 | import webpackPaths from './webpack.paths'; 10 | import { dependencies } from '../../package.json'; 11 | import checkNodeEnv from '../scripts/check-node-env'; 12 | 13 | checkNodeEnv('development'); 14 | 15 | const dist = webpackPaths.dllPath; 16 | 17 | const configuration: webpack.Configuration = { 18 | context: webpackPaths.rootPath, 19 | 20 | devtool: 'eval', 21 | 22 | mode: 'development', 23 | 24 | target: 'electron-renderer', 25 | 26 | externals: ['fsevents', 'crypto-browserify'], 27 | 28 | /** 29 | * Use `module` from `webpack.config.renderer.dev.js` 30 | */ 31 | module: require('./webpack.config.renderer.dev').default.module, 32 | 33 | entry: { 34 | renderer: Object.keys(dependencies || {}), 35 | }, 36 | 37 | output: { 38 | path: dist, 39 | filename: '[name].dev.dll.js', 40 | library: { 41 | name: 'renderer', 42 | type: 'var', 43 | }, 44 | }, 45 | 46 | plugins: [ 47 | new webpack.DllPlugin({ 48 | path: path.join(dist, '[name].json'), 49 | name: '[name]', 50 | }), 51 | 52 | /** 53 | * Create global constants which can be configured at compile time. 54 | * 55 | * Useful for allowing different behaviour between development builds and 56 | * release builds 57 | * 58 | * NODE_ENV should be production so that modules do not perform certain 59 | * development checks 60 | */ 61 | new webpack.EnvironmentPlugin({ 62 | NODE_ENV: 'development', 63 | }), 64 | 65 | new webpack.LoaderOptionsPlugin({ 66 | debug: true, 67 | options: { 68 | context: webpackPaths.srcPath, 69 | output: { 70 | path: webpackPaths.dllPath, 71 | }, 72 | }, 73 | }), 74 | ], 75 | }; 76 | 77 | export default merge(baseConfig, configuration); 78 | -------------------------------------------------------------------------------- /src/renderer/actions/api/db.js: -------------------------------------------------------------------------------- 1 | export async function getHosts() { 2 | try { 3 | const response = await fetch('http://localhost:8080/api/get/hosts'); 4 | return await response.json(); 5 | } catch (error) { 6 | return []; 7 | } 8 | } 9 | 10 | export async function getVendors() { 11 | try { 12 | const response = await fetch('http://localhost:8080/api/data/cpe_vendors'); 13 | return await response.json(); 14 | } catch (error) { 15 | return []; 16 | } 17 | } 18 | 19 | export async function addHost(data) { 20 | try { 21 | const response = await fetch(`http://localhost:8080/api/add/host`, { 22 | method: 'POST', 23 | mode: 'same-origin', 24 | headers: { 'Content-Type': 'application/json' }, 25 | body: JSON.stringify(data), 26 | }); 27 | return await response.json(); 28 | } catch (error) { 29 | return []; 30 | } 31 | } 32 | 33 | export async function taskAgent(data) { 34 | try { 35 | const response = await fetch(`http://localhost:8080/api/agent/task`, { 36 | method: 'POST', 37 | mode: 'same-origin', 38 | headers: { 'Content-Type': 'application/json' }, 39 | body: JSON.stringify(data), 40 | }); 41 | return await response.json(); 42 | } catch (error) { 43 | return []; 44 | } 45 | } 46 | 47 | export async function getTerminalHistory(data) { 48 | try { 49 | const response = await fetch( 50 | `http://localhost:8080/api/data/terminalhistory`, 51 | { 52 | method: 'POST', 53 | mode: 'same-origin', 54 | headers: { 'Content-Type': 'application/json' }, 55 | body: JSON.stringify(data), 56 | } 57 | ); 58 | return await response.json(); 59 | } catch (error) { 60 | return []; 61 | } 62 | } 63 | 64 | export async function getVulnerabilityList(data) { 65 | try { 66 | const response = await fetch(`http://localhost:8080/api/svdb/report/host`, { 67 | method: 'POST', 68 | mode: 'same-origin', 69 | headers: { 'Content-Type': 'application/json' }, 70 | body: JSON.stringify(data), 71 | }); 72 | return await response.json(); 73 | } catch (error) { 74 | return []; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/renderer/components/MenuBar.tsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 6 | import { faWallet, faIndustry, faTerminal, faScroll, faBars, faBug, faKey, faServer, faRadiation, faHeadphones, faTable, faDragon } from '@fortawesome/free-solid-svg-icons'; 7 | import ReactTooltip from 'react-tooltip'; 8 | 9 | import Button from '@mui/material/Button'; 10 | import Avatar from '@mui/material/Avatar'; 11 | import Tabs from '@mui/material/Tabs'; 12 | 13 | 14 | import './Home.css'; 15 | import logo from '/assets/logo.png'; 16 | 17 | 18 | 19 | class MenuBar extends React.Component { 20 | props: Props; 21 | 22 | constructor(props) { 23 | super(props); 24 | 25 | this.state = { 26 | open: false 27 | }; 28 | } 29 | 30 | 31 | render() { 32 | return ( 33 |
34 |
35 | 36 | 37 |
38 |
39 | 40 |
41 |
42 | Dashboard 43 |
44 |
45 | Hosts 46 |
47 |
48 | Vulnerabilities 49 |
50 |
51 | Agents 52 |
53 |
54 | Scans 55 |
56 |
57 | 58 |
59 |
60 | M 61 |
62 |
63 | 64 |
65 |
66 |
67 | ); 68 | } 69 | } 70 | 71 | export default MenuBar; 72 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/1-Bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: You're having technical issues. 🐞 4 | labels: 'bug' 5 | --- 6 | 7 | 8 | 9 | ## Prerequisites 10 | 11 | 12 | 13 | - [ ] Using npm 14 | - [ ] Using an up-to-date [`main` branch](https://github.com/electron-react-boilerplate/electron-react-boilerplate/tree/main) 15 | - [ ] Using latest version of devtools. [Check the docs for how to update](https://electron-react-boilerplate.js.org/docs/dev-tools/) 16 | - [ ] Tried solutions mentioned in [#400](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/400) 17 | - [ ] For issue in production release, add devtools output of `DEBUG_PROD=true npm run build && npm start` 18 | 19 | ## Expected Behavior 20 | 21 | 22 | 23 | ## Current Behavior 24 | 25 | 26 | 27 | ## Steps to Reproduce 28 | 29 | 30 | 31 | 32 | 1. 33 | 34 | 2. 35 | 36 | 3. 37 | 38 | 4. 39 | 40 | ## Possible Solution (Not obligatory) 41 | 42 | 43 | 44 | ## Context 45 | 46 | 47 | 48 | 49 | 50 | ## Your Environment 51 | 52 | 53 | 54 | - Node version : 55 | - electron-react-boilerplate version or branch : 56 | - Operating System and version : 57 | - Link to your project : 58 | 59 | 68 | -------------------------------------------------------------------------------- /.erb/configs/webpack.config.preload.dev.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import webpack from 'webpack'; 3 | import { merge } from 'webpack-merge'; 4 | import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; 5 | import baseConfig from './webpack.config.base'; 6 | import webpackPaths from './webpack.paths'; 7 | import checkNodeEnv from '../scripts/check-node-env'; 8 | 9 | // When an ESLint server is running, we can't set the NODE_ENV so we'll check if it's 10 | // at the dev webpack config is not accidentally run in a production environment 11 | if (process.env.NODE_ENV === 'production') { 12 | checkNodeEnv('development'); 13 | } 14 | 15 | const configuration: webpack.Configuration = { 16 | devtool: 'inline-source-map', 17 | 18 | mode: 'development', 19 | 20 | target: 'electron-preload', 21 | 22 | entry: path.join(webpackPaths.srcMainPath, 'preload.ts'), 23 | 24 | output: { 25 | path: webpackPaths.dllPath, 26 | filename: 'preload.js', 27 | }, 28 | 29 | plugins: [ 30 | new BundleAnalyzerPlugin({ 31 | analyzerMode: process.env.ANALYZE === 'true' ? 'server' : 'disabled', 32 | }), 33 | 34 | /** 35 | * Create global constants which can be configured at compile time. 36 | * 37 | * Useful for allowing different behaviour between development builds and 38 | * release builds 39 | * 40 | * NODE_ENV should be production so that modules do not perform certain 41 | * development checks 42 | * 43 | * By default, use 'development' as NODE_ENV. This can be overriden with 44 | * 'staging', for example, by changing the ENV variables in the npm scripts 45 | */ 46 | new webpack.EnvironmentPlugin({ 47 | NODE_ENV: 'development', 48 | }), 49 | 50 | new webpack.LoaderOptionsPlugin({ 51 | debug: true, 52 | }), 53 | ], 54 | 55 | /** 56 | * Disables webpack processing of __dirname and __filename. 57 | * If you run the bundle in node.js it falls back to these values of node.js. 58 | * https://github.com/webpack/webpack/issues/2010 59 | */ 60 | node: { 61 | __dirname: false, 62 | __filename: false, 63 | }, 64 | 65 | watch: true, 66 | }; 67 | 68 | export default merge(baseConfig, configuration); 69 | -------------------------------------------------------------------------------- /.erb/scripts/check-native-dep.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import chalk from 'chalk'; 3 | import { execSync } from 'child_process'; 4 | import { dependencies } from '../../package.json'; 5 | 6 | if (dependencies) { 7 | const dependenciesKeys = Object.keys(dependencies); 8 | const nativeDeps = fs 9 | .readdirSync('node_modules') 10 | .filter((folder) => fs.existsSync(`node_modules/${folder}/binding.gyp`)); 11 | if (nativeDeps.length === 0) { 12 | process.exit(0); 13 | } 14 | try { 15 | // Find the reason for why the dependency is installed. If it is installed 16 | // because of a devDependency then that is okay. Warn when it is installed 17 | // because of a dependency 18 | const { dependencies: dependenciesObject } = JSON.parse( 19 | execSync(`npm ls ${nativeDeps.join(' ')} --json`).toString() 20 | ); 21 | const rootDependencies = Object.keys(dependenciesObject); 22 | const filteredRootDependencies = rootDependencies.filter((rootDependency) => 23 | dependenciesKeys.includes(rootDependency) 24 | ); 25 | if (filteredRootDependencies.length > 0) { 26 | const plural = filteredRootDependencies.length > 1; 27 | console.log(` 28 | ${chalk.whiteBright.bgYellow.bold( 29 | 'Webpack does not work with native dependencies.' 30 | )} 31 | ${chalk.bold(filteredRootDependencies.join(', '))} ${ 32 | plural ? 'are native dependencies' : 'is a native dependency' 33 | } and should be installed inside of the "./release/app" folder. 34 | First, uninstall the packages from "./package.json": 35 | ${chalk.whiteBright.bgGreen.bold('npm uninstall your-package')} 36 | ${chalk.bold( 37 | 'Then, instead of installing the package to the root "./package.json":' 38 | )} 39 | ${chalk.whiteBright.bgRed.bold('npm install your-package')} 40 | ${chalk.bold('Install the package to "./release/app/package.json"')} 41 | ${chalk.whiteBright.bgGreen.bold( 42 | 'cd ./release/app && npm install your-package' 43 | )} 44 | Read more about native dependencies at: 45 | ${chalk.bold( 46 | 'https://electron-react-boilerplate.js.org/docs/adding-dependencies/#module-structure' 47 | )} 48 | `); 49 | process.exit(1); 50 | } 51 | } catch (e) { 52 | console.log('Native dependencies could not be checked'); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/renderer/components/agent/TerminalCanvas.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { useRef, useEffect, Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import Grid from '@mui/material/Grid'; 6 | import Input from '@mui/material/Input'; 7 | import FormControl from '@mui/material/FormControl'; 8 | 9 | import './Agent.css'; 10 | 11 | 12 | 13 | class TerminalCanvas extends React.Component { 14 | //props: Props; 15 | 16 | constructor(props) { 17 | super(props); 18 | 19 | this.state = { 20 | open: false, 21 | 22 | }; 23 | 24 | } 25 | decodeB64(str) { 26 | let base64ToString = "" 27 | try { 28 | base64ToString = atob(str) 29 | } catch(e) { 30 | console.log(e) 31 | } 32 | 33 | if (base64ToString != "") { 34 | return ( 35 |
36 |           {base64ToString}
37 |         
38 | ) 39 | } 40 | } 41 | encodeB64(str) { 42 | let base64ToString = "" 43 | try { 44 | base64ToString = atob(str) 45 | } catch(e) { 46 | console.log(e) 47 | } 48 | 49 | if (base64ToString != "") { 50 | return ( 51 | 52 | {base64ToString} 53 | 54 | ) 55 | } 56 | } 57 | 58 | render() { 59 | const results = []; 60 | var i = 0 61 | this.props.terminalHistory?.forEach(command => { 62 | if (i > 0) { 63 | results.push ( 64 |
65 | 66 | ({command.IP}){'>'} {this.encodeB64(command.Command)} 67 |
68 | {this.decodeB64(command.Result)} 69 |
70 | ); 71 | } 72 | i++ 73 | }) 74 | return ( 75 |
76 | {results} 77 | 78 | 79 | 80 |
81 | ); 82 | } 83 | } 84 | const AlwaysScrollToBottom = (term) => { 85 | const bottomRef = useRef(null); 86 | useEffect(() => { 87 | // 👇️ scroll to bottom every time messages change 88 | bottomRef.current?.scrollIntoView({behavior: 'smooth', block: 'end', inline: 'end'}); 89 | }, [term]); 90 | return
; 91 | }; 92 | 93 | export default TerminalCanvas; 94 | -------------------------------------------------------------------------------- /.erb/configs/webpack.config.main.prod.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Webpack config for production electron main process 3 | */ 4 | 5 | import path from 'path'; 6 | import webpack from 'webpack'; 7 | import { merge } from 'webpack-merge'; 8 | import TerserPlugin from 'terser-webpack-plugin'; 9 | import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; 10 | import baseConfig from './webpack.config.base'; 11 | import webpackPaths from './webpack.paths'; 12 | import checkNodeEnv from '../scripts/check-node-env'; 13 | import deleteSourceMaps from '../scripts/delete-source-maps'; 14 | 15 | checkNodeEnv('production'); 16 | deleteSourceMaps(); 17 | 18 | const devtoolsConfig = 19 | process.env.DEBUG_PROD === 'true' 20 | ? { 21 | devtool: 'source-map', 22 | } 23 | : {}; 24 | 25 | const configuration: webpack.Configuration = { 26 | ...devtoolsConfig, 27 | 28 | mode: 'production', 29 | 30 | target: 'electron-main', 31 | 32 | entry: { 33 | main: path.join(webpackPaths.srcMainPath, 'main.ts'), 34 | preload: path.join(webpackPaths.srcMainPath, 'preload.ts'), 35 | }, 36 | 37 | output: { 38 | path: webpackPaths.distMainPath, 39 | filename: '[name].js', 40 | }, 41 | 42 | optimization: { 43 | minimizer: [ 44 | new TerserPlugin({ 45 | parallel: true, 46 | }), 47 | ], 48 | }, 49 | 50 | plugins: [ 51 | new BundleAnalyzerPlugin({ 52 | analyzerMode: process.env.ANALYZE === 'true' ? 'server' : 'disabled', 53 | }), 54 | 55 | /** 56 | * Create global constants which can be configured at compile time. 57 | * 58 | * Useful for allowing different behaviour between development builds and 59 | * release builds 60 | * 61 | * NODE_ENV should be production so that modules do not perform certain 62 | * development checks 63 | */ 64 | new webpack.EnvironmentPlugin({ 65 | NODE_ENV: 'production', 66 | DEBUG_PROD: false, 67 | START_MINIMIZED: false, 68 | }), 69 | ], 70 | 71 | /** 72 | * Disables webpack processing of __dirname and __filename. 73 | * If you run the bundle in node.js it falls back to these values of node.js. 74 | * https://github.com/webpack/webpack/issues/2010 75 | */ 76 | node: { 77 | __dirname: false, 78 | __filename: false, 79 | }, 80 | }; 81 | 82 | export default merge(baseConfig, configuration); 83 | -------------------------------------------------------------------------------- /src/renderer/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { MemoryRouter as Router, Routes, Route } from 'react-router-dom'; 3 | import icon from '../../assets/icon.svg'; 4 | 5 | import { styled, createTheme, ThemeProvider } from '@mui/material/styles'; 6 | import { green, purple } from '@mui/material/colors'; 7 | 8 | import './App.css'; 9 | 10 | import Dashboard from './containers/Dashboard'; 11 | import Hosts from './containers/Hosts'; 12 | import Agents from './containers/Agents'; 13 | 14 | import MenuBar from './components/MenuBar'; 15 | import ToolBar from './components/ToolBar'; 16 | 17 | 18 | class Main extends React.Component { 19 | //props: Props; 20 | 21 | constructor(props) { 22 | super(props); 23 | 24 | this.state = { 25 | dashboard: true, 26 | hosts: false, 27 | agents: false, 28 | }; 29 | this.disableViews = this.disableViews.bind(this) 30 | this.toggleDashView = this.toggleDashView.bind(this) 31 | this.toggleHostsView = this.toggleHostsView.bind(this) 32 | this.toggleAgentsView = this.toggleAgentsView.bind(this) 33 | 34 | } 35 | 36 | disableViews() { 37 | this.setState({ 38 | dashboard: false, 39 | hosts: false, 40 | agents: false 41 | }); 42 | } 43 | 44 | toggleDashView() { 45 | this.disableViews() 46 | this.setState({ 47 | dashboard: true 48 | }); 49 | } 50 | toggleHostsView() { 51 | this.disableViews() 52 | this.setState({ 53 | hosts: true 54 | }); 55 | } 56 | toggleAgentsView() { 57 | this.disableViews() 58 | this.setState({ 59 | agents: true 60 | }); 61 | } 62 | 63 | 64 | render() { 65 | return ( 66 |
67 | 68 | 73 | { this.state.dashboard ? : null } 74 | { this.state.hosts ? : null } 75 | { this.state.agents ? : null } 76 |
77 | ); 78 | } 79 | } 80 | 81 | export default function App() { 82 | 83 | return ( 84 | 85 | 86 | } /> 87 | 88 | 89 | ); 90 | } 91 | -------------------------------------------------------------------------------- /src/renderer/components/WindowControls.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import styles from './Home.css'; 6 | 7 | const remote = require('electron').remote; 8 | const {BrowserWindow} = require('electron').remote 9 | 10 | //const ElectronTitlebarWindows = require('electron-titlebar-windows'); 11 | 12 | type Props = { 13 | increment: () => void, 14 | incrementIfOdd: () => void, 15 | incrementAsync: () => void, 16 | decrement: () => void, 17 | counter: number 18 | }; 19 | 20 | export default class WindowControls extends Component { 21 | props: Props; 22 | 23 | windowMaximize() { 24 | var window = BrowserWindow.getFocusedWindow(); 25 | if(window.isMaximized()) { 26 | window.unmaximize(); 27 | } else{ 28 | window.maximize(); 29 | } 30 | } 31 | windowMinimize() { 32 | var window = BrowserWindow.getFocusedWindow(); 33 | window.minimize(); 34 | } 35 | windowClose() { 36 | var window = BrowserWindow.getFocusedWindow(); 37 | window.close(); 38 | } 39 | 40 | render() { 41 | const { 42 | increment, 43 | incrementIfOdd, 44 | incrementAsync, 45 | decrement, 46 | counter 47 | } = this.props; 48 | return ( 49 |
50 |
Prismatica | Diagon UI
51 |
52 |
53 | 54 | 55 | 56 |
57 |
58 | 59 | 60 | 61 |
62 |
63 | 64 | 65 | 66 |
67 |
68 |
69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/renderer/components/host/HostOverview.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import Paper from '@mui/material/Paper'; 6 | import Card from '@mui/material/Card'; 7 | import CardActions from '@mui/material/CardActions'; 8 | import CardContent from '@mui/material/CardContent'; 9 | import Typography from '@mui/material/Typography'; 10 | import Grid from '@mui/material/Grid'; 11 | 12 | import Chip from '@mui/material/Chip'; 13 | import Autocomplete from '@mui/material/Autocomplete'; 14 | import TextField from '@mui/material/TextField'; 15 | import Stack from '@mui/material/Stack'; 16 | 17 | import Security from '@mui/icons-material/Security'; 18 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 19 | import { faWindows } from '@fortawesome/free-brands-svg-icons'; 20 | 21 | import '../Home.css'; 22 | 23 | class HostOverview extends React.Component { 24 | //props: Props; 25 | 26 | constructor(props) { 27 | super(props); 28 | 29 | this.state = { 30 | open: false 31 | }; 32 | } 33 | 34 | 35 | render() { 36 | return ( 37 |
38 | 39 | 40 | 41 | Host Overview 42 |
43 |
44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | IP: {this.props.hostDetails} 54 |
55 |
56 | 57 | HOST: SANS-SEC460 58 |
59 |
60 | 61 | OS: Windows 10 62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | ); 70 | } 71 | } 72 | 73 | export default HostOverview; 74 | -------------------------------------------------------------------------------- /src/renderer/containers/Dashboard.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 6 | import { faWallet, faIndustry, faTerminal, faScroll, faBars, faBug, faKey, faServer, faRadiation, faHeadphones, faTable, faDragon } from '@fortawesome/free-solid-svg-icons'; 7 | import ReactTooltip from 'react-tooltip'; 8 | import { PieChart, Pie, Sector, Cell, ResponsiveContainer } from 'recharts'; 9 | 10 | import Grid from '@mui/material/Grid'; 11 | import Paper from '@mui/material/Paper'; 12 | import Box from '@mui/material/Box'; 13 | import Button from '@mui/material/Button'; 14 | import Avatar from '@mui/material/Avatar'; 15 | import Card from '@mui/material/Card'; 16 | import CardActions from '@mui/material/CardActions'; 17 | import CardContent from '@mui/material/CardContent'; 18 | import Typography from '@mui/material/Typography'; 19 | 20 | import { createTheme, ThemeProvider, styled } from '@mui/material/styles'; 21 | 22 | import './Main.css'; 23 | import logo from '/assets/logo.png'; 24 | 25 | import DashCards from '../components/DashCards.js'; 26 | import VulnPieGraph from '../components/VulnPieGraph.js'; 27 | import TopVulns from '../components/TopVulns.js'; 28 | import TopRemediations from '../components/TopRemediations.js'; 29 | import VulnsBySeverity from '../components/VulnsBySeverity.js'; 30 | import VulnOverTime from '../components/VulnOverTime.js'; 31 | 32 | 33 | const Item = styled(Paper)(({ theme }) => ({ 34 | ...theme.typography.body2, 35 | textAlign: 'center', 36 | color: theme.palette.text.secondary, 37 | height: 60, 38 | backgroundColor: null, 39 | lineHeight: '60px', 40 | })); 41 | 42 | 43 | class Dashboard extends React.Component { 44 | //props: Props; 45 | 46 | constructor(props) { 47 | super(props); 48 | 49 | this.state = { 50 | open: false 51 | }; 52 | } 53 | 54 | 55 | render() { 56 | return ( 57 |
58 |
59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 |
81 |
82 | ); 83 | } 84 | } 85 | 86 | export default Dashboard; 87 | -------------------------------------------------------------------------------- /src/renderer/components/VulnFilter.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import Paper from '@mui/material/Paper'; 6 | import Card from '@mui/material/Card'; 7 | import CardActions from '@mui/material/CardActions'; 8 | import CardContent from '@mui/material/CardContent'; 9 | import Typography from '@mui/material/Typography'; 10 | 11 | import Chip from '@mui/material/Chip'; 12 | import Autocomplete from '@mui/material/Autocomplete'; 13 | import TextField from '@mui/material/TextField'; 14 | import Stack from '@mui/material/Stack'; 15 | 16 | import AddBox from '@mui/icons-material/AddBox'; 17 | import IndeterminateCheckBoxIcon from '@mui/icons-material/IndeterminateCheckBox'; 18 | import UploadFileRoundedIcon from '@mui/icons-material/UploadFileRounded'; 19 | 20 | import './Home.css'; 21 | 22 | class VulnFilter extends React.Component { 23 | //props: Props; 24 | 25 | constructor(props) { 26 | super(props); 27 | 28 | this.state = { 29 | open: false 30 | }; 31 | } 32 | 33 | 34 | render() { 35 | return ( 36 |
37 | 38 | 39 | 40 | Vulnerablity Manager 41 | 42 |
43 |
44 | 45 | option.title} 49 | defaultValue={[top100Films[13]]} 50 | renderInput={(params) => ( 51 | 57 | )} 58 | /> 59 | 60 |
61 |
62 |
63 | ); 64 | } 65 | } 66 | 67 | // Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top 68 | const top100Films = [ 69 | { title: 'The Shawshank Redemption', year: 1994 }, 70 | { title: 'The Godfather', year: 1972 }, 71 | { title: 'The Godfather: Part II', year: 1974 }, 72 | { title: 'The Dark Knight', year: 2008 }, 73 | { title: '12 Angry Men', year: 1957 }, 74 | { title: "Schindler's List", year: 1993 }, 75 | { title: 'Pulp Fiction', year: 1994 }, 76 | ]; 77 | 78 | export default VulnFilter; 79 | -------------------------------------------------------------------------------- /src/renderer/components/agent/AgentFinder.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import Paper from '@mui/material/Paper'; 6 | import Card from '@mui/material/Card'; 7 | import CardActions from '@mui/material/CardActions'; 8 | import CardContent from '@mui/material/CardContent'; 9 | import Typography from '@mui/material/Typography'; 10 | 11 | import Chip from '@mui/material/Chip'; 12 | import Autocomplete from '@mui/material/Autocomplete'; 13 | import TextField from '@mui/material/TextField'; 14 | import Stack from '@mui/material/Stack'; 15 | 16 | import AddBox from '@mui/icons-material/AddBox'; 17 | import IndeterminateCheckBoxIcon from '@mui/icons-material/IndeterminateCheckBox'; 18 | import UploadFileRoundedIcon from '@mui/icons-material/UploadFileRounded'; 19 | 20 | import '../Home.css'; 21 | 22 | 23 | 24 | 25 | 26 | class AgentFinder extends React.Component { 27 | //props: Props; 28 | 29 | constructor(props) { 30 | super(props); 31 | 32 | this.state = { 33 | open: false, 34 | hostList: [{ 35 | "ip": "" 36 | }], 37 | }; 38 | //this.fetchHosts = this.fetchHosts.bind(this); 39 | this.selectHost = this.selectHost.bind(this); 40 | } 41 | 42 | selectHost(event) { 43 | const target = event.target; 44 | const value = target.type === 'checkbox' ? target.checked : target.value; 45 | const name = target.name; 46 | 47 | this.props.setSelectedHost(target.innerHTML); 48 | } 49 | 50 | render() { 51 | return ( 52 |
53 | 54 | 55 | 56 | Host Manager 57 | 58 |
59 |
60 | 61 | option.ip} 65 | defaultValue="IP Address" 66 | name="selectedHost" 67 | onChange={this.selectHost} 68 | renderInput={(params) => ( 69 | 75 | )} 76 | /> 77 | 78 |
79 |
80 |
81 | ); 82 | } 83 | } 84 | 85 | export default AgentFinder; 86 | -------------------------------------------------------------------------------- /src/renderer/components/agent/TerminalPrompt.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import Grid from '@mui/material/Grid'; 6 | import Input from '@mui/material/Input'; 7 | import FormControl from '@mui/material/FormControl'; 8 | import Button from '@mui/material/Button'; 9 | 10 | import './Agent.css'; 11 | 12 | 13 | 14 | class TerminalPrompt extends React.Component { 15 | //props: Props; 16 | 17 | constructor(props) { 18 | super(props); 19 | 20 | this.state = { 21 | open: false, 22 | hostList: [{ 23 | "ip": "" 24 | }], 25 | selectedAgents: [{ 26 | "ip": "192.168.1.15" 27 | }], 28 | terminal: "", 29 | selectedHost: ["192.168.1.15"], 30 | prepCommand: { 31 | hosts : ["192.168.1.15", "10.0.10.5"], 32 | command : "", 33 | }, 34 | }; 35 | this.handleChange = this.handleChange.bind(this); 36 | this.handleSubmit = this.handleSubmit.bind(this); 37 | this.resetPrompt = this.resetPrompt.bind(this); 38 | } 39 | handleChange(event) { 40 | const target = event.target; 41 | const value = target.type === 'checkbox' ? target.checked : target.value; 42 | const name = target.name; 43 | 44 | this.setState({ 45 | [name]: value 46 | }); 47 | } 48 | handleSubmit() { 49 | event.preventDefault(); 50 | this.setState({ 51 | prepCommand: { 52 | "hosts": this.state.selectedHost, 53 | "command": this.state.terminal, 54 | } 55 | }); 56 | if (this.state.prepCommand) { 57 | this.props.handleCommand(this.state.selectedHost, this.state.terminal) 58 | } 59 | 60 | this.resetPrompt() 61 | } 62 | resetPrompt() { 63 | this.setState({ 64 | terminal: "" 65 | }); 66 | } 67 | 68 | render() { 69 | return ( 70 |
71 |
72 | {this.state.selectedHost.map((ip) => { 73 | return ( 74 | 75 | ({ip}) / 76 | 77 | ); 78 | })} 79 |
80 |
81 |
82 | {'>'} 83 | 90 | 95 | 96 |
97 |
98 |
99 | ); 100 | } 101 | } 102 | 103 | export default TerminalPrompt; 104 | -------------------------------------------------------------------------------- /src/renderer/components/host/HostManager.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import Paper from '@mui/material/Paper'; 6 | import Card from '@mui/material/Card'; 7 | import CardActions from '@mui/material/CardActions'; 8 | import CardContent from '@mui/material/CardContent'; 9 | import Typography from '@mui/material/Typography'; 10 | 11 | import Chip from '@mui/material/Chip'; 12 | import Autocomplete from '@mui/material/Autocomplete'; 13 | import TextField from '@mui/material/TextField'; 14 | import Stack from '@mui/material/Stack'; 15 | 16 | import AddBox from '@mui/icons-material/AddBox'; 17 | import IndeterminateCheckBoxIcon from '@mui/icons-material/IndeterminateCheckBox'; 18 | import UploadFileRoundedIcon from '@mui/icons-material/UploadFileRounded'; 19 | 20 | 21 | 22 | import '../Home.css'; 23 | 24 | class HostSearch extends React.Component { 25 | //props: Props; 26 | 27 | constructor(props) { 28 | super(props); 29 | 30 | this.state = { 31 | open: false, 32 | hostList: [{ 33 | "ip": "1" 34 | }], 35 | }; 36 | //this.fetchHosts = this.fetchHosts.bind(this); 37 | this.selectHost = this.selectHost.bind(this); 38 | } 39 | 40 | selectHost(event) { 41 | const target = event.target; 42 | const value = target.type === 'checkbox' ? target.checked : target.value; 43 | const name = target.name; 44 | 45 | this.props.setSelectedHost(target.innerHTML); 46 | } 47 | 48 | render() { 49 | return ( 50 |
51 | 52 | 53 | 54 | Host Manager 55 | 56 |
57 |
58 | 59 | option.ip} 63 | defaultValue="IP Address" 64 | name="selectedHost" 65 | onChange={this.selectHost} 66 | renderInput={(params) => ( 67 | 73 | )} 74 | /> 75 | 76 |
77 |
78 |
79 | ); 80 | } 81 | } 82 | 83 | export default HostSearch; 84 | -------------------------------------------------------------------------------- /src/renderer/components/DashCards.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import { createTheme, ThemeProvider, styled } from '@mui/material/styles'; 6 | 7 | import Paper from '@mui/material/Paper'; 8 | import Grid from '@mui/material/Grid'; 9 | import Card from '@mui/material/Card'; 10 | import CardActions from '@mui/material/CardActions'; 11 | import CardContent from '@mui/material/CardContent'; 12 | import Typography from '@mui/material/Typography'; 13 | 14 | import '../containers/Main.css'; 15 | 16 | const Item = styled(Paper)(({ theme }) => ({ 17 | ...theme.typography.body2, 18 | textAlign: 'center', 19 | color: theme.palette.text.secondary, 20 | height: 60, 21 | backgroundColor: null, 22 | lineHeight: '60px', 23 | })); 24 | 25 | class VulnOverTime extends React.Component { 26 | //props: Props; 27 | 28 | constructor(props) { 29 | super(props); 30 | 31 | 32 | this.state = { 33 | open: false 34 | }; 35 | } 36 | 37 | render() { 38 | 39 | return ( 40 | 41 | 42 | 43 | 44 | 45 | CRITICAL VULNERABILITIES 46 | 47 | 48 | 5 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | HOSTS 58 | 59 | 60 | 21 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | TOTAL VULNERABILITIES 70 | 71 | 72 | 328 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | SCANS 82 | 83 | 84 | 8 85 | 86 | 87 | 88 | 89 | 90 | ); 91 | } 92 | } 93 | 94 | export default VulnOverTime; 95 | -------------------------------------------------------------------------------- /assets/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at electronreactboilerplate@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /.erb/configs/webpack.config.renderer.prod.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Build config for electron renderer process 3 | */ 4 | 5 | import path from 'path'; 6 | import webpack from 'webpack'; 7 | import HtmlWebpackPlugin from 'html-webpack-plugin'; 8 | import MiniCssExtractPlugin from 'mini-css-extract-plugin'; 9 | import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; 10 | import CssMinimizerPlugin from 'css-minimizer-webpack-plugin'; 11 | import { merge } from 'webpack-merge'; 12 | import TerserPlugin from 'terser-webpack-plugin'; 13 | import baseConfig from './webpack.config.base'; 14 | import webpackPaths from './webpack.paths'; 15 | import checkNodeEnv from '../scripts/check-node-env'; 16 | import deleteSourceMaps from '../scripts/delete-source-maps'; 17 | 18 | checkNodeEnv('production'); 19 | deleteSourceMaps(); 20 | 21 | const devtoolsConfig = 22 | process.env.DEBUG_PROD === 'true' 23 | ? { 24 | devtool: 'source-map', 25 | } 26 | : {}; 27 | 28 | const configuration: webpack.Configuration = { 29 | ...devtoolsConfig, 30 | 31 | mode: 'production', 32 | 33 | target: ['web', 'electron-renderer'], 34 | 35 | entry: [path.join(webpackPaths.srcRendererPath, 'index.tsx')], 36 | 37 | output: { 38 | path: webpackPaths.distRendererPath, 39 | publicPath: './', 40 | filename: 'renderer.js', 41 | library: { 42 | type: 'umd', 43 | }, 44 | }, 45 | 46 | module: { 47 | rules: [ 48 | { 49 | test: /\.s?(a|c)ss$/, 50 | use: [ 51 | MiniCssExtractPlugin.loader, 52 | { 53 | loader: 'css-loader', 54 | options: { 55 | modules: true, 56 | sourceMap: true, 57 | importLoaders: 1, 58 | }, 59 | }, 60 | 'sass-loader', 61 | ], 62 | include: /\.module\.s?(c|a)ss$/, 63 | }, 64 | { 65 | test: /\.s?(a|c)ss$/, 66 | use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'], 67 | exclude: /\.module\.s?(c|a)ss$/, 68 | }, 69 | // Fonts 70 | { 71 | test: /\.(woff|woff2|eot|ttf|otf)$/i, 72 | type: 'asset/resource', 73 | }, 74 | // Images 75 | { 76 | test: /\.(png|svg|jpg|jpeg|gif)$/i, 77 | type: 'asset/resource', 78 | }, 79 | ], 80 | }, 81 | 82 | optimization: { 83 | minimize: true, 84 | minimizer: [ 85 | new TerserPlugin({ 86 | parallel: true, 87 | }), 88 | new CssMinimizerPlugin(), 89 | ], 90 | }, 91 | 92 | plugins: [ 93 | /** 94 | * Create global constants which can be configured at compile time. 95 | * 96 | * Useful for allowing different behaviour between development builds and 97 | * release builds 98 | * 99 | * NODE_ENV should be production so that modules do not perform certain 100 | * development checks 101 | */ 102 | new webpack.EnvironmentPlugin({ 103 | NODE_ENV: 'production', 104 | DEBUG_PROD: false, 105 | }), 106 | 107 | new MiniCssExtractPlugin({ 108 | filename: 'style.css', 109 | }), 110 | 111 | new BundleAnalyzerPlugin({ 112 | analyzerMode: process.env.ANALYZE === 'true' ? 'server' : 'disabled', 113 | }), 114 | 115 | new HtmlWebpackPlugin({ 116 | filename: 'index.html', 117 | template: path.join(webpackPaths.srcRendererPath, 'index.ejs'), 118 | minify: { 119 | collapseWhitespace: true, 120 | removeAttributeQuotes: true, 121 | removeComments: true, 122 | }, 123 | isBrowser: false, 124 | isDevelopment: process.env.NODE_ENV !== 'production', 125 | }), 126 | ], 127 | }; 128 | 129 | export default merge(baseConfig, configuration); 130 | -------------------------------------------------------------------------------- /src/main/main.ts: -------------------------------------------------------------------------------- 1 | /* eslint global-require: off, no-console: off, promise/always-return: off */ 2 | 3 | /** 4 | * This module executes inside of electron's main process. You can start 5 | * electron renderer process from here and communicate with the other processes 6 | * through IPC. 7 | * 8 | * When running `npm run build` or `npm run build:main`, this file is compiled to 9 | * `./src/main.js` using webpack. This gives us some performance wins. 10 | */ 11 | import path from 'path'; 12 | import { app, BrowserWindow, shell, ipcMain } from 'electron'; 13 | import { autoUpdater } from 'electron-updater'; 14 | import log from 'electron-log'; 15 | import MenuBuilder from './menu'; 16 | import { resolveHtmlPath } from './util'; 17 | 18 | export default class AppUpdater { 19 | constructor() { 20 | log.transports.file.level = 'info'; 21 | autoUpdater.logger = log; 22 | autoUpdater.checkForUpdatesAndNotify(); 23 | } 24 | } 25 | 26 | let mainWindow: BrowserWindow | null = null; 27 | 28 | ipcMain.on('ipc-example', async (event, arg) => { 29 | const msgTemplate = (pingPong: string) => `IPC test: ${pingPong}`; 30 | console.log(msgTemplate(arg)); 31 | event.reply('ipc-example', msgTemplate('pong')); 32 | }); 33 | 34 | if (process.env.NODE_ENV === 'production') { 35 | const sourceMapSupport = require('source-map-support'); 36 | sourceMapSupport.install(); 37 | } 38 | 39 | const isDevelopment = 40 | process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true'; 41 | 42 | if (isDevelopment) { 43 | require('electron-debug')(); 44 | } 45 | 46 | const installExtensions = async () => { 47 | const installer = require('electron-devtools-installer'); 48 | const forceDownload = !!process.env.UPGRADE_EXTENSIONS; 49 | const extensions = ['REACT_DEVELOPER_TOOLS']; 50 | 51 | return installer 52 | .default( 53 | extensions.map((name) => installer[name]), 54 | forceDownload 55 | ) 56 | .catch(console.log); 57 | }; 58 | 59 | const createWindow = async () => { 60 | if (isDevelopment) { 61 | await installExtensions(); 62 | } 63 | 64 | const RESOURCES_PATH = app.isPackaged 65 | ? path.join(process.resourcesPath, 'assets') 66 | : path.join(__dirname, '../../assets'); 67 | 68 | const getAssetPath = (...paths: string[]): string => { 69 | return path.join(RESOURCES_PATH, ...paths); 70 | }; 71 | 72 | mainWindow = new BrowserWindow({ 73 | show: false, 74 | width: 1024, 75 | height: 728, 76 | icon: getAssetPath('icon.png'), 77 | webPreferences: { 78 | webSecurity: false, 79 | preload: app.isPackaged 80 | ? path.join(__dirname, 'preload.js') 81 | : path.join(__dirname, '../../.erb/dll/preload.js'), 82 | }, 83 | }); 84 | 85 | mainWindow.loadURL(resolveHtmlPath('index.html')); 86 | 87 | mainWindow.on('ready-to-show', () => { 88 | if (!mainWindow) { 89 | throw new Error('"mainWindow" is not defined'); 90 | } 91 | if (process.env.START_MINIMIZED) { 92 | mainWindow.minimize(); 93 | } else { 94 | mainWindow.show(); 95 | } 96 | }); 97 | 98 | mainWindow.on('closed', () => { 99 | mainWindow = null; 100 | }); 101 | 102 | const menuBuilder = new MenuBuilder(mainWindow); 103 | menuBuilder.buildMenu(); 104 | 105 | // Open urls in the user's browser 106 | mainWindow.webContents.setWindowOpenHandler((edata) => { 107 | shell.openExternal(edata.url); 108 | return { action: 'deny' }; 109 | }); 110 | 111 | // Remove this if your app does not use auto updates 112 | // eslint-disable-next-line 113 | new AppUpdater(); 114 | }; 115 | 116 | /** 117 | * Add event listeners... 118 | */ 119 | 120 | app.on('window-all-closed', () => { 121 | // Respect the OSX convention of having the application in memory even 122 | // after all windows have been closed 123 | if (process.platform !== 'darwin') { 124 | app.quit(); 125 | } 126 | }); 127 | 128 | app 129 | .whenReady() 130 | .then(() => { 131 | createWindow(); 132 | app.on('activate', () => { 133 | // On macOS it's common to re-create a window in the app when the 134 | // dock icon is clicked and there are no other windows open. 135 | if (mainWindow === null) createWindow(); 136 | }); 137 | }) 138 | .catch(console.log); 139 | -------------------------------------------------------------------------------- /src/renderer/components/ToolBar.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 6 | import { faWallet, faIndustry, faTerminal, faScroll, faBars, faBug, faKey, faServer, faRadiation, faHeadphones, faTable, faDragon } from '@fortawesome/free-solid-svg-icons'; 7 | import ReactTooltip from 'react-tooltip'; 8 | 9 | import Button from '@mui/material/Button'; 10 | import Avatar from '@mui/material/Avatar'; 11 | 12 | import Box from '@mui/material/Box'; 13 | import Drawer from '@mui/material/Drawer'; 14 | import CssBaseline from '@mui/material/CssBaseline'; 15 | import AppBar from '@mui/material/AppBar'; 16 | import Toolbar from '@mui/material/Toolbar'; 17 | import List from '@mui/material/List'; 18 | import Typography from '@mui/material/Typography'; 19 | import Divider from '@mui/material/Divider'; 20 | import ListItem from '@mui/material/ListItem'; 21 | 22 | import ListItemIcon from '@mui/material/ListItemIcon'; 23 | import InboxIcon from '@mui/icons-material/MoveToInbox'; 24 | import BugReport from '@mui/icons-material/BugReport'; 25 | import Policy from '@mui/icons-material/Policy'; 26 | import Token from '@mui/icons-material/Token'; 27 | import Security from '@mui/icons-material/Security'; 28 | import Settings from '@mui/icons-material/Settings'; 29 | import Logout from '@mui/icons-material/Logout'; 30 | import PrivacyTip from '@mui/icons-material/PrivacyTip'; 31 | import ViewList from '@mui/icons-material/ViewList'; 32 | 33 | 34 | import './Home.css'; 35 | import logo from '/assets/logo.png'; 36 | 37 | 38 | class ToolBar extends React.Component { 39 | //props: Props; 40 | 41 | constructor(props) { 42 | super(props); 43 | 44 | this.state = { 45 | open: false 46 | }; 47 | } 48 | 49 | 50 | render() { 51 | return ( 52 |
53 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 |
97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 |
115 |
116 |
117 | ); 118 | } 119 | } 120 | 121 | export default ToolBar; 122 | -------------------------------------------------------------------------------- /src/renderer/components/VulnsBySeverity.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import Paper from '@mui/material/Paper'; 6 | import Card from '@mui/material/Card'; 7 | import Badge from '@mui/material/Badge'; 8 | import CardActions from '@mui/material/CardActions'; 9 | import CardContent from '@mui/material/CardContent'; 10 | import Typography from '@mui/material/Typography'; 11 | 12 | import { createMuiTheme } from 'material-ui/styles'; 13 | 14 | 15 | import './Home.css'; 16 | 17 | class VulnsBySeverity extends React.Component { 18 | //props: Props; 19 | 20 | constructor(props) { 21 | super(props); 22 | 23 | this.state = { 24 | open: false 25 | }; 26 | } 27 | 28 | 29 | render() { 30 | return ( 31 |
32 | 33 | 34 | 35 | Vulnerabilities by Severity 36 |
37 |
38 | 39 | Critical 40 |
41 | 51 | 52 |
53 |
54 |
55 | 56 | High 57 |
58 | 68 | 69 |
70 |
71 |
72 | 73 | Medium 74 |
75 | 85 | 86 |
87 |
88 |
89 | 90 | Low 91 |
92 | 102 | 103 |
104 |
105 |
106 | 107 | Informational 108 |
109 | 119 | 120 |
121 |
122 |
123 |
124 |
125 |
126 | ); 127 | } 128 | } 129 | 130 | export default VulnsBySeverity; 131 | -------------------------------------------------------------------------------- /src/renderer/components/Home.css: -------------------------------------------------------------------------------- 1 | .logo { 2 | max-width: 50px; 3 | } 4 | .toolbar { 5 | background-color: #333; 6 | color: white; 7 | } 8 | .container { 9 | position: absolute; 10 | text-align: center; 11 | } 12 | 13 | .container h2 { 14 | font-size: 5rem; 15 | } 16 | 17 | .container a { 18 | font-size: 1.4rem; 19 | } 20 | .terminal-base { 21 | width: 100%; 22 | max-width: 100%; 23 | height: 100%; 24 | min-height: 630px; 25 | max-height: 100vh; 26 | text-align: initial; 27 | } 28 | .menucontainer { 29 | position: fixed; 30 | top: 0px; 31 | left: 0px; 32 | height: 65px; 33 | background-color: #222; 34 | width: 100vw; 35 | padding-bottom: 10px; 36 | z-index: 2999; 37 | } 38 | .logoitem { 39 | position: relative; 40 | float: left; 41 | color: #fff; 42 | cursor: pointer; 43 | margin-left: 20px; 44 | margin-top: 12px; 45 | font-size: 20px; 46 | padding-right: 20px; 47 | } 48 | .menuitem { 49 | position: relative; 50 | float: left; 51 | color: #fff; 52 | cursor: pointer; 53 | margin-left: 20px; 54 | margin-top: 23px; 55 | font-size: 25px; 56 | } 57 | .menuitemr { 58 | position: relative; 59 | float: right; 60 | color: #fff; 61 | cursor: pointer; 62 | margin-right: 20px; 63 | margin-top: 18px; 64 | font-size: 25px; 65 | } 66 | .menusettings { 67 | position: relative; 68 | float: right; 69 | color: #fff; 70 | cursor: pointer; 71 | margin-right: 20px; 72 | margin-top: 12px; 73 | font-size: 20px; 74 | } 75 | .menuitem:hover { 76 | color: green; 77 | } 78 | .menugroup { 79 | margin-left: 0px; 80 | } 81 | .termcontainer { 82 | top: -45px; 83 | background-color: #002b36; 84 | } 85 | .basecontainer { 86 | position: absolute; 87 | left: -10px; 88 | } 89 | .customModal { 90 | color: black; 91 | } 92 | .customModalContainer { 93 | width: 650px; 94 | color: black; 95 | } 96 | .menuSpacing { 97 | width: 500px; 98 | } 99 | .modalTextField { 100 | margin-top: 20px; 101 | } 102 | .loader { 103 | position: absolute; 104 | top: 300px; 105 | left: 50%; 106 | } 107 | .terminalText { 108 | color: green; 109 | font-family: monospace; 110 | } 111 | .windowcontrols { 112 | -webkit-app-region: no-drag; 113 | position: fixed; 114 | right: 0px; 115 | margin-right: 2px; 116 | text-align: left; 117 | top: 0; 118 | z-index: 3001; 119 | } 120 | .windowMax, 121 | .windowMin, 122 | .windowClose { 123 | text-align: left; 124 | float: right; 125 | width: 45px; 126 | height: 31px; 127 | margin: 1px 1px 0 0; 128 | text-align: center; 129 | line-height: 29px; 130 | 131 | -webkit-transition: background-color 0.2s; 132 | -moz-transition: background-color 0.2s; 133 | -ms-transition: background-color 0.2s; 134 | -o-transition: background-color 0.2s; 135 | transition: background-color 0.2s; 136 | } 137 | 138 | .windowClose svg, 139 | .windowMax svg, 140 | .windowMin svg { 141 | width: 10px; 142 | height: 10px; 143 | shape-rendering: crispEdges; 144 | fill: rgba(255, 255, 255, 1); 145 | } 146 | .windowClose svg polygon, 147 | .windowMax svg polygon, 148 | .windowMin svg polygon { 149 | fill: rgba(255, 255, 255, 1); 150 | -webkit-transition: fill 0.2s; 151 | -moz-transition: fill 0.2s; 152 | -ms-transition: fill 0.2s; 153 | -o-transition: fill 0.2s; 154 | transition: fill 0.2s; 155 | } 156 | .windowClose svg polygon { 157 | -webkit-transition: fill 0.2s; 158 | -moz-transition: fill 0.2s; 159 | -ms-transition: fill 0.2s; 160 | -o-transition: fill 0.2s; 161 | transition: fill 0.2s; 162 | } 163 | .windowClose:hover, 164 | .windowMax:hover, 165 | .windowMin:hover { 166 | background-color: rgba(255, 255, 255, 0.1); 167 | } 168 | 169 | .windowClose:hover svg polygon, 170 | .windowMax:hover svg path, 171 | .windowMin:hover svg rect { 172 | fill: #222; 173 | } 174 | .settingsmodal { 175 | min-width: 600px; 176 | border-radius: 10px; 177 | z-index: 2015; 178 | } 179 | .boxpadding { 180 | margin-right: 10px; 181 | } 182 | .pagecontent { 183 | position: relative; 184 | top: 50px; 185 | padding: 0px; 186 | margin: 0px; 187 | height: 100vh; 188 | background-color: #333; 189 | width: 100vw; 190 | } 191 | .centeredUserInput { 192 | width: 35em; 193 | height: 25em; 194 | margin: 0 auto; 195 | background-color: #fff; 196 | } 197 | 198 | .centeredUserInput h1 { 199 | text-align: center; 200 | padding-top: 1em; 201 | } 202 | 203 | .centeredUserInput p { 204 | text-align: center; 205 | } 206 | 207 | .centeredUserInput input { 208 | display: block; 209 | width: 50%; 210 | padding: 1em; 211 | margin: 1em auto; 212 | } 213 | .successicon { 214 | color: green; 215 | } 216 | .authmodal { 217 | position: absolute; 218 | top: 20vh; 219 | left: 35vw; 220 | z-index: 2015; 221 | } 222 | .dashbox { 223 | padding-left: 20px; 224 | padding-right: 20px; 225 | padding-bottom: 50px; 226 | } 227 | .right { 228 | float: right; 229 | padding-right: 20px; 230 | } 231 | .MuiBadge-standard { 232 | background-color: red; 233 | color: red; 234 | } 235 | .bottom { 236 | position: absolute; 237 | bottom: 0; 238 | color: 'red'; 239 | } 240 | .navtoolbar { 241 | vh: 100; 242 | } 243 | .leftcard { 244 | padding-left: 10px; 245 | padding-right: 0px; 246 | padding-bottom: 10px; 247 | z-index: 100; 248 | } 249 | .rightcard { 250 | padding-left: 0px; 251 | padding-right: 10px; 252 | padding-bottom: 10px; 253 | } 254 | -------------------------------------------------------------------------------- /.erb/configs/webpack.config.renderer.dev.ts: -------------------------------------------------------------------------------- 1 | import 'webpack-dev-server'; 2 | import path from 'path'; 3 | import fs from 'fs'; 4 | import webpack from 'webpack'; 5 | import HtmlWebpackPlugin from 'html-webpack-plugin'; 6 | import chalk from 'chalk'; 7 | import { merge } from 'webpack-merge'; 8 | import { execSync, spawn } from 'child_process'; 9 | import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin'; 10 | import baseConfig from './webpack.config.base'; 11 | import webpackPaths from './webpack.paths'; 12 | import checkNodeEnv from '../scripts/check-node-env'; 13 | 14 | // When an ESLint server is running, we can't set the NODE_ENV so we'll check if it's 15 | // at the dev webpack config is not accidentally run in a production environment 16 | if (process.env.NODE_ENV === 'production') { 17 | checkNodeEnv('development'); 18 | } 19 | 20 | const port = process.env.PORT || 1212; 21 | const manifest = path.resolve(webpackPaths.dllPath, 'renderer.json'); 22 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion 23 | const requiredByDLLConfig = module.parent!.filename.includes( 24 | 'webpack.config.renderer.dev.dll' 25 | ); 26 | 27 | /** 28 | * Warn if the DLL is not built 29 | */ 30 | if ( 31 | !requiredByDLLConfig && 32 | !(fs.existsSync(webpackPaths.dllPath) && fs.existsSync(manifest)) 33 | ) { 34 | console.log( 35 | chalk.black.bgYellow.bold( 36 | 'The DLL files are missing. Sit back while we build them for you with "npm run build-dll"' 37 | ) 38 | ); 39 | execSync('npm run postinstall'); 40 | } 41 | 42 | const configuration: webpack.Configuration = { 43 | devtool: 'inline-source-map', 44 | 45 | mode: 'development', 46 | 47 | target: ['web', 'electron-renderer'], 48 | 49 | entry: [ 50 | `webpack-dev-server/client?http://localhost:${port}/dist`, 51 | 'webpack/hot/only-dev-server', 52 | path.join(webpackPaths.srcRendererPath, 'index.tsx'), 53 | ], 54 | 55 | output: { 56 | path: webpackPaths.distRendererPath, 57 | publicPath: '/', 58 | filename: 'renderer.dev.js', 59 | library: { 60 | type: 'umd', 61 | }, 62 | }, 63 | 64 | module: { 65 | rules: [ 66 | { 67 | test: /\.s?css$/, 68 | use: [ 69 | 'style-loader', 70 | { 71 | loader: 'css-loader', 72 | options: { 73 | modules: true, 74 | sourceMap: true, 75 | importLoaders: 1, 76 | }, 77 | }, 78 | 'sass-loader', 79 | ], 80 | include: /\.module\.s?(c|a)ss$/, 81 | }, 82 | { 83 | test: /\.s?css$/, 84 | use: ['style-loader', 'css-loader', 'sass-loader'], 85 | exclude: /\.module\.s?(c|a)ss$/, 86 | }, 87 | // Fonts 88 | { 89 | test: /\.(woff|woff2|eot|ttf|otf)$/i, 90 | type: 'asset/resource', 91 | }, 92 | // Images 93 | { 94 | test: /\.(png|svg|jpg|jpeg|gif)$/i, 95 | type: 'asset/resource', 96 | }, 97 | ], 98 | }, 99 | plugins: [ 100 | ...(requiredByDLLConfig 101 | ? [] 102 | : [ 103 | new webpack.DllReferencePlugin({ 104 | context: webpackPaths.dllPath, 105 | manifest: require(manifest), 106 | sourceType: 'var', 107 | }), 108 | ]), 109 | 110 | new webpack.NoEmitOnErrorsPlugin(), 111 | 112 | /** 113 | * Create global constants which can be configured at compile time. 114 | * 115 | * Useful for allowing different behaviour between development builds and 116 | * release builds 117 | * 118 | * NODE_ENV should be production so that modules do not perform certain 119 | * development checks 120 | * 121 | * By default, use 'development' as NODE_ENV. This can be overriden with 122 | * 'staging', for example, by changing the ENV variables in the npm scripts 123 | */ 124 | new webpack.EnvironmentPlugin({ 125 | NODE_ENV: 'development', 126 | }), 127 | 128 | new webpack.LoaderOptionsPlugin({ 129 | debug: true, 130 | }), 131 | 132 | new ReactRefreshWebpackPlugin(), 133 | 134 | new HtmlWebpackPlugin({ 135 | filename: path.join('index.html'), 136 | template: path.join(webpackPaths.srcRendererPath, 'index.ejs'), 137 | minify: { 138 | collapseWhitespace: true, 139 | removeAttributeQuotes: true, 140 | removeComments: true, 141 | }, 142 | isBrowser: false, 143 | env: process.env.NODE_ENV, 144 | isDevelopment: process.env.NODE_ENV !== 'production', 145 | nodeModules: webpackPaths.appNodeModulesPath, 146 | }), 147 | ], 148 | 149 | node: { 150 | __dirname: false, 151 | __filename: false, 152 | }, 153 | 154 | devServer: { 155 | port, 156 | compress: true, 157 | hot: true, 158 | headers: { 'Access-Control-Allow-Origin': '*' }, 159 | static: { 160 | publicPath: '/', 161 | }, 162 | historyApiFallback: { 163 | verbose: true, 164 | }, 165 | setupMiddlewares(middlewares) { 166 | console.log('Starting preload.js builder...'); 167 | const preloadProcess = spawn('npm', ['run', 'start:preload'], { 168 | shell: true, 169 | stdio: 'inherit', 170 | }) 171 | .on('close', (code: number) => process.exit(code!)) 172 | .on('error', (spawnError) => console.error(spawnError)); 173 | 174 | console.log('Starting Main Process...'); 175 | spawn('npm', ['run', 'start:main'], { 176 | shell: true, 177 | stdio: 'inherit', 178 | }) 179 | .on('close', (code: number) => { 180 | preloadProcess.kill(); 181 | process.exit(code!); 182 | }) 183 | .on('error', (spawnError) => console.error(spawnError)); 184 | return middlewares; 185 | }, 186 | }, 187 | }; 188 | 189 | export default merge(baseConfig, configuration); 190 | -------------------------------------------------------------------------------- /src/renderer/components/host/VulnList.tsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import Paper from '@mui/material/Paper'; 6 | import Card from '@mui/material/Card'; 7 | import Badge from '@mui/material/Badge'; 8 | import CardActions from '@mui/material/CardActions'; 9 | import CardContent from '@mui/material/CardContent'; 10 | import Typography from '@mui/material/Typography'; 11 | import Table from '@mui/material/Table'; 12 | import TableBody from '@mui/material/TableBody'; 13 | import TableCell from '@mui/material/TableCell'; 14 | import TableContainer from '@mui/material/TableContainer'; 15 | import TableHead from '@mui/material/TableHead'; 16 | import TableRow from '@mui/material/TableRow'; 17 | import Collapse from '@mui/material/Collapse'; 18 | import IconButton from '@mui/material/IconButton'; 19 | import Box from '@mui/material/Box'; 20 | 21 | import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; 22 | import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'; 23 | import AddBox from '@mui/icons-material/AddBox'; 24 | import IndeterminateCheckBoxIcon from '@mui/icons-material/IndeterminateCheckBox'; 25 | import UploadFileRoundedIcon from '@mui/icons-material/UploadFileRounded'; 26 | 27 | import { createMuiTheme } from 'material-ui/styles'; 28 | 29 | import '../Home.css'; 30 | 31 | function createData( 32 | cve: string, 33 | catagory: string, 34 | tags: string, 35 | cvss: int, 36 | srs: int, 37 | description: string 38 | ) { 39 | return { 40 | cve, 41 | catagory, 42 | tags, 43 | cvss, 44 | srs, 45 | description, 46 | }; 47 | } 48 | 49 | const imp17 = '3,3,3'; 50 | 51 | const rows = [ 52 | createData( 53 | 'CVE-2017-0145 - Remote Code Execution', 54 | 'RCE', 55 | 'CISA Worm RCE Wild', 56 | 9.8, 57 | 10, 58 | 'this.props.vulnerabilityList[0].description', 59 | imp17 60 | ), 61 | createData( 62 | 'CVE-2021-38647 - Microsoft Azure Open Management Infrastructure (OMI) Remote Code Execution Vulnerability', 63 | 237, 64 | 9.0, 65 | 37, 66 | 4.3, 67 | 4.99 68 | ), 69 | createData( 70 | 'CVE-2020-8196 - Application Delivery Controller (ADC), Gateway, and SDWAN WANOP', 71 | 262, 72 | 16.0, 73 | 24, 74 | 6.0, 75 | 3.79 76 | ), 77 | createData( 78 | 'CVE-2021-34473 - Microsoft Exchange Server Remote Code Execution Vulnerability', 79 | 305, 80 | 3.7, 81 | 67, 82 | 4.3, 83 | 2.5 84 | ), 85 | ]; 86 | 87 | function Row(props: { row: ReturnType }) { 88 | const { row } = props; 89 | const [open, setOpen] = React.useState(false); 90 | 91 | return ( 92 | <> 93 | *': { borderBottom: 'unset' } }}> 94 | 95 | setOpen(!open)} 99 | > 100 | {open ? : } 101 | 102 | 103 | 104 | {row.CVEDataMeta.ID} 105 | 106 | {row.CVSSV3.baseSeverity} 107 | {row.Tags} 108 | {row.CVSSV3.baseScore} 109 | 110 | 111 | 112 | 113 | 114 | 115 | Vulnerablity Summary 116 | 117 | 118 | {row.Description.description_data[0].value} 119 | 120 | 121 | Impact 122 | 123 | 124 | 125 | 126 | 127 | Confidentiality Impact 128 | Integrity Impact 129 | Availability Impact 130 | 131 | 132 | 133 | 134 | High 135 | High 136 | High 137 | 138 | 139 |
140 |
141 | 142 | References 143 | 144 | 145 | {row.References[0]} 146 | 147 |
148 |
149 |
150 |
151 | 152 | ); 153 | } 154 | 155 | class VulnList extends React.Component { 156 | //props: Props; 157 | 158 | constructor(props) { 159 | super(props); 160 | this.props.vulnerabilityList.map((row) => console.log(row.CVEDataMeta.ID)); 161 | 162 | this.state = { 163 | open: false, 164 | setOpen: false, 165 | }; 166 | } 167 | 168 | render() { 169 | return ( 170 |
171 | 172 | 173 | 174 | 175 | 176 | Vulnerability 177 | Severity 178 | Tags 179 | CVSS 180 | 181 | 182 | 183 | {this.props.vulnerabilityList.map((row) => ( 184 | 185 | ))} 186 | 187 |
188 |
189 |
190 | ); 191 | } 192 | } 193 | 194 | export default VulnList; 195 | -------------------------------------------------------------------------------- /src/renderer/containers/Agents.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 6 | import { faWallet, faIndustry, faTerminal, faScroll, faBars, faBug, faKey, faServer, faRadiation, faHeadphones, faTable, faDragon } from '@fortawesome/free-solid-svg-icons'; 7 | import ReactTooltip from 'react-tooltip'; 8 | import { PieChart, Pie, Sector, Cell, ResponsiveContainer } from 'recharts'; 9 | 10 | import Grid from '@mui/material/Grid'; 11 | import Paper from '@mui/material/Paper'; 12 | import Box from '@mui/material/Box'; 13 | import Button from '@mui/material/Button'; 14 | import Avatar from '@mui/material/Avatar'; 15 | import Card from '@mui/material/Card'; 16 | import CardActions from '@mui/material/CardActions'; 17 | import CardContent from '@mui/material/CardContent'; 18 | import Typography from '@mui/material/Typography'; 19 | 20 | import { createTheme, ThemeProvider, styled } from '@mui/material/styles'; 21 | 22 | import './Main.css'; 23 | import '../components/agent/Agent.css'; 24 | import logo from '/assets/logo.png'; 25 | 26 | import DashCards from '../components/DashCards.js'; 27 | import VulnPieGraph from '../components/VulnPieGraph.js'; 28 | import VulnFilter from '../components/VulnFilter.js'; 29 | 30 | //Host Compoments 31 | import AgentFinder from '../components/agent/AgentFinder.js'; 32 | import TerminalPrompt from '../components/agent/TerminalPrompt.js'; 33 | import TerminalCanvas from '../components/agent/TerminalCanvas.js'; 34 | 35 | import VulnList from '../components/VulnList.tsx'; 36 | 37 | 38 | import { taskAgent, getHosts, getTerminalHistory } from '../actions/api/db.js' 39 | 40 | 41 | const Item = styled(Paper)(({ theme }) => ({ 42 | ...theme.typography.body2, 43 | textAlign: 'center', 44 | color: theme.palette.text.secondary, 45 | height: 60, 46 | backgroundColor: null, 47 | lineHeight: '60px', 48 | })); 49 | 50 | const test = [ 51 | {"data": "test"} 52 | ]; 53 | 54 | class Agents extends React.Component { 55 | //props: Props; 56 | 57 | constructor(props) { 58 | super(props); 59 | 60 | this.state = { 61 | open: false, 62 | newhost: false, 63 | vulnerabilityview: false, 64 | selectedHost: "", 65 | hostList: [{ 66 | "ip": "" 67 | }], 68 | terminalHistory: [{}], 69 | }; 70 | this.toggleNewHost = this.toggleNewHost.bind(this) 71 | this.setSelectedHost = this.setSelectedHost.bind(this) 72 | this.disableViews = this.disableViews.bind(this) 73 | this.handleCommand = this.handleCommand.bind(this) 74 | this.createTaskID = this.createTaskID.bind(this) 75 | } 76 | 77 | componentDidMount() { 78 | getHosts() 79 | .then(hosts => { 80 | console.log(hosts) 81 | this.setState({ hostList: hosts }) 82 | }); 83 | //.then(data => this.setState({ data })); 84 | setInterval(() => { 85 | getTerminalHistory() 86 | .then(history => { 87 | console.log(history) 88 | this.setState({ terminalHistory: history }) 89 | }); 90 | }, 1000); 91 | } 92 | disableViews() { 93 | this.setState({ 94 | vulnerabilityview: false, 95 | newhost: false 96 | }); 97 | } 98 | 99 | toggleNewHost() { 100 | this.disableViews() 101 | this.setState({ newhost: true }); 102 | } 103 | handleCommand(hosts, command) { 104 | console.log(hosts) 105 | console.log(command) 106 | let encodedCommand = btoa(command) 107 | let newHistory = this.state.terminalHistory 108 | 109 | //Filter for special commands 110 | if (command == "reset") { 111 | this.setState({terminalHistory : [{}]}); 112 | } else { 113 | //Deliver command to agent and push to history 114 | for (let i = 0; i < hosts.length; i++) { 115 | let cmdid = 1 116 | if (this.state.terminalHistory) { 117 | cmdid = this.state.terminalHistory.length 118 | } 119 | console.log(cmdid) 120 | let newCommand = { 121 | id : cmdid, 122 | IP : hosts[i], 123 | Command : encodedCommand, 124 | Result : "PENvbW1hbmQgU2VudD4K" 125 | } 126 | newHistory.push(newCommand) 127 | //Send to DB 128 | /* 129 | Docs: 130 | type SiriusAgent 131 | AgentId string 132 | HostKey string 133 | IP string 134 | OS string 135 | Tasks []Task 136 | type Task 137 | ID string 138 | Type string 139 | Date time.Time 140 | Command string 141 | Result string 142 | Status string 143 | */ 144 | const utcTimestamp = new Date().getTime(); 145 | var taskID = this.createTaskID(hosts[i]) 146 | const task = { 147 | agentid: "13859332", 148 | ip: hosts[i], 149 | hostkey: "", 150 | os: "", 151 | tasks: [{ 152 | id: taskID, 153 | type: "c", 154 | command: encodedCommand, 155 | result: "", 156 | status: "", 157 | date: utcTimestamp, 158 | }] 159 | } 160 | console.log(task) 161 | taskAgent(task) 162 | .then(res => { 163 | console.log(res) 164 | }); 165 | } 166 | this.setState({terminalHistory : newHistory}); 167 | } 168 | } 169 | createTaskID(host) { 170 | var taskID = Math.floor(Math.random() * 900000000 ) 171 | var taskID = "AGENT-" + host + "-" + taskID 172 | return taskID 173 | } 174 | 175 | //Trigger fetchHosts... or such 176 | setSelectedHost = (ip) => { 177 | this.disableViews() 178 | this.setState({ 179 | vulnerabilityview: true, 180 | selectedHost: ip 181 | }); 182 | } 183 | 184 | render() { 185 | return ( 186 |
187 |
188 |
189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 |
197 | 198 | 199 |
200 |
201 |
202 |
203 | ); 204 | } 205 | } 206 | 207 | export default Agents; 208 | -------------------------------------------------------------------------------- /src/renderer/containers/Hosts.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/jsx-filename-extension */ 2 | // @flow 3 | import React, { Component } from 'react'; 4 | import { Link } from 'react-router-dom'; 5 | 6 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 7 | import { 8 | faWallet, 9 | faIndustry, 10 | faTerminal, 11 | faScroll, 12 | faBars, 13 | faBug, 14 | faKey, 15 | faServer, 16 | faRadiation, 17 | faHeadphones, 18 | faTable, 19 | faDragon, 20 | } from '@fortawesome/free-solid-svg-icons'; 21 | import ReactTooltip from 'react-tooltip'; 22 | import { PieChart, Pie, Sector, Cell, ResponsiveContainer } from 'recharts'; 23 | 24 | import Grid from '@mui/material/Grid'; 25 | import Paper from '@mui/material/Paper'; 26 | import Box from '@mui/material/Box'; 27 | import Button from '@mui/material/Button'; 28 | import Avatar from '@mui/material/Avatar'; 29 | import Card from '@mui/material/Card'; 30 | import CardActions from '@mui/material/CardActions'; 31 | import CardContent from '@mui/material/CardContent'; 32 | import Typography from '@mui/material/Typography'; 33 | 34 | import { createTheme, ThemeProvider, styled } from '@mui/material/styles'; 35 | 36 | import './Main.css'; 37 | import logo from '/assets/logo.png'; 38 | 39 | import DashCards from '../components/DashCards.js'; 40 | import VulnPieGraph from '../components/VulnPieGraph.js'; 41 | import VulnFilter from '../components/VulnFilter.js'; 42 | 43 | // Host Compoments 44 | import HostOverview from '../components/host/HostOverview.js'; 45 | import HostManager from '../components/host/HostManager.js'; 46 | import HostServices from '../components/host/HostServices.js'; 47 | import HostSoftware from '../components/host/HostSoftware.js'; 48 | import NewHost from '../components/host/NewHost.tsx'; 49 | import VulnList from '../components/host/VulnList.tsx'; 50 | 51 | // Host Actions 52 | import { handleVulnList } from '../components/host/actions/handleVulnList.js'; 53 | 54 | import { getHosts, getVulnerabilityList } from '../actions/api/db.js'; 55 | 56 | const Item = styled(Paper)(({ theme }) => ({ 57 | ...theme.typography.body2, 58 | textAlign: 'center', 59 | color: theme.palette.text.secondary, 60 | height: 60, 61 | backgroundColor: null, 62 | lineHeight: '60px', 63 | })); 64 | 65 | const test = [{ data: 'test' }]; 66 | 67 | class Hosts extends React.Component { 68 | // props: Props; 69 | 70 | constructor(props) { 71 | super(props); 72 | 73 | this.state = { 74 | open: false, 75 | newhost: false, 76 | vulnerabilityview: false, 77 | selectedHost: '', 78 | hostList: [ 79 | { 80 | ip: '127.0.0.1', 81 | }, 82 | ], 83 | vulnerabilityList: [ 84 | { 85 | CVEDataMeta: { 86 | ID: 'Loading Vulnerability List...', 87 | ASSIGNER: 'cve@mitre.org', 88 | }, 89 | CVSSV3: { 90 | baseScore: 0, 91 | baseSeverity: '', 92 | }, 93 | Description: { 94 | description_data: [ 95 | { 96 | value: 'Loading...', 97 | }, 98 | ], 99 | }, 100 | References: ['Loading...'], 101 | cve: 'CVE-2017-0145 - Remote Code Execution', 102 | catagory: '', 103 | tags: 'CISA Worm RCE Wild', 104 | cvss: 9.8, 105 | srs: 10, 106 | description: 107 | 'The SMBv1 server in Microsoft Windows Vista SP2; Windows Server 2008 SP2 and R2 SP1; Windows 7 SP1; Windows 8.1; Windows Server 2012 Gold and R2; Windows RT 8.1; and Windows 10 Gold, 1511, and 1607; and Windows Server 2016 allows remote attackers to execute arbitrary code via crafted packets, aka "Windows SMB Remote Code Execution Vulnerability." This vulnerability is different from those described in CVE-2017-0143, CVE-2017-0144, CVE-2017-0146, and CVE-2017-0148.', 108 | cia: '3,3,3', 109 | }, 110 | ], 111 | baseVulnerabilityList: [ 112 | { 113 | CVEDataMeta: { 114 | ID: 'Loading Vulnerability List...', 115 | ASSIGNER: 'cve@mitre.org', 116 | }, 117 | CVSSV3: { 118 | baseScore: 0, 119 | baseSeverity: '', 120 | }, 121 | Description: { 122 | description_data: [ 123 | { 124 | value: 'Loading...', 125 | }, 126 | ], 127 | }, 128 | References: ['Loading...'], 129 | cve: 'CVE-2017-0145 - Remote Code Execution', 130 | catagory: '', 131 | tags: 'CISA Worm RCE Wild', 132 | cvss: 9.8, 133 | srs: 10, 134 | description: 135 | 'The SMBv1 server in Microsoft Windows Vista SP2; Windows Server 2008 SP2 and R2 SP1; Windows 7 SP1; Windows 8.1; Windows Server 2012 Gold and R2; Windows RT 8.1; and Windows 10 Gold, 1511, and 1607; and Windows Server 2016 allows remote attackers to execute arbitrary code via crafted packets, aka "Windows SMB Remote Code Execution Vulnerability." This vulnerability is different from those described in CVE-2017-0143, CVE-2017-0144, CVE-2017-0146, and CVE-2017-0148.', 136 | cia: '3,3,3', 137 | }, 138 | ], 139 | }; 140 | this.toggleNewHost = this.toggleNewHost.bind(this); 141 | this.setSelectedHost = this.setSelectedHost.bind(this); 142 | this.disableViews = this.disableViews.bind(this); 143 | } 144 | 145 | componentDidMount() { 146 | getHosts().then((hosts) => { 147 | console.log(hosts); 148 | if (hosts) { 149 | this.setState({ hostList: hosts }); 150 | } 151 | }); 152 | setInterval(() => { 153 | const svdbhost = { 154 | ip: this.state.selectedHost, 155 | }; 156 | getVulnerabilityList(svdbhost).then((data) => { 157 | console.log(data); 158 | if (data) { 159 | this.setState({ vulnerabilityList: data }); 160 | } else { 161 | const emptyList = this.state.baseVulnerabilityList; 162 | emptyList[0].CVEDataMeta.ID = 'No Vulnerabilities Found' 163 | this.setState({ vulnerabilityList: emptyList }); 164 | } 165 | }); 166 | }, 5000); 167 | // .then(data => this.setState({ data })); 168 | } 169 | disableViews() { 170 | this.setState({ 171 | vulnerabilityview: false, 172 | newhost: false, 173 | }); 174 | } 175 | 176 | toggleNewHost() { 177 | this.disableViews(); 178 | this.setState({ newhost: true }); 179 | } 180 | 181 | // Trigger fetchHosts... or such 182 | setSelectedHost = (ip) => { 183 | this.disableViews(); 184 | this.setState({ 185 | vulnerabilityview: true, 186 | selectedHost: ip, 187 | }); 188 | }; 189 | 190 | render() { 191 | return ( 192 |
193 |
194 | 195 | 196 | 201 | {this.state.vulnerabilityview ? ( 202 |
203 | 204 | 205 | 206 |
207 | ) : null} 208 |
209 | 210 | {this.state.vulnerabilityview ? ( 211 |
212 | 213 | 214 |
215 | ) : null} 216 | 217 | {this.state.newhost ? ( 218 | 219 | ) : null} 220 |
221 |
222 |
223 |
224 | ); 225 | } 226 | } 227 | 228 | export default Hosts; 229 | -------------------------------------------------------------------------------- /src/main/menu.ts: -------------------------------------------------------------------------------- 1 | import { 2 | app, 3 | Menu, 4 | shell, 5 | BrowserWindow, 6 | MenuItemConstructorOptions, 7 | } from 'electron'; 8 | 9 | interface DarwinMenuItemConstructorOptions extends MenuItemConstructorOptions { 10 | selector?: string; 11 | submenu?: DarwinMenuItemConstructorOptions[] | Menu; 12 | } 13 | 14 | export default class MenuBuilder { 15 | mainWindow: BrowserWindow; 16 | 17 | constructor(mainWindow: BrowserWindow) { 18 | this.mainWindow = mainWindow; 19 | } 20 | 21 | buildMenu(): Menu { 22 | if ( 23 | process.env.NODE_ENV === 'development' || 24 | process.env.DEBUG_PROD === 'true' 25 | ) { 26 | this.setupDevelopmentEnvironment(); 27 | } 28 | 29 | const template = 30 | process.platform === 'darwin' 31 | ? this.buildDarwinTemplate() 32 | : this.buildDefaultTemplate(); 33 | 34 | const menu = Menu.buildFromTemplate(template); 35 | Menu.setApplicationMenu(menu); 36 | 37 | return menu; 38 | } 39 | 40 | setupDevelopmentEnvironment(): void { 41 | this.mainWindow.webContents.on('context-menu', (_, props) => { 42 | const { x, y } = props; 43 | 44 | Menu.buildFromTemplate([ 45 | { 46 | label: 'Inspect element', 47 | click: () => { 48 | this.mainWindow.webContents.inspectElement(x, y); 49 | }, 50 | }, 51 | ]).popup({ window: this.mainWindow }); 52 | }); 53 | } 54 | 55 | buildDarwinTemplate(): MenuItemConstructorOptions[] { 56 | const subMenuAbout: DarwinMenuItemConstructorOptions = { 57 | label: 'Electron', 58 | submenu: [ 59 | { 60 | label: 'About ElectronReact', 61 | selector: 'orderFrontStandardAboutPanel:', 62 | }, 63 | { type: 'separator' }, 64 | { label: 'Services', submenu: [] }, 65 | { type: 'separator' }, 66 | { 67 | label: 'Hide ElectronReact', 68 | accelerator: 'Command+H', 69 | selector: 'hide:', 70 | }, 71 | { 72 | label: 'Hide Others', 73 | accelerator: 'Command+Shift+H', 74 | selector: 'hideOtherApplications:', 75 | }, 76 | { label: 'Show All', selector: 'unhideAllApplications:' }, 77 | { type: 'separator' }, 78 | { 79 | label: 'Quit', 80 | accelerator: 'Command+Q', 81 | click: () => { 82 | app.quit(); 83 | }, 84 | }, 85 | ], 86 | }; 87 | const subMenuEdit: DarwinMenuItemConstructorOptions = { 88 | label: 'Edit', 89 | submenu: [ 90 | { label: 'Undo', accelerator: 'Command+Z', selector: 'undo:' }, 91 | { label: 'Redo', accelerator: 'Shift+Command+Z', selector: 'redo:' }, 92 | { type: 'separator' }, 93 | { label: 'Cut', accelerator: 'Command+X', selector: 'cut:' }, 94 | { label: 'Copy', accelerator: 'Command+C', selector: 'copy:' }, 95 | { label: 'Paste', accelerator: 'Command+V', selector: 'paste:' }, 96 | { 97 | label: 'Select All', 98 | accelerator: 'Command+A', 99 | selector: 'selectAll:', 100 | }, 101 | ], 102 | }; 103 | const subMenuViewDev: MenuItemConstructorOptions = { 104 | label: 'View', 105 | submenu: [ 106 | { 107 | label: 'Reload', 108 | accelerator: 'Command+R', 109 | click: () => { 110 | this.mainWindow.webContents.reload(); 111 | }, 112 | }, 113 | { 114 | label: 'Toggle Full Screen', 115 | accelerator: 'Ctrl+Command+F', 116 | click: () => { 117 | this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen()); 118 | }, 119 | }, 120 | { 121 | label: 'Toggle Developer Tools', 122 | accelerator: 'Alt+Command+I', 123 | click: () => { 124 | this.mainWindow.webContents.toggleDevTools(); 125 | }, 126 | }, 127 | ], 128 | }; 129 | const subMenuViewProd: MenuItemConstructorOptions = { 130 | label: 'View', 131 | submenu: [ 132 | { 133 | label: 'Toggle Full Screen', 134 | accelerator: 'Ctrl+Command+F', 135 | click: () => { 136 | this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen()); 137 | }, 138 | }, 139 | ], 140 | }; 141 | const subMenuWindow: DarwinMenuItemConstructorOptions = { 142 | label: 'Window', 143 | submenu: [ 144 | { 145 | label: 'Minimize', 146 | accelerator: 'Command+M', 147 | selector: 'performMiniaturize:', 148 | }, 149 | { label: 'Close', accelerator: 'Command+W', selector: 'performClose:' }, 150 | { type: 'separator' }, 151 | { label: 'Bring All to Front', selector: 'arrangeInFront:' }, 152 | ], 153 | }; 154 | const subMenuHelp: MenuItemConstructorOptions = { 155 | label: 'Help', 156 | submenu: [ 157 | { 158 | label: 'Learn More', 159 | click() { 160 | shell.openExternal('https://electronjs.org'); 161 | }, 162 | }, 163 | { 164 | label: 'Documentation', 165 | click() { 166 | shell.openExternal( 167 | 'https://github.com/electron/electron/tree/main/docs#readme' 168 | ); 169 | }, 170 | }, 171 | { 172 | label: 'Community Discussions', 173 | click() { 174 | shell.openExternal('https://www.electronjs.org/community'); 175 | }, 176 | }, 177 | { 178 | label: 'Search Issues', 179 | click() { 180 | shell.openExternal('https://github.com/electron/electron/issues'); 181 | }, 182 | }, 183 | ], 184 | }; 185 | 186 | const subMenuView = 187 | process.env.NODE_ENV === 'development' || 188 | process.env.DEBUG_PROD === 'true' 189 | ? subMenuViewDev 190 | : subMenuViewProd; 191 | 192 | return [subMenuAbout, subMenuEdit, subMenuView, subMenuWindow, subMenuHelp]; 193 | } 194 | 195 | buildDefaultTemplate() { 196 | const templateDefault = [ 197 | { 198 | label: '&File', 199 | submenu: [ 200 | { 201 | label: '&Open', 202 | accelerator: 'Ctrl+O', 203 | }, 204 | { 205 | label: '&Close', 206 | accelerator: 'Ctrl+W', 207 | click: () => { 208 | this.mainWindow.close(); 209 | }, 210 | }, 211 | ], 212 | }, 213 | { 214 | label: '&View', 215 | submenu: 216 | process.env.NODE_ENV === 'development' || 217 | process.env.DEBUG_PROD === 'true' 218 | ? [ 219 | { 220 | label: '&Reload', 221 | accelerator: 'Ctrl+R', 222 | click: () => { 223 | this.mainWindow.webContents.reload(); 224 | }, 225 | }, 226 | { 227 | label: 'Toggle &Full Screen', 228 | accelerator: 'F11', 229 | click: () => { 230 | this.mainWindow.setFullScreen( 231 | !this.mainWindow.isFullScreen() 232 | ); 233 | }, 234 | }, 235 | { 236 | label: 'Toggle &Developer Tools', 237 | accelerator: 'Alt+Ctrl+I', 238 | click: () => { 239 | this.mainWindow.webContents.toggleDevTools(); 240 | }, 241 | }, 242 | ] 243 | : [ 244 | { 245 | label: 'Toggle &Full Screen', 246 | accelerator: 'F11', 247 | click: () => { 248 | this.mainWindow.setFullScreen( 249 | !this.mainWindow.isFullScreen() 250 | ); 251 | }, 252 | }, 253 | ], 254 | }, 255 | { 256 | label: 'Help', 257 | submenu: [ 258 | { 259 | label: 'Learn More', 260 | click() { 261 | shell.openExternal('https://electronjs.org'); 262 | }, 263 | }, 264 | { 265 | label: 'Documentation', 266 | click() { 267 | shell.openExternal( 268 | 'https://github.com/electron/electron/tree/main/docs#readme' 269 | ); 270 | }, 271 | }, 272 | { 273 | label: 'Community Discussions', 274 | click() { 275 | shell.openExternal('https://www.electronjs.org/community'); 276 | }, 277 | }, 278 | { 279 | label: 'Search Issues', 280 | click() { 281 | shell.openExternal('https://github.com/electron/electron/issues'); 282 | }, 283 | }, 284 | ], 285 | }, 286 | ]; 287 | 288 | return templateDefault; 289 | } 290 | } 291 | -------------------------------------------------------------------------------- /src/renderer/components/MenuBar2.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 6 | import { faWallet, faIndustry, faTerminal, faScroll, faBars, faBug, faKey, faServer, faRadiation, faHeadphones, faTable } from '@fortawesome/free-solid-svg-icons'; 7 | import ReactTooltip from 'react-tooltip'; 8 | import Modal from 'react-responsive-modal'; 9 | 10 | import FormControl from '@material-ui/core/FormControl'; 11 | import FormHelperText from '@material-ui/core/FormHelperText'; 12 | import InputLabel from '@material-ui/core/InputLabel'; 13 | import TextField from '@material-ui/core/TextField'; 14 | import Input from '@material-ui/core/Input'; 15 | import Button from '@material-ui/core/Button'; 16 | import Grid from '@material-ui/core/Grid'; 17 | 18 | 19 | import styles from './Home.css'; 20 | 21 | const remote = require('electron').remote; 22 | 23 | import Settings from './menus/Settings'; 24 | import Listeners from './menus/Listeners'; 25 | 26 | import payloadGenerator from '../renderers/backdoor-factory'; 27 | 28 | 29 | export default class MenuBar extends Component { 30 | props: Props; 31 | 32 | constructor(props) { 33 | super(props); 34 | 35 | this.state = { 36 | open: false, 37 | showSettings: false, 38 | showListeners: false, 39 | payload: "Gryffindor", 40 | listener: "", 41 | c2profile: "default.profile", 42 | loader: false, 43 | }; 44 | this.toggleSettings = this.toggleSettings.bind(this) 45 | this.toggleListeners = this.toggleListeners.bind(this) 46 | } 47 | 48 | toggleSettings() { 49 | if (this.state.showSettings == true) { 50 | this.setState({ showSettings: false }); 51 | } else { 52 | this.setState({ showSettings: true }); 53 | } 54 | } 55 | toggleListeners() { 56 | if (this.state.showListeners == true) { 57 | this.setState({ showListeners: false }); 58 | } else { 59 | this.setState({ showListeners: true }); 60 | } 61 | } 62 | openBackdoorFactory() { 63 | this.setState({ open: true }); 64 | } 65 | closeBackdoorFactory() { 66 | this.setState({ open: false }); 67 | } 68 | generatePayload() { 69 | this.closeBackdoorFactory(); 70 | this.showLoader(); 71 | 72 | var settings = { 73 | "name": "Gryffindor", 74 | "listener": this.state.listener, 75 | "profile": this.state.c2profile 76 | } 77 | 78 | payloadGenerator(settings); 79 | } 80 | showLoader() { 81 | this.setState({ loader: true }); 82 | setTimeout(function() { //Start the timer 83 | this.setState({loader: false}) //After 1 second, set render to true 84 | }.bind(this), 3000) 85 | } 86 | 87 | handleChange = name => event => { 88 | this.setState({ [name]: event.target.value }); 89 | }; 90 | 91 | render() { 92 | const { 93 | increment, 94 | incrementIfOdd, 95 | incrementAsync, 96 | decrement, 97 | counter 98 | } = this.props; 99 | const { open } = this.state; 100 | const payloads = [ 101 | { 102 | name: "Gryffindor" 103 | } 104 | ] 105 | const Loading = () => { 106 | return ( 107 |
108 | 109 |

Saving payload to engagement directory...

110 |
111 | ) 112 | } 113 | return ( 114 |
115 |
116 | {this.state.loader ? : null } 117 |
118 | 119 |
120 |
121 | 122 |
123 |
124 | 125 |
126 |
127 | 128 |
129 |
130 | 131 |
132 |
133 | 134 |
135 |
136 | 137 |
138 |
139 | 140 |
141 |
142 | 143 |
144 |
145 | 146 |
147 |
148 | 149 |
150 |
151 | 152 |
153 |
154 | 162 |
163 |

Backdoor Factory

164 |
165 | 166 | 167 | 168 | 184 | {payloads.map(option => ( 185 | 188 | ))} 189 | 190 | 191 | 192 | 193 |
194 |
195 | 196 | 197 | 198 | Listener 199 | 208 | 209 | 210 | 211 | 212 | C2 Profile 213 | 222 | 223 | 224 | 225 |
226 |
227 |
228 | 229 | 232 | 233 | 234 |
235 |
236 | {this.state.showSettings ? : null } 237 | {this.state.showListeners ? : null } 238 |
239 | ); 240 | } 241 | } 242 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sirius-scan", 3 | "description": "A foundation for scalable desktop apps", 4 | "scripts": { 5 | "build": "concurrently \"npm run build:main\" \"npm run build:renderer\"", 6 | "build:main": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.main.prod.ts", 7 | "build:renderer": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.prod.ts", 8 | "rebuild": "electron-rebuild --parallel --types prod,dev,optional --module-dir release/app", 9 | "lint": "cross-env NODE_ENV=development eslint . --ext .js,.jsx,.ts,.tsx", 10 | "package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --win --ia32 --publish never", 11 | "postinstall": "ts-node .erb/scripts/check-native-dep.js && electron-builder install-app-deps && cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.dev.dll.ts && opencollective-postinstall", 12 | "start": "ts-node ./.erb/scripts/check-port-in-use.js && npm run start:renderer", 13 | "start:main": "cross-env NODE_ENV=development electron -r ts-node/register/transpile-only ./src/main/main.ts", 14 | "start:preload": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.preload.dev.ts", 15 | "start:renderer": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.renderer.dev.ts", 16 | "test": "jest", 17 | "prepare": "husky install" 18 | }, 19 | "lint-staged": { 20 | "*.{js,jsx,ts,tsx}": [ 21 | "cross-env NODE_ENV=development eslint --cache" 22 | ], 23 | "*.json,.{eslintrc,prettierrc}": [ 24 | "prettier --ignore-path .eslintignore --parser json --write" 25 | ], 26 | "*.{css,scss}": [ 27 | "prettier --ignore-path .eslintignore --single-quote --write" 28 | ], 29 | "*.{html,md,yml}": [ 30 | "prettier --ignore-path .eslintignore --single-quote --write" 31 | ] 32 | }, 33 | "build": { 34 | "productName": "SiriusScan", 35 | "appId": "org.erb.SiriusScan", 36 | "asar": true, 37 | "asarUnpack": "**\\*.{node,dll}", 38 | "files": [ 39 | "dist", 40 | "node_modules", 41 | "package.json" 42 | ], 43 | "afterSign": ".erb/scripts/notarize.js", 44 | "mac": { 45 | "target": { 46 | "target": "default", 47 | "arch": [ 48 | "arm64", 49 | "x64" 50 | ] 51 | }, 52 | "type": "distribution", 53 | "hardenedRuntime": true, 54 | "entitlements": "assets/entitlements.mac.plist", 55 | "entitlementsInherit": "assets/entitlements.mac.plist", 56 | "gatekeeperAssess": false 57 | }, 58 | "dmg": { 59 | "contents": [ 60 | { 61 | "x": 130, 62 | "y": 220 63 | }, 64 | { 65 | "x": 410, 66 | "y": 220, 67 | "type": "link", 68 | "path": "/Applications" 69 | } 70 | ] 71 | }, 72 | "win": { 73 | "target": [ 74 | "nsis" 75 | ] 76 | }, 77 | "linux": { 78 | "target": [ 79 | "AppImage" 80 | ], 81 | "category": "Development" 82 | }, 83 | "directories": { 84 | "app": "release/app", 85 | "buildResources": "assets", 86 | "output": "release/build" 87 | }, 88 | "extraResources": [ 89 | "./assets/**" 90 | ], 91 | "publish": { 92 | "provider": "github", 93 | "owner": "electron-react-boilerplate", 94 | "repo": "electron-react-boilerplate" 95 | } 96 | }, 97 | "repository": { 98 | "type": "git", 99 | "url": "git+https://github.com/electron-react-boilerplate/electron-react-boilerplate.git" 100 | }, 101 | "author": { 102 | "name": "Electron React Boilerplate Maintainers", 103 | "email": "electronreactboilerplate@gmail.com", 104 | "url": "https://electron-react-boilerplate.js.org" 105 | }, 106 | "contributors": [ 107 | { 108 | "name": "Amila Welihinda", 109 | "email": "amilajack@gmail.com", 110 | "url": "https://github.com/amilajack" 111 | }, 112 | { 113 | "name": "John Tran", 114 | "email": "jptran318@gmail.com", 115 | "url": "https://github.com/jooohhn" 116 | } 117 | ], 118 | "license": "MIT", 119 | "bugs": { 120 | "url": "https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues" 121 | }, 122 | "keywords": [ 123 | "electron", 124 | "boilerplate", 125 | "react", 126 | "typescript", 127 | "ts", 128 | "sass", 129 | "webpack", 130 | "hot", 131 | "reload" 132 | ], 133 | "homepage": "https://github.com/electron-react-boilerplate/electron-react-boilerplate#readme", 134 | "jest": { 135 | "testURL": "http://localhost/", 136 | "testEnvironment": "jsdom", 137 | "transform": { 138 | "\\.(ts|tsx|js|jsx)$": "ts-jest" 139 | }, 140 | "moduleNameMapper": { 141 | "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/.erb/mocks/fileMock.js", 142 | "\\.(css|less|sass|scss)$": "identity-obj-proxy" 143 | }, 144 | "moduleFileExtensions": [ 145 | "js", 146 | "jsx", 147 | "ts", 148 | "tsx", 149 | "json" 150 | ], 151 | "moduleDirectories": [ 152 | "node_modules", 153 | "release/app/node_modules" 154 | ], 155 | "testPathIgnorePatterns": [ 156 | "release/app/dist" 157 | ], 158 | "setupFiles": [ 159 | "./.erb/scripts/check-build-exists.ts" 160 | ] 161 | }, 162 | "devDependencies": { 163 | "@pmmmwh/react-refresh-webpack-plugin": "0.5.5", 164 | "@teamsupercell/typings-for-css-modules-loader": "^2.5.1", 165 | "@testing-library/jest-dom": "^5.16.4", 166 | "@testing-library/react": "^13.0.0", 167 | "@types/jest": "^27.4.1", 168 | "@types/node": "17.0.23", 169 | "@types/react": "^17.0.43", 170 | "@types/react-dom": "^17.0.14", 171 | "@types/react-test-renderer": "^17.0.1", 172 | "@types/terser-webpack-plugin": "^5.0.4", 173 | "@types/webpack-bundle-analyzer": "^4.4.1", 174 | "@types/webpack-env": "^1.16.3", 175 | "@typescript-eslint/eslint-plugin": "^5.18.0", 176 | "@typescript-eslint/parser": "^5.18.0", 177 | "browserslist-config-erb": "^0.0.3", 178 | "chalk": "^4.1.2", 179 | "concurrently": "^7.1.0", 180 | "core-js": "^3.21.1", 181 | "cross-env": "^7.0.3", 182 | "css-loader": "^6.7.1", 183 | "css-minimizer-webpack-plugin": "^3.4.1", 184 | "detect-port": "^1.3.0", 185 | "electron": "^18.0.1", 186 | "electron-builder": "22.14.13", 187 | "electron-devtools-installer": "^3.2.0", 188 | "electron-notarize": "^1.2.1", 189 | "electron-rebuild": "^3.2.7", 190 | "eslint": "^8.12.0", 191 | "eslint-config-airbnb-base": "^15.0.0", 192 | "eslint-config-erb": "^4.0.3", 193 | "eslint-import-resolver-typescript": "^2.7.1", 194 | "eslint-import-resolver-webpack": "^0.13.2", 195 | "eslint-plugin-compat": "^4.0.2", 196 | "eslint-plugin-import": "^2.25.4", 197 | "eslint-plugin-jest": "^26.1.3", 198 | "eslint-plugin-jsx-a11y": "^6.5.1", 199 | "eslint-plugin-promise": "^6.0.0", 200 | "eslint-plugin-react": "^7.29.4", 201 | "eslint-plugin-react-hooks": "^4.4.0", 202 | "file-loader": "^6.2.0", 203 | "html-webpack-plugin": "^5.5.0", 204 | "husky": "^7.0.4", 205 | "identity-obj-proxy": "^3.0.0", 206 | "jest": "^27.5.1", 207 | "lint-staged": "^12.3.7", 208 | "mini-css-extract-plugin": "^2.6.0", 209 | "opencollective-postinstall": "^2.0.3", 210 | "prettier": "^2.6.2", 211 | "react-refresh": "^0.12.0", 212 | "react-refresh-typescript": "^2.0.4", 213 | "react-test-renderer": "^18.0.0", 214 | "rimraf": "^3.0.2", 215 | "sass": "^1.49.11", 216 | "sass-loader": "^12.6.0", 217 | "style-loader": "^3.3.1", 218 | "terser-webpack-plugin": "^5.3.1", 219 | "ts-jest": "^27.1.4", 220 | "ts-loader": "^9.2.8", 221 | "ts-node": "^10.7.0", 222 | "typescript": "^4.6.3", 223 | "url-loader": "^4.1.1", 224 | "webpack": "^5.71.0", 225 | "webpack-bundle-analyzer": "^4.5.0", 226 | "webpack-cli": "^4.9.2", 227 | "webpack-dev-server": "^4.8.0", 228 | "webpack-merge": "^5.8.0" 229 | }, 230 | "dependencies": { 231 | "@emotion/react": "^11.9.0", 232 | "@emotion/styled": "^11.8.1", 233 | "@fortawesome/fontawesome-svg-core": "^6.1.1", 234 | "@fortawesome/free-brands-svg-icons": "^6.1.1", 235 | "@fortawesome/free-regular-svg-icons": "^6.1.1", 236 | "@fortawesome/free-solid-svg-icons": "^6.1.1", 237 | "@fortawesome/react-fontawesome": "^0.1.18", 238 | "@mui/icons-material": "^5.6.0", 239 | "@mui/material": "^5.6.0", 240 | "chart.js": "^3.7.1", 241 | "electron-debug": "^3.2.0", 242 | "electron-log": "^4.4.6", 243 | "electron-updater": "^4.6.5", 244 | "fs": "^0.0.1-security", 245 | "history": "^5.3.0", 246 | "react": "^18.0.0", 247 | "react-dom": "^18.0.0", 248 | "react-router-dom": "^6.3.0", 249 | "react-tooltip": "^4.2.21", 250 | "react-vis": "^1.11.7", 251 | "recharts": "^2.1.9" 252 | }, 253 | "devEngines": { 254 | "node": ">=14.x", 255 | "npm": ">=7.x" 256 | }, 257 | "collective": { 258 | "url": "https://opencollective.com/electron-react-boilerplate-594" 259 | }, 260 | "browserslist": [], 261 | "prettier": { 262 | "overrides": [ 263 | { 264 | "files": [ 265 | ".prettierrc", 266 | ".eslintrc" 267 | ], 268 | "options": { 269 | "parser": "json" 270 | } 271 | } 272 | ], 273 | "singleQuote": true 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /src/renderer/components/host/NewHost.tsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, { Component } from 'react'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | import Paper from '@mui/material/Paper'; 6 | import Card from '@mui/material/Card'; 7 | import Grid from '@mui/material/Grid'; 8 | import CardActions from '@mui/material/CardActions'; 9 | import CardContent from '@mui/material/CardContent'; 10 | import Typography from '@mui/material/Typography'; 11 | import Box from '@mui/material/Box'; 12 | 13 | import Divider from '@mui/material/Divider'; 14 | import Chip from '@mui/material/Chip'; 15 | import Autocomplete from '@mui/material/Autocomplete'; 16 | import TextField from '@mui/material/TextField'; 17 | import Stack from '@mui/material/Stack'; 18 | 19 | import Table from '@mui/material/Table'; 20 | import TableBody from '@mui/material/TableBody'; 21 | import TableCell from '@mui/material/TableCell'; 22 | import TableContainer from '@mui/material/TableContainer'; 23 | import TableHead from '@mui/material/TableHead'; 24 | import TableRow from '@mui/material/TableRow'; 25 | 26 | import Close from '@mui/icons-material/Close'; 27 | import Add from '@mui/icons-material/Add'; 28 | import IndeterminateCheckBoxIcon from '@mui/icons-material/IndeterminateCheckBox'; 29 | import UploadFileRoundedIcon from '@mui/icons-material/UploadFileRounded'; 30 | import Button from '@mui/material/Button'; 31 | 32 | import { getHosts, addHost, getVendors } from '../../actions/api/db.js'; 33 | 34 | import '../Home.css'; 35 | 36 | const vendors = [ 37 | { 38 | "vendor_name": "\\$0.99_kindle_books_project", 39 | "product": null 40 | }, 41 | { 42 | "vendor_name": "-", 43 | "product": null 44 | }, 45 | { 46 | "vendor_name": ".bbsoftware", 47 | "product": [ 48 | { 49 | "product_name": "wireless_ip_camera_360" 50 | } 51 | ] 52 | }, 53 | { 54 | "vendor_name": ".joomclan", 55 | "product": [ 56 | { 57 | "product_name": "wireless_ip_camera_360" 58 | } 59 | ] 60 | }, 61 | { 62 | "vendor_name": ".matteoiammarrone", 63 | "product": [ 64 | { 65 | "product_name": "wireless_ip_camera_360" 66 | } 67 | ] 68 | }, 69 | { 70 | "vendor_name": "\\@mail", 71 | "product": [ 72 | { 73 | "product_name": "wireless_ip_camera_360" 74 | }, 75 | { 76 | "product_name": "iamma_simple_gallery" 77 | } 78 | ] 79 | }, 80 | { 81 | "vendor_name": "\\@thi.ng\\/egf_project", 82 | "product": [ 83 | { 84 | "product_name": "wireless_ip_camera_360" 85 | }, 86 | { 87 | "product_name": "iamma_simple_gallery" 88 | } 89 | ] 90 | }, 91 | { 92 | "vendor_name": "\\[gwa\\]_autoresponder_project", 93 | "product": [ 94 | { 95 | "product_name": "wireless_ip_camera_360" 96 | }, 97 | { 98 | "product_name": "iamma_simple_gallery" 99 | } 100 | ] 101 | }, 102 | { 103 | "vendor_name": "_akindo_sushiro_co_ltd", 104 | "product": [ 105 | { 106 | "product_name": "wireless_ip_camera_360" 107 | }, 108 | { 109 | "product_name": "iamma_simple_gallery" 110 | } 111 | ] 112 | }, 113 | { 114 | "vendor_name": "_wp_favorite_posts_project", 115 | "product": [ 116 | { 117 | "product_name": "wireless_ip_camera_360" 118 | }, 119 | { 120 | "product_name": "iamma_simple_gallery" 121 | }, 122 | { 123 | "product_name": "sushiro" 124 | } 125 | ] 126 | }, 127 | { 128 | "vendor_name": "0verkill", 129 | "product": [ 130 | { 131 | "product_name": "wireless_ip_camera_360" 132 | }, 133 | { 134 | "product_name": "iamma_simple_gallery" 135 | }, 136 | { 137 | "product_name": "sushiro" 138 | } 139 | ] 140 | }, 141 | { 142 | "vendor_name": "1-script", 143 | "product": [ 144 | { 145 | "product_name": "wireless_ip_camera_360" 146 | }, 147 | { 148 | "product_name": "iamma_simple_gallery" 149 | }, 150 | { 151 | "product_name": "sushiro" 152 | } 153 | ] 154 | }, 155 | { 156 | "vendor_name": "10web", 157 | "product": [ 158 | { 159 | "product_name": "wireless_ip_camera_360" 160 | }, 161 | { 162 | "product_name": "iamma_simple_gallery" 163 | }, 164 | { 165 | "product_name": "sushiro" 166 | } 167 | ] 168 | } 169 | ]; 170 | 171 | class NewHost extends React.Component { 172 | constructor(props) { 173 | super(props); 174 | 175 | this.state = { 176 | open: false, 177 | os: '', 178 | osversion: '', 179 | ip: '', 180 | hostname: '', 181 | port: null, 182 | product: '', 183 | vendor: '', 184 | pversion: '', 185 | cpe: [], 186 | vendors: [], 187 | products: [ 188 | { name: 'Apache' }, 189 | ], 190 | tags: [], 191 | }; 192 | this.handleChange = this.handleChange.bind(this); 193 | this.handleSubmit = this.handleSubmit.bind(this); 194 | this.handleVendorChange = this.handleVendorChange.bind(this); 195 | this.handleProductChange = this.handleProductChange.bind(this); 196 | this.addCPE = this.addCPE.bind(this); 197 | this.fetchHosts = this.fetchHosts.bind(this); 198 | this.submitHost = this.submitHost.bind(this); 199 | } 200 | 201 | fetchHosts() { 202 | getHosts().then((hosts) => { 203 | console.log(hosts); 204 | }); 205 | } 206 | 207 | componentDidMount() { 208 | getVendors().then((vendors) => { 209 | console.log(vendors); 210 | if (vendors) { 211 | this.setState({ vendors: vendors }); 212 | } 213 | }); 214 | } 215 | 216 | submitHost() { 217 | // HOST CREATION FROM STATE DATA 218 | this.props.disableViews(); 219 | const host = { 220 | os: this.state.os, 221 | osversion: this.state.osversion, 222 | ip: this.state.ip, 223 | hostname: this.state.hostname, 224 | cpe: this.state.cpe, 225 | }; 226 | addHost(host).then((res) => { 227 | console.log(res); 228 | }); 229 | } 230 | 231 | handleVendorChange(event, values) { 232 | //Get products from vendor 233 | const productList = []; 234 | console.log(values) 235 | for (let i = 0; i < this.state.vendors.length; i++) { 236 | if (this.state.vendors[i].vendor_name === values) { 237 | if (this.state.vendors[i].product) { 238 | for (let j = 0; j < this.state.vendors[i].product.length; j++) { 239 | var product = this.state.vendors[i].product[j].product_name//.replace(/\\/g, ''); 240 | productList.push({ 241 | name: product, 242 | }); 243 | } 244 | } 245 | } 246 | } 247 | //Remove escape characters from vendor name 248 | values = values.replace(/\\/g, ''); 249 | 250 | 251 | this.setState({ 252 | products: productList, 253 | vendor: values, 254 | }); 255 | console.log(this.state.products); 256 | } 257 | handleProductChange(event, values) { 258 | console.log(values) 259 | 260 | this.setState({ 261 | product: values, 262 | }); 263 | console.log(this.state.product); 264 | } 265 | 266 | handleChange(event) { 267 | const target = event.target; 268 | const value = target.type === 'checkbox' ? target.checked : target.value; 269 | const name = target.name; 270 | 271 | this.setState({ 272 | [name]: value, 273 | }); 274 | } 275 | addCPE() { 276 | const newcpe ="cpe:2.3:a:" + this.state.vendor + ':' + this.state.product + ':' + this.state.pversion + ':*:*:*:*:*:*:*' 277 | 278 | this.setState({ 279 | cpe: [...this.state.cpe, newcpe], 280 | }); 281 | console.log(newcpe); 282 | } 283 | 284 | handleSubmit(event) { 285 | alert('A name was submitted: ' + this.state.value); 286 | event.preventDefault(); 287 | } 288 | 289 | render() { 290 | const { error, isLoaded, items } = this.state; 291 | return ( 292 |
293 | 294 | 295 | 296 | New Host Details{' '} 297 | 301 |
302 |
303 | 304 | option.title)} 308 | defaultValue={[hostTags[2].title]} 309 | freeSolo 310 | renderTags={(value: readonly string[], getTagProps) => 311 | value.map((option: string, index: number) => ( 312 | 317 | )) 318 | } 319 | renderInput={(params) => ( 320 | 326 | )} 327 | /> 328 | 329 | 330 | 331 | 332 | 333 | :not(style)': { m: 1, width: '25ch' }, 337 | marginTop: '15px', 338 | }} 339 | noValidate 340 | autoComplete="off" 341 | > 342 | 349 | 356 | 363 | 364 | 365 | 366 | 367 | :not(style)': { m: 1, width: '25ch' }, 371 | marginTop: '15px', 372 | }} 373 | noValidate 374 | autoComplete="off" 375 | > 376 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 397 | 398 | 399 | CPE 400 | 401 | 402 | 403 | {this.state.cpe.map((row, i) => ( 404 | 410 | {row} 411 | 412 | ))} 413 | 414 |
415 |
416 | 417 | :not(style)': { m: 1 }, 421 | marginTop: '15px', 422 | }} 423 | noValidate 424 | autoComplete="off" 425 | > 426 | option.vendor_name)} 431 | sx={{ width: 300 }} 432 | onChange={this.handleVendorChange} 433 | renderInput={(params) => } 440 | /> 441 | option.name)} 447 | sx={{ width: 300 }} 448 | onChange={this.handleProductChange} 449 | renderInput={(params) => } 456 | /> 457 | 464 | 471 | 472 |
473 |
474 | 475 | 476 | 477 | 478 |
479 | 482 |
483 |
484 |
485 |
486 |
487 |
488 | ); 489 | } 490 | } 491 | 492 | // Host Tags Get From Host DB Component Mount // Hardcoding for now 493 | const hostTags = [ 494 | { title: 'Compliance Required', year: 1994 }, 495 | { title: 'Critical Asset', year: 1972 }, 496 | { title: 'Windows', year: 1974 }, 497 | { title: 'Linux', year: 2008 }, 498 | { title: 'NERC-SIP', year: 1957 }, 499 | { title: 'PCI', year: 1993 }, 500 | ]; 501 | 502 | 503 | 504 | 505 | export default NewHost; 506 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 2.1.0 2 | 3 | - Migrate to `css-minifier-webpack-plugin` 4 | 5 | # 2.0.1 6 | 7 | ## Fixes 8 | 9 | - Fix broken css linking in production build 10 | 11 | # 2.0.0 12 | 13 | ## Breaking Changes 14 | 15 | - drop redux 16 | - remove counter example app 17 | - simplify directory structure 18 | - move `dll` dir to `.erb` dir 19 | - fix icon/font import paths 20 | - migrate to `react-refresh` from `react-hot-loader` 21 | - migrate to webpack@5 22 | - migrate to electron@11 23 | - remove e2e tests and testcafe integration 24 | - rename `app` dir to more conventional `src` dir 25 | - rename `resources` dir to `assets` 26 | - simplify npm scripts 27 | - drop stylelint 28 | - simplify styling of boilerplate app 29 | - remove `START_HOT` env variable 30 | - notarize support 31 | - landing page boilerplate 32 | - docs updates 33 | - restore removed debugging support 34 | 35 | # 1.4.0 36 | 37 | - Migrate to `eslint-config-erb@2` 38 | - Rename `dev` npm script to `start` 39 | - GitHub Actions: only publish GitHub releases when on master branch 40 | 41 | # 1.3.1 42 | 43 | - Fix sass building bug ([#2540](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2540)) 44 | - Fix CI bug related to E2E tests and network timeouts 45 | - Move automated dependency PRs to `next` ([#2554](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2554)) 46 | - Bump dependencies to patch semver 47 | 48 | # 1.3.0 49 | 50 | - Fixes E2E tests ([#2516](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2516)) 51 | - Fixes preload entrypoint ([#2503](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2503)) 52 | - Downgrade to `electron@8` 53 | - Bump dependencies to latest semver 54 | 55 | # 1.2.0 56 | 57 | - Migrate to redux toolkit 58 | - Lazy load routes with react suspense 59 | - Drop support for azure-pipelines and use only github actions 60 | - Bump all deps to latest semver 61 | - Remove `test-e2e` script from tests (blocked on release of https://github.com/DevExpress/testcafe-browser-provider-electron/pull/65) 62 | - Swap `typed-css-modules-webpack-plugin` for `typings-for-css-modules-loader` 63 | - Use latest version of `eslint-config-erb` 64 | - Remove unnecessary file extensions from ts exclude 65 | - Add experimental support for vscode debugging 66 | - Revert https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2365 as default for users, provide as opt in option 67 | 68 | # 1.1.0 69 | 70 | - Fix #2402 71 | - Simplify configs (https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2406) 72 | 73 | # 1.0.0 74 | 75 | - Migrate to TypeScript from Flow ([#2363](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2363)) 76 | - Use browserslist for `@babel/preset-env` targets ([#2368](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2368)) 77 | - Use preload script, disable `nodeIntegration` in renderer process for [improved security](https://www.electronjs.org/docs/tutorial/security#2-do-not-enable-nodejs-integration-for-remote-content) ([#2365](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2365)) 78 | - Add support for azure pipelines ([#2369](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2369)) 79 | - Disable sourcemaps in production 80 | 81 | # 0.18.1 (2019.12.12) 82 | 83 | - Fix HMR env bug ([#2343](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2343)) 84 | - Bump all deps to latest semver 85 | - Bump to `electron@7` 86 | 87 | # 0.18.0 (2019.11.19) 88 | 89 | - Bump electron to `electron@6` (`electron@7` introduces breaking changes to testcafe end to end tests) 90 | - Revert back to [two `package.json` structure](https://www.electron.build/tutorials/two-package-structure) 91 | - Bump all deps to latest semver 92 | 93 | # 0.17.1 (2018.11.20) 94 | 95 | - Fix `yarn test-e2e` and testcafe for single package.json structure 96 | - Fixes incorrect path in `yarn start` script 97 | - Bumped deps 98 | - Bump g++ in travis 99 | - Change clone arguments to clone only master 100 | - Change babel config to target current electron version 101 | 102 | For full change list, see https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2021 103 | 104 | # 0.17.0 (2018.10.30) 105 | 106 | - upgraded to `babel@7` (thanks to @vikr01 🎉🎉🎉) 107 | - migrated from [two `package.json` structure](https://www.electron.build/tutorials/two-package-structure) (thanks to @HyperSprite!) 108 | - initial auto update support (experimental) 109 | - migrate from greenkeeper to [renovate](https://renovatebot.com) 110 | - added issue template 111 | - use `babel-preset-env` to target current electron version 112 | - add [opencollective](https://opencollective.com/electron-react-boilerplate-594) banner message display in postinstall script (help support ERB 🙏) 113 | - fix failing ci issues 114 | 115 | # 0.16.0 (2018.10.3) 116 | 117 | - removed unused dependencies 118 | - migrate from `react-redux-router` to `connect-react-router` 119 | - move webpack configs to `./webpack` dir 120 | - use `g++` on travis when testing linux 121 | - migrate from `spectron` to `testcafe` for e2e tests 122 | - add linting support for config styles 123 | - changed stylelint config 124 | - temporarily disabled flow in appveyor to make ci pass 125 | - added necessary infra to publish releases from ci 126 | 127 | # 0.15.0 (2018.8.25) 128 | 129 | - Performance: cache webpack uglify results 130 | - Feature: add start minimized feature 131 | - Feature: lint and fix styles with prettier and stylelint 132 | - Feature: add greenkeeper support 133 | 134 | # 0.14.0 (2018.5.24) 135 | 136 | - Improved CI timings 137 | - Migrated README commands to yarn from npm 138 | - Improved vscode config 139 | - Updated all dependencies to latest semver 140 | - Fix `electron-rebuild` script bug 141 | - Migrated to `mini-css-extract-plugin` from `extract-text-plugin` 142 | - Added `optimize-css-assets-webpack-plugin` 143 | - Run `prettier` on json, css, scss, and more filetypes 144 | 145 | # 0.13.3 (2018.5.24) 146 | 147 | - Add git precommit hook, when git commit will use `prettier` to format git add code 148 | - Add format code function in `lint-fix` npm script which can use `prettier` to format project js code 149 | 150 | # 0.13.2 (2018.1.31) 151 | 152 | - Hot Module Reload (HMR) fixes 153 | - Bumped all dependencies to latest semver 154 | - Prevent error propagation of `CheckNativeDeps` script 155 | 156 | # 0.13.1 (2018.1.13) 157 | 158 | - Hot Module Reload (HMR) fixes 159 | - Bumped all dependencies to latest semver 160 | - Fixed electron-rebuild script 161 | - Fixed tests scripts to run on all platforms 162 | - Skip redux logs in console in test ENV 163 | 164 | # 0.13.0 (2018.1.6) 165 | 166 | #### Additions 167 | 168 | - Add native dependencies check on postinstall 169 | - Updated all dependencies to latest semver 170 | 171 | # 0.12.0 (2017.7.8) 172 | 173 | #### Misc 174 | 175 | - Removed `babel-polyfill` 176 | - Renamed and alphabetized npm scripts 177 | 178 | #### Breaking 179 | 180 | - Changed node dev `__dirname` and `__filename` to node built in fn's (https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/1035) 181 | - Renamed `src/bundle.js` to `src/renderer.prod.js` for consistency 182 | - Renamed `dll/vendor.js` to `dll/renderer.dev.dll.js` for consistency 183 | 184 | #### Additions 185 | 186 | - Enable node_modules cache on CI 187 | 188 | # 0.11.2 (2017.5.1) 189 | 190 | Yay! Another patch release. This release mostly includes refactorings and router bug fixes. Huge thanks to @anthonyraymond! 191 | 192 | ⚠️ Windows electron builds are failing because of [this issue](https://github.com/electron/electron/issues/9321). This is not an issue with the boilerplate ⚠️ 193 | 194 | #### Breaking 195 | 196 | - **Renamed `./src/main.development.js` => `./src/main.{dev,prod}.js`:** [#963](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/963) 197 | 198 | #### Fixes 199 | 200 | - **Fixed reloading when not on `/` path:** [#958](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/958) [#949](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/949) 201 | 202 | #### Additions 203 | 204 | - **Added support for stylefmt:** [#960](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/960) 205 | 206 | # 0.11.1 (2017.4.23) 207 | 208 | You can now debug the production build with devtools like so: 209 | 210 | ``` 211 | DEBUG_PROD=true npm run package 212 | ``` 213 | 214 | 🎉🎉🎉 215 | 216 | #### Additions 217 | 218 | - **Added support for debugging production build:** [#fab245a](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/941/commits/fab245a077d02a09630f74270806c0c534a4ff95) 219 | 220 | #### Bug Fixes 221 | 222 | - **Fixed bug related to importing native dependencies:** [#933](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/933) 223 | 224 | #### Improvements 225 | 226 | - **Updated all deps to latest semver** 227 | 228 | # 0.11.0 (2017.4.19) 229 | 230 | Here's the most notable changes since `v0.10.0`. Its been about a year since a release has been pushed. Expect a new release to be published every 3-4 weeks. 231 | 232 | #### Breaking Changes 233 | 234 | - **Dropped support for node < 6** 235 | - **Refactored webpack config files** 236 | - **Migrate to two-package.json project structure** 237 | - **Updated all devDeps to latest semver** 238 | - **Migrated to Jest:** [#768](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/768) 239 | - **Migrated to `react-router@4`** 240 | - **Migrated to `electron-builder@4`** 241 | - **Migrated to `webpack@2`** 242 | - **Migrated to `react-hot-loader@3`** 243 | - **Changed default live reload server PORT to `1212` from `3000`** 244 | 245 | #### Additions 246 | 247 | - **Added support for Yarn:** [#451](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/451) 248 | - **Added support for Flow:** [#425](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/425) 249 | - **Added support for stylelint:** [#911](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/911) 250 | - **Added support for electron-builder:** [#876](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/876) 251 | - **Added optional support for SASS:** [#880](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/880) 252 | - **Added support for eslint-plugin-flowtype:** [#911](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/911) 253 | - **Added support for appveyor:** [#280](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/280) 254 | - **Added support for webpack dlls:** [#860](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/860) 255 | - **Route based code splitting:** [#884](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/884) 256 | - **Added support for Webpack Bundle Analyzer:** [#922](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/922) 257 | 258 | #### Improvements 259 | 260 | - **Parallelize renderer and main build processes when running `npm run build`** 261 | - **Dynamically generate electron app menu** 262 | - **Improved vscode integration:** [#856](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/856) 263 | 264 | #### Bug Fixes 265 | 266 | - **Fixed hot module replacement race condition bug:** [#917](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/917) [#920](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/920) 267 | 268 | # 0.10.0 (2016.4.18) 269 | 270 | #### Improvements 271 | 272 | - **Use Babel in main process with Webpack build:** [#201](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/201) 273 | - **Change targets to built-in support by webpack:** [#197](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/197) 274 | - **use es2015 syntax for webpack configs:** [#195](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/195) 275 | - **Open application when webcontent is loaded:** [#192](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/192) 276 | - **Upgraded dependencies** 277 | 278 | #### Bug fixed 279 | 280 | - **Fix `npm list electron-prebuilt` in package.js:** [#188](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/188) 281 | 282 | # 0.9.0 (2016.3.23) 283 | 284 | #### Improvements 285 | 286 | - **Added [redux-logger](https://github.com/fcomb/redux-logger)** 287 | - **Upgraded [react-router-redux](https://github.com/reactjs/react-router-redux) to v4** 288 | - **Upgraded dependencies** 289 | - **Added `npm run dev` command:** [#162](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/162) 290 | - **electron to v0.37.2** 291 | 292 | #### Breaking Changes 293 | 294 | - **css module as default:** [#154](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/154). 295 | - **set default NODE_ENV to production:** [#140](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/140) 296 | 297 | # 0.8.0 (2016.2.17) 298 | 299 | #### Bug fixed 300 | 301 | - **Fix lint errors** 302 | - **Fix Webpack publicPath for production builds**: [#119](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/119). 303 | - **package script now chooses correct OS icon extension** 304 | 305 | #### Improvements 306 | 307 | - **babel 6** 308 | - **Upgrade Dependencies** 309 | - **Enable CSS source maps** 310 | - **Add json-loader**: [#128](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/128). 311 | - **react-router 2.0 and react-router-redux 3.0** 312 | 313 | # 0.7.1 (2015.12.27) 314 | 315 | #### Bug fixed 316 | 317 | - **Fixed npm script on windows 10:** [#103](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/103). 318 | - **history and react-router version bump**: [#109](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/109), [#110](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/110). 319 | 320 | #### Improvements 321 | 322 | - **electron 0.36** 323 | 324 | # 0.7.0 (2015.12.16) 325 | 326 | #### Bug fixed 327 | 328 | - **Fixed process.env.NODE_ENV variable in webpack:** [#74](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/74). 329 | - **add missing object-assign**: [#76](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/76). 330 | - **packaging in npm@3:** [#77](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/77). 331 | - **compatibility in windows:** [#100](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/100). 332 | - **disable chrome debugger in production env:** [#102](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/102). 333 | 334 | #### Improvements 335 | 336 | - **redux** 337 | - **css-modules** 338 | - **upgrade to react-router 1.x** 339 | - **unit tests** 340 | - **e2e tests** 341 | - **travis-ci** 342 | - **upgrade to electron 0.35.x** 343 | - **use es2015** 344 | - **check dev engine for node and npm** 345 | 346 | # 0.6.5 (2015.11.7) 347 | 348 | #### Improvements 349 | 350 | - **Bump style-loader to 0.13** 351 | - **Bump css-loader to 0.22** 352 | 353 | # 0.6.4 (2015.10.27) 354 | 355 | #### Improvements 356 | 357 | - **Bump electron-debug to 0.3** 358 | 359 | # 0.6.3 (2015.10.26) 360 | 361 | #### Improvements 362 | 363 | - **Initialize ExtractTextPlugin once:** [#64](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/64). 364 | 365 | # 0.6.2 (2015.10.18) 366 | 367 | #### Bug fixed 368 | 369 | - **Babel plugins production env not be set properly:** [#57](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/57). 370 | 371 | # 0.6.1 (2015.10.17) 372 | 373 | #### Improvements 374 | 375 | - **Bump electron to v0.34.0** 376 | 377 | # 0.6.0 (2015.10.16) 378 | 379 | #### Breaking Changes 380 | 381 | - **From react-hot-loader to react-transform** 382 | 383 | # 0.5.2 (2015.10.15) 384 | 385 | #### Improvements 386 | 387 | - **Run tests with babel-register:** [#29](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/29). 388 | 389 | # 0.5.1 (2015.10.12) 390 | 391 | #### Bug fixed 392 | 393 | - **Fix #51:** use `path.join(__dirname` instead of `./`. 394 | 395 | # 0.5.0 (2015.10.11) 396 | 397 | #### Improvements 398 | 399 | - **Simplify webpack config** see [#50](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/50). 400 | 401 | #### Breaking Changes 402 | 403 | - **webpack configs** 404 | - **port changed:** changed default port from 2992 to 3000. 405 | - **npm scripts:** remove `start-dev` and `dev-server`. rename `hot-dev-server` to `hot-server`. 406 | 407 | # 0.4.3 (2015.9.22) 408 | 409 | #### Bug fixed 410 | 411 | - **Fix #45 zeromq crash:** bump version of `electron-prebuilt`. 412 | 413 | # 0.4.2 (2015.9.15) 414 | 415 | #### Bug fixed 416 | 417 | - **run start-hot breaks chrome refresh(CTRL+R) (#42)**: bump `electron-debug` to `0.2.1` 418 | 419 | # 0.4.1 (2015.9.11) 420 | 421 | #### Improvements 422 | 423 | - **use electron-prebuilt version for packaging (#33)** 424 | 425 | # 0.4.0 (2015.9.5) 426 | 427 | #### Improvements 428 | 429 | - **update dependencies** 430 | 431 | # 0.3.0 (2015.8.31) 432 | 433 | #### Improvements 434 | 435 | - **eslint-config-airbnb** 436 | 437 | # 0.2.10 (2015.8.27) 438 | 439 | #### Features 440 | 441 | - **custom placeholder icon** 442 | 443 | #### Improvements 444 | 445 | - **electron-renderer as target:** via [webpack-target-electron-renderer](https://github.com/chentsulin/webpack-target-electron-renderer) 446 | 447 | # 0.2.9 (2015.8.18) 448 | 449 | #### Bug fixed 450 | 451 | - **Fix hot-reload** 452 | 453 | # 0.2.8 (2015.8.13) 454 | 455 | #### Improvements 456 | 457 | - **bump electron-debug** 458 | - **babelrc** 459 | - **organize webpack scripts** 460 | 461 | # 0.2.7 (2015.7.9) 462 | 463 | #### Bug fixed 464 | 465 | - **defaultProps:** fix typos. 466 | 467 | # 0.2.6 (2015.7.3) 468 | 469 | #### Features 470 | 471 | - **menu** 472 | 473 | #### Bug fixed 474 | 475 | - **package.js:** include webpack build. 476 | 477 | # 0.2.5 (2015.7.1) 478 | 479 | #### Features 480 | 481 | - **NPM Script:** support multi-platform 482 | - **package:** `--all` option 483 | 484 | # 0.2.4 (2015.6.9) 485 | 486 | #### Bug fixed 487 | 488 | - **Eslint:** typo, [#17](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/17) and improve `.eslintrc` 489 | 490 | # 0.2.3 (2015.6.3) 491 | 492 | #### Features 493 | 494 | - **Package Version:** use latest release electron version as default 495 | - **Ignore Large peerDependencies** 496 | 497 | #### Bug fixed 498 | 499 | - **Npm Script:** typo, [#6](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/6) 500 | - **Missing css:** [#7](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/7) 501 | 502 | # 0.2.2 (2015.6.2) 503 | 504 | #### Features 505 | 506 | - **electron-debug** 507 | 508 | #### Bug fixed 509 | 510 | - **Webpack:** add `.json` and `.node` to extensions for imitating node require. 511 | - **Webpack:** set `node_modules` to externals for native module support. 512 | 513 | # 0.2.1 (2015.5.30) 514 | 515 | #### Bug fixed 516 | 517 | - **Webpack:** #1, change build target to `atom`. 518 | 519 | # 0.2.0 (2015.5.30) 520 | 521 | #### Features 522 | 523 | - **Ignore:** `test`, `tools`, `release` folder and devDependencies in `package.json`. 524 | - **Support asar** 525 | - **Support icon** 526 | 527 | # 0.1.0 (2015.5.27) 528 | 529 | #### Features 530 | 531 | - **Webpack:** babel, react-hot, ... 532 | - **Flux:** actions, api, components, containers, stores.. 533 | - **Package:** darwin (osx), linux and win32 (windows) platform. 534 | --------------------------------------------------------------------------------