sudo apt update
sudo apt install qemu -y
In your SSH session, execute these commands:
sudo apt install python-pip -y
pip install gdown
.local/bin/gdown https://drive.google.com/uc?id=1msD8ukSdxwb6sOramc-UFcJ_BymtkT5c
sudo apt install unzip -y
unzip armv6_stretch.zip
cd armv6_stretch
cat start.sh
As you can see, the startup script
defines an "EXTRA_PORT" which maps
port 4444 on the Qemu emulated Arm
system to port 6987 on the host
Debian Linux system,
as shown below.
We'll use that port below for remote debugging.
In your SSH session, execute this command:
./start.sh
The emulated Raspberry Pi starts
up, and a couple of screens ot text
scroll by.
Log in with these credentials:
nano pwd.c
Enter this code,
as shown below:
#include <stdlib.h>
#include <stdio.h>
int test_pw() {
char password[10];
printf("Password address: %p\n", password);
printf("Enter password: ");
fgets(password, 50, stdin);
return 1;
}
void win() {
printf("You win!\n");
}
void main() {
if (test_pw()) printf("Fail!\n");
else win();
}
The interface is a little show and buggy.
Save the file with Ctrl+X, Y, Enter.
Now execute this command:
cat pwd.c
Make sure it's correct,
as shown below.
Now execute these commands:
gcc -g -o pwd pwd.c
./pwd
HELLO
The program runs, printing out
"HELLO", and then "Fail!",
as shown below:
./pwd
AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIJJJJ
The program
crashes
with a "Segmentation
fault",
as shown below:
In Qemu, at the "pi@raspberrypi:~$" prompt, execute this command:
gdbserver --multi :4444
Your Raspberry Pi is now
listening on port 4444,
as shown below:
Open an SSH session to this server and execute these commands to get "armgdb" ready:
sudo apt update
sudo apt install bzip2 build-essential gcc-multilib -y
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install libncurses5:i386 libc6-i386 lib32z1 -y
wget https://launchpad.net/linaro-toolchain-binaries/trunk/2012.12/+download/gcc-linaro-arm-linux-gnueabihf-4.7-2012.12-20121214_linux.tar.bz2
tar xjvf gcc-linaro-arm-linux-gnueabihf-4.7-2012.12-20121214_linux.tar.bz2
cp ./gcc-linaro-arm-linux-gnueabihf-4.7-2012.12-20121214_linux/bin/arm-linux-gnueabihf-gdb armgdb
./armgdb
target extended 10.128.0.9:6987
remote get /home/pi/pwd.c pwd.c
remote get /home/pi/pwd pwd
file pwd
set remote exec-file /home/pi/pwd
break main
run
list 1,20
You see the C source code for
"pwd.c",
as shown below:
disassemble main
Notice that the instruction after the
call to test_pw has address 0x00010544,
as shown below:
delete breakpoints
y
break 9
continue
AAAA
The program proceeds to the breakpoint,
as shown below.
On your Debian instance running gdb, execute this command to examine the stack:
x/10x $sp
As shown below,
the password is on the stack
(outlined in green) and the return
pointer is 16 bytes lower
(outlined in red).
On your Debian instance running gdb, execute this command to continue execution:
continue
run
In your Qemu session,
enter this password,
as shown below:
AAAABBBBCCCCDDDDEEEE
The program proceeds to the breakpoint,
as shown below.
On your Debian instance running gdb, execute this command to view the stack:
x/10x $sp
The return pointer now contains
0x45454545, or "EEEE",
as shown below.
On your Debian instance running gdb, execute this command to continue execution:
continue
The progran crashes, trying to execute
code at address
0x45454545,
as shown below.
disassemble win
As shown below,
this function is at address
0x0001051c
monitor exit
quit
y
nano winpwd
Enter this code into the file,
as shown below.
prefix = "AAAABBBBCCCCDDDD"
eip = "\x1c\x05\x01\x00"
print prefix + eip
Save the file with Ctrl+X,
Y, Enter.
Execute this command to write the output into a file:
python winpwd > winpwda
cat winpwda | ./pwd
You see the "You win!" message.
The flag is covered by a green rectangle
in the image below.