initial commit
1 parent bb3752a commit 952c6e1f551d95b158114a6af99629fa08a9e108
0xRoM authored on 11 Feb
Showing 27 changed files
View
4
FaultInjection/README.md 0 → 100644
Fault Injection
===============
 
Dump of useful fault injection / glitching scripts and examples
View
FaultInjection/examples/FaultyCat/01_simple_restart/cause_restart.png 0 → 100644
View
17
FaultInjection/examples/FaultyCat/01_simple_restart/example_v1.0.ino 0 → 100644
#include <SoftwareSerial.h>
 
#define RX 3 // *** D3, Pin 2
#define TX 4 // *** D4, Pin 3
SoftwareSerial Serial(RX, TX);
 
void setup(){
Serial.begin(9600);
Serial.println("Initializing...");
}
 
void loop() {
// put your main code here, to run repeatedly:
Serial.println("running");
delay(1000);
}
View
38
FaultInjection/examples/FaultyCat/01_simple_restart/example_v1.2_pretty.ino 0 → 100644
#include <SoftwareSerial.h>
 
#define RX 3 // *** D3, Pin 2
#define TX 4 // *** D4, Pin 3
SoftwareSerial Serial(RX, TX);
 
void setup() {
Serial.begin(9600);
Serial.println(" ");
Serial.println("Initializing...");
delay(2000); // Delay to give time for the setup message
}
 
void loop() {
static int dotCount = 0; // Keeps track of how many dots are printed
// Create the base "running" message followed by spaces to clear previous dots
Serial.print("running");
// Add the appropriate number of dots
for (int i = 0; i < dotCount; i++) {
Serial.print(".");
}
// Clear any extra dots from previous loops by adding spaces
for (int i = dotCount; i < 3; i++) {
Serial.print(" ");
}
// Use carriage return to overwrite the line on the next iteration
Serial.print("\r");
 
// Update the dot count, cycling from 0 to 3
dotCount = (dotCount + 1) % 4; // Cycles through 0, 1, 2, 3 dots
delay(1000); // 1-second delay before updating
}
View
63
FaultInjection/examples/FaultyCat/02_match_numbers/example_v2.0.ino 0 → 100644
#include <SoftwareSerial.h>
 
#define RX 3 // *** D3, Pin 2
#define TX 4 // *** D4, Pin 3
SoftwareSerial Serial(RX, TX);
 
void setup() {
Serial.begin(9600);
Serial.println(" ");
Serial.println("Initializing...");
randomSeed(analogRead(0)); // Seed the random number generator for more randomness
delay(2000); // Delay for initialization
}
 
void loop() {
// Generate one random number and assign it to both variables
volatile int originalNumber = random(10, 100);
volatile int num1 = originalNumber;
volatile int num2 = originalNumber;
 
// Perform reversible operations to increase glitch susceptibility but keep values comparable
num1 = num1 ^ 0x55; // XOR num1 with 0x55
num2 = num2 ^ 0x55; // XOR num2 with 0x55
delayMicroseconds(5); // Critical timing for glitches
 
num1 = num1 ^ 0x55; // XOR again to reverse
num2 = num2 ^ 0x55; // XOR again to reverse
 
delayMicroseconds(5); // Another critical timing for glitches
 
// Extract the first and second digits
volatile int num1FirstDigit = num1 / 10; // Get the first digit of num1
volatile int num1SecondDigit = num1 % 10; // Get the second digit of num1
 
delayMicroseconds(5); // More chances for glitches
volatile int num2FirstDigit = num2 / 10; // Get the first digit of num2
volatile int num2SecondDigit = num2 % 10; // Get the second digit of num2
 
delayMicroseconds(5); // Increased vulnerability
 
// Check if the numbers still match after the potential glitch
int match = 0;
if (num1FirstDigit == num2FirstDigit) {
if (num1SecondDigit == num2SecondDigit) {
match = 1;
}
}
if (match == 1) {
Serial.print("Numbers match: "); Serial.print(num1); Serial.print(" "); Serial.print(num2); Serial.print("\r");
} else {
Serial.print("Glitch detected! Numbers do not match: ");
Serial.print(num1); Serial.print(" "); Serial.print(num2);
Serial.print(" ("); Serial.print(num1FirstDigit); Serial.print(":"); Serial.print(num1SecondDigit); Serial.print(") ");
Serial.print("("); Serial.print(num2FirstDigit); Serial.print(":"); Serial.print(num2SecondDigit); Serial.println(")");
Serial.println(" ");
}
delay(100); // Shorter delay to increase glitch detection chances
}
View
FaultInjection/examples/FaultyCat/02_match_numbers/no_match.png 0 → 100644
View
201
FaultInjection/examples/FaultyCat/03_password_check/attack.py 0 → 100644
import sys
import time
import pexpect # Required to handle screen sessions
import threading
from Modules import Worker
 
