diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 1065bbb..3aa4afd 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -10,6 +10,6 @@ #issuehunt: # Replace with a single IssueHunt username #lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry #polar: # Replace with a single Polar username -#buy_me_a_coffee: # Replace with a single Buy Me a Coffee username +buy_me_a_coffee: infinition #thanks_dev: # Replace with a single thanks.dev username #custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 423404f..e1339fc 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -23,7 +23,7 @@ We are committed to fostering an open and welcoming environment for all contribu ## πŸ“’ Reporting Misconduct -If you encounter any behavior that violates this code of conduct, please report it by contacting [email@dominio.com](mailto:email@dominio.com). All complaints will be reviewed and handled appropriately. +If you encounter any behavior that violates this code of conduct, please report it by contacting [bjorn-cyberviking@outlook.com](mailto:bjorn-cyberviking@outlook.com). All complaints will be reviewed and handled appropriately. ## βš–οΈ Enforcement diff --git a/INSTALL.md b/INSTALL.md index d9c3953..225552f 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -14,9 +14,8 @@ Use Raspberry Pi Imager to install your OS https://www.raspberrypi.com/software/ -### πŸ“Œ Prerequisites - -![image](https://github.com/user-attachments/assets/e775f454-1771-4d6c-bff5-b262b3d98452) +### πŸ“Œ Prerequisites for RPI zero W (32bits) +![image](https://github.com/user-attachments/assets/3980ec5f-a8fc-4848-ab25-4356e0529639) - Raspberry Pi OS installed. - Stable: @@ -26,7 +25,23 @@ https://www.raspberrypi.com/software/ - Username and hostname set to `bjorn`. - 2.13-inch e-Paper HAT connected to GPIO pins. -At the moment the paper screen v2 & v4 have been tested and implemented. +### πŸ“Œ Prerequisites for RPI zero W2 (64bits) + +![image](https://github.com/user-attachments/assets/e8d276be-4cb2-474d-a74d-b5b6704d22f5) + +I did not develop Bjorn for the raspberry pi zero w2 64bits, but several feedbacks have attested that the installation worked perfectly. + +- Raspberry Pi OS installed. + - Stable: + - System: 64-bit + - Kernel version: 6.6 + - Debian version: 12 (bookworm) '2024-10-22-raspios-bookworm-arm64-lite' +- Username and hostname set to `bjorn`. +- 2.13-inch e-Paper HAT connected to GPIO pins. + + + +At the moment the paper screen v2 v4 have been tested and implemented. I juste hope the V1 & V3 will work the same. ### ⚑ Quick Install diff --git a/README.md b/README.md index 5d8fcef..e8aa67c 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,11 @@ # thumbnail_IMG_0546 Bjorn +![Python](https://img.shields.io/badge/Python-3776AB?logo=python&logoColor=fff) +![Status](https://img.shields.io/badge/Status-Development-blue.svg) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + [![Reddit](https://img.shields.io/badge/Reddit-Bjorn__CyberViking-orange?style=for-the-badge&logo=reddit)](https://www.reddit.com/r/Bjorn_CyberViking) [![Discord](https://img.shields.io/badge/Discord-Join%20Us-7289DA?style=for-the-badge&logo=discord)](https://discord.com/invite/B3ZH9taVfT) -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

