Skip to content

Mistery Challenge #5

@iledesma08

Description

@iledesma08

How to Solve the Secret

1. Identify if secret is encoded

  • For this, we wrote file secret
  • The result was secret: ASCII text
    • Now we know that the file contains ASCII text
  • Even so, we need to analyze the content by ourselves. For this, we can write head secret, which gives us
H4sICEjNJmcAA3Byb2dyYW0A7Vx7cBvHed8DeCQokiD4FClKFmRLtvwgSFAyRVGWBYgPgRL1pEi9
dQSBI4EIrwIHWvQjVqz4QT9aOUldN5UjOZ5xk4zSuk2reOzapq2MLbdux+4j1ngyLRtHrRQ/Ssd2
LNuy0O/b2z3cHQHZk3Sm/2Al3Lffb7/v228fd9y92907e/p7LYJAeLCQmwlyUw4P5T0MP7ReEwGs
g1TA9WqyhBQDX6ST8xCPgZ6xEAO1MTkr02uwqnyD1WOg85kcp4KOFhF98Bjo0yXEQIkjqyfqeMLK
x+njzA9O9Xo0PyfDnR4D/QUrF6d6PaybmWaVn1ntMVCFyd9n0rMwPeJi+M0eA51mFcEpr88i9utg
/neweuRUc5/k1tvJ9HYyeU67mVy3Th7DwFkl+Lvkt4XpnVik8icWeQw0X35bQa+YfPXAm3kbyy9f
OzhY/XPK+1lLJDzSvrwlEmyOhGPpg80HO9qb25e7UnFXm+YX5oF9at2mQWI5RKYQ490H47WMx/Rn
zq5/6835T/16QfSJwb4Rec3wHT98ldsQmAxh8rxLEBa3k2x/ImuRcVCsEn7XLnhw/mTqvrJ89fBH
8KvOgY/nwbfmwTF/Zw78D/LI35UHfyQPHsiDL8iT7/o88rflwW/IY2cyj/zX4FdFGknI46E877+9
VN5OnqxS8Xu4gtS3faMUlJPyWDilyMntG7si8Zi83T8SkYkkjUXjMSml+JOKJKmiOQVH43ES9Uci
  • The content is only alphanumeric characters with + and /. A Base64 kind of file looks like this.

2. Decode the secret from the recognized file type

  • We write base64 -d secret > decoded_secret.
    • -d flag tells Linux to decode the content of secret using base64 format

3. Identify what the secret really is

  • Now that we've decoded the secret, we need to check the type of the decoded file, for this do file decoded_secret inside the terminal, from which we get:
decoded_secret: gzip compressed data, from Unix, original size modulo 2^32 51200
  • Behind the layed of Base64 encoding we can see that its just a compressed archive that uses gzip as the outer compression layer. We can see its content without extraction using file -z decoded_secret, that outputs the following:
decoded_secret: POSIX tar archive (GNU) (gzip compressed data, from Unix)

4. Extract the contents of decoded_secret

  • Now that we've identified that decoded_secret is a compressed archive, we can decompress it using tar xvzf decoded_secret.
    • tar: Calls the tar command, which is used for creating, extracting, and managing tar archives.
    • x: Extracts the contents of the archive.
    • v: Displays the progress in the terminal (verbose mode), showing the names of files as they’re extracted.
    • z: Specifies that the archive is compressed with gzip (a .gz file).
    • f: Indicates that the following argument, decoded_secret, is the name of the file to operate on.
  • After doing this, the terminal gives us the next output:
87014aef1d77646b/
87014aef1d77646b/pendrive_image.bmp.gz
87014aef1d77646b/program.gz
  • This means that the content of decoded_secret has been extracted to a folder called 87014aef1d77646b with contents inside. These are two single compressed files that we can decompress with gzip, as follows:

    • gzip -d 87014aef1d77646b/program.gz
    • gzip -d 87014aef1d77646b/pendrive_image.bmp.gz

5. Analyze the program executable

Before doing anything risky and compromise our system, we should check what the executable contains, for this we can do the following:

  • strings program: displays any readable strings within the binary, which can sometimes provide hints about its functionality
  • file program: displays information about the file.
    • This will let us see that our file is just an ELF Executable
    • We get the following:
    program: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=bae54adad71cb0ea1d6da3554962653f607da9c9, for GNU/Linux 3.2.0, with debug_info, not stripped
  • objdump -x program: To display information about sections, headers, and other low-level details
  • ldd program: To check the shared libraries the executable depends on
  • (Not recommended) gdb program: If you want to debug or step through the program’s execution, you can load it into the GNU debugger. This isnt recommended yet because you should never execute something without knowing what it does.

From all of these options, the one that takes our attention is ldd program, which gives us:

linux-vdso.so.1 (0x00007fffe49d4000)
lib87014aef.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007c8874600000)
/lib64/ld-linux-x86-64.so.2 (0x00007c8874982000)
  • Now we can see that there are no unresolved dependencies except one called lib87014aef.so. We need to figure out what this library is and how we can obtain it.