DEFAULT_COMPORT = "/dev/ttyACM0"
SCREEN_NAME = "ttyUSB0_screen" # Replace this with the actual screen session name
 
# Initialize the FaultyWorker
faulty_worker = Worker.FaultyWorker()
# Shared variable to store the response from the device
device_response = None
child = None # Global child variable
 
def initialize_child():
"""Initialize the global child process for the screen session."""
global child
child = pexpect.spawn(f'screen -x {SCREEN_NAME}', encoding='utf-8')
child.expect(pexpect.TIMEOUT, timeout=1) # Clear out any pre-existing buffer
 
def send_test_message_and_read_response():
"""Send 'ping' via screen to a serial device and check for 'correct!\\n' or 'incorrect\\n'."""
global child
 
# Send 'ping' to the screen session
child.sendline("ping")
sys.stdout.write("\rSent 'ping' to screen session.")
sys.stdout.flush()
 
# Wait a bit to ensure the command is processed
time.sleep(0.5)
 
# Try reading any new output from the screen session
try:
response = child.read_nonblocking(size=1024, timeout=2) # Read up to 1024 bytes of new data
if "pong" in response:
sys.stdout.write("\rReceived 'pong' response.")
return True
else:
sys.stdout.write(f"\rReceived unexpected response: {response}")
sys.stdout.flush()
except pexpect.exceptions.TIMEOUT:
sys.stdout.write("\rNo response received from the screen session (timeout).")
sys.stdout.flush()
 
return False
 
def read_screen_output():
"""Read output from the screen session in a separate thread."""
global device_response
buffer = "" # Initialize a buffer to store incoming characters
 
try:
while True:
response = child.read_nonblocking(size=1024, timeout=2) # Read up to 1024 bytes of new data
buffer += response # Append the new response to the buffer
# Check if there's a complete line in the buffer
while "\n" in buffer:
line, buffer = buffer.split("\n", 1) # Split the buffer at the first newline
line = line.strip() # Remove any leading/trailing whitespace
 
# Check for specific responses
if "incorrect!" in line:
#sys.stdout.write("\rReceived 'incorrect' response.")
device_response = 'incorrect'
return # Exit the loop on incorrect response
elif "correct" in line:
# Die here: Echo message, disarm device, and kill the program
sys.stdout.write("\nReceived 'correct' response.\n PWNT, U R ADMIN\n Disarming the device and exiting...\n")
sys.stdout.flush()
 
# Disarm the board
faulty_worker.board_uart.send(faulty_worker.board_configurator.board_commands.COMMAND_DISARM.value.encode("utf-8"))
faulty_worker.board_uart.close()
 
# Exit the program
sys.exit(0)
 
else:
sys.stdout.write(f"\rReceived unexpected response: {line}")
sys.stdout.flush()
 
except pexpect.exceptions.TIMEOUT:
sys.stdout.write("\rNo response received from the screen session (timeout).")
sys.stdout.flush()
except Exception as e:
sys.stdout.write(f"\rError reading from screen session: {e}")
sys.stdout.flush()
 
def send_pulse_and_check_response():
"""Send a pulse and check for 'correct!\\n' or 'incorrect\\n' response in parallel."""
global device_response
try:
# Wait a bit to ensure the command is processed
 
# Send 'incorrectPassword' command to the screen session
sys.stdout.write("\rSending 'incorrectPassword' to screen session.")
sys.stdout.flush()
child.sendline("incorrectPassword")
time.sleep(0.35)
 
# Send 'pulse' command (simulating the pulse trigger)
faulty_worker.board_uart.send(faulty_worker.board_configurator.board_commands.COMMAND_PULSE.value.encode("utf-8"))
sys.stdout.write("\rSent pulse...")
sys.stdout.flush()
 
