Official description
I sealed my master phassphrase on this device and protected it using my own TOTP algorithm. Can you recover it ?
Once ready, come to the organizers desk to validate your solution on the device. (No connection to the device allowed)
We are given a challenge.elf
file.
Exploration
The challenge.elf
file
First, let’s confirm it is an ELF file:
$ file challenge.elf
challenge.elf: ELF 32-bit LSB executable, Tensilica Xtensa, version 1 (SYSV), statically linked, with debug_info, not stripped
We note that it is not stripped and includes debug information. The architecture is unusual, it uses Tensilica Xtensa instructions set. We now look at some strings in the file:
$ strings -n10 challenge.elf
esp-idf: v4.4.3 6407ecb3f8
arduino-lib-builder
Dec 20 2022
[...]
axp: esp32 power voltage was set to 3.35v
[...]
M5Core2 initializing...
[...]
/home/azox/.arduino15/packages/m5stack/hardware/esp32/2.0.6/cores/esp32/esp32-hal-uart.c
/home/azox/git_repos/INS23_Spatial_TOTP/firmware/src/ins23_spatial_totp
/home/azox/Arduino/libraries/M5Core2/src/AXP192.cpp
/home/azox/Arduino/libraries/M5Core2/src/M5Core2.cpp
/home/azox/Arduino/libraries/M5Core2/src/M5Display.cpp
/home/azox/Arduino/libraries/M5Core2/src/M5Touch.cpp
/home/azox/Arduino/libraries/M5Core2/src/RTC.cpp
/home/azox/Arduino/libraries/M5Core2/src/Speaker.cpp
/home/azox/Arduino/libraries/M5Core2/src/utility/CommUtil.cpp
/home/azox/Arduino/libraries/M5Core2/src/utility/In_eSPI.cpp
/home/azox/Arduino/libraries/M5Core2/src/utility/M5Button.cpp
/home/azox/Arduino/libraries/M5Core2/src/utility/M5Timer.cpp
/home/azox/Arduino/libraries/M5Core2/src/utility/MPU6886.cpp
/home/azox/Arduino/libraries/M5Core2/src/utility/PointAndZone.cpp
/home/azox/Arduino/libraries/M5Core2/src/utility/Sprite.cpp
/home/azox/Arduino/libraries/M5Core2/src/utility/quaternionFilters.cpp
/home/azox/Arduino/libraries/TOTP_library/src/TOTP.cpp
/home/azox/Arduino/libraries/TOTP_library/src/sha1.cpp
From these strings, we known that the ELF file is a firmware for the M5Core2. It is based on an ESP32 and is using the Arduino framework with the TOTP library.
The mysterious device
We get a look at the device near the organizers desk. There is no keyboard to enter the TOTP. After moving the device around, we notice that we can only enter 6 digits between 0 and 3 by rotating the device around two axes.
Proposed solution
We start by opening the firmware in Ghidra, then we reverse the TOTP code computation and extract its HMAC key.
Firmware analysis
As of March 2023, Ghidra does not officially support Xtensa instruction set, but a community processor definition exists at https://github.com/Ebiroll/ghidra-xtensa. After installing this processor, Ghidra is able to import the firmware successfully.
As it is using the Arduino framework, we find a setup()
and loop()
functions.
The setup function initializes the M5Core2, an EEPROM, a MPU6886 inertial
measurement unit, a TFT screen and an RTC.
The loop function starts by getting a timestamp in seconds, then calls TOTP::getCode(&totp, timestamp)
.
It then transforms the output into a code_sequence
.
The remaining of the function displays information on the screen and manage
the sequence input and verification.
TOTP HMAC key extraction
Using Ghidra and TOTP library source code, we reimplement TOTP::getCode
in Python.
Then we implement the same transformation to get a TOTP code with 6 digits between 0 and 3.
The TOTP library needs a HMAC key. By looking at &totp
structure references,
we find _GLOBAL__sub_I_prev_state
function that sets the key to eed2976a1dcb29e02e42
and the timestep to 60
:
|
|
We can now write the following Python script:
|
|
We then run this script and enter the sequence:
We get the following flag: INS{0r13nt3d_T1m3d_P455wd}
.