6. Obtaining info from the image

  • One could think that the remaining info is inside the pendrive_image.bmp file, and to be sure we can run grep 'ELF' *.

    • This confirms that this image has a binary file inside, that could be our missing library
    • From this command we get
    grep: pendrive_image.bmp: binary file matches
    grep: program: binary file matches
  • To discover exactly what’s in a file without being able to rely on any standard assumptions about the file contents, you’ll have to analyze it at the byte level. To do this, you can use any numeric system to display bits and bytes on the screen. For instance, you could use the binary system, displaying all the ones and zeros individually. But because that makes for some tedious analysis, it’s better to use the hexadecimal system

    • To display the bytes of a file in hexadecimal representation, you use a hex-dumping program like xxd. Therefore, now we write xxd pendrive_image.bmp in our terminal, but to simplify things and considering the library we need surely starts with 0x7f45 (ELF start magic sequence), we can run xxd pendrive_image.bmp | grep 7f45, where we get:
      00006f30: 3631 3731 2629 7f45 4c46 0201 0100 0000  6171&).ELF......
      0000abc0: 0000 0000 0000 7f45 4c46 0201 0100 0000  .......ELF......
    • This way, the ELF files appear on directions 0x6f36 = 28470 and abc0 = 43974
    • We dont know which one of these two ELF files is our library and either way, we dont know where these files end. To find out both things, we extract a header from each ELF file, for that we write dd skip=28470 count=64 if=pendrive_image.bmp of=header1 bs=1 and dd skip=43974 count=64 if=pendrive_image.bmp of=header2 bs=1
    • Now, to see the extend of each file, we use readelf -h header1:
      ELF Header:
        Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
        Class:                             ELF64
        Data:                              2's complement, little endian
        Version:                           1 (current)
        OS/ABI:                            UNIX - System V
        ABI Version:                       0
      readelf: Error: Too many program headers - 0x9 - the file is not that big
        Type:                              DYN (Shared object file)
        Machine:                           Advanced Micro Devices X86-64
        Version:                           0x1
        Entry point address:               0x0
        Start of program headers:          64 (bytes into file)
        Start of section headers:          13712 (bytes into file)
        Flags:                             0x0
        Size of this header:               64 (bytes)
        Size of program headers:           56 (bytes)
        Number of program headers:         9
        Size of section headers:           64 (bytes)
        Number of section headers:         28
        Section header string table index: 27
      readelf: Error: Reading 1792 bytes extends past end of file for section headers
      readelf: Error: Too many program headers - 0x9 - the file is not that big
    • And readelf -h header2:
      ELF Header:
        Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
        Class:                             ELF64
        Data:                              2's complement, little endian
        Version:                           1 (current)
        OS/ABI:                            UNIX - System V
        ABI Version:                       0
      readelf: Error: Too many program headers - 0x9 - the file is not that big
        Type:                              DYN (Shared object file)
        Machine:                           Advanced Micro Devices X86-64
        Version:                           0x1
        Entry point address:               0x1070
        Start of program headers:          64 (bytes into file)
        Start of section headers:          48184 (bytes into file)
        Flags:                             0x0
        Size of this header:               64 (bytes)
        Size of program headers:           56 (bytes)
        Number of program headers:         9
        Size of section headers:           64 (bytes)
        Number of section headers:         35
        Section header string table index: 34
      readelf: Error: Reading 2240 bytes extends past end of file for section headers
      readelf: Error: Too many program headers - 0x9 - the file is not that big
    • From this, what matters is Start of section headers (e_shoff), Size of section headers (e_shentsize = 64) y Number of section headers (e_shnum. We will use all these things in the next formula:
      $$ size = e_{shoff} + (e_{shnum} * e_{shentsize}) $$
      $$ size_{header1} = 13712 + (28 * 64) = 15504 $$
      $$ size_{header2} = 48184 + (35 * 64) = 50424 $$
  • With this, we can reconstruct the whole library because now we know where it ends. We can do use with the command dd skip=28470 count=15504 if=pendrive_image.bmp of=lib87014aef.so bs=1 or dd skip=43974 count=50424 if=pendrive_image.bmp of=lib87014aef.so bs=1, where we use of=lib87014aef.so because it is the name of the library thats missing.

  • To see if the extraction was succesful and if we extracted the right library, we can do readelf -hs lib87014aef.so. We try this command with each header, and the one that seems to be our missing library is header2, so lets stick with that.

7. Loading the Library

  • Now that we have our library, we need to link it with program somehow. For that, we use export LD_LIBRARY_PATH=`pwd`
  • Now, when we do ./program, we get:
Loading system...OK
Starting encrypting system...OK
Starting collect sensitive information system...FAIL
Segmentation fault (core dumped)

8. Solving the secret

  • The next steps involve debugging the given code with gdb ./program and reading the debug symbols, so we can reproduce the program elsewhere and use the hint about PI that we found on the room.
    • The segmentation fault is caused because theres a free of an object before using the object (thats what we should see when debugging)
    • For solving the secret, we use backtrace and coredumps (besides the gdb tool)
    • In the end, the secret was related to something like "you shouldnt free before using" I think, I do not remember now (we did it in class after some time trying, but we cant see the debug symbols inside the given program and that makes the secret impossible to solve)

Metadata

Metadata

Assignees

Labels

taskIndividual tasks within a project.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions