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
-
-
+### π Prerequisites for RPI zero W (32bits)
+
- 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)
+
+
+
+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 @@
# Bjorn
+
+
+[](https://opensource.org/licenses/MIT)
+
[](https://www.reddit.com/r/Bjorn_CyberViking)
[](https://discord.com/invite/B3ZH9taVfT)
-[](https://opensource.org/licenses/MIT)
@@ -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
-
+### π Prerequisites for RPI zero W (32bits)
+
+
- 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)
+
+
+
+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)

**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
+
+[](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));