Hackvent 2024: Day 19

Hackvent 202440

[HV24.19] Santa's Workshop: A Technical Emergency

Santa's magical workshop is more modern than ever this year! In addition to the classic toys and presents, Santa has launched a major project: Old computers are to be repaired, cleaned and recycled for children all over the world. His aim is not only to spread the magic of Christmas, but also to protect the environment.

But just before the big celebration, there is a problem: One of the elves discovers that some of the computers have not been properly prepared. Confidential data from previous owners may have been left on them, and some devices are displaying strange error messages that could indicate hardware problems.

As the elves in the workshop have their hands full, Santa turns to you, his specialist in digital magic. You are given access to a magical virtual machine that simulates one of the affected computers. Your job is to make sure that the computer gets under the Christmas tree safely and on time.

After you start the PC, you can connect to it via SSH with the credentials root:santa on port 2222.
Start the service and get the flag.
Flag format: HV24{}

This challenge was written by darkstar. A web interface to control a VM that works out of the box, I'm happy.

Solution

Initial Analysis

We are granted root access to a virtual machine and are instructed to pay attention to hardware errors. We SSH into the machine and take some time to explore. The VM is a QEMU virtual machine with limited functionality. It is primarily powered by BusyBox.

We notice that the machine has a single disk with one partition:

$ fdisk -l /dev/sda
Found valid GPT with protective MBR; using GPT

Disk /dev/sda: 204800 sectors,  100M
Logical sector size: 512
Disk identifier (GUID): 2f6d5b26-1100-1e41-a58f-4b91958b3a0f
Partition table holds up to 128 entries
First usable sector is 2048, last usable sector is 204766

Number  Start (sector)    End (sector)  Size Name
     1            2048          204766 98.9M

After exploring the user directories, we notice an interesting .ack_history file located at /home/Santa/.ack_history, which contains a few commands the Santa user attempted to run. We notice that Santa tried to run ddrescue, suggesting there are issues with the disk. However, the ddrescue binary is not present on the machine. We do have access to the dd command though.

We run the following command to simulate dumping sectors from the /dev/sda disk:

$ dd if=/dev/sda of=/dev/null bs=512
dd: reading `/dev/sda': Input/output error

We encounter an input/output error. When using dd, we can also specify a count and skip parameter to skip over various sectors. Through trial and error, we discover that the disk errors only occur at the very end of the disk (the last few hundred sectors or so).

$ dd if=/dev/sda of=/tmp/data.img bs=512 count=20480 skip=0

$ dd if=/dev/sda of=/tmp/data.img bs=512 count=20480 skip=20480
...

$ dd if=/dev/sda of=/tmp/data.img bs=512 count=20480 skip=163840

$ dd if=/dev/sda of=/tmp/data.img bs=512 count=20480 skip=184320
dd: reading `/dev/sda': Input/output error

Further testing revealed the disk errors start shortly after the 198320 sector, which corresponds to the 101539840 byte offset. All sectors prior to this seem to be healthy.

Running ddrescue

Based on the fact that the Santa user ran ddrescue and that we have disk errors, we attempt to run ddrescue ourselves on the machine. To do this, we need to copy the ddrescue binaries to the virtual machine. We use the WinSCP application on Windows to complete the file transfer but scp from the command line would have also worked well. The ddrescue binary we used originated from a Ubuntu machine. The binary had dynamic links to libstdc++.so.6 so we also copied this library over to avoid compiling a statically linked version.

After we have copied the files to the /tmp directory, we run the commands:

$ cp /tmp/ddrescue /bin

$ chmod +x /bin/ddrescue

$ cp /tmp/libstdc++.so.6 /lib

We can now run ddrescue, so we run the following command:

$ ddrescue -d -i 101539840 /dev/sda /dev/null /tmp/mapfile

GNU ddrescue 1.27
Press Ctrl-C to interrupt
     ipos:  104792 kB, non-trimmed:   262144 B,  current rate:       0 B/s
     opos:  104792 kB, non-scraped:        0 B,  average rate:       0 B/s
non-tried:   983040 B,  bad-sector:        0 B,    error rate:       0 B/s
  rescued:    2072 kB,   bad areas:        0,        run time:          0s
pct rescued:   62.46%, read errors:        4,  remaining time:         n/a
                              time since last successful read:         n/a
Copying non-tried blocks... Pass 1 (forwards)
     ipos:  102498 kB, non-trimmed:   458752 B,  current rate:       0 B/s
     opos:  102498 kB, non-scraped:        0 B,  average rate:       0 B/s
