diff --git a/.gitignore b/.gitignore index 2064707..b8e1744 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .micropico PiPicoPATLFGGGGG.code-workspace main_dev.py +ComicCode-Regular.* \ No newline at end of file diff --git a/COPYING.txt b/COPYING.txt new file mode 100644 index 0000000..a4bb4d4 --- /dev/null +++ b/COPYING.txt @@ -0,0 +1,12 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. + diff --git a/README.md b/README.md index fb423a0..829ba9d 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A tool for simplifying power analysis attacks against other gadgets. Built on the Raspberry Pi Pico W, it runs a PWM channel to do manual clock control on the nugget you're hacking, and then reads an ADC channel to measure voltage used at each clock cycle. -## Installataion +## Installation Make sure you have Micropython installed on your Pico W. Open up your Pico W in your favorite IDE (Thonny and VS Code are commonly used) and upload main.py. If you're having trouble, see the official [Raspberry Pi Pico W Getting Started Page](https://projects.raspberrypi.org/en/projects/get-started-pico-w) @@ -74,4 +74,19 @@ For #2, we need to remove the builtin crystal oscilator and replace that connect For this example, I will describe a firmware decryption power analysis attack. -Scenario: You have and ESP32-S3 based device with flash and bootloader encryption set up on it. You Can remove the RF sheield and get a raw dump of the flash chip with a SOP8 test clip and a programmer, but the data is encrypted. \ No newline at end of file +Scenario: You have and ESP32-S3 based device with flash and bootloader encryption set up on it. You Can remove the RF sheield and get a raw dump of the flash chip with a SOP8 test clip and a programmer, but the data is encrypted. + +## Method +1) We disassemble the device to the bare board we're interested in +2) Then remove the RF shield and crystal oscilator from the ESP32-S3 via reflow +3) Clip a SOP8 test clip on the 8pin flash chip and dump the encrypted data with a programmer like a CH431a or T48 +4) Set up the breadboard with the Pico W. +5) Place the clock_pulse_pin probe where the crystal oscillator used to be +6) Place power_analysis_pin probe on the rawest vin power spot you can find +7) Run the Pico W (see Usage) +8) Dump serial data to some manner of logger Todo: figure out this tooling +9) Perform statistical attack to dump key! Todo: automate and figure out tooling + +Distributed under the [WTFPL - The Do What the Fuck You Want to Public License](http://www.wtfpl.net/) +See [COPYING.txt](COPYING.txt) +![WTFPL](resources/wtfpl.png) \ No newline at end of file diff --git a/main.py b/main.py index 3130395..6093879 100644 --- a/main.py +++ b/main.py @@ -4,7 +4,7 @@ import machine import utime import _thread import math -import os +#import os # gpio pin to read power analysis off of (int) @@ -33,6 +33,7 @@ def do_pwm(outpin = 20, duty_cycle = 0.5, frequency = 2000): pwm_pin.duty_u16(pwm_duty) print(f"Clock Pulses Running\n\tGPIO Pin: {outpin}\n\tDuty Cycle: {percent_duty}%\n\tFrequency: {frequency}Hz") +# us of sleep calculate4d by floor(1000000 / (frequency_in_Hz * samples_per_pulse)) def us_samples(frequency, samples_per_pulse): return math.floor(1000000/(frequency*samples_per_pulse)) @@ -53,52 +54,71 @@ def do_adc(adcpin=28, duty_cycle = 0.5, frequency = 2000, samples_per_pulse = 10 # == HTTP Stuff == # # HTML template for the webpage -def default_webpage(): - template = f""" +header = f""" - Power Analysis Tool LFGGGGg + SillyFilly Pi Pico Power Analysis Tool (LFFGGGGG) + + -

SillyFilly Pi Pico Power Analysis Tool (LFFGGGGG)

+""" + +footer = f""" + + +""" + +def default_webpage(): + template = f""" + {header}
- Clock Control Config
- 50% Duty Cycle (% of time clock is on)

- Frequency (Hz aka number of pulses per second)

- Samplerate Config:
- Samples Per Manual Clock Pulse

+

SillyFilly Pi Pico Power Analysis Tool (LFFGGGGG)

+ Config:
+ Duty Cycle
50%

+ Frequency (Hz)


+ Samples Per Clock Pulse:


- - + {footer} """ return str(template) -# us of sleep calculate4d by floor(1000000 / (frequency_in_Hz * samples_per_pulse)) def running_webpage(outpin = 20, adcpin = 28, duty_cycle = 0.5, frequency = 2000, samples_per_pulse = 100): dutyy = duty_cycle*100 us_sample = us_samples(frequency, samples_per_pulse) template = f""" - - - - RUNNING - Power Analysis Tool LFGGGGg - - - + {header} +

SillyFilly Pi Pico Power Analysis Tool (LFFGGGGG)

WE RUNNING NOWWWWW LFGGGGGGGGGGGGG

@@ -110,8 +130,8 @@ def running_webpage(outpin = 20, adcpin = 28, duty_cycle = 0.5, frequency = 2000 Delay Between Samples: {us_sample}us

LFGGGGGGGG FRONG

- - +
+ {footer} """ return str(template) @@ -137,7 +157,6 @@ if wlan.status() != 3: else: print('Connection successful!') network_info = wlan.ifconfig() - #print('IP address:', network_info[0]) print(f"\n\nOpen web browser and navigate to http://{network_info[0]}\n\n") # Set up socket and start listening @@ -187,10 +206,10 @@ while True: response = running_webpage() - else: + else: response = default_webpage() - # Send the HTTP response and close the connection + # Send the HTTP response and close the conn conn.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n') conn.send(response) conn.close() diff --git a/resources/index.png b/resources/index.png new file mode 100644 index 0000000..08f6764 Binary files /dev/null and b/resources/index.png differ diff --git a/resources/running.png b/resources/running.png new file mode 100644 index 0000000..abbb32b Binary files /dev/null and b/resources/running.png differ diff --git a/resources/wtfpl.png b/resources/wtfpl.png new file mode 100644 index 0000000..d039d0b Binary files /dev/null and b/resources/wtfpl.png differ