# Start a thread to read the screen output
reader_thread = threading.Thread(target=read_screen_output)
reader_thread.start()
 
# Wait for the reading thread to complete
reader_thread.join()
except Exception as e:
sys.stdout.write(f"\rError interacting with screen session during pulse: {e}")
sys.stdout.flush()
return False
 
def start_faulty_attack():
"""Send a pulse through the FaultyCat and listen for the response concurrently."""
global child
try:
# Initialize the child process for screen session
initialize_child()
 
# Open FaultyCat connection
faulty_worker.board_uart.open()
time.sleep(0.1)
sys.stdout.write("\rBoard connected.\n")
sys.stdout.flush()
 
# Arming the board
sys.stdout.write("\r[*] ARMING BOARD, BE CAREFUL!\n")
sys.stdout.flush()
faulty_worker.board_uart.send(faulty_worker.board_configurator.board_commands.COMMAND_DISARM.value.encode("utf-8"))
time.sleep(1)
faulty_worker.board_uart.send(faulty_worker.board_configurator.board_commands.COMMAND_ARM.value.encode("utf-8"))
 
sys.stdout.write("\r[*] ARMED BOARD.\n")
sys.stdout.flush()
time.sleep(1)
 
# Sending pulses and checking responses in a loop (up to 5 times)
max_iterations = 5
for i in range(max_iterations):
sys.stdout.write(f"\rLoop {i+1}/{max_iterations}: Sending pulse and checking response.\n")
sys.stdout.flush()
 
# Send the test message and check for pong
if send_test_message_and_read_response():
 
max_iterations_2 = 3
for j in range(max_iterations_2):
# Send pulse and check for correct/incorrect response
if send_pulse_and_check_response():
break # Break the loop if 'correct!' is received
 
# Small delay before next iteration
time.sleep(1)
 
# Disarm the board
sys.stdout.write("\rDISARMING BOARD. \n")
sys.stdout.flush()
faulty_worker.board_uart.send(faulty_worker.board_configurator.board_commands.COMMAND_DISARM.value.encode("utf-8"))
faulty_worker.board_uart.close()
sys.stdout.write("\rBOARD DISARMED.\n")
sys.stdout.flush()
except Exception as e:
sys.stdout.write(f"\rError: {e}\n")
sys.stdout.flush()
finally:
# Make sure to clean up the child process
if child:
child.close()
 
def faulty():
"""Configure and send pulses through the FaultyCat."""
comport = DEFAULT_COMPORT
 
print("Configuring the FaultyCat...")
print(f"Using serial port: {comport}")
 
# Set the serial port
faulty_worker.set_serial_port(comport)
 
# Validate the serial connection
if not faulty_worker.validate_serial_connection():
print(f"Error: Could not establish connection on: {comport}")
return
 
# Start the faulty attack (send pulse)
start_faulty_attack()
 
if __name__ == "__main__":
print("Starting FaultyCat...")
faulty()
View
84
FaultInjection/examples/FaultyCat/03_password_check/example_v3.0.ino 0 → 100644
#include <SoftwareSerial.h>
 
#define RX 3 // *** D3, Pin 2
#define TX 4 // *** D4, Pin 3
SoftwareSerial Serial(RX, TX);
 
const String correctPassword = "secure123"; // Hardcoded password
String inputString = ""; // Variable to hold user input
bool stringComplete = false; // Flag to indicate when a string is complete
bool loggedIn = false;
 
void setup() {
Serial.begin(9600);
Serial.println(" ");
Serial.println("Initializing...");
delay(200); // Delay for initialization
Serial.print("[-]> ");
}
 
void prompt(){
// Reset for the next input without checking password
inputString = "";
stringComplete = false;
if(loggedIn == false){
Serial.print("[-]"); // not logged in
}else{
Serial.print("[+]"); // logged in
}
Serial.print("> ");
}
 