non-tried:   262144 B,  bad-sector:        0 B,    error rate:       0 B/s
  rescued:    2596 kB,   bad areas:        0,        run time:          0s
pct rescued:   78.27%, read errors:        7,  remaining time:         n/a
                              time since last successful read:         n/a
Copying non-tried blocks... Pass 2 (backwards)
     ipos:  102957 kB, non-trimmed:   720896 B,  current rate:   2596 kB/s
     opos:  102957 kB, non-scraped:        0 B,  average rate:   2596 kB/s
non-tried:        0 B,  bad-sector:        0 B,    error rate:    655 kB/s
  rescued:    2596 kB,   bad areas:        0,        run time:          1s
pct rescued:   78.27%, read errors:       11,  remaining time:          1s
                              time since last successful read:          0s
Copying non-tried blocks... Pass 5 (forwards)
     ipos:  103117 kB, non-trimmed:        0 B,  current rate:   2596 kB/s
     opos:  103117 kB, non-scraped:   650752 B,  average rate:   2596 kB/s
non-tried:        0 B,  bad-sector:     1024 B,    error rate:    655 kB/s
  rescued:    2665 kB,   bad areas:        2,        run time:          1s
pct rescued:   80.35%, read errors:       13,  remaining time:          1s
                              time since last successful read:          0s
Trimming failed blocks... (forwards)
     ipos:  103117 kB, non-trimmed:        0 B,  current rate:   24064 B/s
     opos:  103117 kB, non-scraped:        0 B,  average rate:    166 kB/s
non-tried:        0 B,  bad-sector:   157184 B,    error rate:    1536 B/s
  rescued:    3160 kB,   bad areas:      187,        run time:         18s
pct rescued:   95.26%, read errors:      318,  remaining time:          0s
                              time since last successful read:         n/a
Scraping failed blocks... (forwards)
Finished

We specify an offset index of 101539840 bytes to speed up the process, knowing from our earlier trial and error that all the disk errors are beyond this point. We redirect the actual output to /dev/null as otherwise the VM would crash due to low disk space or high CPU/RAM usage. Finally, we specify a location for the mapfile which is the file of interest to solve this challenge.

After running the command we have a mapfile which looks like this:

