CSAW'19: beleaf

Finding the address of the "main" function

GDB

  • We can see that the entry point for the program is at 0x6f0

  • Refer to the link above for the full sequence of steps to perform, to discover the address of the main function directly from GDB

Ghidra

Open up the binary in Ghidra, and open the Functions tab under the "Symbol Tree" section. We can see a function named entry:

  • We can see a call to the __libc_start_main function. The first argument as FUN_001008a1 is the address of the main function.

"main" before refinement

a. local_98: variable that stores user string input

b. sVar1: integer value indicating length of user input

c. &DAT_003014e0: value within the .bss (or .data array during runtime), which stores the series of integer values to satisfy the condition (used for checking purposes within the FUN_001007fa function -more below)

  • As we can see from the memory (and also since + local_b0 * 8 is used in the code to address), we know that the characters are in offsets of 8

  • The first value at 0x3014e0 is 0x01 -> 1

  • The second value at 0x3014e0 + 8 = 0x3014e8 is 0x9 -> 9

  • The third value at 0x3014e8 + 8 = 0x3014f0 is 0x11 -> 17

  • etc.

"main" after refinement

Analysis of "main" function

1. First IF statement

  • This simply ensures that the length of the input string is 0x21 (33 bytes)

2. For loop

  • Simply, given an input character (each index of the input string) to the FUN_00107fa function, a value stored in the lVar2 variable will be retrieved and compared to memory address within &DAT_003014e0

"FUN_001007fa" before refinement

a. &DAT_00301020: value within the .bss (or .data array during runtime), which stores the series of characters to form the final flag (required input string)

  • As we can see from the memory (and also since + local_10 * 4 is used in the code to address), we know that the characters are in offsets of 4

"FUN_001007fa" after refinement

Main purpose of the FUN_001007a function

Given an input value in the param_1 variable, we need to find a value that fails the second condition in the while loop, to exit and return from the function:

  • Simply, we need to find a value for the local_10 variable that will equate param_1 to be equals to *(int *)(&DAT_00301020 + local_10 * 4))

    • Notice that the final value of the local_10 variable is returned from function when the while loop exits

    • Thus, we can ignore the logic within the while loop itself

  • Notice that the return value of local_10 will be stored in the lVar2 variable in the main function

  • Thus, we can discover the values required for the local_10 by enumerating the values from DAT_003014e0 in the main function

Steps to retrieve the flag

  • The following shows the steps taken in iterating through each value of local_b0 in the main function

(1) local_b0 = 0

a. local_bo * 8 = 0 * 8 = 0

b. From DAT_003014e @ offset 0-> 0x01 -> 1

c. Substitute value 1 into local_10 (FUN_00107fa):

  • local_10 * 4 = 1 * 4 = 4 (decimal)

  • From DAT_00301020 @ offset 4-> 00301024 -> 0x66 -> f

(2) local_b0 = 1

a. local_bo * 8 = 1 * 8 = 0

b. From DAT_003014e @ offset 8 -> 003014e8 -> 0x09 -> 9

c. Substitute value 9 into local_10 (FUN_00107fa):

  • local_10 * 4 = 9 * 4 = 36 (decimal)

  • From DAT_00301020 @ offset 36 -> 0x00301044 -> 0x6c -> l

(3) Peform the same series of steps until we eventually find the final string value!

Last updated