void loop() {
// If the string is complete, process the input
if (stringComplete) {
// Glitch-prone section: making the comparison more complex and glitch-susceptible
volatile bool match = false; // Using 'volatile' to increase glitch vulnerability
// Introduce some artificial delays (vulnerable points for glitching)
for (volatile int i = 0; i < 100; i++) {
delayMicroseconds(1); // Short delay to give more opportunity for glitches
}
// Dummy operation: XOR password with itself (reversible) before comparison
volatile String tempPassword = correctPassword;
for (int i = 0; i < tempPassword.length(); i++) {
tempPassword[i] ^= 0xFF; // XOR with 0xFF (dummy operation to increase complexity)
tempPassword[i] ^= 0xFF; // XOR back to restore original password
}
 
// Check if input is "ping"
if (inputString == "ping") {
Serial.println("pong"); // Respond with "pong" if input is "ping"
prompt();
return; // Exit the loop to avoid further processing (no "Password incorrect!" after "pong")
}
// Now compare the user input with the hardcoded password, but with timing window
else if (inputString == correctPassword) {
match = true; // Passwords match
}
 
// Add a chance for glitches to affect this critical condition
if (match) {
Serial.println("Password correct!");
loggedIn = true;
} else {
Serial.println("Password incorrect!");
}
prompt();
}
 
// Listen for input from the user
while (Serial.available()) {
char inChar = (char)Serial.read(); // Read the incoming character
// Check if it is the return character (indicating the end of input)
if (inChar == '\r' || inChar == '\n') {
stringComplete = true;
} else {
// Append the character to the input string
inputString += inChar;
}
}
}
View
FaultInjection/examples/FaultyCat/03_password_check/pass_correct_01.png 0 → 100644
View
81
FaultInjection/prereqs/FaultyCat/Modules/CmdInterface.py 0 → 100644
import cmd
import typer
from rich.console import Console
from rich.table import Table
 
 
def is_valid_number(number):
if number < 0:
raise typer.BadParameter("Number must be positive.")
return number
 
class CMDInterface(cmd.Cmd):
intro = "Type help or ? to list commands.\n"
prompt = "?> "
file = None
doc_header = "Commands"
misc_header = "Misc Commands"
undoc_header = "Undocumented Commands"
 
def __init__(self, faulty_worker):
super().__init__()
self.faulty_worker = faulty_worker
 
def do_config(self, args):
"""Configure the FaultyCat."""
print("Configuring the FaultyCat...")
table_config = Table(title="Board configuration")
table_config.add_column("Parameter", style="cyan")
table_config.add_column("Value", style="magenta")
table_config.add_row(
"Serial port", f"{self.faulty_worker.board_uart.serial_worker.port}"
)
table_config.add_row(
"Pulse time",
f"{self.faulty_worker.board_configurator.BOARD_CONFIG['pulse_time']}",
)
table_config.add_row(
"Pulse power",
f"{self.faulty_worker.board_configurator.BOARD_CONFIG['pulse_power']}",
)
table_config.add_row("Pulse count", f"{self.faulty_worker.pulse_count}")
Console().print(table_config)
 
def do_set(self, args):
"""Set a parameter."""
print("Setting a parameter...")
args_list = args.split()
if args == "help" or args == "?":
print("Available parameters:")
print("\t[time] pulse_time")
print("\t[count] pulse_count")
print("\tport")
return
 
if len(args_list) != 2:
print("Invalid number of arguments.")
return
 
if args_list[0] == "pulse_time" or args_list[0] == "time":
self.faulty_worker.set_pulse_time(is_valid_number(float(args_list[1])))
 
if args_list[0] == "pulse_count" or args_list[0] == "count":
self.faulty_worker.set_pulse_count(is_valid_number(int(args_list[1])))
 
if args_list[0] == "port":
self.faulty_worker.set_serial_port(args_list[1])
if not self.faulty_worker.validate_serial_connection():
typer.secho("Invalid serial port.", fg=typer.colors.BRIGHT_RED)
return
 
self.do_config(args)
 
def do_start(self, args):
"""Start the FaultyCat."""
print("Starting the FaultyCat...")
self.faulty_worker.start_faulty_attack()
 
def do_exit(self, line):
"""Exit the CLI."""
return True
View
61
FaultInjection/prereqs/FaultyCat/Modules/ConfigBoard.py 0 → 100644
from enum import Enum
 