# Mapfile. Created by GNU ddrescue version 1.27
# Command line: ddrescue -d -i 101539840 /dev/sda /tmp/out.img /tmp/mapfile
# Start time:   2024-12-19 14:22:25
# Current time: 2024-12-19 14:22:42
# Finished
# current_pos  current_status  current_pass
0x06257200     +               1
#      pos        size  status
0x00000000  0x060D6000  ?
0x060D6000  0x000E2400  +
0x061B8400  0x00000200  -
0x061B8600  0x00000600  +
0x061B8C00  0x00000200  -
0x061B8E00  0x00000200  +
0x061B9000  0x00000200  -
0x061B9200  0x00000800  +
0x061B9A00  0x00000200  -
0x061B9C00  0x00000400  +
0x061BA000  0x00000600  -
0x061BA600  0x00000800  +
0x061BAE00  0x00000600  -
0x061BB400  0x00000600  +
0x061BBA00  0x00000600  -
0x061BC000  0x00000A00  +
0x061BCA00  0x00000400  -
0x061BCE00  0x00000A00  +
0x061BD800  0x00000400  -
0x061BDC00  0x00000400  +
0x061BE000  0x00000200  -
0x061BE200  0x00001000  +
0x061BF200  0x00000400  -
0x061BF600  0x00000C00  +
0x061C0200  0x00000200  -
0x061C0400  0x00001E00  +
0x061C2200  0x00000800  -
0x061C2A00  0x00001400  +
0x061C3E00  0x00000200  -
0x061C4000  0x00000C00  +
0x061C4C00  0x00000600  -
0x061C5200  0x00002000  +
0x061C7200  0x00000400  -
0x061C7600  0x00000E00  +
0x061C8400  0x00000200  -
0x061C8600  0x00000600  +
0x061C8C00  0x00000200  -
0x061C8E00  0x00000200  +
0x061C9000  0x00000400  -
0x061C9400  0x00000600  +
0x061C9A00  0x00000200  -
0x061C9C00  0x00000200  +
0x061C9E00  0x00000200  -
0x061CA000  0x00000400  +
0x061CA400  0x00000200  -
0x061CA600  0x00000600  +
0x061CAC00  0x00000200  -
0x061CAE00  0x00000400  +
0x061CB200  0x00000400  -
0x061CB600  0x00000200  +
0x061CB800  0x00000200  -
0x061CBA00  0x00000400  +
0x061CBE00  0x00000200  -
0x061CC000  0x00000A00  +
0x061CCA00  0x00000400  -
0x061CCE00  0x00000A00  +
0x061CD800  0x00000200  -
0x061CDA00  0x00000600  +
0x061CE000  0x00000200  -
0x061CE200  0x00001000  +
0x061CF200  0x00000400  -
0x061CF600  0x00000C00  +
0x061D0200  0x00000200  -
0x061D0400  0x00002400  +
0x061D2800  0x00000200  -
0x061D2A00  0x00001400  +
0x061D3E00  0x00000200  -
0x061D4000  0x00000A00  +
0x061D4A00  0x00000200  -
0x061D4C00  0x00000400  +
0x061D5000  0x00000400  -
0x061D5400  0x00002200  +
0x061D7600  0x00000200  -
0x061D7800  0x00000C00  +
0x061D8400  0x00000200  -
0x061D8600  0x00000600  +
0x061D8C00  0x00000200  -
0x061D8E00  0x00000400  +
0x061D9200  0x00000200  -
0x061D9400  0x00000600  +
0x061D9A00  0x00000200  -
0x061D9C00  0x00000800  +
0x061DA400  0x00000200  -
0x061DA600  0x00000600  +
0x061DAC00  0x00000200  -
0x061DAE00  0x00000400  +
0x061DB200  0x00000400  -
0x061DB600  0x00000800  +
0x061DBE00  0x00000200  -
0x061DC000  0x00000800  +
0x061DC800  0x00000200  -
0x061DCA00  0x00000200  +
0x061DCC00  0x00000200  -
0x061DCE00  0x00000A00  +
0x061DD800  0x00000200  -
0x061DDA00  0x00000600  +
0x061DE000  0x00000200  -
0x061DE200  0x00000200  +
0x061DE400  0x00000400  -
0x061DE800  0x00000800  +
0x061DF000  0x00000200  -
0x061DF200  0x00000200  +
0x061DF400  0x00000200  -
0x061DF600  0x00000600  +
0x061DFC00  0x00000800  -
0x061E0400  0x00001400  +
0x061E1800  0x00000600  -
0x061E1E00  0x00000A00  +
0x061E2800  0x00000200  -
0x061E2A00  0x00000800  +
0x061E3200  0x00001400  -
0x061E4600  0x00000400  +
0x061E4A00  0x00000200  -
0x061E4C00  0x00000400  +
0x061E5000  0x00000400  -
0x061E5400  0x00000400  +
0x061E5800  0x00000200  -
0x061E5A00  0x00000200  +
0x061E5C00  0x00000400  -
0x061E6000  0x00000600  +
0x061E6600  0x00000600  -
0x061E6C00  0x00000A00  +
0x061E7600  0x00000200  -
0x061E7800  0x00000C00  +
0x061E8400  0x00000A00  -
0x061E8E00  0x00000400  +
0x061E9200  0x00000200  -
0x061E9400  0x00000400  +
0x061E9800  0x00000200  -
0x061E9A00  0x00000A00  +
0x061EA400  0x00000200  -
0x061EA600  0x00000600  +
0x061EAC00  0x00000200  -
0x061EAE00  0x00000200  +
0x061EB000  0x00000200  -
0x061EB200  0x00000200  +
0x061EB400  0x00000200  -
0x061EB600  0x00000800  +
0x061EBE00  0x00000200  -
0x061EC000  0x00000600  +
0x061EC600  0x00000200  -
0x061EC800  0x00000400  +
0x061ECC00  0x00000200  -
0x061ECE00  0x00000800  +
0x061ED600  0x00000200  -
0x061ED800  0x00000800  +
0x061EE000  0x00000400  -
0x061EE400  0x00000400  +
0x061EE800  0x00000200  -
0x061EEA00  0x00000400  +
0x061EEE00  0x00000200  -
0x061EF000  0x00000400  +
0x061EF400  0x00000200  -
0x061EF600  0x00000400  +
0x061EFA00  0x00000200  -
0x061EFC00  0x00000600  +
0x061F0200  0x00000200  -
0x061F0400  0x00001200  +
0x061F1600  0x00000200  -
0x061F1800  0x00000C00  +
0x061F2400  0x00000600  -
0x061F2A00  0x00000600  +
0x061F3000  0x00000400  -
0x061F3400  0x00000A00  +
0x061F3E00  0x00000200  -
0x061F4000  0x00000A00  +
0x061F4A00  0x00000200  -
0x061F4C00  0x00000200  +
0x061F4E00  0x00000200  -
0x061F5000  0x00000200  +
0x061F5200  0x00000200  -
0x061F5400  0x00000400  +
0x061F5800  0x00000400  -
0x061F5C00  0x00000400  +
0x061F6000  0x00000200  -
0x061F6200  0x00000200  +
0x061F6400  0x00000200  -
0x061F6600  0x00001000  +
0x061F7600  0x00000200  -
0x061F7800  0x00000C00  +
0x061F8400  0x00000200  -
0x061F8600  0x00000600  +
0x061F8C00  0x00000200  -
0x061F8E00  0x00000400  +
0x061F9200  0x00000400  -
0x061F9600  0x00000200  +
0x061F9800  0x00000200  -
0x061F9A00  0x00000800  +
0x061FA200  0x00000400  -
0x061FA600  0x00000600  +
0x061FAC00  0x00000400  -
0x061FB000  0x00000400  +
0x061FB400  0x00000200  -
0x061FB600  0x00000600  +
0x061FBC00  0x00000400  -
0x061FC000  0x00000600  +
0x061FC600  0x00000200  -
0x061FC800  0x00000400  +
0x061FCC00  0x00000200  -
0x061FCE00  0x00000600  +
0x061FD400  0x00000400  -
0x061FD800  0x00000800  +
0x061FE000  0x00000200  -
0x061FE200  0x00000600  +
0x061FE800  0x00000200  -
0x061FEA00  0x00000400  +
0x061FEE00  0x00000200  -
0x061FF000  0x00000400  +
0x061FF400  0x00000200  -
0x061FF600  0x00000400  +
0x061FFA00  0x00000200  -
0x061FFC00  0x00000600  +
0x06200200  0x00000200  -
0x06200400  0x00001400  +
0x06201800  0x00000200  -
0x06201A00  0x00000E00  +
0x06202800  0x00000400  -
0x06202C00  0x00000400  +
0x06203000  0x00000200  -
0x06203200  0x00000C00  +
0x06203E00  0x00000200  -
0x06204000  0x00000A00  +
0x06204A00  0x00000400  -
0x06204E00  0x00000400  +
0x06205200  0x00000200  -
0x06205400  0x00000400  +
0x06205800  0x00000200  -
0x06205A00  0x00000C00  +
0x06206600  0x00000200  -
0x06206800  0x00001000  +
0x06207800  0x00000400  -
0x06207C00  0x00000800  +
0x06208400  0x00000200  -
0x06208600  0x00000600  +
0x06208C00  0x00000200  -
0x06208E00  0x00000600  +
0x06209400  0x00000200  -
0x06209600  0x00000200  +
0x06209800  0x00000200  -
0x06209A00  0x00000600  +
0x0620A000  0x00000400  -
0x0620A400  0x00000800  +
0x0620AC00  0x00000200  -
0x0620AE00  0x00000600  +
0x0620B400  0x00000200  -
0x0620B600  0x00000400  +
0x0620BA00  0x00000400  -
0x0620BE00  0x00000600  +
0x0620C400  0x00000C00  -
0x0620D000  0x00000600  +
0x0620D600  0x00000200  -
0x0620D800  0x00000800  +
0x0620E000  0x00000200  -
0x0620E200  0x00000600  +
0x0620E800  0x00000200  -
0x0620EA00  0x00000200  +
0x0620EC00  0x00000C00  -
0x0620F800  0x00000200  +
0x0620FA00  0x00000200  -
0x0620FC00  0x00000600  +
0x06210200  0x00000200  -
0x06210400  0x00001600  +
0x06211A00  0x00000400  -
0x06211E00  0x00000C00  +
0x06212A00  0x00000200  -
0x06212C00  0x00000400  +
0x06213000  0x00000200  -
0x06213200  0x00000C00  +
0x06213E00  0x00000200  -
0x06214000  0x00000A00  +
0x06214A00  0x00000200  -
0x06214C00  0x00000600  +
0x06215200  0x00000200  -
0x06215400  0x00000400  +
0x06215800  0x00000200  -
0x06215A00  0x00000E00  +
0x06216800  0x00000400  -
0x06216C00  0x00000A00  +
0x06217600  0x00000200  -
0x06217800  0x00000C00  +
0x06218400  0x00000200  -
0x06218600  0x00000600  +
0x06218C00  0x00000200  -
0x06218E00  0x00000600  +
0x06219400  0x00000400  -
0x06219800  0x00000600  +
0x06219E00  0x00000400  -
0x0621A200  0x00000A00  +
0x0621AC00  0x00000200  -
0x0621AE00  0x00000400  +
0x0621B200  0x00000400  -
0x0621B600  0x00000200  +
0x0621B800  0x00000400  -
0x0621BC00  0x00001000  +
0x0621CC00  0x00000200  -
0x0621CE00  0x00000A00  +
0x0621D800  0x00000200  -
0x0621DA00  0x00000600  +
0x0621E000  0x00000200  -
0x0621E200  0x00000400  +
0x0621E600  0x00000400  -
0x0621EA00  0x00000A00  +
0x0621F400  0x00000200  -
0x0621F600  0x00000400  +
0x0621FA00  0x00000200  -
0x0621FC00  0x00000400  +
0x06220000  0x00000400  -
0x06220400  0x00001800  +
0x06221C00  0x00000400  -
0x06222000  0x00000800  +
0x06222800  0x00000200  -
0x06222A00  0x00000600  +
0x06223000  0x00000400  -
0x06223400  0x00000A00  +
0x06223E00  0x00000200  -
0x06224000  0x00000A00  +
0x06224A00  0x00000200  -
0x06224C00  0x00000400  +
0x06225000  0x00000400  -
0x06225400  0x00000400  +
0x06225800  0x00000200  -
0x06225A00  0x00001000  +
0x06226A00  0x00000400  -
0x06226E00  0x00000800  +
0x06227600  0x00000200  -
0x06227800  0x00000C00  +
0x06228400  0x00000200  -
0x06228600  0x00000600  +
0x06228C00  0x00000200  -
0x06228E00  0x00000600  +
0x06229400  0x00000400  -
0x06229800  0x00000600  +
0x06229E00  0x00000A00  -
0x0622A800  0x00000600  +
0x0622AE00  0x00000600  -
0x0622B400  0x00000400  +
0x0622B800  0x00000A00  -
0x0622C200  0x00000A00  +
0x0622CC00  0x00000200  -
0x0622CE00  0x00000A00  +
0x0622D800  0x00000200  -
0x0622DA00  0x00000600  +
0x0622E000  0x00000800  -
0x0622E800  0x00000C00  +
0x0622F400  0x00000200  -
0x0622F600  0x00000400  +
0x0622FA00  0x00000600  -
0x06230000  0x00000200  +
0x06230200  0x00000200  -
0x06230400  0x00001200  +
0x06231600  0x00000800  -
0x06231E00  0x00000400  +
0x06232200  0x00000600  -
0x06232800  0x00000A00  +
0x06233200  0x00000800  -
0x06233A00  0x00000600  +
0x06234000  0x00000600  -
0x06234600  0x00000600  +
0x06234C00  0x00000600  -
0x06235200  0x00000600  +
0x06235800  0x00000200  -
0x06235A00  0x00000A00  +
0x06236400  0x00000800  -
0x06236C00  0x00000A00  +
0x06237600  0x00000200  -
0x06237800  0x00006000  +
0x0623D800  0x00000200  -
0x0623DA00  0x00009C00  +
0x06247600  0x00000200  -
0x06247800  0x00006000  +
0x0624D800  0x00000400  -
0x0624DC00  0x00002A00  +
0x06250600  0x00000E00  -
0x06251400  0x00005E00  +
0x06257200  0x00000400  -
0x06257600  0x001A8A00  +

The CTF author hints to us that the mapfile can be visualised. It turns out that GDDRescuebiew is a useful graphical tool that can visualise a mapfile using blocks. We install this on our own Linux system and open our mapfile with the GUI tool. This displays a bunch of green and red blocks at the end of the file corresponding to good and bad sectors. By resizing our window to find the optimal arrangement of blocks we are able to see that the bad sectors (red blocks) spell out the flag for today:

Hackvent 2024 - Day 19 - DDRescueview Flag

Flag:

HV24{b4d_s3ct0rs}

Leave a comment

(required)(will not be published)(required)

Comments

There are no comments yet. Be the first to add one!