thumbnail_IMG_0546 @@ -18,7 +21,7 @@ Bjorn is a « Tamagotchi likeΒ Β» sophisticated, autonomous network scanning, - [Features](#-features) - [Getting Started](#-getting-started) - [Prerequisites](#-prerequisites) - - [Installation](#-Installation) + - [Installation](#-installation) - [Quick Start](#-quick-start) - [Usage Example](#-usage-example) - [Contributing](#-contributing) @@ -43,9 +46,11 @@ The e-Paper HAT display and web interface make it easy to monitor and interact w ## πŸš€ Getting Started -### πŸ“Œ Prerequisites +## πŸ“Œ Prerequisites -![image](https://github.com/user-attachments/assets/e775f454-1771-4d6c-bff5-b262b3d98452) +### πŸ“‹ Prerequisites for RPI zero W (32bits) + +![image](https://github.com/user-attachments/assets/3980ec5f-a8fc-4848-ab25-4356e0529639) - Raspberry Pi OS installed. - Stable: @@ -55,7 +60,22 @@ The e-Paper HAT display and web interface make it easy to monitor and interact w - Username and hostname set to `bjorn`. - 2.13-inch e-Paper HAT connected to GPIO pins. -At the moment the paper screen v2 & v4 have been tested and implemented. +### πŸ“‹ Prerequisites for RPI zero W2 (64bits) + +![image](https://github.com/user-attachments/assets/e8d276be-4cb2-474d-a74d-b5b6704d22f5) + +I did not develop Bjorn for the raspberry pi zero w2 64bits, but several feedbacks have attested that the installation worked perfectly. + +- Raspberry Pi OS installed. + - Stable: + - System: 64-bit + - Kernel version: 6.6 + - Debian version: 12 (bookworm) '2024-10-22-raspios-bookworm-arm64-lite' +- Username and hostname set to `bjorn`. +- 2.13-inch e-Paper HAT connected to GPIO pins. + + +At the moment the paper screen v2 v4 have been tested and implemented. I juste hope the V1 & V3 will work the same. ### πŸ”¨ Installation @@ -69,25 +89,60 @@ sudo chmod +x install_bjorn.sh && sudo ./install_bjorn.sh # Choose the choice 1 for automatic installation. It may take a while as a lot of packages and modules will be installed. You must reboot at the end. ``` -For **detailed information** about installation process go to [Install Guide](INSTALL.md) +For **detailed information** about **installation** process go to [Install Guide](INSTALL.md) ## ⚑ Quick Start **Need help ? You struggle to find Bjorn's IP after the installation ?** Use my Bjorn Detector & SSH Launcher : -https://github.com/infinition/Bjorn_Detector +[https://github.com/infinition/bjorn-detector](https://github.com/infinition/bjorn-detector) ![ezgif-1-a310f5fe8f](https://github.com/user-attachments/assets/182f82f0-5c3a-48a9-a75e-37b9cfa2263a) **Hmm, You still need help ?** For **detailed information** about **troubleshooting** go to [Troubleshooting](TROUBLESHOOTING.md) -**Quick Installation**: you can use the fastest way to install Bjorn [Getting Started](#-getting-started) +**Quick Installation**: you can use the fastest way to install **Bjorn** [Getting Started](#-getting-started) ## πŸ’‘ Usage Example -... +Here's a demonstration of how Bjorn autonomously hunts through your network like a Viking raider (fake demo for illustration): + +```bash +# Reconnaissance Phase +[NetworkScanner] Discovering alive hosts... +[+] Host found: 192.168.1.100 + β”œβ”€β”€ Ports: 22,80,445,3306 + └── MAC: 00:11:22:33:44:55 + +# Attack Sequence +[NmapVulnScanner] Found vulnerabilities on 192.168.1.100 + β”œβ”€β”€ MySQL 5.5 < 5.7 - User Enumeration + └── SMB - EternalBlue Candidate + +[SSHBruteforce] Cracking credentials... +[+] Success! user:password123 +[StealFilesSSH] Extracting sensitive data... + +# Automated Data Exfiltration +[SQLBruteforce] Database accessed! +[StealDataSQL] Dumping tables... +[SMBBruteforce] Share accessible +[+] Found config files, credentials, backups... +``` + +This is just a demo output - actual results will vary based on your network and target configuration. + +All discovered data is automatically organized in the data/output/ directory, viewable through both the e-Paper display (as indicators) and web interface. +Bjorn works tirelessly, expanding its network knowledge base and growing stronger with each discovery. + +No constant monitoring needed - just deploy and let Bjorn do what it does best: hunt for vulnerabilities. + +πŸ”§ Expand Bjorn's Arsenal! +Bjorn is designed to be a community-driven weapon forge. Create and share your own attack modules! + +⚠️ **For educational and authorized testing purposes only** ⚠️ ## 🀝 Contributing @@ -98,7 +153,7 @@ The project welcomes contributions in: - Documentation. - Feature improvements. -For **detailed information** about contributing process go to [Contributing Docs](CONTRIBUTING.md), [Code Of Conduct](CODE_OF_CONDUCT.md) and [Development Guide](DEVELOPMENT.md). +For **detailed information** about **contributing** process go to [Contributing Docs](CONTRIBUTING.md), [Code Of Conduct](CODE_OF_CONDUCT.md) and [Development Guide](DEVELOPMENT.md). ## πŸ“« Contact @@ -111,6 +166,10 @@ For **detailed information** about contributing process go to [Contributing Docs - **Author**: __infinition__ - **GitHub**: [infinition/Bjorn](https://github.com/infinition/Bjorn) +## 🌠 Stargazers + +[![Star History Chart](https://api.star-history.com/svg?repos=infinition/bjorn&type=Date)](https://star-history.com/#infinition/bjorn&Date) + --- ## πŸ“œ License diff --git a/SECURITY.md b/SECURITY.md index 848063e..a3dc6dd 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -27,7 +27,7 @@ If you discover a security vulnerability within this project, please follow thes 1. **Do not create a public issue.** Instead, contact us directly to responsibly disclose the vulnerability. -2. **Email** [email@dominio.com](mailto:email@dominio.com) with the following information: +2. **Email** [bjorn-cyberviking@outlook.com](mailto:bjorn-cyberviking@outlook.com) with the following information: - A description of the vulnerability. - Steps to reproduce the issue. diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md index a8a3560..5fe0241 100644 --- a/TROUBLESHOOTING.md +++ b/TROUBLESHOOTING.md @@ -25,12 +25,20 @@ ### Service Issues ```bash +#See bjorn journalctl service +journalctl -fu bjorn.service + # Check service status sudo systemctl status bjorn.service # View detailed logs sudo journalctl -u bjorn.service -f +or + +sudo tail -f /home/bjorn/Bjorn/data/logs/* + + # Check port 8000 usage sudo lsof -i :8000 ``` diff --git a/install_bjorn.sh b/install_bjorn.sh index e5775eb..92d6675 100644 --- a/install_bjorn.sh +++ b/install_bjorn.sh @@ -112,9 +112,9 @@ check_system_compatibility() { # Check RAM (Raspberry Pi Zero has 512MB RAM) total_ram=$(free -m | awk '/^Mem:/{print $2}') - if [ "$total_ram" -lt 429 ]; then - log "WARNING" "Low RAM detected. Required: 512MB, Found: ${total_ram}MB" - echo -e "${YELLOW}Your system has less RAM than recommended. This might affect performance.${NC}" + if [ "$total_ram" -lt 410 ]; then + log "WARNING" "Low RAM detected. Required: 512MB (410 With OS Running), Found: ${total_ram}MB" + echo -e "${YELLOW}Your system has less RAM than recommended. This might affect performance, but you can continue.${NC}" should_ask_confirmation=true else log "SUCCESS" "RAM check passed: ${total_ram}MB available" @@ -122,7 +122,7 @@ check_system_compatibility() { # Check available disk space available_space=$(df -m /home | awk 'NR==2 {print $4}') - if [ "$available_space" -lt 1024 ]; then + if [ "$available_space" -lt 2048 ]; then log "WARNING" "Low disk space. Recommended: 1GB, Found: ${available_space}MB" echo -e "${YELLOW}Your system has less free space than recommended. This might affect installation.${NC}" should_ask_confirmation=true diff --git a/resources/waveshare_epd/epd2in13.py b/resources/waveshare_epd/epd2in13.py index 611e9d7..e8fa364 100644 --- a/resources/waveshare_epd/epd2in13.py +++ b/resources/waveshare_epd/epd2in13.py @@ -9,6 +9,7 @@ logger = logging.getLogger(__name__) class EPD: def __init__(self): + self.is_initialized = False # New flag to track if the display has been initialized #INFINITION self.reset_pin = epdconfig.RST_PIN self.dc_pin = epdconfig.DC_PIN self.busy_pin = epdconfig.BUSY_PIN @@ -66,10 +67,10 @@ class EPD: logger.debug("e-Paper busy release") def init(self, lut): - if (epdconfig.module_init() != 0): - return -1 - # EPD hardware init start - self.reset() + if not self.is_initialized: # Avoid repeated initialization and accumulation of File descriptors #INFINITION + if epdconfig.module_init() != 0: + return -1 + self.reset() self.send_command(0x01) # DRIVER_OUTPUT_CONTROL self.send_data((EPD_HEIGHT - 1) & 0xFF) self.send_data(((EPD_HEIGHT - 1) >> 8) & 0xFF) diff --git a/resources/waveshare_epd/epd2in13_V2.py b/resources/waveshare_epd/epd2in13_V2.py index cbaad67..700b14d 100644 --- a/resources/waveshare_epd/epd2in13_V2.py +++ b/resources/waveshare_epd/epd2in13_V2.py @@ -9,6 +9,7 @@ logger = logging.getLogger(__name__) class EPD: def __init__(self): + self.is_initialized = False # New flag to track if the display has been initialized #INFINITION self.reset_pin = epdconfig.RST_PIN self.dc_pin = epdconfig.DC_PIN self.busy_pin = epdconfig.BUSY_PIN @@ -99,10 +100,12 @@ class EPD: self.ReadBusy() def init(self, update): - if (epdconfig.module_init() != 0): - return -1 - # EPD hardware init start - self.reset() + if not self.is_initialized: # Avoid repeated initialization and accumulation of File descriptors #INFINITION + if epdconfig.module_init() != 0: + return -1 + self.reset() + self.is_initialized = True + if(update == self.FULL_UPDATE): self.ReadBusy() self.send_command(0x12) # soft reset diff --git a/resources/waveshare_epd/epd2in13_V3.py b/resources/waveshare_epd/epd2in13_V3.py index c19c771..395eae0 100644 --- a/resources/waveshare_epd/epd2in13_V3.py +++ b/resources/waveshare_epd/epd2in13_V3.py @@ -9,6 +9,7 @@ logger = logging.getLogger(__name__) class EPD: def __init__(self): + self.is_initialized = False # New flag to track if the display has been initialized #INFINITION self.reset_pin = epdconfig.RST_PIN self.dc_pin = epdconfig.DC_PIN self.busy_pin = epdconfig.BUSY_PIN @@ -200,42 +201,54 @@ class EPD: parameter: ''' def init(self, update=None): + # Prevent reinitialization if already initialized #INFINITION + if self.is_initialized: + logger.debug("EPD is already initialized. Skipping redundant init.") + return 0 + if update is None: update = self.FULL_UPDATE + # Initialize the module if epdconfig.module_init() != 0: + logger.error("Failed to initialize module") return -1 - # EPD hardware init start - self.reset() - - self.ReadBusy() - self.send_command(0x12) #SWRESET - self.ReadBusy() - self.send_command(0x01) #Driver output control + # EPD hardware initialization start + self.reset() + + self.ReadBusy() + self.send_command(0x12) # SWRESET + self.ReadBusy() + + self.send_command(0x01) # Driver output control self.send_data(0xf9) self.send_data(0x00) self.send_data(0x00) - - self.send_command(0x11) #data entry mode + + self.send_command(0x11) # Data entry mode self.send_data(0x03) - self.SetWindow(0, 0, self.width-1, self.height-1) + self.SetWindow(0, 0, self.width - 1, self.height - 1) self.SetCursor(0, 0) - + self.send_command(0x3c) self.send_data(0x05) - self.send_command(0x21) # Display update control + self.send_command(0x21) # Display update control self.send_data(0x00) self.send_data(0x80) - + self.send_command(0x18) self.send_data(0x80) - + self.ReadBusy() - + self.SetLut(self.lut_full_update) + + # Mark the EPD as initialized #INFINITION + self.is_initialized = True + logger.info("EPD initialized successfully") return 0 ''' diff --git a/resources/waveshare_epd/epd2in13_V4.py b/resources/waveshare_epd/epd2in13_V4.py index da328b1..f32906a 100644 --- a/resources/waveshare_epd/epd2in13_V4.py +++ b/resources/waveshare_epd/epd2in13_V4.py @@ -9,6 +9,7 @@ logger = logging.getLogger(__name__) class EPD: def __init__(self): + self.is_initialized = False # New flag to track if the display has been initialized #INFINITION self.reset_pin = epdconfig.RST_PIN self.dc_pin = epdconfig.DC_PIN self.busy_pin = epdconfig.BUSY_PIN @@ -138,11 +139,11 @@ class EPD: parameter: ''' def init(self): - if (epdconfig.module_init() != 0): - return -1 - # EPD hardware init start - self.reset() - + if not self.is_initialized: # Avoid repeated initialization and accumulation of File descriptors #INFINITION + if epdconfig.module_init() != 0: + return -1 + self.reset() + self.is_initialized = True self.ReadBusy() self.send_command(0x12) #SWRESET self.ReadBusy() diff --git a/resources/waveshare_epd/epd2in7.py b/resources/waveshare_epd/epd2in7.py index 831492b..60c584c 100644 --- a/resources/waveshare_epd/epd2in7.py +++ b/resources/waveshare_epd/epd2in7.py @@ -43,6 +43,7 @@ logger = logging.getLogger(__name__) class EPD: def __init__(self): + self.is_initialized = False # New flag to track if the display has been initialized #INFINITION self.reset_pin = epdconfig.RST_PIN self.dc_pin = epdconfig.DC_PIN self.busy_pin = epdconfig.BUSY_PIN @@ -222,11 +223,10 @@ class EPD: self.send_data(self.gray_lut_ww[count]) def init(self): - if (epdconfig.module_init() != 0): - return -1 - - # EPD hardware init start - self.reset() + if not self.is_initialized: # Avoid repeated initialization and accumulation of File descriptors #INFINITION + if epdconfig.module_init() != 0: + return -1 + self.reset() self.send_command(0x01) # POWER_SETTING self.send_data(0x03) # VDS_EN, VDG_EN diff --git a/utils.py b/utils.py index a679677..621839a 100644 --- a/utils.py +++ b/utils.py @@ -728,6 +728,10 @@ method=auto elif isinstance(value, (int, float)): current_config[key] = value elif isinstance(value, list): + # Lets boot any values in a list that are just empty strings + for val in value[:]: + if val == "" : + value.remove(val) current_config[key] = value elif isinstance(value, str): if value.replace('.', '', 1).isdigit(): diff --git a/web/css/styles.css b/web/css/styles.css index 1e061a8..448977b 100644 --- a/web/css/styles.css +++ b/web/css/styles.css @@ -60,7 +60,7 @@ html { cursor: pointer; } -.toolbar a:hover, .toolbar button:hover, .toolbar-button:hover, .action-button:hover { +.toolbar a:hover, .toolbar button:hover, .toolbar-button:hover, .toolbar-button:hover button.toolbar-button, .action-button:hover { background-color: #e99f00; color: black; } @@ -514,6 +514,7 @@ td:first-child, th:first-child { background-color: #333; text-align: left; border-radius: 8px; + cursor: pointer; } .dropdown-content button:hover { diff --git a/web/scripts/config.js b/web/scripts/config.js index 583a706..633ad34 100644 --- a/web/scripts/config.js +++ b/web/scripts/config.js @@ -68,12 +68,21 @@ function generateConfigForm(config) { const formData = new FormData(formElement); const formDataObj = {}; - + // Each of these fields contains an array of data. Lets track these so we can ensure the format remains an array for the underlying structure. + const arrayFields = [ + "portlist", + "mac_scan_blacklist", + "ip_scan_blacklist", + "steal_file_names", + "steal_file_extensions", + ]; + formData.forEach((value, key) => { - if (value.includes(',')) { + // Check if the input from the user contains a `,` character or is a known array field + if (value.includes(',') || arrayFields.includes(key)) { formDataObj[key] = value.split(',').map(item => { const trimmedItem = item.trim(); - return isNaN(trimmedItem) ? trimmedItem : parseFloat(trimmedItem); + return isNaN(trimmedItem) || trimmedItem == "" ? trimmedItem : parseFloat(trimmedItem); }); } else { formDataObj[key] = value === 'on' ? true : (isNaN(value) ? value : parseFloat(value));