class Commands(Enum):
COMMAND_HELP = "h"
COMMAND_ARM = "a"
COMMAND_DISARM = "d"
COMMAND_PULSE = "p"
COMMAND_ENABLE_TIMEOUT = "en"
COMMAND_DISABLE_TIMEOUT = "di"
COMMAND_FAST_TRIGGER = "f"
COMMAND_FAST_TRIGGER_CONF = "fa"
COMMAND_INTERNAL_HVP = "ih"
COMMAND_EXTERNAL_HVP = "eh"
COMMAND_CONFIGURE = "c"
COMMAND_TOGGLE_GPIO = "t"
COMMAND_STATUS = "s"
COMMAND_RESET = "r"
def __str__(self):
return self.value
 
class BoardStatus(Enum):
STATUS_ARMED = "armed"
STATUS_DISARMED = "disarmed"
STATUS_CHARGED = "charged"
STATUS_PULSE = "pulsed"
STATUS_NOT_CHARGED = "Not Charged"
STATUS_TIMEOUT_ACTIVE = "Timeout active"
STATUS_TIMEOUT_DEACT = "Timeout deactivated"
STATUS_HVP_INTERVAL = "HVP interval"
def __str__(self):
return self.value
@classmethod
def get_status_by_value(cls, value):
for status in cls.__members__.values():
if status.value == value:
return status
return None
 
class ConfigBoard:
BOARD_CONFIG = {
"pulse_time" : 1.0,
"pulse_power": 0.012200,
"pulse_count": 1,
"port" : "COM1"
}
def __init__(self) -> None:
self.board_config = ConfigBoard.BOARD_CONFIG
self.board_commands = Commands
def get_config(self) -> dict:
return self.board_config
 
def set_config(self, config: dict) -> None:
self.board_config = config
def __str__(self) -> str:
return f"Board config: {self.board_config}"
View
97
FaultInjection/prereqs/FaultyCat/Modules/UART.py 0 → 100644
import platform
import serial
import time
import serial.tools.list_ports
import threading
 
from .ConfigBoard import BoardStatus
 
if platform.system() == "Windows":
DEFAULT_COMPORT = "COM1"
else:
DEFAULT_COMPORT = "/dev/ttyACM0"
 
DEFAULT_SERIAL_BAUDRATE = 921600
 
class UART(threading.Thread):
def __init__(self, serial_port: str = DEFAULT_COMPORT):
self.serial_worker = serial.Serial()
self.serial_worker.port = serial_port
self.serial_worker.baudrate = DEFAULT_SERIAL_BAUDRATE
self.recv_cancel = False
#self.daemon = True
 
def __del__(self):
self.serial_worker.close()
 
def __str__(self):
return f"Serial port: {self.serial_worker.port}"
 
def set_serial_port(self, serial_port: str):
self.serial_worker.port = serial_port
def set_serial_baudrate(self, serial_baudrate: int):
self.serial_worker.baudrate = serial_baudrate
 
def is_valid_connection(self) -> bool:
try:
self.open()
self.close()
return True
except serial.SerialException as e:
return False
 
def get_serial_ports(self):
return serial.tools.list_ports.comports()
 
def reset_buffer(self):
self.serial_worker.reset_input_buffer()
self.serial_worker.reset_output_buffer()
 
def cancel_recv(self):
self.recv_cancel = True
 
def open(self):
self.serial_worker.open()
self.reset_buffer()
def close(self):
self.reset_buffer()
self.serial_worker.close()
 
def is_connected(self):
return self.serial_worker.is_open
 
def send(self, data):
self.serial_worker.write(data)
self.serial_worker.write(b"\n\r")
self.serial_worker.flush()
def recv(self):
if not self.is_connected():
self.open()
try:
while not self.recv_cancel:
time.sleep(0.1)
bytestream = self.serial_worker.readline()
if self.recv_cancel:
self.recv_cancel = False
return None
return bytestream
except serial.SerialException as e:
print(e)
return None
except KeyboardInterrupt:
self.recv_cancel = True
return None
def send_recv(self, data):
self.send(data)
return self.recv()
 
def stop_worker(self):
self.recv_cancel = True
self.reset_buffer()
self.close()
self.join()
View
68
FaultInjection/prereqs/FaultyCat/Modules/Worker.py 0 → 100644
import threading
import time
import typer
from rich.console import Console
from rich.table import Table
 
from .UART import UART
from .ConfigBoard import ConfigBoard
 
class FaultyWorker(threading.Thread):
def __init__(self):
super().__init__()
#self.daemon = True
self.workers = []
self.board_uart = UART()
self.board_configurator = ConfigBoard()
self.pulse_count = self.board_configurator.BOARD_CONFIG["pulse_count"]
self.pulse_time = self.board_configurator.BOARD_CONFIG["pulse_time"]
def add_worker(self, worker):
self.workers.append(worker)
def stop_workers(self):
for worker in self.workers:
worker.join()
def run_workers(self):
for worker in self.workers:
worker.start()
def set_serial_port(self, serial_port):
self.board_uart.set_serial_port(serial_port)
def validate_serial_connection(self):
return self.board_uart.is_valid_connection()
def set_pulse_count(self, pulse_count):
self.pulse_count = pulse_count
self.board_configurator.BOARD_CONFIG["pulse_count"] = pulse_count
def set_pulse_time(self, pulse_time):
self.pulse_time = pulse_time
self.board_configurator.BOARD_CONFIG["pulse_time"] = pulse_time
def start_faulty_attack(self):
try:
self.board_uart.open()
time.sleep(0.1)
typer.secho("Board connected.", fg=typer.colors.GREEN)
typer.secho("[*] ARMING BOARD, BE CAREFULL!", fg=typer.colors.BRIGHT_YELLOW)
self.board_uart.send(self.board_configurator.board_commands.COMMAND_DISARM.value.encode("utf-8"))
time.sleep(1)
self.board_uart.send(self.board_configurator.board_commands.COMMAND_ARM.value.encode("utf-8"))
typer.secho("[*] ARMED BOARD.", fg=typer.colors.BRIGHT_GREEN)
time.sleep(1)
typer.secho(f"[*] SENDING {self.pulse_count} PULSES.", fg=typer.colors.BRIGHT_GREEN)
for i in range(self.pulse_count):
typer.secho(f"\t- SENDING PULSE {i+1} OF {self.pulse_count}.", fg=typer.colors.BRIGHT_GREEN)
self.board_uart.send(self.board_configurator.board_commands.COMMAND_PULSE.value.encode("utf-8"))
time.sleep(self.pulse_time)
typer.secho("DISARMING BOARD.", fg=typer.colors.BRIGHT_YELLOW)
self.board_uart.send(self.board_configurator.board_commands.COMMAND_DISARM.value.encode("utf-8"))
self.board_uart.close()
typer.secho("BOARD DISARMING.", fg=typer.colors.BRIGHT_YELLOW)
except Exception as e:
typer.secho(f"Error: {e}", fg=typer.colors.BRIGHT_RED)
View
0
■■■■■
FaultInjection/prereqs/FaultyCat/Modules/__init__.py 0 → 100644
View
FaultInjection/prereqs/FaultyCat/Modules/__pycache__/CmdInterface.cpython-37.pyc 0 → 100644
Not supported
View
FaultInjection/prereqs/FaultyCat/Modules/__pycache__/ConfigBoard.cpython-37.pyc 0 → 100644
Not supported
View
FaultInjection/prereqs/FaultyCat/Modules/__pycache__/UART.cpython-37.pyc 0 → 100644
Not supported
View
FaultInjection/prereqs/FaultyCat/Modules/__pycache__/Worker.cpython-37.pyc 0 → 100644
Not supported
View
FaultInjection/prereqs/FaultyCat/Modules/__pycache__/__init__.cpython-37.pyc 0 → 100644
Not supported
View
134
FaultInjection/prereqs/FaultyCat/faultycmd.py 0 → 100644
import typer
import platform
import signal
import threading
import sys
from rich.console import Console
from rich.table import Table
 
from Modules import CmdInterface
from Modules.CmdInterface import is_valid_number
from Modules import Worker
 
if platform.system() == "Windows":
DEFAULT_COMPORT = "COM1"
else:
DEFAULT_COMPORT = "/dev/ttyACM0"
 
 
app = typer.Typer(
name="FaultyCat",
help="Script to control the FaultyCat and launch faulty attacks.",
add_completion=False,
no_args_is_help=True,
)
 
faulty_worker = Worker.FaultyWorker()
workers = []
 
 
def signal_handler(sig, frame):
print("You pressed Ctrl+C!")
faulty_worker.stop_workers()
for work in workers:
work.join()
sys.exit(0)
 
 
@app.command("config")
def config():
"""Get the current configuration of the FaultyCat."""
table_config = Table(title="Board configuration")
table_config.add_column("Parameter", style="cyan")
table_config.add_column("Value", style="magenta")
table_config.add_row(
"Pulse time", f"{faulty_worker.board_configurator.BOARD_CONFIG['pulse_time']}"
)
table_config.add_row(
"Pulse power", f"{faulty_worker.board_configurator.BOARD_CONFIG['pulse_power']}"
)
 
Console().print(table_config)
 
 
@app.command("devices")
def devices():
"""Get the list of available devices."""
table_devices = Table(title="Available devices")
table_devices.add_column("Device", style="cyan")
table_devices.add_column("Description", style="magenta")
for device in faulty_worker.board_uart.get_serial_ports():
table_devices.add_row(f"{device.device}", f"{device.description}")
 
Console().print(table_devices)
 
 
@app.command("fault")
def faulty(
comport: str = typer.Argument(
default=DEFAULT_COMPORT,
help="Serial port to use for uploading.",
),
pulse_count: int = typer.Option(
1, "--pulse-count", "-p", help="Number of pulses to send.", show_default=True
),
pulse_timeout: float = typer.Option(
1.0,
"--pulse-timeout",
"-t",
help="Time in seconds between pulses.",
show_default=True,
),
cmd: bool = typer.Option(
False, "--cmd", "-c", help="Launch the CMD Interface.", show_default=True
),
):
"""Setting up the FaultyCat. With this command you can configure the FaultyCat and launch faulty attacks."""
typer.echo("Configuring the FaultyCat...")
table_config = Table(title="Board configuration")
table_config.add_column("Parameter", style="cyan")
table_config.add_column("Value", style="magenta")
table_config.add_row("Serial port", f"{comport}")
table_config.add_row(
"Pulse time", f"{faulty_worker.board_configurator.BOARD_CONFIG['pulse_time']}"
)
table_config.add_row(
"Pulse power", f"{faulty_worker.board_configurator.BOARD_CONFIG['pulse_power']}"
)
table_config.add_row("Pulse count", f"{pulse_count}")
table_config.add_row("Pulse timeout", f"{pulse_timeout}")
 
Console().print(table_config)
 
faulty_worker.set_serial_port(comport)
if cmd:
CmdInterface.CMDInterface(faulty_worker).cmdloop()
return
 
if not faulty_worker.validate_serial_connection():
typer.secho(
f"FaultyCMD could not stablish connection withe the board on: {comport}.",
fg=typer.colors.RED,
)
return
 
faulty_worker.set_pulse_count(is_valid_number(pulse_count))
faulty_worker.set_pulse_time(is_valid_number(pulse_timeout))
 
faulty_worker.start_faulty_attack()
 
 
if __name__ == "__main__":
print(
"""\x1b[36;1m
.@@@%@*%+ -@@+ #@@: @@% =@@@@%- %@% %+ @= |
.@@-.-.#@+=@@* %@@- .@@@.@@%:@@@ @@@ %+ :+++- @*+++- | FaultyCat v0.0.1
.@*.=.+@@:=@@* %@@- .@@@.@@% @@@ @@@ %+ #%:.:## @%:.:## | by JahazielLem
.@@%*+*=. :@@%==@@@#-*@@#.@@% @@@-@@@ %+ @+ =@.@+ =@. | Company: PWNLabs - Electronics Cats
%@% :#@@@%*#@@@%+ %@* :#@@@#: =%#**=.*####@..*####: |
\x1b[0m"""
)
signal.signal(signal.SIGINT, signal_handler)
app()
View
10
FaultInjection/prereqs/FaultyCat/requirements.txt 0 → 100644
click==8.1.7
colorama
markdown-it-py
mdurl
Pygments==2.17.2
pyserial
rich==13.7.0
typer==0.9.0
typing_extensions
View
README.md 100644 → 0
View
SideChannel/ATtiny85_Timing_Attack/4_digit.ino 0 → 100644
View
SideChannel/ATtiny85_Timing_Attack/4_digit_attack.py 0 → 100644
View
SideChannel/ATtiny85_Timing_Attack/breadboard_setup.jpg 0 → 100644
View
SideChannel/ATtiny85_Timing_Attack/multi_digit.ino 0 → 100644
View
SideChannel/ATtiny85_Timing_Attack/multi_digit_attack.py 0 → 100644
Buy Me A Coffee